/// <summary> /// Builds payment URI /// </summary> /// <param name="processingUri">Base processing URI</param> /// <param name="paymentMethod">Payment method</param> /// <param name="language">Payment form language</param> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <param name="redirectParameters">Redirect parameters</param> /// <param name="customData">Custom data parameters</param> /// <returns>Payment form URI</returns> private static string BuildUri( Uri processingUri, PaymentMethod paymentMethod, Language language, MerchantSettings merchantSettings, OrderInfo orderInfo, RedirectParameters redirectParameters, NameValueCollection customData) { if (processingUri == null) { throw new ArgumentNullException(nameof(processingUri)); } if (merchantSettings == null) { throw new ArgumentNullException(nameof(merchantSettings)); } if (orderInfo == null) { throw new ArgumentNullException(nameof(orderInfo)); } var uriBuilder = new UriBuilder(processingUri) { Path = GetLanguagePath(language) + GetPaymentMethodPath(paymentMethod), Query = GetQuery(merchantSettings, orderInfo, redirectParameters, customData), }; return(uriBuilder.ToString()); }
/// <summary> /// Initializes a new instance of the <see cref="PaymentUri"/> class /// </summary> /// <param name="processingUri">Base processing URI</param> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <param name="paymentMethod">Payment method</param> /// <param name="language">Form language</param> /// <param name="redirectParameters">Redirect parameters</param> /// <param name="customData">Additional custom data</param> public PaymentUri( Uri processingUri, MerchantSettings merchantSettings, OrderInfo orderInfo, PaymentMethod paymentMethod = PaymentMethod.Card, Language language = Language.Russian, RedirectParameters redirectParameters = null, NameValueCollection customData = null) : base(BuildUri(processingUri, paymentMethod, language, merchantSettings, orderInfo, redirectParameters, customData)) { }
/// <summary> /// Initializes a new instance of the <see cref="SecurityKey"/> class /// </summary> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <param name="transactionId">Transaction unique identifier</param> /// <param name="transactionDateTime">Transaction date time</param> internal SecurityKey(MerchantSettings merchantSettings, OrderInfo orderInfo, int transactionId, DateTime transactionDateTime) { if (merchantSettings == null) { throw new ArgumentNullException(nameof(merchantSettings)); } if (orderInfo == null) { throw new ArgumentNullException(nameof(orderInfo)); } this.Value = CalculateKey(merchantSettings, orderInfo, transactionId, transactionDateTime); }
/// <summary> /// Calculates security key /// </summary> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <param name="transactionId">Transaction unique identifier</param> /// <param name="transactionDateTime">Transaction date time</param> /// <returns>Security key</returns> private static string CalculateKey(MerchantSettings merchantSettings, OrderInfo orderInfo, int transactionId, DateTime transactionDateTime) { var datetimeChunk = FormattableString.Invariant($"DateTime={transactionDateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)}"); var transactiondIdChunk = FormattableString.Invariant($"&TransactionID={transactionId}"); var orderIdChunk = FormattableString.Invariant($"&OrderId={orderInfo.OrderId}"); var amountChunk = FormattableString.Invariant($"&Amount={orderInfo.Amount.ToString("#.00", CultureInfo.InvariantCulture)}"); var currencyChunk = FormattableString.Invariant($"&Currency={orderInfo.Currency.ToUpperInvariant()}"); var keyChunk = FormattableString.Invariant($"&PrivateSecurityKey={merchantSettings.Key}"); return(CalculateMd5Hash(FormattableString.Invariant($"{datetimeChunk}{transactiondIdChunk}{orderIdChunk}{amountChunk}{currencyChunk}{keyChunk}"))); }
/// <summary> /// Initializes a new instance of the <see cref="CallbackData"/> class /// </summary> /// <param name="callbackQuery">Callback query</param> /// <param name="merchantSettings">Merchant settings</param> public CallbackData(NameValueCollection callbackQuery, MerchantSettings merchantSettings) { if (callbackQuery == null) { throw new ArgumentNullException(nameof(callbackQuery)); } this.TransactionId = ParseInt(callbackQuery, "TransactionId"); this.TransactionDate = ParseDateTime(callbackQuery, "DateTime"); this.OrderInfo = new OrderInfo(callbackQuery["OrderId"], ParseDecimal(callbackQuery, "Amount"), callbackQuery["Currency"]); this.PaymentAmount = ParseDecimal(callbackQuery, "PaymentAmount"); this.PaymentCurrency = callbackQuery["PaymentCurrency"]; this.MaskedCardNumber = callbackQuery["CardNumber"]; this.CardholderName = callbackQuery["CardHolder"]; this.Issuer = callbackQuery["BankName"]; this.AuthorizationCode = callbackQuery["AuthCode"]; this.BankTransactionId = callbackQuery["GatewayTransactionId"]; this.EcommerceIndicator = GetEcommerceIndicator(callbackQuery["ECI"]); this.CardEnrollmentStatus = GetCardEnrollmentStatus(callbackQuery["ThreedsEnrollment"]); this.CountryCode = callbackQuery["Country"]; this.City = callbackQuery["City"]; this.StreetAddress = callbackQuery["Address"]; this.ZipCode = callbackQuery["Zip"]; this.Phone = callbackQuery["Phone"]; this.Email = callbackQuery["Email"]; IPAddress ip; this.IPAddress = IPAddress.TryParse(callbackQuery["IpAddress"], out ip) ? ip : null; this.IPCountryCode = callbackQuery["IpCountry"]; this.BinCountryCode = callbackQuery["BinCountry"]; this.SpecialConditions = callbackQuery["SpecialConditions"]; this.RebillAnchor = callbackQuery["RebillAnchor"]; this.DeclineCode = string.IsNullOrEmpty(callbackQuery["Code"]) ? (int?)null : ParseInt(callbackQuery, "Code"); this.ErrorCode = string.IsNullOrEmpty(callbackQuery["ErrorCode"]) ? (int?)null : ParseInt(callbackQuery, "ErrorCode"); var securityKey = new SecurityKey(merchantSettings, this.OrderInfo, this.TransactionId, this.TransactionDate).Value; if (callbackQuery["SecurityKey"] != securityKey) { throw new SecurityException(FormattableString.Invariant($"Security key mismatch. Expected: {securityKey}, but got: {callbackQuery["SecurityKey"]}")); } }
/// <summary> /// Calculates security key /// </summary> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <returns>Security key</returns> private static string CalculateKey(MerchantSettings merchantSettings, OrderInfo orderInfo) { var merchantIdChunk = FormattableString.Invariant($"MerchantId={merchantSettings.MerchantId}"); var orderIdChunk = FormattableString.Invariant($"&OrderId={orderInfo.OrderId}"); var amountChunk = FormattableString.Invariant($"&Amount={orderInfo.Amount.ToString("#.00", CultureInfo.InvariantCulture)}"); var currencyChunk = FormattableString.Invariant($"&Currency={orderInfo.Currency.ToUpperInvariant()}"); var validUtilChunk = orderInfo.ValidUntil.HasValue ? FormattableString.Invariant($"&ValidUntil={orderInfo.ValidUntil.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)}") : string.Empty; var orderDescriptionChunk = string.IsNullOrEmpty(orderInfo.OrderDecription) ? string.Empty : FormattableString.Invariant($"&OrderDescription={orderInfo.OrderDecription}"); var keyChunk = FormattableString.Invariant($"&PrivateSecurityKey={merchantSettings.Key}"); return(CalculateMd5Hash(FormattableString.Invariant($"{merchantIdChunk}{orderIdChunk}{amountChunk}{currencyChunk}{validUtilChunk}{orderDescriptionChunk}{keyChunk}"))); }
/// <summary> /// Creates payment form query /// </summary> /// <param name="merchantSettings">Merchant settings</param> /// <param name="orderInfo">Order information</param> /// <param name="redirectParameters">Redirect parameters</param> /// <param name="customData">Custom data</param> /// <returns>Query string</returns> private static string GetQuery(MerchantSettings merchantSettings, OrderInfo orderInfo, RedirectParameters redirectParameters, NameValueCollection customData) { var queryString = HttpUtility.ParseQueryString(string.Empty); queryString["MerchantId"] = merchantSettings.MerchantId.ToString(CultureInfo.InvariantCulture); queryString["OrderId"] = orderInfo.OrderId; queryString["Amount"] = orderInfo.Amount.ToString("#.00", CultureInfo.InvariantCulture); queryString["Currency"] = orderInfo.Currency.ToUpperInvariant(); if (orderInfo.ValidUntil.HasValue) { queryString["ValidUntil"] = orderInfo.ValidUntil.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); } if (!string.IsNullOrEmpty(orderInfo.OrderDecription)) { queryString["OrderDescription"] = orderInfo.OrderDecription; } queryString["SecurityKey"] = new SecurityKey(merchantSettings, orderInfo).Value; if (redirectParameters?.ReturnUrl != null) { queryString["ReturnUrl"] = redirectParameters.ReturnUrl.ToString(); } if (redirectParameters?.FailUrl != null) { queryString["FailUrl"] = redirectParameters.FailUrl.ToString(); } if (customData != null) { queryString.Add(customData); } return(queryString.ToString()); }