示例#1
0
        public bool IsHashValid(string secret)
        {
            bool hashValid = false;

            //check for any null values and set them to empty string for hashing
            string timeStamp         = this.Timestamp ?? string.Empty;
            string merchantId        = this.MerchantId ?? string.Empty;
            string orderId           = this.OrderId ?? string.Empty;
            string result            = this.Result ?? string.Empty;
            string message           = this.Message ?? string.Empty;
            string paymentsReference = this.PaymentsReference ?? string.Empty;
            string authCode          = this.AuthCode ?? string.Empty;

            //create String to hash
            var toHash = new StringBuilder()
                         .Append(timeStamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(result).Append(".")
                         .Append(message).Append(".")
                         .Append(paymentsReference).Append(".")
                         .Append(authCode).ToString();

            //check if calculated hash matches returned value
            string expectedHash = GenerationUtils.GenerateHash(toHash, secret);

            if (expectedHash == this.Hash)
            {
                hashValid = true;
            }

            return(hashValid);
        }
示例#2
0
        public ThreeDSecureRequest GenerateHash(string secret)
        {
            string timestamp  = this.Timestamp ?? string.Empty;
            string merchantId = this.MerchantId ?? string.Empty;
            string orderId    = this.OrderId ?? string.Empty;
            string amount     = string.Empty;
            string currency   = string.Empty;

            if (this.Amount != null)
            {
                amount   = this.Amount.Amount == default(long) ? "" : this.Amount.Amount.ToString();
                currency = this.Amount.Currency ?? string.Empty;
            }

            string cardNumber = string.Empty;

            if (this.Card != null)
            {
                cardNumber = this.Card.Number ?? string.Empty;
            }

            string toHash = new StringBuilder()
                            .Append(timestamp).Append(".")
                            .Append(merchantId).Append(".")
                            .Append(orderId).Append(".")
                            .Append(amount).Append(".")
                            .Append(currency).Append(".")
                            .Append(cardNumber).ToString();

            this.Hash = GenerationUtils.GenerateHash(toHash, secret);
            return(this);
        }
示例#3
0
        private string ConvertResponse(JsonDoc request, Transaction trans)
        {
            var merchantId = request.GetValue <string>("MERCHANT_ID");
            var account    = request.GetValue <string>("ACCOUNT");

            // begin building response
            var response = new JsonDoc(JsonEncoders.Base64Encoder);

            response.Set("MERCHANT_ID", merchantId);
            response.Set("ACCOUNT", request.GetValue <string>("ACCOUNT"));
            response.Set("ORDER_ID", trans.OrderId);
            response.Set("TIMESTAMP", trans.Timestamp);
            response.Set("RESULT", trans.ResponseCode);
            response.Set("PASREF", trans.TransactionId);
            response.Set("AUTHCODE", trans.AuthorizationCode);
            response.Set("AVSPOSTCODERESULT", trans.AvsResponseCode);
            response.Set("CVNRESULT", trans.CvnResponseCode);
            response.Set("HPP_LANG", request.GetValue <string>("HPP_LANG"));
            response.Set("SHIPPING_CODE", request.GetValue <string>("SHIPPING_CODE"));
            response.Set("SHIPPING_CO", request.GetValue <string>("SHIPPING_CO"));
            response.Set("BILLING_CODE", request.GetValue <string>("BILLING_CODE"));
            response.Set("BILLING_CO", request.GetValue <string>("BILLING_CO"));
            response.Set("ECI", request.GetValue <string>("ECI"));
            response.Set("CAVV", request.GetValue <string>("CAVV"));
            response.Set("XID", request.GetValue <string>("XID"));
            response.Set("MERCHANT_RESPONSE_URL", request.GetValue <string>("MERCHANT_RESPONSE_URL"));
            response.Set("CARD_PAYMENT_BUTTON", request.GetValue <string>("CARD_PAYMENT_BUTTON"));
            response.Set("MESSAGE", trans.ResponseMessage);
            response.Set("AMOUNT", trans.AuthorizedAmount);
            response.Set("SHA1HASH", GenerationUtils.GenerateHash(_sharedSecret, trans.Timestamp, merchantId, trans.OrderId, trans.ResponseCode, trans.ResponseMessage, trans.TransactionId, trans.AuthorizationCode));

            return(response.ToString());
        }
 public void CalculatesSha1HashCorrectlyInMultiThreadedEnvironment()
 {
     Parallel.For(1, 51, (i, state) =>
     {
         var result = GenerationUtils.GenerateHash(DataToHash, HashSecret);
         Assert.AreEqual(ExpectedHashResult, result);
     });
 }
示例#5
0
        public Transaction ManageTransaction(ManagementBuilder builder)
        {
            var    et              = new ElementTree();
            string timestamp       = GenerationUtils.GenerateTimestamp();
            string orderId         = builder.OrderId ?? GenerationUtils.GenerateOrderId();
            string transactionType = MapManageRequestType(builder.TransactionType);

            // Build Request
            var request = et.Element("request")
                          .Set("timestamp", timestamp)
                          .Set("type", transactionType);

            et.SubElement(request, "merchantid").Text(MerchantId);
            et.SubElement(request, "account", AccountId);
            et.SubElement(request, "channel", Channel);
            et.SubElement(request, "orderid", orderId);
            et.SubElement(request, "pasref", builder.TransactionId);
            if (builder.Amount.HasValue)
            {
                et.SubElement(request, "amount", builder.Amount.ToNumericCurrencyString()).Set("currency", builder.Currency);
            }
            else if (builder.TransactionType == TransactionType.Capture)
            {
                throw new BuilderException("Amount cannot be null for capture.");
            }

            // payer authentication response
            if (builder.TransactionType == TransactionType.VerifySignature)
            {
                et.SubElement(request, "pares", builder.PayerAuthenticationResponse);
            }

            // rebate hash
            if (builder.TransactionType == TransactionType.Refund)
            {
                et.SubElement(request, "authcode").Text(builder.AuthorizationCode);
                et.SubElement(request, "refundhash", GenerationUtils.GenerateHash(RebatePassword ?? string.Empty));
            }

            // reason code
            if (builder.ReasonCode != null)
            {
                et.SubElement(request, "reasoncode").Text(builder.ReasonCode.ToString());
            }

            // TODO: needs to be multiple
            if (builder.Description != null)
            {
                var comments = et.SubElement(request, "comments");
                et.SubElement(comments, "comment", builder.Description).Set("id", "1");
            }

            et.SubElement(request, "sha1hash", GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, ""));

            var response = DoTransaction(et.ToString(request));

            return(MapResponse(response, MapAcceptedCodes(transactionType)));
        }
示例#6
0
        public PaymentRequest GenerateHash(string secret)
        {
            string timestamp  = this.Timestamp ?? string.Empty;
            string merchantId = this.MerchantId ?? string.Empty;
            string orderId    = this.OrderId ?? string.Empty;
            string amount     = string.Empty;
            string currency   = string.Empty;
            string token      = this.Token ?? string.Empty;

            if (this.Amount != null)
            {
                amount   = this.Amount.Amount == default(long) ? string.Empty : this.Amount.Amount.ToString();
                currency = this.Amount.Currency ?? string.Empty;
            }

            string cardNumber = string.Empty;

            if (this.Card != null)
            {
                cardNumber = this.Card.Number ?? string.Empty;
            }

            string toHash = string.Empty;

            if (this.Type == PaymentType.AUTH_MOBILE)
            {
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append("...")
                         .Append(token).ToString();
            }
            else if (this.Type == PaymentType.OTB)
            {
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(cardNumber).ToString();
            }
            else
            {
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(cardNumber).ToString();
            }

            this.Hash = GenerationUtils.GenerateHash(toHash, secret);
            return(this);
        }
示例#7
0
        private string ConvertResponse(JsonDoc request, Transaction trans)
        {
            var merchantId = request.GetValue <string>("MERCHANT_ID");
            var account    = request.GetValue <string>("ACCOUNT");

            // begin building response
            var response = new JsonDoc(JsonEncoders.Base64Encoder);

            response.Set("MERCHANT_ID", merchantId);
            response.Set("ACCOUNT", request.GetValue <string>("ACCOUNT"));
            response.Set("ORDER_ID", trans.OrderId);
            response.Set("TIMESTAMP", trans.Timestamp);
            response.Set("RESULT", trans.ResponseCode);
            response.Set("PASREF", trans.TransactionId);
            response.Set("AUTHCODE", trans.AuthorizationCode);
            response.Set("AVSPOSTCODERESULT", trans.AvsResponseCode);
            response.Set("CVNRESULT", trans.CvnResponseCode);
            response.Set("HPP_LANG", request.GetValue <string>("HPP_LANG"));
            response.Set("SHIPPING_CODE", request.GetValue <string>("SHIPPING_CODE"));
            response.Set("SHIPPING_CO", request.GetValue <string>("SHIPPING_CO"));
            response.Set("BILLING_CODE", request.GetValue <string>("BILLING_CODE"));
            response.Set("BILLING_CO", request.GetValue <string>("BILLING_CO"));
            response.Set("ECI", request.GetValue <string>("ECI"));
            response.Set("CAVV", request.GetValue <string>("CAVV"));
            response.Set("XID", request.GetValue <string>("XID"));
            response.Set("MERCHANT_RESPONSE_URL", request.GetValue <string>("MERCHANT_RESPONSE_URL"));
            response.Set("CARD_PAYMENT_BUTTON", request.GetValue <string>("CARD_PAYMENT_BUTTON"));
            response.Set("MESSAGE", trans.ResponseMessage);
            response.Set("AMOUNT", trans.AuthorizedAmount);
            response.Set("SHA1HASH", GenerationUtils.GenerateHash(_sharedSecret, trans.Timestamp, merchantId, trans.OrderId, trans.ResponseCode, trans.ResponseMessage, trans.TransactionId, trans.AuthorizationCode));
            response.Set("DCC_INFO_REQUST", request.GetValue <string>("DCC_INFO"));
            response.Set("HPP_FRAUDFILTER_MODE", request.GetValue <string>("HPP_FRAUDFILTER_MODE"));
            if (trans?.FraudResponse?.Rules != null)
            {
                response.Set("HPP_FRAUDFILTER_RESULT", trans.FraudResponse?.Result);

                foreach (var rule in trans.FraudResponse.Rules)
                {
                    response.Set("HPP_FRAUDFILTER_RULE_" + rule.Id, rule.Action);
                }
            }
            if (trans?.AlternativePaymentResponse != null)
            {
                AlternativePaymentResponse alternativePaymentResponse = trans.AlternativePaymentResponse;
                response.Set("HPP_CUSTOMER_FIRSTNAME", request.GetValue <string>("HPP_CUSTOMER_FIRSTNAME"));
                response.Set("HPP_CUSTOMER_LASTNAME", request.GetValue <string>("HPP_CUSTOMER_LASTNAME"));
                response.Set("HPP_CUSTOMER_COUNTRY", request.GetValue <string>("HPP_CUSTOMER_COUNTRY"));
                response.Set("PAYMENTMETHOD", alternativePaymentResponse.ProviderName);
                response.Set("PAYMENTPURPOSE", alternativePaymentResponse.PaymentPurpose);
                response.Set("HPP_CUSTOMER_BANK_ACCOUNT", alternativePaymentResponse.BankAccount);
            }

            return(response.ToString());
        }
        private string GenerateHash(string secret)
        {
            var hashFields = new List <string>();

            hashFields.AddRange(new string[]
            {
                Timestamp, MerchantID, OrderID, Result, Message, PASRef, AuthCode
            });

            // Join the fields with . separator and hash it
            var toHash = string.Join(".", hashFields);

            return(GenerationUtils.GenerateHash(toHash, secret));
        }
示例#9
0
        public Transaction ParseResponse(string json, bool encoded = false)
        {
            var response = JsonDoc.Parse(json, encoded ? JsonEncoders.Base64Encoder : null);

            var timestamp     = response.GetValue <string>("TIMESTAMP");
            var merchantId    = response.GetValue <string>("MERCHANT_ID");
            var orderId       = response.GetValue <string>("ORDER_ID");
            var result        = response.GetValue <string>("RESULT");
            var message       = response.GetValue <string>("MESSAGE");
            var transactionId = response.GetValue <string>("PASREF");
            var authCode      = response.GetValue <string>("AUTHCODE");

            var sha1Hash = response.GetValue <string>("SHA1HASH");
            var hash     = GenerationUtils.GenerateHash(_config.SharedSecret, timestamp, merchantId, orderId, result, message, transactionId, authCode);

            if (!hash.Equals(sha1Hash))
            {
                throw new ApiException("Incorrect hash. Please check your code and the Developers Documentation.");
            }

            // remainder of the values
            var rvalues = new Dictionary <string, string>();

            foreach (var key in response.Keys)
            {
                var value = response.GetValue <string>(key);
                if (value != null)
                {
                    rvalues.Add(key, value);
                }
            }

            return(new Transaction {
                AuthorizedAmount = response.GetValue <decimal>("AMOUNT"),
                AutoSettleFlag = response.GetValue <string>("AUTO_SETTLE_FLAG"),
                CvnResponseCode = response.GetValue <string>("CVNRESULT"),
                ResponseCode = result,
                ResponseMessage = message,
                AvsResponseCode = response.GetValue <string>("AVSPOSTCODERESULT"),
                Timestamp = timestamp,
                TransactionReference = new TransactionReference {
                    AuthCode = authCode,
                    OrderId = orderId,
                    PaymentMethodType = PaymentMethodType.Credit,
                    TransactionId = transactionId
                },
                ResponseValues = rvalues
            });
        }
示例#10
0
        /// <summary>
        /// Explicitly initialise the Request Hash using the secret
        /// </summary>
        /// <param name="secret"></param>
        private void InitHash(string secret)
        {
            // Override payerRef with hppSelectStoredCard if present.
            if (!string.IsNullOrEmpty(HPPSelectStoredCard))
            {
                PayerReference = HPPSelectStoredCard;
            }

            // Create String to hash.
            List <string> hashFields = new List <string>();

            // Check for card storage enable flag to determine if Real Vault transaction
            if (!string.IsNullOrEmpty(CardStorageEnable) && CardStorageEnable.Equals(HPPConstants.Flag.TRUE.ToString()) ||
                !string.IsNullOrEmpty(HPPSelectStoredCard))
            {
                hashFields.AddRange(new string[]
                {
                    Timestamp, MerchantID, OrderID, Amount, Currency, PayerReference, PaymentReference
                });
            }
            else
            {
                hashFields.AddRange(new string[]
                {
                    Timestamp, MerchantID, OrderID, Amount, Currency
                });
            }

            // Add fraud filter mode if it has been set
            if (!string.IsNullOrEmpty(HPPFraudFilterMode))
            {
                hashFields.Add(HPPFraudFilterMode);
            }

            // Join the fields with . separator and hash it
            string toHash = string.Join(".", hashFields);

            Hash = GenerationUtils.GenerateHash(toHash, secret);
        }
示例#11
0
        public Transaction ProcessSecure3d(Secure3dBuilder builder)
        {
            TransactionType transType     = builder.TransactionType;
            IPaymentMethod  paymentMethod = builder.PaymentMethod;
            ISecure3d       secure3d      = (ISecure3d)paymentMethod;
            string          timestamp     = DateTime.Now.ToString("yyyy-MM-dd'T'hh:mm:ss.ffffff");

            JsonDoc request = new JsonDoc();

            if (transType.Equals(TransactionType.VerifyEnrolled))
            {
                request.Set("request_timestamp", timestamp);
                request.Set("merchant_id", MerchantId);
                request.Set("account_id", AccountId);
                request.Set("method_notification_url", MethodNotificationUrl);

                string hashValue = string.Empty;
                if (paymentMethod is CreditCardData cardData)
                {
                    request.Set("number", cardData.Number);
                    request.Set("scheme", MapCardScheme(cardData.CardType.ToUpper()));
                    hashValue = cardData.Number;
                }
                else if (paymentMethod is RecurringPaymentMethod storedCard)
                {
                    request.Set("payer_reference", storedCard.CustomerKey);
                    request.Set("payment_method_reference", storedCard.Key);
                    hashValue = storedCard.CustomerKey;
                }

                string hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, hashValue);
                SetAuthHeader(hash);

                string rawResponse = DoTransaction(HttpMethod.Post, "protocol-versions", request.ToString());
                return(MapResponse(rawResponse));
            }
            else if (transType.Equals(TransactionType.VerifySignature))
            {
                string hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, builder.ServerTransactionId);
                SetAuthHeader(hash);

                var queryValues = new Dictionary <string, string>();
                queryValues.Add("merchant_id", MerchantId);
                queryValues.Add("request_timestamp", timestamp);

                string rawResponse = DoTransaction(HttpMethod.Get, string.Format("authentications/{0}", builder.ServerTransactionId), null, queryValues);
                return(MapResponse(rawResponse));
            }
            else if (transType.Equals(TransactionType.InitiateAuthentication))
            {
                string orderId = builder.OrderId;
                if (string.IsNullOrEmpty(orderId))
                {
                    orderId = GenerationUtils.GenerateOrderId();
                }
                ThreeDSecure secureEcom = secure3d.ThreeDSecure;

                request.Set("request_timestamp", timestamp);
                request.Set("authentication_source", builder.AuthenticationSource.ToString());
                request.Set("authentication_request_type", builder.AuthenticationRequestType.ToString());
                request.Set("message_category", builder.MessageCategory.ToString());
                request.Set("message_version", "2.1.0");
                request.Set("server_trans_id", secureEcom.ServerTransactionId);
                request.Set("merchant_id", MerchantId);
                request.Set("account_id", AccountId);
                request.Set("challenge_notification_url", ChallengeNotificationUrl);
                request.Set("method_url_completion", builder.MethodUrlCompletion.ToString());
                request.Set("merchant_contact_url", MerchantContactUrl);
                request.Set("merchant_initiated_request_type", builder.MerchantInitiatedRequestType?.ToString());
                request.Set("whitelist_status", builder.WhitelistStatus);
                request.Set("decoupled_flow_request", builder.DecoupledFlowRequest);
                request.Set("decoupled_flow_timeout", builder.DecoupledFlowTimeout);
                request.Set("decoupled_notification_url", builder.DecoupledNotificationUrl);
                request.Set("enable_exemption_optimization", builder.EnableExemptionOptimization);

                // card details
                string  hashValue  = string.Empty;
                JsonDoc cardDetail = request.SubElement("card_detail");
                if (paymentMethod is CreditCardData cardData)
                {
                    hashValue = cardData.Number;
                    cardDetail.Set("number", cardData.Number);
                    cardDetail.Set("scheme", cardData.CardType.ToUpper());
                    cardDetail.Set("expiry_month", cardData.ExpMonth.ToString());
                    cardDetail.Set("expiry_year", cardData.ExpYear.ToString().Substring(2));
                    cardDetail.Set("full_name", cardData.CardHolderName);

                    if (!string.IsNullOrEmpty(cardData.CardHolderName))
                    {
                        string[] names = cardData.CardHolderName.Split(' ');
                        if (names.Length >= 1)
                        {
                            cardDetail.Set("first_name", names[0]);
                        }
                        if (names.Length >= 2)
                        {
                            cardDetail.Set("last_name", string.Join(" ", names.Skip(1)));
                        }
                    }
                }
                else if (paymentMethod is RecurringPaymentMethod storedCard)
                {
                    hashValue = storedCard.CustomerKey;
                    cardDetail.Set("payer_reference", storedCard.CustomerKey);
                    cardDetail.Set("payment_method_reference", storedCard.Key);
                }

                // order details
                JsonDoc order = request.SubElement("order");
                order.Set("amount", builder.Amount.ToNumericCurrencyString());
                order.Set("currency", builder.Currency);
                order.Set("id", orderId);
                order.Set("address_match_indicator", builder.AddressMatchIndicator ? "true" : "false");
                order.Set("date_time_created", builder.OrderCreateDate?.ToString("yyyy-MM-dd'T'hh:mm'Z'"));
                order.Set("gift_card_count", builder.GiftCardCount);
                order.Set("gift_card_currency", builder.GiftCardCurrency);
                order.Set("gift_card_amount", builder.GiftCardAmount.ToNumericCurrencyString());
                order.Set("delivery_email", builder.DeliveryEmail);
                order.Set("delivery_timeframe", builder.DeliveryTimeframe?.ToString());
                order.Set("shipping_method", builder.ShippingMethod?.ToString());
                order.Set("shipping_name_matches_cardholder_name", builder.ShippingNameMatchesCardHolderName);
                order.Set("preorder_indicator", builder.PreOrderIndicator?.ToString());
                order.Set("reorder_indicator", builder.ReorderIndicator?.ToString());
                order.Set("transaction_type", builder.OrderTransactionType?.ToString());
                order.Set("preorder_availability_date", builder.PreOrderAvailabilityDate?.ToString("yyyy-MM-dd"));

                // shipping address
                Address shippingAddress = builder.ShippingAddress;
                if (shippingAddress != null)
                {
                    JsonDoc shippingAddressElement = order.SubElement("shipping_address");
                    shippingAddressElement.Set("line1", shippingAddress.StreetAddress1);
                    shippingAddressElement.Set("line2", shippingAddress.StreetAddress2);
                    shippingAddressElement.Set("line3", shippingAddress.StreetAddress3);
                    shippingAddressElement.Set("city", shippingAddress.City);
                    shippingAddressElement.Set("postal_code", shippingAddress.PostalCode);
                    shippingAddressElement.Set("state", shippingAddress.State);
                    shippingAddressElement.Set("country", shippingAddress.CountryCode);
                }

                // payer
                JsonDoc payer = request.SubElement("payer");
                payer.Set("email", builder.CustomerEmail);
                payer.Set("id", builder.CustomerAccountId);
                payer.Set("account_age", builder.AccountAgeIndicator?.ToString());
                payer.Set("account_creation_date", builder.AccountCreateDate?.ToString("yyyy-MM-dd"));
                payer.Set("account_change_indicator", builder.AccountChangeIndicator?.ToString());
                payer.Set("account_change_date", builder.AccountChangeDate?.ToString("yyyy-MM-dd"));
                payer.Set("account_password_change_indicator", builder.PasswordChangeIndicator?.ToString());
                payer.Set("account_password_change_date", builder.PasswordChangeDate?.ToString("yyyy-MM-dd"));
                payer.Set("payment_account_age_indicator", builder.PaymentAgeIndicator?.ToString());
                payer.Set("payment_account_creation_date", builder.PaymentAccountCreateDate?.ToString("yyyy-MM-dd"));
                payer.Set("purchase_count_last_6months", builder.NumberOfPurchasesInLastSixMonths);
                payer.Set("transaction_count_last_24hours", builder.NumberOfTransactionsInLast24Hours);
                payer.Set("transaction_count_last_year", builder.NumberOfTransactionsInLastYear);
                payer.Set("provision_attempt_count_last_24hours", builder.NumberOfAddCardAttemptsInLast24Hours);
                payer.Set("shipping_address_creation_indicator", builder.ShippingAddressUsageIndicator?.ToString());
                payer.Set("shipping_address_creation_date", builder.ShippingAddressCreateDate?.ToString("yyyy-MM-dd"));

                // suspicious activity
                if (builder.PreviousSuspiciousActivity != null)
                {
                    payer.Set("suspicious_account_activity", builder.PreviousSuspiciousActivity.Value ? "SUSPICIOUS_ACTIVITY" : "NO_SUSPICIOUS_ACTIVITY");
                }

                // home phone
                if (!string.IsNullOrEmpty(builder.HomeNumber))
                {
                    payer.SubElement("home_phone")
                    .Set("country_code", builder.HomeCountryCode)
                    .Set("subscriber_number", builder.HomeNumber);
                }

                // work phone
                if (!string.IsNullOrEmpty(builder.WorkNumber))
                {
                    payer.SubElement("work_phone")
                    .Set("country_code", builder.WorkCountryCode)
                    .Set("subscriber_number", builder.WorkNumber);
                }

                // payer login data
                if (builder.HasPayerLoginData)
                {
                    request.SubElement("payer_login_data")
                    .Set("authentication_data", builder.CustomerAuthenticationData)
                    .Set("authentication_timestamp", builder.CustomerAuthenticationTimestamp?.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'"))
                    .Set("authentication_type", builder.CustomerAuthenticationMethod?.ToString());
                }

                // prior authentication data
                if (builder.HasPriorAuthenticationData)
                {
                    request.SubElement("payer_prior_three_ds_authentication_data")
                    .Set("authentication_method", builder.PriorAuthenticationMethod?.ToString())
                    .Set("acs_transaction_id", builder.PriorAuthenticationTransactionId)
                    .Set("authentication_timestamp", builder.PriorAuthenticationTimestamp?.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'"))
                    .Set("authentication_data", builder.PriorAuthenticationData);
                }

                // recurring authorization data
                if (builder.HasRecurringAuthData)
                {
                    request.SubElement("recurring_authorization_data")
                    .Set("max_number_of_instalments", builder.MaxNumberOfInstallments)
                    .Set("frequency", builder.RecurringAuthorizationFrequency)
                    .Set("expiry_date", builder.RecurringAuthorizationExpiryDate?.ToString("yyyy-MM-dd"));
                }

                // billing details
                Address billingAddress = builder.BillingAddress;
                if (billingAddress != null)
                {
                    JsonDoc billingAddressElement = payer.SubElement("billing_address");
                    billingAddressElement.Set("line1", billingAddress.StreetAddress1);
                    billingAddressElement.Set("line2", billingAddress.StreetAddress2);
                    billingAddressElement.Set("line3", billingAddress.StreetAddress3);
                    billingAddressElement.Set("city", billingAddress.City);
                    billingAddressElement.Set("postal_code", billingAddress.PostalCode);
                    billingAddressElement.Set("state", billingAddress.State);
                    billingAddressElement.Set("country", billingAddress.CountryCode);
                }

                // mobile phone
                if (!string.IsNullOrEmpty(builder.MobileNumber))
                {
                    JsonDoc mobilePhone = payer.SubElement("mobile_phone");
                    mobilePhone.Set("country_code", builder.MobileCountryCode);
                    mobilePhone.Set("subscriber_number", builder.MobileNumber);
                }

                // browser_data
                BrowserData broswerData = builder.BrowserData;
                if (broswerData != null)
                {
                    JsonDoc browserDataElement = request.SubElement("browser_data");
                    browserDataElement.Set("accept_header", broswerData.AcceptHeader);
                    browserDataElement.Set("color_depth", broswerData.ColorDepth.ToString());
                    browserDataElement.Set("ip", broswerData.IpAddress);
                    browserDataElement.Set("java_enabled", broswerData.JavaEnabled);
                    browserDataElement.Set("javascript_enabled", broswerData.JavaScriptEnabled);
                    browserDataElement.Set("language", broswerData.Language);
                    browserDataElement.Set("screen_height", broswerData.ScreenHeight);
                    browserDataElement.Set("screen_width", broswerData.ScreenWidth);
                    browserDataElement.Set("challenge_window_size", broswerData.ChallengeWindowSize.ToString());
                    browserDataElement.Set("timezone", broswerData.Timezone);
                    browserDataElement.Set("user_agent", broswerData.UserAgent);
                }

                // mobile fields
                if (builder.HasMobileFields)
                {
                    JsonDoc sdkInformationElement = request.SubElement("sdk_information")
                                                    .Set("application_id", builder.ApplicationId)
                                                    .Set("ephemeral_public_key", builder.EphemeralPublicKey)
                                                    .Set("maximum_timeout", builder.MaximumTimeout)
                                                    .Set("reference_number", builder.ReferenceNumber)
                                                    .Set("sdk_trans_id", builder.SdkTransactionId)
                                                    .Set("encoded_data", builder.EncodedData)
                    ;

                    // device render options
                    if (builder.SdkInterface != null || builder.SdkUiTypes != null)
                    {
                        var dro = sdkInformationElement.SubElement("device_render_options");
                        dro.Set("sdk_interface", builder.SdkInterface?.ToString());
                        if (builder.SdkUiTypes != null)
                        {
                            var uiTypes = new List <string>();
                            foreach (var sdkuiType in builder.SdkUiTypes)
                            {
                                uiTypes.Add(sdkuiType.ToString());
                            }
                            dro.Set("sdk_ui_type", uiTypes.ToArray());
                        }
                    }
                }

                string hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, hashValue, secureEcom.ServerTransactionId);
                SetAuthHeader(hash);

                string rawResponse = DoTransaction(HttpMethod.Post, "authentications", request.ToString());
                return(MapResponse(rawResponse));
            }

            throw new ApiException(string.Format("Unknown transaction type {0}.", transType));
        }
        public TResult ProcessRecurring <TResult>(RecurringBuilder <TResult> builder) where TResult : class
        {
            var    et        = new ElementTree();
            string timestamp = GenerationUtils.GenerateTimestamp();
            string orderId   = builder.OrderId ?? GenerationUtils.GenerateOrderId();

            // Build Request
            var request = et.Element("request")
                          .Set("type", MapRecurringRequestType(builder))
                          .Set("timestamp", timestamp);

            et.SubElement(request, "merchantid").Text(MerchantId);
            et.SubElement(request, "account", AccountId);
            et.SubElement(request, "orderid", orderId);

            if (builder.TransactionType == TransactionType.Create || builder.TransactionType == TransactionType.Edit)
            {
                if (builder.Entity is Customer)
                {
                    var customer = builder.Entity as Customer;
                    request.Append(BuildCustomer(et, customer));
                    et.SubElement(request, "sha1hash").Text(GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, null, null, customer.Key));
                }
                else if (builder.Entity is RecurringPaymentMethod)
                {
                    var payment     = builder.Entity as RecurringPaymentMethod;
                    var cardElement = et.SubElement(request, "card");
                    et.SubElement(cardElement, "ref").Text(payment.Key ?? payment.Id);
                    et.SubElement(cardElement, "payerref").Text(payment.CustomerKey);

                    if (payment.PaymentMethod != null)
                    {
                        var    card   = payment.PaymentMethod as CreditCardData;
                        string expiry = card.ShortExpiry;
                        et.SubElement(cardElement, "number").Text(card.Number);
                        et.SubElement(cardElement, "expdate").Text(expiry);
                        et.SubElement(cardElement, "chname").Text(card.CardHolderName);
                        et.SubElement(cardElement, "type").Text(card.CardType);

                        string sha1hash = string.Empty;
                        if (builder.TransactionType == TransactionType.Create)
                        {
                            sha1hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, null, null, payment.CustomerKey, card.CardHolderName, card.Number);
                        }
                        else
                        {
                            sha1hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, payment.CustomerKey, payment.Key ?? payment.Id, expiry, card.Number);
                        }
                        et.SubElement(request, "sha1hash").Text(sha1hash);
                    }
                }
            }
            else if (builder.TransactionType == TransactionType.Delete)
            {
                if (builder.Entity is RecurringPaymentMethod)
                {
                    var payment     = builder.Entity as RecurringPaymentMethod;
                    var cardElement = et.SubElement(request, "card");
                    et.SubElement(cardElement, "ref").Text(payment.Key ?? payment.Id);
                    et.SubElement(cardElement, "payerref").Text(payment.CustomerKey);

                    string sha1hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, payment.CustomerKey, payment.Key ?? payment.Id);
                    et.SubElement(request, "sha1hash").Text(sha1hash);
                }
            }

            var response = DoTransaction(et.ToString(request));

            return(MapRecurringResponse <TResult>(response, builder));
        }
        public Transaction ProcessAuthorization(AuthorizationBuilder builder)
        {
            var    et              = new ElementTree();
            string timestamp       = builder.Timestamp ?? GenerationUtils.GenerateTimestamp();
            string orderId         = builder.OrderId ?? GenerationUtils.GenerateOrderId();
            string transactionType = MapAuthRequestType(builder);

            if (builder.PaymentMethod is CreditCardData)
            {
                var card = builder.PaymentMethod as CreditCardData;
                if (builder.TransactionModifier == TransactionModifier.EncryptedMobile)
                {
                    if (card.Token == null || card.MobileType == null)
                    {
                        throw new BuilderException("Token and  MobileType can not be null");
                    }
                    if (card.MobileType == MobilePaymentMethodType.GOOGLEPAY.ToString() && (builder.Amount == null || builder.Currency == null))
                    {
                        throw new BuilderException("Amount and Currency can not be null for capture.");
                    }
                }
            }
            if (builder.PaymentMethod is AlternatePaymentMethod)
            {
                var apm = builder.PaymentMethod as AlternatePaymentMethod;
                if (apm.ReturnUrl == null || apm.StatusUpdateUrl == null || apm.AccountHolderName == null || apm.Country == null || apm.Descriptor == null)
                {
                    throw new BuilderException("PaymentMethod, ReturnUrl, StatusUpdateUrl, AccountHolderName, Country, Descriptor can not be null ");
                }
            }
            // Build Request
            var request = et.Element("request")
                          .Set("timestamp", timestamp)
                          .Set("type", transactionType);

            et.SubElement(request, "merchantid").Text(MerchantId);
            et.SubElement(request, "account", AccountId);
            et.SubElement(request, "channel", Channel);
            if (builder.Amount.HasValue)
            {
                et.SubElement(request, "amount").Text(builder.Amount.ToNumericCurrencyString()).Set("currency", builder.Currency);
            }
            // This needs to be figured out based on txn type and set to 0, 1 or MULTI
            if (builder.TransactionType == TransactionType.Sale || builder.TransactionType == TransactionType.Auth)
            {
                var autoSettle = builder.TransactionType == TransactionType.Sale ? "1" : builder.MultiCapture == true ? "MULTI" : "0";
                et.SubElement(request, "autosettle").Set("flag", autoSettle);
            }
            et.SubElement(request, "orderid", orderId);

            // Hydrate the payment data fields
            if (builder.PaymentMethod is CreditCardData)
            {
                var card = builder.PaymentMethod as CreditCardData;

                if (builder.TransactionModifier == TransactionModifier.EncryptedMobile)
                {
                    et.SubElement(request, "mobile", card.MobileType);
                    et.SubElement(request, "token", card.Token);
                }
                else
                {
                    var cardElement = et.SubElement(request, "card");
                    et.SubElement(cardElement, "number", card.Number);
                    et.SubElement(cardElement, "expdate", card.ShortExpiry);
                    et.SubElement(cardElement, "chname").Text(card.CardHolderName);
                    et.SubElement(cardElement, "type", card.CardType.ToUpper());

                    if (card.Cvn != null)
                    {
                        var cvnElement = et.SubElement(cardElement, "cvn");
                        et.SubElement(cvnElement, "number", card.Cvn);
                        et.SubElement(cvnElement, "presind", (int)card.CvnPresenceIndicator);
                    }
                }
                // mpi
                if (card.ThreeDSecure != null)
                {
                    var mpi = et.SubElement(request, "mpi");
                    et.SubElement(mpi, "cavv", card.ThreeDSecure.Cavv);
                    et.SubElement(mpi, "xid", card.ThreeDSecure.Xid);
                    et.SubElement(mpi, "eci", card.ThreeDSecure.Eci);
                }

                // issueno
                string hash = string.Empty;
                if (builder.TransactionType == TransactionType.Verify)
                {
                    hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, card.Number);
                }
                else
                {
                    if (builder.TransactionModifier == TransactionModifier.EncryptedMobile && card.MobileType == MobilePaymentMethodType.APPLEPAY)
                    {
                        hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, "", "", card.Token);
                    }
                    else if (builder.TransactionModifier == TransactionModifier.EncryptedMobile && card.MobileType == MobilePaymentMethodType.GOOGLEPAY)
                    {
                        hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, card.Token);
                    }
                    else
                    {
                        hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, card.Number);
                    }
                }
                et.SubElement(request, "sha1hash").Text(hash);
            }
            else if (builder.PaymentMethod is AlternatePaymentMethod)
            {
                var apm = builder.PaymentMethod as AlternatePaymentMethod;
                et.SubElement(request, "paymentmethod", apm.AlternativePaymentMethodType);
                var paymentmethoddetails = et.SubElement(request, "paymentmethoddetails");
                et.SubElement(paymentmethoddetails, "returnurl", apm.ReturnUrl);
                et.SubElement(paymentmethoddetails, "statusupdateurl", apm.StatusUpdateUrl);
                et.SubElement(paymentmethoddetails, "descriptor", apm.Descriptor);
                et.SubElement(paymentmethoddetails, "country", apm.Country);
                et.SubElement(paymentmethoddetails, "accountholdername", apm.AccountHolderName);

                // issueno
                string hash = string.Empty;
                hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, apm.AlternativePaymentMethodType.ToString());
                et.SubElement(request, "sha1hash").Text(hash);
            }
            if (builder.PaymentMethod is RecurringPaymentMethod)
            {
                var recurring = builder.PaymentMethod as RecurringPaymentMethod;
                et.SubElement(request, "payerref").Text(recurring.CustomerKey);
                et.SubElement(request, "paymentmethod").Text(recurring.Key ?? recurring.Id);

                if (!string.IsNullOrEmpty(builder.Cvn))
                {
                    var paymentData = et.SubElement(request, "paymentdata");
                    var cvn         = et.SubElement(paymentData, "cvn");
                    et.SubElement(cvn, "number").Text(builder.Cvn);
                }

                string hash = string.Empty;
                if (builder.TransactionType == TransactionType.Verify)
                {
                    hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, recurring.CustomerKey);
                }
                else
                {
                    hash = GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, recurring.CustomerKey);
                }
                et.SubElement(request, "sha1hash").Text(hash);
            }
            else
            {
                // TODO: Token Processing
                //et.SubElement(request, "sha1hash", GenerateHash(order, token));
            }

            // refund hash
            if (builder.TransactionType == TransactionType.Refund)
            {
                et.SubElement(request, "refundhash", GenerationUtils.GenerateHash(RefundPassword) ?? string.Empty);
            }

            // TODO: needs to be multiple
            if (builder.Description != null)
            {
                var comments = et.SubElement(request, "comments");
                et.SubElement(comments, "comment", builder.Description).Set("id", "1");
            }

            // fraudfilter
            if (builder.RecurringType != null || builder.RecurringSequence != null)
            {
                et.SubElement(request, "recurring")
                .Set("type", builder.RecurringType.ToString().ToLower())
                .Set("sequence", builder.RecurringSequence.ToString().ToLower());
            }

            // tssinfo
            if (builder.CustomerId != null || builder.ProductId != null || builder.CustomerId != null || builder.ClientTransactionId != null || builder.BillingAddress != null || builder.ShippingAddress != null)
            {
                var tssInfo = et.SubElement(request, "tssinfo");
                et.SubElement(tssInfo, "custnum", builder.CustomerId);
                et.SubElement(tssInfo, "prodid", builder.ProductId);
                et.SubElement(tssInfo, "varref", builder.ClientTransactionId);
                et.SubElement(tssInfo, "custipaddress", builder.CustomerIpAddress);
                if (builder.BillingAddress != null)
                {
                    tssInfo.Append(BuildAddress(et, builder.BillingAddress));
                }
                if (builder.ShippingAddress != null)
                {
                    tssInfo.Append(BuildAddress(et, builder.ShippingAddress));
                }
            }
            var response    = DoTransaction(et.ToString(request));
            var mapResponse = MapResponse(response, MapAcceptedCodes(transactionType));

            if (builder.MultiCapture)
            {
                mapResponse.MultiCapture = builder.MultiCapture;
            }

            return(mapResponse);
        }
        public Transaction ManageTransaction(ManagementBuilder builder)
        {
            var    et              = new ElementTree();
            string timestamp       = GenerationUtils.GenerateTimestamp();
            string orderId         = builder.OrderId ?? GenerationUtils.GenerateOrderId();
            string transactionType = MapManageRequestType(builder);

            // Build Request
            var request = et.Element("request")
                          .Set("timestamp", timestamp)
                          .Set("type", transactionType);

            et.SubElement(request, "merchantid").Text(MerchantId);
            et.SubElement(request, "account", AccountId);
            et.SubElement(request, "channel", Channel);
            et.SubElement(request, "orderid", orderId);
            et.SubElement(request, "pasref", builder.TransactionId);
            if (builder.Amount.HasValue)
            {
                var amtElement = et.SubElement(request, "amount", builder.Amount.ToNumericCurrencyString());
                if (!builder.MultiCapture)
                {
                    amtElement.Set("currency", builder.Currency);
                }
            }
            else if (builder.TransactionType == TransactionType.Capture)
            {
                throw new BuilderException("Amount cannot be null for capture.");
            }

            // Capture Authcode
            if (builder.TransactionType == TransactionType.Capture && builder.MultiCapture == true)
            {
                et.SubElement(request, "authcode").Text(builder.AuthorizationCode);
            }

            et.SubElement(request, "channel", Channel);
            et.SubElement(request, "orderid", orderId);
            et.SubElement(request, "pasref", builder.TransactionId);

            // Check is APM for Refund
            if (builder.AlternativePaymentType != null)
            {
                et.SubElement(request, "paymentmethod", builder.AlternativePaymentType);
            }

            // payer authentication response
            if (builder.TransactionType == TransactionType.VerifySignature)
            {
                et.SubElement(request, "pares", builder.PayerAuthenticationResponse);
            }


            // reason code
            if (builder.ReasonCode != null)
            {
                et.SubElement(request, "reasoncode").Text(builder.ReasonCode.ToString());
            }

            // TODO: needs to be multiple
            if (builder.Description != null)
            {
                var comments = et.SubElement(request, "comments");
                et.SubElement(comments, "comment", builder.Description).Set("id", "1");
            }

            // tssinfo
            if (builder.CustomerId != null || builder.ClientTransactionId != null)
            {
                var tssInfo = et.SubElement(request, "tssinfo");
                et.SubElement(tssInfo, "custnum", builder.CustomerId);
                et.SubElement(tssInfo, "varref", builder.ClientTransactionId);
            }

            // data supplimentary
            if (builder.SupplementaryData != null)
            {
                var supplementaryData = et.SubElement(request, "supplementarydata");
                Dictionary <string, List <string[]> > suppData = builder.SupplementaryData;

                foreach (string key in suppData.Keys)
                {
                    List <string[]> dataSets = suppData[key];

                    foreach (string[] data in dataSets)
                    {
                        Element item = et.SubElement(supplementaryData, "item").Set("type", key);
                        for (int i = 1; i <= data.Length; i++)
                        {
                            et.SubElement(item, "field" + i.ToString().PadLeft(2, '0'), data[i - 1]);
                        }
                    }
                }
            }

            et.SubElement(request, "sha1hash", GenerationUtils.GenerateHash(SharedSecret, timestamp, MerchantId, orderId, builder.Amount.ToNumericCurrencyString(), builder.Currency, builder.AlternativePaymentType != null?builder.AlternativePaymentType.ToString():null));

            // rebate hash
            if (builder.TransactionType == TransactionType.Refund)
            {
                if (builder.AuthorizationCode != null)
                {
                    et.SubElement(request, "authcode").Text(builder.AuthorizationCode);
                }
                et.SubElement(request, "refundhash", GenerationUtils.GenerateHash(builder.AlternativePaymentType != null ? RefundPassword : RebatePassword));
            }
            var response = DoTransaction(et.ToString(request));

            return(MapResponse(response, MapAcceptedCodes(transactionType)));
        }
        public string SerializeRequest(AuthorizationBuilder builder)
        {
            // check for hpp config
            if (HostedPaymentConfig == null)
            {
                throw new ApiException("Hosted configuration missing, Please check you configuration.");
            }

            var encoder = (HostedPaymentConfig.Version == HppVersion.VERSION_2) ? null : JsonEncoders.Base64Encoder;
            var request = new JsonDoc(encoder);

            var orderId   = builder.OrderId ?? GenerationUtils.GenerateOrderId();
            var timestamp = builder.Timestamp ?? GenerationUtils.GenerateTimestamp();

            // check for right transaction types
            if (builder.TransactionType != TransactionType.Sale && builder.TransactionType != TransactionType.Auth && builder.TransactionType != TransactionType.Verify)
            {
                throw new UnsupportedTransactionException("Only Charge and Authorize are supported through hpp.");
            }

            request.Set("MERCHANT_ID", MerchantId);
            request.Set("ACCOUNT", AccountId);
            request.Set("CHANNEL", Channel);
            request.Set("ORDER_ID", orderId);
            if (builder.Amount != null)
            {
                request.Set("AMOUNT", builder.Amount.ToNumericCurrencyString());
            }
            request.Set("CURRENCY", builder.Currency);
            request.Set("TIMESTAMP", timestamp);
            request.Set("AUTO_SETTLE_FLAG", (builder.TransactionType == TransactionType.Sale) ? "1" : builder.MultiCapture == true ? "MULTI" : "0");
            request.Set("COMMENT1", builder.Description);
            // request.Set("COMMENT2", );
            if (HostedPaymentConfig.RequestTransactionStabilityScore.HasValue)
            {
                request.Set("RETURN_TSS", HostedPaymentConfig.RequestTransactionStabilityScore.Value ? "1" : "0");
            }
            if (HostedPaymentConfig.DynamicCurrencyConversionEnabled.HasValue)
            {
                request.Set("DCC_ENABLE", HostedPaymentConfig.DynamicCurrencyConversionEnabled.Value ? "1" : "0");
            }
            if (builder.HostedPaymentData != null)
            {
                AlternativePaymentType[] PaymentTypes = builder.HostedPaymentData.PresetPaymentMethods;
                if (PaymentTypes != null)
                {
                    PaymentValues = string.Join("|", PaymentTypes);
                }
                request.Set("CUST_NUM", builder.HostedPaymentData.CustomerNumber);
                if (HostedPaymentConfig.DisplaySavedCards.HasValue && builder.HostedPaymentData.CustomerKey != null)
                {
                    request.Set("HPP_SELECT_STORED_CARD", builder.HostedPaymentData.CustomerKey);
                }
                if (builder.HostedPaymentData.OfferToSaveCard.HasValue)
                {
                    request.Set("OFFER_SAVE_CARD", builder.HostedPaymentData.OfferToSaveCard.Value ? "1" : "0");
                }
                if (builder.HostedPaymentData.CustomerExists.HasValue)
                {
                    request.Set("PAYER_EXIST", builder.HostedPaymentData.CustomerExists.Value ? "1" : "0");
                }
                if (!HostedPaymentConfig.DisplaySavedCards.HasValue)
                {
                    request.Set("PAYER_REF", builder.HostedPaymentData.CustomerKey);
                }
                request.Set("PMT_REF", builder.HostedPaymentData.PaymentKey);
                request.Set("PROD_ID", builder.HostedPaymentData.ProductId);
                request.Set("HPP_CUSTOMER_COUNTRY", builder.HostedPaymentData.Country);
                request.Set("HPP_CUSTOMER_FIRSTNAME", builder.HostedPaymentData.CustomerFirstName);
                request.Set("HPP_CUSTOMER_LASTNAME", builder.HostedPaymentData.CustomerLastName);
                request.Set("MERCHANT_RESPONSE_URL", builder.HostedPaymentData.ReturnUrl);
                request.Set("HPP_TX_STATUS_URL", builder.HostedPaymentData.StatusUpdateUrl);
                request.Set("PM_METHODS", PaymentValues);
            }
            if (builder.ShippingAddress != null)
            {
                request.Set("SHIPPING_CODE", builder.ShippingAddress.PostalCode);
                request.Set("SHIPPING_CO", builder.ShippingAddress.Country);
            }
            if (builder.BillingAddress != null)
            {
                request.Set("BILLING_CODE", builder.BillingAddress.PostalCode);
                request.Set("BILLING_CO", builder.BillingAddress.Country);
            }
            request.Set("CUST_NUM", builder.CustomerId);
            request.Set("VAR_REF", builder.ClientTransactionId);
            request.Set("HPP_LANG", HostedPaymentConfig.Language);
            request.Set("MERCHANT_RESPONSE_URL", HostedPaymentConfig.ResponseUrl);
            request.Set("CARD_PAYMENT_BUTTON", HostedPaymentConfig.PaymentButtonText);
            if (HostedPaymentConfig.CardStorageEnabled.HasValue)
            {
                request.Set("CARD_STORAGE_ENABLE", HostedPaymentConfig.CardStorageEnabled.Value ? "1" : "0");
            }
            if (builder.TransactionType == TransactionType.Verify)
            {
                request.Set("VALIDATE_CARD_ONLY", builder.TransactionType == TransactionType.Verify ? "1" : "0");
            }
            if (HostedPaymentConfig.FraudFilterMode != FraudFilterMode.NONE)
            {
                request.Set("HPP_FRAUDFILTER_MODE", HostedPaymentConfig.FraudFilterMode.ToString());
            }
            if (builder.RecurringType != null || builder.RecurringSequence != null)
            {
                request.Set("RECURRING_TYPE", builder.RecurringType.ToString().ToLower());
                request.Set("RECURRING_SEQUENCE", builder.RecurringSequence.ToString().ToLower());
            }
            request.Set("HPP_VERSION", HostedPaymentConfig.Version);
            request.Set("HPP_POST_DIMENSIONS", HostedPaymentConfig.PostDimensions);
            request.Set("HPP_POST_RESPONSE", HostedPaymentConfig.PostResponse);

            var toHash = new List <string> {
                timestamp,
                MerchantId,
                orderId,
                (builder.Amount != null) ? builder.Amount.ToNumericCurrencyString() : null,
                builder.Currency
            };

            if (HostedPaymentConfig.CardStorageEnabled.HasValue || (builder.HostedPaymentData != null && builder.HostedPaymentData.OfferToSaveCard.HasValue) || HostedPaymentConfig.DisplaySavedCards.HasValue)
            {
                toHash.Add(builder.HostedPaymentData.CustomerKey ?? null);
                toHash.Add(builder.HostedPaymentData.PaymentKey ?? null);
            }

            if (HostedPaymentConfig.FraudFilterMode != FraudFilterMode.NONE)
            {
                toHash.Add(HostedPaymentConfig.FraudFilterMode.ToString());
            }

            request.Set("SHA1HASH", GenerationUtils.GenerateHash(SharedSecret, toHash.ToArray()));
            return(request.ToString());
        }
        public T ProcessReport <T>(ReportBuilder <T> builder) where T : class
        {
            Dictionary <string, string> queryParams = new Dictionary <string, string>();
            string timestamp = GenerationUtils.GenerateTimestamp();

            switch (builder.ReportType)
            {
            case ReportType.FindBankPayment:
                if (builder is TransactionReportBuilder <T> )
                {
                    var    trb       = builder as TransactionReportBuilder <T>;
                    var    accountId = string.IsNullOrEmpty(trb.SearchBuilder.BankPaymentId) ? AccountId : "";
                    string hash      = GenerationUtils.GenerateHash(SharedSecret, ShaHashType, timestamp, MerchantId, accountId,
                                                                    !string.IsNullOrEmpty(trb.SearchBuilder.BankPaymentId) ? trb.SearchBuilder.BankPaymentId : "",
                                                                    trb.SearchBuilder.StartDate.HasValue ? trb.SearchBuilder.StartDate.Value.ToString("yyyyMMddHHmmss") : "",
                                                                    trb.SearchBuilder.EndDate.HasValue ? trb.SearchBuilder.EndDate.Value.ToString("yyyyMMddHHmmss") : "",
                                                                    trb.SearchBuilder.ReturnPII.HasValue ? (trb.SearchBuilder.ReturnPII.Value ? "True" : "False") : "");

                    SetAuthorizationHeader(hash);

                    queryParams.Add("timestamp", timestamp);
                    queryParams.Add("merchantId", MerchantId);
                    if (!string.IsNullOrEmpty(accountId))
                    {
                        queryParams.Add("accountId", accountId);
                    }
                    var obTransId = !string.IsNullOrEmpty(trb.SearchBuilder.BankPaymentId) ? trb.SearchBuilder.BankPaymentId : "";
                    if (!string.IsNullOrEmpty(obTransId))
                    {
                        queryParams.Add("obTransId", obTransId);
                    }
                    var startDate = trb.SearchBuilder.StartDate.HasValue ? trb.SearchBuilder.StartDate.Value.ToString("yyyyMMddHHmmss") : "";
                    if (!string.IsNullOrEmpty(startDate))
                    {
                        queryParams.Add("startDateTime", startDate);
                    }
                    var endDate = trb.SearchBuilder.EndDate.HasValue ? trb.SearchBuilder.EndDate.Value.ToString("yyyyMMddHHmmss") : "";
                    if (!string.IsNullOrEmpty(endDate))
                    {
                        queryParams.Add("endDateTime", endDate);
                    }
                    var transState = trb.SearchBuilder.BankPaymentStatus.HasValue ? trb.SearchBuilder.BankPaymentStatus.Value.ToString() : "";
                    if (!string.IsNullOrEmpty(transState))
                    {
                        queryParams.Add("transactionState", transState);
                    }
                    var returnPii = trb.SearchBuilder.ReturnPII.HasValue ? (trb.SearchBuilder.ReturnPII.Value ? "True" : "False") : "";
                    if (!string.IsNullOrEmpty(returnPii))
                    {
                        queryParams.Add("returnPii", returnPii);
                    }
                }
                break;

            default:
                break;
            }

            try
            {
                string response = DoTransaction(HttpMethod.Get, "/payments", null, queryParams);
                return(OpenBankingMapping.MapReportResponse <T>(response, builder.ReportType));
            }
            catch (GatewayException ex)
            {
                throw ex;
            }
        }
示例#17
0
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            string response = await request.Content.ReadAsStringAsync();

            // gather information
            var json           = JsonDoc.Parse(response, JsonEncoders.Base64Encoder);
            var timestamp      = json.GetValue <string>("TIMESTAMP");
            var merchantId     = json.GetValue <string>("MERCHANT_ID");
            var account        = json.GetValue <string>("ACCOUNT");
            var orderId        = json.GetValue <string>("ORDER_ID");
            var amount         = json.GetValue <string>("AMOUNT");
            var currency       = json.GetValue <string>("CURRENCY");
            var autoSettle     = json.GetValue <int>("AUTO_SETTLE_FLAG") == 1;
            var description    = json.GetValue <string>("COMMENT1");
            var shaHashTagName = _shaHashType + "HASH";
            var requestHash    = json.GetValue <string>(shaHashTagName);

            // gather additional information
            var shippingCode    = json.GetValue <string>("SHIPPING_CODE");
            var shippingCountry = json.GetValue <string>("SHIPPING_CO");
            var billingCode     = json.GetValue <string>("BILLING_CODE");
            var billingCountry  = json.GetValue <string>("BILLING_CO");
            var fraudFilterMode = json.GetValue <string>("HPP_FRAUDFILTER_MODE");


            List <string> hashParam = new List <string>
            {
                timestamp,
                merchantId,
                orderId,
                amount,
                currency
            };

            //create the card/APM/LPM/OB object
            if (json.Has("PM_METHODS"))
            {
                string[] apmTypes = json.GetValue <string>("PM_METHODS").Split("|");
                string   apmType  = apmTypes[0];

                //OB
                if (apmTypes.Contains(HostedPaymentMethods.OB.ToString()))
                {
                    var card = new BankPayment {
                        SortCode        = json.GetValue <string>("HPP_OB_DST_ACCOUNT_SORT_CODE"),
                        AccountNumber   = json.GetValue <string>("HPP_OB_DST_ACCOUNT_NUMBER"),
                        AccountName     = json.GetValue <string>("HPP_OB_DST_ACCOUNT_NAME"),
                        BankPaymentType = (BankPaymentType)(Enum.Parse(typeof(BankPaymentType), json.GetValue <string>("HPP_OB_PAYMENT_SCHEME"))),
                        Iban            = json.GetValue <string>("HPP_OB_DST_ACCOUNT_IBAN"),
                        ReturnUrl       = json.GetValue <string>("MERCHANT_RESPONSE_URL"),
                        StatusUpdateUrl = json.GetValue <string>("HPP_TX_STATUS_URL")
                    };

                    paymentMethod = card;

                    if (!string.IsNullOrEmpty(card.SortCode))
                    {
                        hashParam.Add(card.SortCode);
                    }
                    if (!string.IsNullOrEmpty(card.AccountNumber))
                    {
                        hashParam.Add(card.AccountNumber);
                    }
                    if (!string.IsNullOrEmpty(card.Iban))
                    {
                        hashParam.Add(card.Iban);
                    }
                }
                else
                {
                    AlternativePaymentMethod apm = new AlternativePaymentMethod();
                    apm.AlternativePaymentMethodType = (AlternativePaymentType)(Enum.Parse(typeof(AlternativePaymentType), apmType));
                    apm.ReturnUrl       = json.GetValue <string>("MERCHANT_RESPONSE_URL");
                    apm.StatusUpdateUrl = json.GetValue <string>("HPP_TX_STATUS_URL");

                    if (apmType.Equals(AlternativePaymentType.PAYPAL.ToString()))
                    {
                        apm.CancelUrl = "https://www.example.com/failure/cancelURL";
                    }
                    apm.Country           = json.GetValue <string>("HPP_CUSTOMER_COUNTRY");
                    apm.AccountHolderName = json.GetValue <string>("HPP_CUSTOMER_FIRSTNAME") + " " + json.GetValue <string>("HPP_CUSTOMER_LASTNAME");

                    paymentMethod = apm;
                }
            }
            else
            {
                CreditCardData card = new CreditCardData {
                    Number         = "4111111111111111",
                    ExpMonth       = 12,
                    ExpYear        = 2025,
                    Cvn            = "123",
                    CardHolderName = "John Smithe"
                };

                paymentMethod = card;
            }

            //for stored card
            if (json.Has("OFFER_SAVE_CARD"))
            {
                if (json.Has("PAYER_REF"))
                {
                    hashParam.Add(json.GetValue <string>("PAYER_REF"));
                }
                if (json.Has("PMT_REF"))
                {
                    hashParam.Add(json.GetValue <string>("PMT_REF"));
                }
            }

            if (json.Has("HPP_FRAUDFILTER_MODE"))
            {
                hashParam.Add(json.GetValue <string>("HPP_FRAUDFILTER_MODE"));
            }

            // check hash
            var newhash = GenerationUtils.GenerateHash(_sharedSecret, hashParam.ToArray());

            if (!newhash.Equals(requestHash))
            {
                return(BadRequest("Incorrect hash. Please check your code and the Developers Documentation."));
            }

            // configure the container
            ServicesContainer.ConfigureService(new GpEcomConfig {
                MerchantId    = merchantId,
                AccountId     = account,
                SharedSecret  = _sharedSecret,
                RequestLogger = new RequestConsoleLogger()
            }, "realexResponder");

            // build request
            AuthorizationBuilder gatewayRequest = null;

            if (amount.ToAmount().Equals(0m) || amount == null)
            {
                var validate = json.GetValue <int>("VALIDATE_CARD_ONLY") == 1;
                if (validate)
                {
                    gatewayRequest = ((CreditCardData)paymentMethod).Verify();
                }
                else
                {
                    gatewayRequest = ((CreditCardData)paymentMethod).Verify().WithRequestMultiUseToken(true);
                }
            }
            else
            {
                if (autoSettle)
                {
                    if (paymentMethod is CreditCardData)
                    {
                        gatewayRequest = ((CreditCardData)paymentMethod).Charge(amount.ToAmount());
                    }
                    if (paymentMethod is AlternativePaymentMethod)
                    {
                        gatewayRequest = ((AlternativePaymentMethod)paymentMethod).Charge(amount.ToAmount());
                    }
                    if (paymentMethod is BankPayment)
                    {
                        var gatewayBankRequest = AddRemittanceRef(((BankPayment)paymentMethod).Charge(amount.ToAmount())
                                                                  .WithCurrency(currency)
                                                                  .WithDescription(description), json);
                        var gatewayResponse = gatewayBankRequest.Execute();
                        if (gatewayResponse.BankPaymentResponse.PaymentStatus.Equals("PAYMENT_INITIATED"))
                        {
                            return(BuildResponse(HttpStatusCode.OK, ConvertResponse(json, gatewayResponse)));
                        }
                        else
                        {
                            return(BadRequest(gatewayResponse.ResponseMessage));
                        }
                    }
                }
                else
                {
                    gatewayRequest = ((CreditCardData)paymentMethod).Authorize(amount.ToAmount());
                }
            }

            try {
                gatewayRequest.WithCurrency(currency).WithOrderId(orderId).WithTimestamp(timestamp);
                if (billingCode != null || billingCountry != null)
                {
                    gatewayRequest.WithAddress(new Address {
                        PostalCode = billingCode, Country = billingCountry
                    });
                }
                if (shippingCode != null || shippingCountry != null)
                {
                    gatewayRequest.WithAddress(new Address {
                        PostalCode = shippingCode, Country = shippingCountry
                    }, AddressType.Shipping);
                }

                if (fraudFilterMode != null)
                {
                    gatewayRequest.WithFraudFilter((FraudFilterMode)Enum.Parse(typeof(FraudFilterMode), fraudFilterMode), getFraudFilterRules(json));
                }

                var gatewayResponse = gatewayRequest.Execute("realexResponder");
                if (gatewayResponse.ResponseCode.Equals("00") || gatewayResponse.ResponseCode.Equals("01"))
                {
                    return(BuildResponse(HttpStatusCode.OK, ConvertResponse(json, gatewayResponse)));
                }
                else
                {
                    return(BadRequest(gatewayResponse.ResponseMessage));
                }
            }
            catch (ApiException exc) {
                return(ServerError(exc.Message));
            }
        }
        public Transaction ProcessOpenBanking(BankPaymentBuilder builder)
        {
            string timestamp = builder.Timestamp ?? GenerationUtils.GenerateTimestamp();
            string orderId   = builder.OrderId ?? GenerationUtils.GenerateOrderId();
            var    amount    = builder.Amount != null?builder.Amount.ToNumericCurrencyString() : null;

            JsonDoc request = new JsonDoc();

            var paymentMethod = builder.PaymentMethod as BankPayment;

            switch (builder.TransactionType)
            {
            case TransactionType.Sale:
                var bankPaymentType = paymentMethod.BankPaymentType != null ?
                                      paymentMethod.BankPaymentType : GetBankPaymentType(builder.Currency);
                string hash = GenerationUtils.GenerateHash(SharedSecret, ShaHashType, timestamp, MerchantId, orderId, amount, builder.Currency,
                                                           !string.IsNullOrEmpty(paymentMethod.SortCode) && bankPaymentType.Equals(BankPaymentType.FASTERPAYMENTS) ?
                                                           paymentMethod.SortCode : "",
                                                           !string.IsNullOrEmpty(paymentMethod.AccountNumber) && bankPaymentType.Equals(BankPaymentType.FASTERPAYMENTS) ?
                                                           paymentMethod.AccountNumber : "",
                                                           !string.IsNullOrEmpty(paymentMethod.Iban) && bankPaymentType.Equals(BankPaymentType.SEPA) ? paymentMethod.Iban : "");
                SetAuthorizationHeader(hash);

                request.Set("request_timestamp", timestamp)
                .Set("merchant_id", MerchantId)
                .Set("account_id", AccountId);

                JsonDoc order = new JsonDoc();
                order.Set("id", orderId)
                .Set("currency", builder.Currency)
                .Set("amount", amount)
                .Set("description", builder.Description);

                JsonDoc payment = new JsonDoc();

                JsonDoc destination = new JsonDoc();
                destination.Set("account_number", bankPaymentType.Equals(BankPaymentType.FASTERPAYMENTS) ? paymentMethod.AccountNumber : null)
                .Set("sort_code", bankPaymentType.Equals(BankPaymentType.FASTERPAYMENTS) ? paymentMethod.SortCode : null)
                .Set("iban", bankPaymentType.Equals(BankPaymentType.SEPA) ? paymentMethod.Iban : null)
                .Set("name", paymentMethod.AccountName);


                JsonDoc remittance_reference = new JsonDoc();
                remittance_reference.Set("type", builder.RemittanceReferenceType != null ? builder.RemittanceReferenceType.ToString() : null)
                .Set("value", builder.RemittanceReferenceValue);

                payment.Set("scheme", bankPaymentType.ToString())
                .Set("destination", destination);

                if (remittance_reference.HasKeys())
                {
                    payment.Set("remittance_reference", remittance_reference);
                }

                request.Set("order", order)
                .Set("payment", payment)
                .Set("return_url", paymentMethod.ReturnUrl)
                .Set("status_url", paymentMethod.StatusUpdateUrl);

                break;

            default:
                break;
            }

            try
            {
                string rawResponse = DoTransaction(HttpMethod.Post, "/payments", request.ToString());
                return(OpenBankingMapping.MapResponse(rawResponse));
            }
            catch (GatewayException gatewayException)
            {
                throw gatewayException;
            }
        }
        public PaymentRequest GenerateHash(string secret)
        {
            var timestamp     = Timestamp ?? string.Empty;
            var merchantId    = MerchantId ?? string.Empty;
            var orderId       = OrderId ?? string.Empty;
            var amount        = string.Empty;
            var currency      = string.Empty;
            var token         = Token ?? string.Empty;
            var payerRef      = Payer != null ? Payer.Ref : PayerRef;
            var paymentMethod = Card != null ? Card.Ref : PaymentMethod;

            if (Amount != null)
            {
                amount   = Amount.Amount == default(long) ? string.Empty : Amount.Amount.ToString();
                currency = Amount.Currency ?? string.Empty;
            }

            var cardNumber = string.Empty;

            if (Card != null)
            {
                cardNumber = Card.Number ?? string.Empty;
            }

            string toHash;

            switch (Type)
            {
            case PaymentType.AUTH_MOBILE:
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append("...")
                         .Append(token).ToString();
                break;

            case PaymentType.OTB:
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(cardNumber).ToString();
                break;

            case PaymentType.PAYER_NEW:
                // timestamp.merchantid.orderid.amount.currency.payerref
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(payerRef).ToString();
                break;

            case PaymentType.CARD_NEW:
                // timestamp.merchantid.orderid.amount.currency.payerref.chname.cardnumber
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(Card?.PayerRef).Append(".")
                         .Append(Card?.CardHolderName).Append(".")
                         .Append(cardNumber).ToString();
                break;

            case PaymentType.CARD_CANCEL:
                // timestamp.merchantid.payerref.cardref
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(Card?.PayerRef).Append(".")
                         .Append(Card?.Ref).ToString();
                break;

            case PaymentType.RECEIPT_IN:
                // timestamp.merchantid.orderid.amount.currency.payerref
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(payerRef).ToString();
                break;

            case PaymentType.PAYMENT_OUT:
                // timestamp.merchantid.orderid.amount.currency.payerref
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(payerRef).ToString();
                break;

            default:
                toHash = new StringBuilder()
                         .Append(timestamp).Append(".")
                         .Append(merchantId).Append(".")
                         .Append(orderId).Append(".")
                         .Append(amount).Append(".")
                         .Append(currency).Append(".")
                         .Append(cardNumber).ToString();
                break;
            }

            Hash = GenerationUtils.GenerateHash(toHash, secret);
            return(this);
        }
        public void CalculatesSha1HashCorrectly()
        {
            var result = GenerationUtils.GenerateHash(DataToHash, HashSecret);

            Assert.AreEqual(ExpectedHashResult, result);
        }
示例#21
0
        protected async override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            string response = await request.Content.ReadAsStringAsync();

            // gather information
            var json        = JsonDoc.Parse(response, JsonEncoders.Base64Encoder);
            var timestamp   = json.GetValue <string>("TIMESTAMP");
            var merchantId  = json.GetValue <string>("MERCHANT_ID");
            var account     = json.GetValue <string>("ACCOUNT");
            var orderId     = json.GetValue <string>("ORDER_ID");
            var amount      = json.GetValue <string>("AMOUNT");
            var currency    = json.GetValue <string>("CURRENCY");
            var autoSettle  = json.GetValue <int>("AUTO_SETTLE_FLAG") == 1;
            var requestHash = json.GetValue <string>("SHA1HASH");

            // check hash
            var newhash = GenerationUtils.GenerateHash(_sharedSecret, timestamp, merchantId, orderId, amount, currency);

            if (!newhash.Equals(requestHash))
            {
                return(BadRequest("Incorrect hash. Please check your code and the Developers Documentation."));
            }

            // configure the container
            ServicesContainer.ConfigureService(new GatewayConfig {
                MerchantId   = merchantId,
                AccountId    = account,
                ServiceUrl   = "https://api.sandbox.realexpayments.com/epage-remote.cgi",
                SharedSecret = _sharedSecret
            }, "realexResponder");

            // gather additional information
            var shippingCode    = json.GetValue <string>("SHIPPING_CODE");
            var shippingCountry = json.GetValue <string>("SHIPPING_CO");
            var billingCode     = json.GetValue <string>("BILLING_CODE");
            var billingCountry  = json.GetValue <string>("BILLING_CO");

            // build request
            AuthorizationBuilder gatewayRequest = null;

            if (amount == null)
            {
                var validate = json.GetValue <int>("VALIDATE_CARD_ONLY") == 1;
                if (validate)
                {
                    gatewayRequest = _card.Verify();
                }
                else
                {
                    gatewayRequest = _card.Verify().WithRequestMultiUseToken(true);
                }
            }
            else
            {
                if (autoSettle)
                {
                    gatewayRequest = _card.Charge(amount.ToAmount());
                }
                else
                {
                    gatewayRequest = _card.Authorize(amount.ToAmount());
                }
            }

            try {
                gatewayRequest.WithCurrency(currency).WithOrderId(orderId).WithTimestamp(timestamp);
                if (billingCode != null || billingCountry != null)
                {
                    gatewayRequest.WithAddress(new Address {
                        PostalCode = billingCode, Country = billingCountry
                    });
                }
                if (shippingCode != null || shippingCountry != null)
                {
                    gatewayRequest.WithAddress(new Address {
                        PostalCode = shippingCode, Country = shippingCountry
                    }, AddressType.Shipping);
                }

                var gatewayResponse = gatewayRequest.Execute("realexResponder");
                if (gatewayResponse.ResponseCode.Equals("00"))
                {
                    return(BuildResponse(HttpStatusCode.OK, ConvertResponse(json, gatewayResponse)));
                }
                else
                {
                    return(BadRequest(gatewayResponse.ResponseMessage));
                }
            }
            catch (ApiException exc) {
                return(ServerError(exc.Message));
            }
        }
示例#22
0
        public async Task <IActionResult> PayByLink(Datos detalles)
        {
            // Shared Secret del terminal
            string SharedSecret = "secret";

            // Timestamp
            string time = GenerationUtils.GenerateTimestamp();

            // Order ID
            string orderID = GenerationUtils.GenerateOrderId();

            // Calculamos la firma concatenando los valores obligatorios
            var firma = GenerationUtils.GenerateHash(SharedSecret, time, "addonnettest", orderID, detalles.Op.importe, "EUR");

            // Petición Pay By Link
            using (HttpClient client = new HttpClient()) {
                PayByLink datos = new PayByLink {
                    TIMESTAMP                       = time,
                    AMOUNT                          = detalles.Op.importe,
                    ORDER_ID                        = orderID,
                    SHA1HASH                        = firma,
                    MERCHANT_RESPONSE_URL           = "https://midominio.es/ResponseHpp",
                    MERCHANT_ID                     = "addonnettest",
                    ACCOUNT                         = "api",
                    AUTO_SETTLE_FLAG                = "1",
                    CURRENCY                        = "EUR",
                    HPP_VERSION                     = "2",
                    COMMENT1                        = detalles.Cliente.comments,
                    HPP_LANG                        = detalles.Cliente.lang,
                    HPP_CUSTOMER_EMAIL              = detalles.Cliente.email,
                    HPP_CUSTOMER_PHONENUMBER_MOBILE = detalles.Cliente.workphone,
                    HPP_BILLING_STREET1             = detalles.Billing.billing1,
                    HPP_BILLING_STREET2             = detalles.Billing.billing2,
                    HPP_BILLING_STREET3             = detalles.Billing.billing3,
                    HPP_BILLING_CITY                = detalles.Billing.billingcity,
                    HPP_BILLING_POSTALCODE          = detalles.Billing.billingcode,
                    HPP_SHIPPING_STREET1            = detalles.Shipping.street1,
                    HPP_SHIPPING_STREET2            = detalles.Shipping.street2,
                    HPP_SHIPPING_STREET3            = detalles.Shipping.street3,
                    HPP_SHIPPING_CITY               = detalles.Shipping.enviocity,
                    HPP_SHIPPING_STATE              = detalles.Shipping.enviostate,
                    HPP_SHIPPING_POSTALCODE         = detalles.Shipping.enviocode,
                    CUST_NUM                        = detalles.Fraud.custnum,
                    VAR_REF                         = detalles.Fraud.varref,
                    PROD_ID                         = detalles.Fraud.prodid,
                    SUPPLEMENTARY_DATA              = detalles.Cliente.suplementary
                };

                try {
                    // Llamada al servidor de Addon Payments
                    try {
                        var                 jsonObject = JsonConvert.SerializeObject(datos);
                        StringContent       content    = new StringContent(jsonObject, Encoding.UTF8, MediaTypeNames.Application.Json);
                        HttpResponseMessage response   = await client.PostAsync("https://hpp.sandbox.addonpayments.com/pay", content);

                        string responseBody = await response.Content.ReadAsStringAsync();

                        if (response.StatusCode == HttpStatusCode.BadRequest)
                        {
                            throw new Exception(responseBody);
                        }

                        Respuesta jsonResponse = JsonConvert.DeserializeObject <Respuesta>(responseBody);


                        return(Ok(responseBody));
                    } catch (Exception ex) {
                        return(BadRequest(ex.Message));
                    }
                } catch (HttpRequestException e) {
                    return(BadRequest(e));
                }
            }
        }