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_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), request.ToString(), 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);

                // 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", names[1]);
                        }
                    }
                }
                else if (paymentMethod is RecurringPaymentMethod storedCard)
                {
                    hashValue = storedCard.CustomerKey;
                    cardDetail.Set("payer_reference", storedCard.CustomerKey);
                    cardDetail.Set("payment_reference", storedCard.Key);
                }

                // order details
                JsonDoc order = request.SubElement("order");
                order.Set("amount", builder.Amount.ToNumericString());
                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?.ToNumericString());
                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("post_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("post_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));
        }
Example #2
0
        public BatchReportResponse(JsonDoc root)
        {
            var firstDataNode = root.Get("data");

            if (firstDataNode == null)
            {
                throw new MessageException(INVALID_RESPONSE_FORMAT);
            }

            var cmdResult = firstDataNode.Get("cmdResult");

            if (cmdResult == null)
            {
                throw new MessageException(INVALID_RESPONSE_FORMAT);
            }

            Status = cmdResult.GetValue <string>("result");
            if (string.IsNullOrEmpty(Status))
            {
                var errorCode = cmdResult.GetValue <string>("errorCode");
                var errorMsg  = cmdResult.GetValue <string>("errorMessage");
                DeviceResponseText = $"Error: {errorCode} - {errorMsg}";
            }
            else
            {
                // If the Status is not "Success", there is either nothing to process, or something else went wrong.
                // Skip the processing of the rest of the message, as we'll likely hit null reference exceptions
                if (Status == "Success")
                {
                    var secondDataNode = firstDataNode.Get("data");
                    if (secondDataNode == null)
                    {
                        throw new MessageException(INVALID_RESPONSE_FORMAT);
                    }

                    MerchantName    = secondDataNode.GetValue <string>("merchantName");
                    Multiplemessage = secondDataNode.GetValue <string>("multipleMessage");

                    var batchRecord = secondDataNode.Get("batchRecord");
                    if (batchRecord != null)
                    {
                        BatchRecord = new BatchRecordResponse()
                        {
                            BatchId           = batchRecord.GetValue <int>("batchId"),
                            BatchSeqNbr       = batchRecord.GetValue <int>("batchSeqNbr"),
                            BatchStatus       = batchRecord.GetValue <string>("batchStatus"),
                            OpenUtcDateTime   = batchRecord.GetValue <string>("openUtcDateTime"),
                            CloseUtcDateTime  = batchRecord.GetValue <string>("closeUtcDateTime"),
                            OpenTnxId         = batchRecord.GetValue <string>("openTnxId"),
                            TotalAmount       = batchRecord.GetValue <decimal>("totalAmount"),
                            TotalCnt          = batchRecord.GetValue <int>("totalCnt"),
                            CreditCnt         = batchRecord.GetValue <int>("credictCnt"),
                            CreditAmt         = batchRecord.GetValue <decimal>("creditAmt"),
                            DebitCnt          = batchRecord.GetValue <int>("debitCnt"),
                            DebitAmt          = batchRecord.GetValue <decimal>("debitAmt"),
                            SaleCnt           = batchRecord.GetValue <int>("saleCnt"),
                            SaleAmt           = batchRecord.GetValue <decimal>("saleAmt"),
                            ReturnCnt         = batchRecord.GetValue <int>("returnCnt"),
                            ReturnAmt         = batchRecord.GetValue <decimal>("returnAmt"),
                            TotalGratuityAmt  = batchRecord.GetValue <decimal>("totalGratuityAmt"),
                            BatchTransactions = new List <BatchTransactionResponse>()
                        };

                        foreach (var transaction in batchRecord.GetEnumerator("batchTransactions"))
                        {
                            var batchTransaction = new BatchTransactionResponse();
                            batchTransaction.CardType         = transaction.GetValue <string>("cardType");
                            batchTransaction.TotalAmount      = transaction.GetValue <decimal>("totalAmount");
                            batchTransaction.TotalCnt         = transaction.GetValue <int>("totalCnt");
                            batchTransaction.CreditCnt        = transaction.GetValue <int>("creditCnt");
                            batchTransaction.CreditAmt        = transaction.GetValue <decimal>("creditAmt");
                            batchTransaction.DebitCnt         = transaction.GetValue <int>("debitCnt");
                            batchTransaction.DebitAmt         = transaction.GetValue <decimal>("debitAmt");
                            batchTransaction.SaleCnt          = transaction.GetValue <int>("saleCnt");
                            batchTransaction.SaleAmt          = transaction.GetValue <decimal>("saleAmt");
                            batchTransaction.ReturnCnt        = transaction.GetValue <int>("returnCnt");
                            batchTransaction.ReturnAmt        = transaction.GetValue <decimal>("returnAmt");
                            batchTransaction.TotalGratuityAmt = transaction.GetValue <decimal>("totalGratuityAmt");
                            BatchRecord.BatchTransactions.Add(batchTransaction);
                        }
                    }
                }
                else   // the only other option is "Failed"
                {
                    var errorCode = cmdResult.GetValue <string>("errorCode");
                    var errorMsg  = cmdResult.GetValue <string>("errorMessage");
                    DeviceResponseText = $"Error: {errorCode} - {errorMsg}";
                }
            }
        }
        private T MapResponse <T>(string response, ReportType reportType)
        {
            var doc = JsonDoc.Parse(response);

            if (doc.Has("error"))
            {
                var error        = doc.Get("error");
                var errorType    = error.GetValue <string>("errorType");
                var errorCode    = error.GetValue <string>("errorCode");
                var errorMessage = error.GetValue <string>("errorMsg");

                // If it's 1205, then it's no data... which is not an error
                if (errorCode != "1205")
                {
                    throw new GatewayException(errorMessage, errorCode, errorType);
                }
            }

            Func <string, DateTime?> formatDate = (date) => {
                if (!string.IsNullOrEmpty(date))
                {
                    var pattern = "yyyy-MM-dd";
                    if (date.Contains(" "))
                    {
                        pattern += " hh:mm:ss";
                    }

                    return(DateTime.ParseExact(date, pattern, CultureInfo.InvariantCulture));
                }
                return(null);
            };

            T rvalue = Activator.CreateInstance <T>();

            if (reportType.HasFlag(ReportType.FindTransactions))
            {
                Func <JsonDoc, TransactionSummary> hydrateTransactionSummary = (root) => {
                    var summary = new TransactionSummary {
                        MerchantHierarchy    = root.GetValue <string>("merchantHierarchy"),
                        MerchantName         = root.GetValue <string>("merchantName"),
                        MerchantDbaName      = root.GetValue <string>("merchantDbaName"),
                        MerchantNumber       = root.GetValue <string>("merchantNumber"),
                        MerchantCategory     = root.GetValue <string>("merchantCategory"),
                        DepositDate          = formatDate(root.GetValue <string>("transactionDepositDate")),
                        DepositReference     = root.GetValue <string>("transactionDepositReference"),
                        DepositType          = root.GetValue <string>("transactionDepositType"),
                        ServiceName          = root.GetValue <string>("transactionType"),
                        OrderId              = root.GetValue <string>("transactionOrderId"),
                        TransactionLocalDate = formatDate(root.GetValue <string>("transactionLocalTime")),
                        TransactionDate      = formatDate(root.GetValue <string>("transactionTime")),
                        Amount                 = root.GetValue <string>("transactionAmount").ToAmount(),
                        Currency               = root.GetValue <string>("transactionCurrency"),
                        DepositAmount          = root.GetValue <string>("transactionMerchantAmount").ToAmount(),
                        DepositCurrency        = root.GetValue <string>("transactionMerchantCurrency"),
                        MerchantId             = root.GetValue <string>("transactionMid"),
                        TerminalId             = root.GetValue <string>("transactionTid"),
                        BatchSequenceNumber    = root.GetValue <string>("transactionBatchReference"),
                        EntryMode              = root.GetValue <string>("transactionEntryMode"),
                        AquirerReferenceNumber = root.GetValue <string>("transactionArn"),
                        ReferenceNumber        = root.GetValue <string>("transactionReferenceNumber"),
                        CardType               = root.GetValue <string>("transactionCardType"),
                        MaskedCardNumber       = root.GetValue <string>("transactionCardNo"),
                        AuthCode               = root.GetValue <string>("transactionAuthcode"),
                        SchemeReferenceData    = root.GetValue <string>("transactionSrd"),
                        AdjustmentAmount       = root.GetValue <string>("transactionAdjustAmount").ToAmount(),
                        AdjustmentCurrency     = root.GetValue <string>("transactionAdjustCurrency"),
                        AdjustmentReason       = root.GetValue <string>("transactionAdjustReason")
                    };

                    return(summary);
                };

                if (rvalue is IEnumerable <TransactionSummary> )
                {
                    var list = rvalue as List <TransactionSummary>;
                    if (doc.Has("merchantTransactionDetails"))
                    {
                        foreach (var transaction in doc.GetEnumerator("merchantTransactionDetails"))
                        {
                            list.Add(hydrateTransactionSummary(transaction));
                        }
                    }
                }
            }
            else if (reportType.HasFlag(ReportType.FindDepoits))
            {
                Func <JsonDoc, DepositSummary> hydrateDepositSummary = (root) => {
                    var summary = new DepositSummary {
                        MerchantHierarchy = root.GetValue <string>("merchantHierarchy"),
                        MerchantName      = root.GetValue <string>("merchantName"),
                        MerchantDbaName   = root.GetValue <string>("merchantDba"),
                        MerchantNumber    = root.GetValue <string>("merchantNumber"),
                        MerchantCategory  = root.GetValue <string>("merchantCategory"),
                        DepositDate       = DateTime.Parse(root.GetValue <string>("depositDate")),
                        Reference         = root.GetValue <string>("depositReference"),
                        Amount            = root.GetValue <string>("depositPaymentAmount").ToAmount(),
                        Currency          = root.GetValue <string>("depositPaymentCurrency"),
                        Type                       = root.GetValue <string>("depositType"),
                        RoutingNumber              = root.GetValue <string>("depositRoutingNumber"),
                        AccountNumber              = root.GetValue <string>("depositAccountNumber"),
                        Mode                       = root.GetValue <string>("depositMode"),
                        SummaryModel               = root.GetValue <string>("depositSummaryModel"),
                        SalesTotalCount            = root.GetValue <int>("salesTotalNo"),
                        SalesTotalAmount           = root.GetValue <string>("salesTotalAmount").ToAmount(),
                        SalesTotalCurrency         = root.GetValue <string>("salesTotalCurrency"),
                        RefundsTotalCount          = root.GetValue <int>("refundsTotalNo"),
                        RefundsTotalAmount         = root.GetValue <string>("refundsTotalAmount").ToAmount(),
                        RefundsTotalCurrency       = root.GetValue <string>("refundsTotalCurrency"),
                        ChargebackTotalCount       = root.GetValue <int>("disputeCbTotalNo"),
                        ChargebackTotalAmount      = root.GetValue <string>("disputeCbTotalAmount").ToAmount(),
                        ChargebackTotalCurrency    = root.GetValue <string>("disputeCbTotalCurrency"),
                        RepresentmentTotalCount    = root.GetValue <int>("disputeRepresentmentTotalNo"),
                        RepresentmentTotalAmount   = root.GetValue <string>("disputeRepresentmentTotalAmount").ToAmount(),
                        RepresentmentTotalCurrency = root.GetValue <string>("disputeRepresentmentTotalCurrency"),
                        FeesTotalAmount            = root.GetValue <string>("feesTotalAmount").ToAmount(),
                        FeesTotalCurrency          = root.GetValue <string>("feesTotalCurrency"),
                        AdjustmentTotalCount       = root.GetValue <int>("adjustmentTotalNumber"),
                        AdjustmentTotalAmount      = root.GetValue <string>("adjustmentTotalAmount").ToAmount(),
                        AdjustmentTotalCurrency    = root.GetValue <string>("adjustmentTotalCurrency")
                    };
                    return(summary);
                };

                if (rvalue is IEnumerable <DepositSummary> )
                {
                    var list = rvalue as List <DepositSummary>;
                    if (doc.Has("merchantDepositDetails"))
                    {
                        foreach (var deposit in doc.GetEnumerator("merchantDepositDetails"))
                        {
                            list.Add(hydrateDepositSummary(deposit));
                        }
                    }
                }
            }
            else if (reportType.HasFlag(ReportType.FindDisputes))
            {
                Func <JsonDoc, DisputeSummary> hydrateDisputeSummary = (root) => {
                    var summary = new DisputeSummary {
                        MerchantHierarchy = root.GetValue <string>("merchantHierarchy"),
                        MerchantName      = root.GetValue <string>("merchantName"),
                        MerchantDbaName   = root.GetValue <string>("merchantDba"),
                        MerchantNumber    = root.GetValue <string>("merchantNumber"),
                        MerchantCategory  = root.GetValue <string>("merchantCategory"),
                        DepositDate       = formatDate(root.GetValue <string>("disputeDepositDate")),
                        DepositReference  = root.GetValue <string>("disputeDepositReference"),
                        DepositType       = root.GetValue <string>("disputeDepositType"),
                        Type                        = root.GetValue <string>("disputeType"),
                        CaseAmount                  = root.GetValue <string>("disputeCaseAmount").ToAmount(),
                        CaseCurrency                = root.GetValue <string>("disputeCaseCurrency"),
                        CaseStatus                  = root.GetValue <string>("disputeCaseStatus"),
                        CaseDescription             = root.GetValue <string>("disputeCaseDescription"),
                        TransactionOrderId          = root.GetValue <string>("disputeTransactionOrderId"),
                        TransactionLocalTime        = formatDate(root.GetValue <string>("disputeTransactionLocalTime")),
                        TransactionTime             = formatDate(root.GetValue <string>("disputeTransactionTime")),
                        TransactionType             = root.GetValue <string>("disputeTransactionType"),
                        TransactionAmount           = root.GetValue <string>("disputeTransactionAmount").ToAmount(),
                        TransactionCurrency         = root.GetValue <string>("disputeTransactionCurrency"),
                        CaseNumber                  = root.GetValue <string>("disputeCaseNo"),
                        CaseTime                    = formatDate(root.GetValue <string>("disputeCaseTime")),
                        CaseId                      = root.GetValue <string>("disputeCaseId"),
                        CaseIdTime                  = formatDate(root.GetValue <string>("disputeCaseIdTime")),
                        CaseMerchantId              = root.GetValue <string>("disputeCaseMid"),
                        CaseTerminalId              = root.GetValue <string>("disputeCaseTid"),
                        TransactionARN              = root.GetValue <string>("disputeTransactionARN"),
                        TransactionReferenceNumber  = root.GetValue <string>("disputeTransactionReferenceNumber"),
                        TransactionSRD              = root.GetValue <string>("disputeTransactionSRD"),
                        TransactionAuthCode         = root.GetValue <string>("disputeTransactionAuthcode"),
                        TransactionCardType         = root.GetValue <string>("disputeTransactionCardType"),
                        TransactionMaskedCardNumber = root.GetValue <string>("disputeTransactionCardNo"),
                        Reason                      = root.GetValue <string>("disputeReason"),
                        IssuerComment               = root.GetValue <string>("disputeIssuerComment"),
                        IssuerCaseNumber            = root.GetValue <string>("disputeIssuerCaseNo"),
                        DisputeAmount               = root.GetValue <string>("disputeAmount").ToAmount(),
                        DisputeCurrency             = root.GetValue <string>("disputeCurrency"),
                        DisputeCustomerAmount       = root.GetValue <string>("disputeCustomerAmount").ToAmount(),
                        DisputeCustomerCurrency     = root.GetValue <string>("disputeCustomerCurrency"),
                        RespondByDate               = formatDate(root.GetValue <string>("disputeRespondByDate")),
                        CaseOriginalReference       = root.GetValue <string>("disputeCaseOriginalReference")
                    };
                    return(summary);
                };

                if (rvalue is IEnumerable <DisputeSummary> )
                {
                    var list = rvalue as List <DisputeSummary>;
                    if (doc.Has("merchantDisputeDetails"))
                    {
                        foreach (var dispute in doc.GetEnumerator("merchantDisputeDetails"))
                        {
                            list.Add(hydrateDisputeSummary(dispute));
                        }
                    }
                }
            }

            return(rvalue);
        }
        private Transaction MapResponse(string rawResponse)
        {
            JsonDoc doc = JsonDoc.Parse(rawResponse);

            ThreeDSecure secureEcom = new ThreeDSecure();

            // check enrolled
            secureEcom.ServerTransactionId = doc.GetValue <string>("server_trans_id");
            if (doc.Has("enrolled"))
            {
                secureEcom.Enrolled = doc.GetValue <string>("enrolled");
            }
            secureEcom.IssuerAcsUrl = doc.GetValue <string>("method_url", "challenge_request_url");

            // get authentication data
            secureEcom.AcsTransactionId             = doc.GetValue <string>("acs_trans_id");
            secureEcom.DirectoryServerTransactionId = doc.GetValue <string>("ds_trans_id");
            secureEcom.AuthenticationType           = doc.GetValue <string>("authentication_type");
            secureEcom.AuthenticationValue          = doc.GetValue <string>("authentication_value");
            secureEcom.Eci                  = doc.GetValue <int>("eci");
            secureEcom.Status               = doc.GetValue <string>("status");
            secureEcom.StatusReason         = doc.GetValue <string>("status_reason");
            secureEcom.AuthenticationSource = doc.GetValue <string>("authentication_source");
            secureEcom.MessageCategory      = doc.GetValue <string>("message_category");
            secureEcom.MessageVersion       = doc.GetValue <string>("message_version");

            // challenge mandated
            if (doc.Has("challenge_mandated"))
            {
                secureEcom.ChallengeMandated = doc.GetValue <bool>("challenge_mandated");
            }

            // initiate authentication
            secureEcom.CardHolderResponseInfo = doc.GetValue <string>("cardholder_response_info");

            // device_render_options
            if (doc.Has("device_render_options"))
            {
                JsonDoc renderOptions = doc.Get("device_render_options");
                secureEcom.SdkInterface = renderOptions.GetValue <string>("sdk_interface");
                secureEcom.SdkUiType    = renderOptions.GetArray <string>("sdk_ui_type");
            }

            // message_extension
            if (doc.Has("message_extension"))
            {
                foreach (JsonDoc messageExtension in doc.GetEnumerator("message_extension"))
                {
                    secureEcom.CriticalityIndicator = messageExtension.GetValue <string>("criticality_indicator");
                    //secureEcom.MessageExtensionData = messageExtensions.GetValue<string>("data");
                    secureEcom.MessageExtensionId   = messageExtension.GetValue <string>("id");
                    secureEcom.MessageExtensionName = messageExtension.GetValue <string>("name");
                }
            }

            // versions
            secureEcom.DirectoryServerEndVersion   = doc.GetValue <string>("ds_protocol_version_end");
            secureEcom.DirectoryServerStartVersion = doc.GetValue <string>("ds_protocol_version_start");
            secureEcom.AcsEndVersion   = doc.GetValue <string>("acs_protocol_version_end");
            secureEcom.AcsStartVersion = doc.GetValue <string>("acs_protocol_version_start");

            // payer authentication request
            if (doc.Has("method_data"))
            {
                JsonDoc methodData = doc.Get("method_data");
                secureEcom.PayerAuthenticationRequest = methodData.GetValue <string>("encoded_method_data");
            }
            else if (doc.Has("encoded_creq"))
            {
                secureEcom.PayerAuthenticationRequest = doc.GetValue <string>("encoded_creq");
            }

            Transaction response = new Transaction {
                ThreeDSecure = secureEcom
            };

            return(response);
        }
Example #5
0
 internal override void FromJson(JsonDoc doc, PayrollEncoder encoder)
 {
     throw new NotImplementedException();
 }
        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("HPP_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);

                // 3DSv2
                request.Set("HPP_CUSTOMER_EMAIL", builder.HostedPaymentData.CustomerEmail);
                request.Set("HPP_CUSTOMER_PHONENUMBER_MOBILE", builder.HostedPaymentData.CustomerPhoneMobile);
                request.Set("HPP_CHALLENGE_REQUEST_INDICATOR", builder.HostedPaymentData.ChallengeRequest);
                if (builder.HostedPaymentData.AddressesMatch != null)
                {
                    request.Set("HPP_ADDRESS_MATCH_INDICATOR", builder.HostedPaymentData.AddressesMatch.Value ? "TRUE" : "FALSE");
                }

                // SUPPLIMENTARY DATA
                if (builder.HostedPaymentData.SupplementaryData != null)
                {
                    foreach (string key in builder.HostedPaymentData.SupplementaryData.Keys)
                    {
                        request.Set(key, builder.HostedPaymentData.SupplementaryData[key]);
                    }
                }
            }
            if (builder.ShippingAddress != null)
            {
                // FRAUD VALUES
                request.Set("SHIPPING_CODE", builder.ShippingAddress.PostalCode);
                request.Set("SHIPPING_CO", builder.ShippingAddress.Country);

                // 3DS2 VALUES
                request.Set("HPP_SHIPPING_STREET1", builder.ShippingAddress.StreetAddress1);
                request.Set("HPP_SHIPPING_STREET2", builder.ShippingAddress.StreetAddress2);
                request.Set("HPP_SHIPPING_STREET3", builder.ShippingAddress.StreetAddress3);
                request.Set("HPP_SHIPPING_CITY", builder.ShippingAddress.City);
                request.Set("HPP_SHIPPING_STATE", builder.ShippingAddress.State);
                request.Set("HPP_SHIPPING_POSTALCODE", builder.ShippingAddress.PostalCode);
                request.Set("HPP_SHIPPING_COUNTRY", builder.ShippingAddress.Country);
            }
            if (builder.BillingAddress != null)
            {
                // FRAUD VALUES
                request.Set("BILLING_CODE", builder.BillingAddress.PostalCode);
                request.Set("BILLING_CO", builder.BillingAddress.Country);

                // 3DS2 VALUES
                request.Set("HPP_BILLING_STREET1", builder.BillingAddress.StreetAddress1);
                request.Set("HPP_BILLING_STREET2", builder.BillingAddress.StreetAddress2);
                request.Set("HPP_BILLING_STREET3", builder.BillingAddress.StreetAddress3);
                request.Set("HPP_BILLING_CITY", builder.BillingAddress.City);
                request.Set("HPP_BILLING_STATE", builder.BillingAddress.State);
                request.Set("HPP_BILLING_POSTALCODE", builder.BillingAddress.PostalCode);
                request.Set("HPP_BILLING_COUNTRY", 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());
        }
 private static void SetPagingInfo <T>(PagedResult <T> result, JsonDoc json) where T : class
 {
     result.TotalRecordCount = json.GetValue <int>("total_record_count", "total_count");
     result.PageSize         = json.GetValue <int>("max_page_size");
     result.Page             = json.GetValue <int>("page_number");
 }
Example #8
0
        public GpApiTokenResponse(string jsonString)
        {
            JsonDoc doc = JsonDoc.Parse(jsonString);

            MapResponseValues(doc);
        }
Example #9
0
        internal static GpApiRequest BuildRequest(AuthorizationBuilder builder, GpApiConnector gateway)
        {
            var paymentMethod = new JsonDoc()
                                .Set("entry_mode", GetEntryMode(builder)); // [MOTO, ECOM, IN_APP, CHIP, SWIPE, MANUAL, CONTACTLESS_CHIP, CONTACTLESS_SWIPE]

            if (builder.PaymentMethod is ICardData)
            {
                var cardData = builder.PaymentMethod as ICardData;

                var card = new JsonDoc()
                           .Set("number", cardData.Number)
                           .Set("expiry_month", cardData.ExpMonth.HasValue ? cardData.ExpMonth.ToString().PadLeft(2, '0') : null)
                           .Set("expiry_year", cardData.ExpYear.HasValue ? cardData.ExpYear.ToString().PadLeft(4, '0').Substring(2, 2) : null)
                           //.Set("track", "")
                           .Set("tag", builder.TagData)
                           .Set("cvv", cardData.Cvn)
                           .Set("cvv_indicator", EnumConverter.GetMapping(Target.GP_API, cardData.CvnPresenceIndicator)) // [ILLEGIBLE, NOT_PRESENT, PRESENT]
                           .Set("avs_address", builder.BillingAddress?.StreetAddress1)
                           .Set("avs_postal_code", builder.BillingAddress?.PostalCode)
                           .Set("funding", builder.PaymentMethod?.PaymentMethodType == PaymentMethodType.Debit ? "DEBIT" : "CREDIT") // [DEBIT, CREDIT]
                           .Set("authcode", builder.OfflineAuthCode);
                //.Set("brand_reference", "")

                card.Set("chip_condition", EnumConverter.GetMapping(Target.GP_API, builder.EmvChipCondition)); // [PREV_SUCCESS, PREV_FAILED]

                paymentMethod.Set("card", card);

                var tokenizationData = new JsonDoc()
                                       .Set("account_name", gateway.TokenizationAccountName)
                                       .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                       .Set("usage_mode", EnumConverter.GetMapping(Target.GP_API, builder.TokenUsageMode))
                                       .Set("name", "")
                                       .Set("card", card);

                if (builder.TransactionType == TransactionType.Tokenize)
                {
                    return(new GpApiRequest {
                        Verb = HttpMethod.Post,
                        Endpoint = "/payment-methods",
                        RequestBody = tokenizationData.ToString(),
                    });
                }
                else if (builder.TransactionType == TransactionType.Verify)
                {
                    if (builder.RequestMultiUseToken && string.IsNullOrEmpty((builder.PaymentMethod as ITokenizable).Token))
                    {
                        return(new GpApiRequest {
                            Verb = HttpMethod.Post,
                            Endpoint = "/payment-methods",
                            RequestBody = tokenizationData.ToString(),
                        });
                    }
                    else
                    {
                        var verificationData = new JsonDoc()
                                               .Set("account_name", gateway.TransactionProcessingAccountName)
                                               .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.Channel))
                                               .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                               .Set("currency", builder.Currency)
                                               .Set("country", gateway.Country)
                                               .Set("payment_method", paymentMethod);

                        if (builder.PaymentMethod is ITokenizable && !string.IsNullOrEmpty((builder.PaymentMethod as ITokenizable).Token))
                        {
                            verificationData.Remove("payment_method");
                            verificationData.Set("payment_method", new JsonDoc()
                                                 .Set("entry_mode", GetEntryMode(builder))
                                                 .Set("id", (builder.PaymentMethod as ITokenizable).Token)
                                                 );
                        }

                        return(new GpApiRequest {
                            Verb = HttpMethod.Post,
                            Endpoint = "/verifications",
                            RequestBody = verificationData.ToString(),
                        });
                    }
                }
            }
            else if (builder.PaymentMethod is ITrackData)
            {
                var track = builder.PaymentMethod as ITrackData;

                var card = new JsonDoc()
                           .Set("track", track.Value)
                           .Set("tag", builder.TagData)
                           .Set("avs_address", builder.BillingAddress?.StreetAddress1)
                           .Set("avs_postal_code", builder.BillingAddress?.PostalCode)
                           .Set("authcode", builder.OfflineAuthCode);

                if (builder.TransactionType == TransactionType.Verify)
                {
                    paymentMethod.Set("card", card);

                    var verificationData = new JsonDoc()
                                           .Set("account_name", gateway.TransactionProcessingAccountName)
                                           .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.Channel))
                                           .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                           .Set("currency", builder.Currency)
                                           .Set("country", gateway.Country)
                                           .Set("payment_method", paymentMethod);

                    return(new GpApiRequest {
                        Verb = HttpMethod.Post,
                        Endpoint = "/verifications",
                        RequestBody = verificationData.ToString(),
                    });
                }

                if (builder.TransactionType == TransactionType.Sale || builder.TransactionType == TransactionType.Refund)
                {
                    if (string.IsNullOrEmpty(track.Value))
                    {
                        card.Set("number", track.Pan);
                        card.Set("expiry_month", track.Expiry?.Substring(2, 2));
                        card.Set("expiry_year", track.Expiry?.Substring(0, 2));
                    }
                    if (string.IsNullOrEmpty(builder.TagData))
                    {
                        card.Set("chip_condition", EnumConverter.GetMapping(Target.GP_API, builder.EmvChipCondition)); // [PREV_SUCCESS, PREV_FAILED]
                    }
                }

                if (builder.TransactionType == TransactionType.Sale)
                {
                    card.Set("funding", builder.PaymentMethod?.PaymentMethodType == PaymentMethodType.Debit ? "DEBIT" : "CREDIT"); // [DEBIT, CREDIT]
                }

                paymentMethod.Set("card", card);
            }

            // payment method storage mode
            if (builder.RequestMultiUseToken)
            {
                //ToDo: there might be a typo: should be storage_mode
                paymentMethod.Set("storage_model", "ON_SUCCESS");
            }

            // tokenized payment method
            if (builder.PaymentMethod is ITokenizable)
            {
                string token = ((ITokenizable)builder.PaymentMethod).Token;
                if (!string.IsNullOrEmpty(token))
                {
                    paymentMethod.Set("id", token);
                }
            }

            // pin block
            if (builder.PaymentMethod is IPinProtected)
            {
                paymentMethod.Get("card")?.Set("pin_block", ((IPinProtected)builder.PaymentMethod).PinBlock);
            }

            // authentication
            if (builder.PaymentMethod is CreditCardData)
            {
                paymentMethod.Set("name", (builder.PaymentMethod as CreditCardData).CardHolderName);

                var secureEcom = (builder.PaymentMethod as CreditCardData).ThreeDSecure;
                if (secureEcom != null)
                {
                    var three_ds = new JsonDoc()
                                   // Indicates the version of 3DS
                                   .Set("message_version", secureEcom.MessageVersion)
                                   // An indication of the degree of the authentication and liability shift obtained for this transaction.
                                   // It is determined during the 3D Secure process.
                                   .Set("eci", secureEcom.Eci)
                                   // The authentication value created as part of the 3D Secure process.
                                   .Set("value", secureEcom.AuthenticationValue)
                                   // The reference created by the 3DSecure provider to identify the specific authentication attempt.
                                   .Set("server_trans_ref", secureEcom.ServerTransactionId)
                                   // The reference created by the 3DSecure Directory Server to identify the specific authentication attempt.
                                   .Set("ds_trans_ref", secureEcom.DirectoryServerTransactionId);

                    var authentication = new JsonDoc().Set("three_ds", three_ds);

                    paymentMethod.Set("authentication", authentication);
                }
            }

            // encryption
            if (builder.PaymentMethod is IEncryptable)
            {
                var encryptionData = ((IEncryptable)builder.PaymentMethod).EncryptionData;

                if (encryptionData != null)
                {
                    var encryption = new JsonDoc()
                                     .Set("version", encryptionData.Version);

                    if (!string.IsNullOrEmpty(encryptionData.KTB))
                    {
                        encryption.Set("method", "KTB");
                        encryption.Set("info", encryptionData.KTB);
                    }
                    else if (!string.IsNullOrEmpty(encryptionData.KSN))
                    {
                        encryption.Set("method", "KSN");
                        encryption.Set("info", encryptionData.KSN);
                    }

                    if (encryption.Has("info"))
                    {
                        paymentMethod.Set("encryption", encryption);
                    }
                }
            }

            var data = new JsonDoc()
                       .Set("account_name", gateway.TransactionProcessingAccountName)
                       .Set("type", builder.TransactionType == TransactionType.Refund ? "REFUND" : "SALE") // [SALE, REFUND]
                       .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.Channel))           // [CP, CNP]
                       .Set("capture_mode", GetCaptureMode(builder))                                       // [AUTO, LATER, MULTIPLE]
                                                                                                           //.Set("remaining_capture_count", "") //Pending Russell
                       .Set("authorization_mode", builder.AllowPartialAuth ? "PARTIAL" : null)
                       .Set("amount", builder.Amount.ToNumericCurrencyString())
                       .Set("currency", builder.Currency)
                       .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                       .Set("description", builder.Description)
                       //.Set("order_reference", builder.OrderId)
                       .Set("gratuity_amount", builder.Gratuity.ToNumericCurrencyString())
                       .Set("cashback_amount", builder.CashBackAmount.ToNumericCurrencyString())
                       .Set("surcharge_amount", builder.SurchargeAmount.ToNumericCurrencyString())
                       .Set("convenience_amount", builder.ConvenienceAmount.ToNumericCurrencyString())
                       .Set("country", gateway.Country)
                       //.Set("language", EnumConverter.GetMapping(Target.GP_API, Language))
                       .Set("ip_address", builder.CustomerIpAddress)
                       //.Set("site_reference", "") //
                       .Set("payment_method", paymentMethod);

            // set order reference
            if (!string.IsNullOrEmpty(builder.OrderId))
            {
                var order = new JsonDoc()
                            .Set("reference", builder.OrderId);

                data.Set("order", order);
            }

            // stored credential
            if (builder.StoredCredential != null)
            {
                data.Set("initiator", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Initiator));
                var storedCredential = new JsonDoc()
                                       .Set("model", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Type))
                                       .Set("reason", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Reason))
                                       .Set("sequence", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Sequence));
                data.Set("stored_credential", storedCredential);
            }

            return(new GpApiRequest {
                Verb = HttpMethod.Post,
                Endpoint = "/transactions",
                RequestBody = data.ToString(),
            });
        }
        private static JsonDoc setOrderInformation(AuthorizationBuilder builder, ref JsonDoc requestBody)
        {
            JsonDoc order;

            if (requestBody.Has("order"))
            {
                order = requestBody.Get("order");
            }
            else
            {
                order = new JsonDoc();
            }
            order.Set("description", builder.OrderDetails?.Description);

            if (builder.ShippingAddress != null)
            {
                var shippingAddress = new JsonDoc()
                                      .Set("line1", builder.ShippingAddress.StreetAddress1)
                                      .Set("line2", builder.ShippingAddress.StreetAddress2)
                                      .Set("line3", builder.ShippingAddress.StreetAddress3)
                                      .Set("city", builder.ShippingAddress.City)
                                      .Set("postal_code", builder.ShippingAddress.PostalCode)
                                      .Set("state", builder.ShippingAddress.State)
                                      .Set("country", builder.ShippingAddress.CountryCode);

                order.Set("shipping_address", shippingAddress);
            }

            var shippingPhone = new JsonDoc()
                                .Set("country_code", builder.ShippingPhone?.CountryCode)
                                .Set("subscriber_number", builder.ShippingPhone?.Number);

            order.Set("shipping_phone", shippingPhone);

            decimal taxTotalAmount = 0;
            decimal itemsAmount    = 0;
            decimal?orderAmount    = null;

            if (builder.MiscProductData != null)
            {
                var items = new List <Dictionary <string, object> >();
                foreach (var product in builder.MiscProductData)
                {
                    var qta        = product.Quantity ?? 0;
                    var taxAmount  = product.TaxAmount ?? 0;
                    var unitAmount = product.UnitPrice ?? 0;
                    var item       = new Dictionary <string, object>();
                    item.Add("reference", product.ProductId);
                    item.Add("label", product.ProductName);
                    item.Add("description", product.Description);
                    item.Add("quantity", qta);
                    item.Add("unit_amount", unitAmount.ToNumericCurrencyString());
                    item.Add("unit_currency", product.UnitCurrency);
                    item.Add("tax_amount", taxAmount.ToNumericCurrencyString());
                    item.Add("amount", (qta * unitAmount).ToNumericCurrencyString());
                    items.Add(item);
                    taxTotalAmount += taxAmount;
                    itemsAmount    += unitAmount;
                }

                order.Set("tax_amount", taxTotalAmount.ToNumericCurrencyString());
                order.Set("item_amount", itemsAmount.ToNumericCurrencyString());
                var shippingAmount = builder.ShippingAmt ?? 0;
                order.Set("shipping_amount", builder.ShippingAmt.ToNumericCurrencyString());
                order.Set("insurance_offered", builder.OrderDetails != null ? (builder.OrderDetails.HasInsurance ? "YES" : "NO") : null);
                order.Set("shipping_discount", builder.ShippingDiscount?.ToNumericCurrencyString());
                order.Set("insurance_amount", builder.OrderDetails?.InsuranceAmount?.ToNumericCurrencyString());
                order.Set("handling_amount", builder.OrderDetails?.HandlingAmount?.ToNumericCurrencyString());
                var insuranceAmount = builder.OrderDetails?.InsuranceAmount ?? 0;
                var handlingAmount  = builder.OrderDetails?.HandlingAmount ?? 0;
                orderAmount = itemsAmount + taxTotalAmount + handlingAmount + insuranceAmount + shippingAmount;
                order.Set("amount", orderAmount.ToNumericCurrencyString());
                order.Set("currency", builder.Currency);
                order.Set("items", items);
            }
            if (!requestBody.Has("order"))
            {
                requestBody.Set("order", order);
            }

            return(requestBody);
        }
        internal static GpApiRequest BuildRequest(AuthorizationBuilder builder, GpApiConnector gateway)
        {
            var merchantUrl   = !string.IsNullOrEmpty(gateway.GpApiConfig.MerchantId) ? $"/merchants/{gateway.GpApiConfig.MerchantId}" : string.Empty;
            var paymentMethod = new JsonDoc()
                                .Set("entry_mode", GetEntryMode(builder, gateway.GpApiConfig.Channel)); // [MOTO, ECOM, IN_APP, CHIP, SWIPE, MANUAL, CONTACTLESS_CHIP, CONTACTLESS_SWIPE]

            paymentMethod.Set("narrative", !string.IsNullOrEmpty(builder.DynamicDescriptor) ? builder.DynamicDescriptor : null);
            if (builder.PaymentMethod is CreditCardData && (builder.TransactionModifier == TransactionModifier.EncryptedMobile || builder.TransactionModifier == TransactionModifier.DecryptedMobile))
            {
                var digitalWallet  = new JsonDoc();
                var creditCardData = (builder.PaymentMethod as CreditCardData);
                //Digital Wallet
                if (builder.TransactionModifier == TransactionModifier.EncryptedMobile)
                {
                    digitalWallet
                    .Set("payment_token", JsonDoc.Parse(creditCardData.Token));
                }
                else if (builder.TransactionModifier == TransactionModifier.DecryptedMobile)
                {
                    var tokenFormat = DigitalWalletTokenFormat.CARD_NUMBER;
                    digitalWallet
                    .Set("token", creditCardData.Token)
                    .Set("token_format", DigitalWalletTokenFormat.CARD_NUMBER)
                    .Set("expiry_month", creditCardData.ExpMonth.HasValue ? creditCardData.ExpMonth.ToString().PadLeft(2, '0') : null)
                    .Set("expiry_year", creditCardData.ExpYear.HasValue ? creditCardData.ExpYear.ToString().PadLeft(4, '0').Substring(2, 2) : null)
                    .Set("cryptogram", creditCardData.Cryptogram)
                    .Set("eci", creditCardData.Eci);
                }
                digitalWallet.Set("provider", (builder.PaymentMethod as CreditCardData).MobileType);
                paymentMethod.Set("digital_wallet", digitalWallet);
            }
            else
            {
                if (builder.PaymentMethod is ICardData)
                {
                    var cardData = builder.PaymentMethod as ICardData;

                    var card = new JsonDoc()
                               .Set("number", cardData.Number)
                               .Set("expiry_month", cardData.ExpMonth.HasValue ? cardData.ExpMonth.ToString().PadLeft(2, '0') : null)
                               .Set("expiry_year", cardData.ExpYear.HasValue ? cardData.ExpYear.ToString().PadLeft(4, '0').Substring(2, 2) : null)
                               //.Set("track", "")
                               .Set("tag", builder.TagData)
                               .Set("cvv", cardData.Cvn)
                               .Set("avs_address", builder.BillingAddress?.StreetAddress1)
                               .Set("avs_postal_code", builder.BillingAddress?.PostalCode)
                               .Set("authcode", builder.OfflineAuthCode)
                               .Set("brand_reference", builder.CardBrandTransactionId);

                    card.Set("chip_condition", EnumConverter.GetMapping(Target.GP_API, builder.EmvChipCondition)); // [PREV_SUCCESS, PREV_FAILED]

                    if (!(builder.TransactionType == TransactionType.Tokenize || builder.TransactionType == TransactionType.Verify))
                    {
                        card.Set("cvv_indicator", cardData.CvnPresenceIndicator != 0 ? EnumConverter.GetMapping(Target.GP_API, cardData.CvnPresenceIndicator) : null); // [ILLEGIBLE, NOT_PRESENT, PRESENT]
                        card.Set("funding", builder.PaymentMethod?.PaymentMethodType == PaymentMethodType.Debit ? "DEBIT" : "CREDIT");                                 // [DEBIT, CREDIT]
                    }

                    var hasToken = builder.PaymentMethod is ITokenizable tokenData && !string.IsNullOrEmpty(tokenData.Token);

                    if (!hasToken)
                    {
                        paymentMethod.Set("card", card);
                    }


                    if (builder.TransactionType == TransactionType.Tokenize)
                    {
                        var tokenizationData = new JsonDoc()
                                               .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TokenizationAccountName)
                                               .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                               .Set("usage_mode", EnumConverter.GetMapping(Target.GP_API, builder.PaymentMethodUsageMode))
                                               .Set("card", card);

                        return(new GpApiRequest {
                            Verb = HttpMethod.Post,
                            Endpoint = $"{merchantUrl}/payment-methods",
                            RequestBody = tokenizationData.ToString(),
                        });
                    }
                    else if (builder.TransactionType == TransactionType.DccRateLookup)
                    {
                        // tokenized payment method
                        if (builder.PaymentMethod is ITokenizable)
                        {
                            string token = ((ITokenizable)builder.PaymentMethod).Token;
                            if (!string.IsNullOrEmpty(token))
                            {
                                paymentMethod.Set("id", token);
                            }
                        }

                        var RequestData = new JsonDoc()
                                          .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TransactionProcessingAccountName)
                                          .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.GpApiConfig.Channel))
                                          .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                          .Set("amount", builder.Amount.ToNumericCurrencyString())
                                          .Set("currency", builder.Currency)
                                          .Set("country", gateway.GpApiConfig.Country)
                                          .Set("payment_method", paymentMethod);

                        return(new GpApiRequest
                        {
                            Verb = HttpMethod.Post,
                            Endpoint = $"{merchantUrl}/currency-conversions",
                            RequestBody = RequestData.ToString(),
                        });
                    }
                    else if (builder.TransactionType == TransactionType.Verify)
                    {
                        if (builder.RequestMultiUseToken && string.IsNullOrEmpty((builder.PaymentMethod as ITokenizable).Token))
                        {
                            var tokenizationData = new JsonDoc()
                                                   .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TokenizationAccountName)
                                                   .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                                   .Set("usage_mode", EnumConverter.GetMapping(Target.GP_API, builder.PaymentMethodUsageMode))
                                                   .Set("fingerprint_mode", builder.CustomerData?.DeviceFingerPrint ?? null)
                                                   .Set("card", card);

                            return(new GpApiRequest {
                                Verb = HttpMethod.Post,
                                Endpoint = $"{merchantUrl}/payment-methods",
                                RequestBody = tokenizationData.ToString(),
                            });
                        }
                        else
                        {
                            var verificationData = new JsonDoc()
                                                   .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TransactionProcessingAccountName)
                                                   .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.GpApiConfig.Channel))
                                                   .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                                   .Set("currency", builder.Currency)
                                                   .Set("country", gateway.GpApiConfig.Country)
                                                   .Set("payment_method", paymentMethod);

                            if (builder.PaymentMethod is ITokenizable && !string.IsNullOrEmpty((builder.PaymentMethod as ITokenizable).Token))
                            {
                                verificationData.Remove("payment_method");
                                verificationData.Set("payment_method", new JsonDoc()
                                                     .Set("entry_mode", GetEntryMode(builder, gateway.GpApiConfig.Channel))
                                                     .Set("id", (builder.PaymentMethod as ITokenizable).Token)
                                                     .Set("fingerprint_mode", builder.CustomerData?.DeviceFingerPrint ?? null)
                                                     );
                            }

                            return(new GpApiRequest {
                                Verb = HttpMethod.Post,
                                Endpoint = $"{merchantUrl}/verifications",
                                RequestBody = verificationData.ToString(),
                            });
                        }
                    }
                }
                else if (builder.PaymentMethod is ITrackData)
                {
                    var track = builder.PaymentMethod as ITrackData;

                    var card = new JsonDoc()
                               .Set("track", track.Value)
                               .Set("tag", builder.TagData)
                               .Set("avs_address", builder.BillingAddress?.StreetAddress1)
                               .Set("avs_postal_code", builder.BillingAddress?.PostalCode)
                               .Set("authcode", builder.OfflineAuthCode);

                    if (builder.TransactionType == TransactionType.Verify)
                    {
                        paymentMethod.Set("card", card);

                        var verificationData = new JsonDoc()
                                               .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TransactionProcessingAccountName)
                                               .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.GpApiConfig.Channel))
                                               .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                                               .Set("currency", builder.Currency)
                                               .Set("country", gateway.GpApiConfig.Country)
                                               .Set("payment_method", paymentMethod)
                                               .Set("fingerprint_mode", builder.CustomerData?.DeviceFingerPrint ?? null);

                        return(new GpApiRequest {
                            Verb = HttpMethod.Post,
                            Endpoint = $"{merchantUrl}/verifications",
                            RequestBody = verificationData.ToString(),
                        });
                    }

                    if (builder.TransactionType == TransactionType.Sale || builder.TransactionType == TransactionType.Refund)
                    {
                        if (string.IsNullOrEmpty(track.Value))
                        {
                            card.Set("number", track.Pan);
                            card.Set("expiry_month", track.Expiry?.Substring(2, 2));
                            card.Set("expiry_year", track.Expiry?.Substring(0, 2));
                        }
                        if (string.IsNullOrEmpty(builder.TagData))
                        {
                            card.Set("chip_condition", EnumConverter.GetMapping(Target.GP_API, builder.EmvChipCondition)); // [PREV_SUCCESS, PREV_FAILED]
                        }
                    }

                    if (builder.TransactionType == TransactionType.Sale)
                    {
                        card.Set("funding", builder.PaymentMethod?.PaymentMethodType == PaymentMethodType.Debit ? "DEBIT" : "CREDIT"); // [DEBIT, CREDIT]
                    }

                    paymentMethod.Set("card", card);
                }

                // tokenized payment method
                if (builder.PaymentMethod is ITokenizable)
                {
                    string token = ((ITokenizable)builder.PaymentMethod).Token;
                    if (!string.IsNullOrEmpty(token))
                    {
                        paymentMethod.Set("id", token);
                    }
                }
            }
            // payment method storage mode
            if (builder.RequestMultiUseToken)
            {
                //ToDo: there might be a typo: should be storage_mode
                paymentMethod.Set("storage_mode", "ON_SUCCESS");
            }

            // pin block
            if (builder.PaymentMethod is IPinProtected)
            {
                paymentMethod.Get("card")?.Set("pin_block", ((IPinProtected)builder.PaymentMethod).PinBlock);
            }

            // authentication
            if (builder.PaymentMethod is CreditCardData)
            {
                paymentMethod.Set("name", (builder.PaymentMethod as CreditCardData).CardHolderName);

                var secureEcom = (builder.PaymentMethod as CreditCardData).ThreeDSecure;
                if (secureEcom != null)
                {
                    var authentication = new JsonDoc().Set("id", secureEcom.ServerTransactionId);

                    paymentMethod.Set("authentication", authentication);
                }

                paymentMethod.Set("fingerprint_mode", builder.CustomerData?.DeviceFingerPrint ?? null);
            }

            if (builder.PaymentMethod is EBT)
            {
                paymentMethod.Set("name", (builder.PaymentMethod as EBT).CardHolderName);
            }

            if (builder.PaymentMethod is eCheck)
            {
                eCheck check = (builder.PaymentMethod as eCheck);
                paymentMethod.Set("name", check.CheckHolderName);

                var bankTransfer = new JsonDoc()
                                   .Set("account_number", check.AccountNumber)
                                   .Set("account_type", (check.AccountType != null) ? EnumConverter.GetMapping(Target.GP_API, check.AccountType) : null)
                                   .Set("check_reference", check.CheckReference)
                                   .Set("sec_code", check.SecCode)
                                   .Set("narrative", check.MerchantNotes);

                var bank = new JsonDoc()
                           .Set("code", check.RoutingNumber)
                           .Set("name", check.BankName);

                var address = new JsonDoc()
                              .Set("line_1", check.BankAddress?.StreetAddress1)
                              .Set("line_2", check.BankAddress?.StreetAddress2)
                              .Set("line_3", check.BankAddress?.StreetAddress3)
                              .Set("city", check.BankAddress?.City)
                              .Set("postal_code", check.BankAddress?.PostalCode)
                              .Set("state", check.BankAddress?.State)
                              .Set("country", check.BankAddress?.CountryCode);

                bank.Set("address", address);

                bankTransfer.Set("bank", bank);

                paymentMethod.Set("bank_transfer", bankTransfer);
            }

            if (builder.PaymentMethod is AlternativePaymentMethod)
            {
                var alternatepaymentMethod = (AlternativePaymentMethod)builder.PaymentMethod;

                paymentMethod.Set("name", alternatepaymentMethod.AccountHolderName);

                var apm = new JsonDoc()
                          .Set("provider", alternatepaymentMethod.AlternativePaymentMethodType?.ToString()?.ToLower())
                          .Set("address_override_mode", alternatepaymentMethod.AddressOverrideMode);
                paymentMethod.Set("apm", apm);
            }

            // encryption
            if (builder.PaymentMethod is IEncryptable)
            {
                var encryptionData = ((IEncryptable)builder.PaymentMethod).EncryptionData;

                if (encryptionData != null)
                {
                    var encryption = new JsonDoc()
                                     .Set("version", encryptionData.Version);

                    if (!string.IsNullOrEmpty(encryptionData.KTB))
                    {
                        encryption.Set("method", "KTB");
                        encryption.Set("info", encryptionData.KTB);
                    }
                    else if (!string.IsNullOrEmpty(encryptionData.KSN))
                    {
                        encryption.Set("method", "KSN");
                        encryption.Set("info", encryptionData.KSN);
                    }

                    if (encryption.Has("info"))
                    {
                        paymentMethod.Set("encryption", encryption);
                    }
                }
            }

            if (builder.TransactionType == TransactionType.Create && builder.PayLinkData is PayLinkData)
            {
                var payLinkData = builder.PayLinkData;
                var requestData = new JsonDoc()
                                  .Set("usage_limit", payLinkData.UsageLimit.ToString())
                                  .Set("usage_mode", EnumConverter.GetMapping(Target.GP_API, payLinkData.UsageMode))
                                  .Set("images", payLinkData.Images)
                                  .Set("description", builder.Description ?? null)
                                  .Set("type", payLinkData.Type?.ToString())
                                  .Set("expiration_date", payLinkData.ExpirationDate ?? null);

                var transaction = new JsonDoc()
                                  .Set("country", gateway.GpApiConfig.Country)
                                  .Set("amount", builder.Amount.ToNumericCurrencyString())
                                  .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.GpApiConfig.Channel))
                                  .Set("currency", builder.Currency)
                                  .Set("allowed_payment_methods", GetAllowedPaymentMethod(payLinkData.AllowedPaymentMethods));

                requestData.Set("transactions", transaction)
                .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                .Set("shipping_amount", payLinkData.ShippingAmount.ToNumericCurrencyString())
                .Set("shippable", payLinkData.IsShippable?.ToString() ?? false.ToString())
                .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TransactionProcessingAccountName)
                .Set("name", payLinkData.Name ?? null);

                var notification = new JsonDoc()
                                   .Set("cancel_url", payLinkData.CancelUrl)
                                   .Set("return_url", payLinkData.ReturnUrl)
                                   .Set("status_url", payLinkData.StatusUpdateUrl);

                requestData.Set("notifications", notification)
                .Set("status", payLinkData.Status.ToString());

                return(new GpApiRequest
                {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/links",
                    RequestBody = requestData.ToString(),
                });
            }

            var data = new JsonDoc()
                       .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TransactionProcessingAccountName)
                       .Set("type", builder.TransactionType == TransactionType.Refund ? "REFUND" : "SALE")   // [SALE, REFUND]
                       .Set("channel", EnumConverter.GetMapping(Target.GP_API, gateway.GpApiConfig.Channel)) // [CP, CNP]
                       .Set("capture_mode", GetCaptureMode(builder))                                         // [AUTO, LATER, MULTIPLE]
                                                                                                             //.Set("remaining_capture_count", "") //Pending Russell
                       .Set("authorization_mode", builder.AllowPartialAuth ? "PARTIAL" : null)
                       .Set("amount", builder.Amount.ToNumericCurrencyString())
                       .Set("currency", builder.Currency)
                       .Set("reference", builder.ClientTransactionId ?? Guid.NewGuid().ToString())
                       .Set("description", builder.Description)
                       //.Set("order_reference", builder.OrderId)
                       .Set("gratuity_amount", builder.Gratuity.ToNumericCurrencyString())
                       .Set("cashback_amount", builder.CashBackAmount.ToNumericCurrencyString())
                       .Set("surcharge_amount", builder.SurchargeAmount.ToNumericCurrencyString())
                       .Set("convenience_amount", builder.ConvenienceAmount.ToNumericCurrencyString())
                       .Set("country", gateway.GpApiConfig.Country)
                       //.Set("language", EnumConverter.GetMapping(Target.GP_API, Language))
                       .Set("ip_address", builder.CustomerIpAddress)
                       //.Set("site_reference", "") //
                       .Set("currency_conversion", !string.IsNullOrEmpty(builder.DccRateData?.DccId) ? new JsonDoc().Set("id", builder.DccRateData.DccId) : null)
                       .Set("payment_method", paymentMethod)
                       .Set("link", !string.IsNullOrEmpty(builder.PaymentLinkId) ? new JsonDoc()
                            .Set("id", builder.PaymentLinkId) : null);

            if (builder.PaymentMethod is eCheck || builder.PaymentMethod is AlternativePaymentMethod)
            {
                data.Set("payer", SetPayerInformation(builder));
            }

            // set order reference
            if (!string.IsNullOrEmpty(builder.OrderId))
            {
                var order = new JsonDoc()
                            .Set("reference", builder.OrderId);

                data.Set("order", order);
            }

            if (builder.PaymentMethod is AlternativePaymentMethod)
            {
                setOrderInformation(builder, ref data);

                var alternatepaymentMethod = (AlternativePaymentMethod)builder.PaymentMethod;

                var notifications = new JsonDoc()
                                    .Set("return_url", alternatepaymentMethod?.ReturnUrl)
                                    .Set("status_url", alternatepaymentMethod?.StatusUpdateUrl)
                                    .Set("cancel_url", alternatepaymentMethod?.CancelUrl);

                data.Set("notifications", notifications);
            }

            // stored credential
            if (builder.StoredCredential != null)
            {
                data.Set("initiator", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Initiator));
                var storedCredential = new JsonDoc()
                                       .Set("model", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Type))
                                       .Set("reason", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Reason))
                                       .Set("sequence", EnumConverter.GetMapping(Target.GP_API, builder.StoredCredential.Sequence));
                data.Set("stored_credential", storedCredential);
            }

            return(new GpApiRequest {
                Verb = HttpMethod.Post,
                Endpoint = $"{merchantUrl}/transactions",
                RequestBody = data.ToString(),
            });
        }
Example #12
0
        internal static GpApiRequest BuildRequest(ManagementBuilder builder, GpApiConnector gateway)
        {
            var merchantUrl = !string.IsNullOrEmpty(gateway.GpApiConfig.MerchantId) ? $"/merchants/{gateway.GpApiConfig.MerchantId}" : string.Empty;

            if (builder.TransactionType == TransactionType.Capture)
            {
                var data = new JsonDoc()
                           .Set("amount", builder.Amount.ToNumericCurrencyString())
                           .Set("gratuity_amount", builder.Gratuity.ToNumericCurrencyString())
                           .Set("currency_conversion", builder.DccRateData?.DccId ?? null);

                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/capture",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.Refund)
            {
                var data = new JsonDoc()
                           .Set("amount", builder.Amount.ToNumericCurrencyString())
                           .Set("currency_conversion", builder.DccRateData == null ? null : new JsonDoc()
                                .Set("id", builder.DccRateData?.DccId));

                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/refund",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.Reversal)
            {
                var data = new JsonDoc()
                           .Set("amount", builder.Amount.ToNumericCurrencyString())
                           .Set("currency_conversion", builder.DccRateData?.DccId ?? null);

                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/reversal",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.TokenUpdate)
            {
                if (!(builder.PaymentMethod is CreditCardData))
                {
                    throw new GatewayException("Payment method doesn't support this action!");
                }

                var cardData = builder.PaymentMethod as CreditCardData;

                var card = new JsonDoc()
                           .Set("expiry_month", cardData.ExpMonth.HasValue ? cardData.ExpMonth.ToString().PadLeft(2, '0') : string.Empty)
                           .Set("expiry_year", cardData.ExpYear.HasValue ? cardData.ExpYear.ToString().PadLeft(4, '0').Substring(2, 2) : string.Empty);

                var data = new JsonDoc()
                           .Set("usage_mode", !string.IsNullOrEmpty(builder.PaymentMethodUsageMode.ToString()) ? EnumConverter.GetMapping(Target.GP_API, builder.PaymentMethodUsageMode) : null)
                           .Set("name", !string.IsNullOrEmpty(cardData.CardHolderName) ? cardData.CardHolderName : null)
                           .Set("card", card);

                return(new GpApiRequest {
                    Verb = new HttpMethod("PATCH"),
                    Endpoint = $"{merchantUrl}/payment-methods/{(builder.PaymentMethod as ITokenizable).Token}",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.TokenDelete && builder.PaymentMethod is ITokenizable)
            {
                return(new GpApiRequest {
                    Verb = HttpMethod.Delete,
                    Endpoint = $"{merchantUrl}/payment-methods/{(builder.PaymentMethod as ITokenizable).Token}",
                });
            }
            else if (builder.TransactionType == TransactionType.DisputeAcceptance)
            {
                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/disputes/{builder.DisputeId}/acceptance",
                });
            }
            else if (builder.TransactionType == TransactionType.DisputeChallenge)
            {
                var data = new JsonDoc()
                           .Set("documents", builder.DisputeDocuments);

                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/disputes/{builder.DisputeId}/challenge",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.BatchClose)
            {
                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/batches/{builder.BatchReference}",
                });
            }
            else if (builder.TransactionType == TransactionType.Reauth)
            {
                var data = new JsonDoc()
                           .Set("amount", builder.Amount.ToNumericCurrencyString());
                if (builder.PaymentMethod.PaymentMethodType == PaymentMethodType.ACH)
                {
                    data.Set("description", builder.Description);
                    if (builder.BankTransferDetails != null)
                    {
                        var eCheck = builder.BankTransferDetails;

                        var paymentMethod = new JsonDoc()
                                            .Set("narrative", eCheck.MerchantNotes);

                        var bankTransfer = new JsonDoc()
                                           .Set("account_number", eCheck.AccountNumber)
                                           .Set("account_type", (eCheck.AccountType != null) ? EnumConverter.GetMapping(Target.GP_API, eCheck.AccountType) : null)
                                           .Set("check_reference", eCheck.CheckReference);

                        var bank = new JsonDoc()
                                   .Set("code", eCheck.RoutingNumber)
                                   .Set("name", eCheck.BankName);

                        bankTransfer.Set("bank", bank);

                        paymentMethod.Set("bank_transfer", bankTransfer);

                        data.Set("payment_method", paymentMethod);
                    }
                }

                return(new GpApiRequest {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/reauthorization",
                    RequestBody = data.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.Confirm)
            {
                if (builder.PaymentMethod is TransactionReference && builder.PaymentMethod.PaymentMethodType == PaymentMethodType.APM)
                {
                    var transactionReference = (TransactionReference)builder.PaymentMethod;
                    var apmResponse          = transactionReference.AlternativePaymentResponse;
                    var apm = new JsonDoc()
                              .Set("provider", apmResponse?.ProviderName)
                              .Set("provider_payer_reference", apmResponse?.ProviderReference);

                    var payment_method = new JsonDoc()
                                         .Set("apm", apm);

                    var data = new JsonDoc()
                               .Set("payment_method", payment_method);

                    return(new GpApiRequest
                    {
                        Verb = HttpMethod.Post,
                        Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/confirmation",
                        RequestBody = data.ToString(),
                    });
                }
            }
            else if (builder.TransactionType == TransactionType.Auth)
            {
                var payload = new JsonDoc();
                payload.Set("amount", builder.Amount);

                if (builder.LodgingData != null)
                {
                    var lodging = builder.LodgingData;
                    if (lodging.Items != null)
                    {
                        var lodginItems = new List <LodgingItems>();

                        foreach (var item in lodging.Items)
                        {
                            lodginItems.Add(new LodgingItems {
                                Types       = item.Types,
                                Reference   = item.Reference,
                                TotalAmount = item.TotalAmount,
                                paymentMethodProgramCodes = item.paymentMethodProgramCodes
                            });
                        }

                        var lodgingData = new JsonDoc()
                                          .Set("booking_reference", lodging.bookingReference)
                                          .Set("duration_days", lodging.StayDuration)
                                          .Set("date_checked_in", lodging.CheckInDate?.ToString("yyyy-MM-dd"))
                                          .Set("date_checked_out", lodging.CheckOutDate?.ToString("yyyy-MM-dd"))
                                          .Set("daily_rate_amount", lodging.Rate.ToNumericCurrencyString())
                                          .Set("charge_items", lodginItems);

                        payload.Set("lodging", lodgingData);
                    }

                    return(new GpApiRequest
                    {
                        Verb = HttpMethod.Post,
                        Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/incremental",
                        RequestBody = payload.ToString(),
                    });
                }
            }
            else if (builder.TransactionType == TransactionType.Edit)
            {
                var card = new JsonDoc()
                           .Set("tag", builder.TagData);

                var payment_method = new JsonDoc()
                                     .Set("card", card);

                var payload = new JsonDoc()
                              .Set("amount", builder.Amount.ToNumericCurrencyString())
                              .Set("gratuity_amount", builder.Gratuity.ToNumericCurrencyString())
                              .Set("payment_method", payment_method);

                return(new GpApiRequest
                {
                    Verb = HttpMethod.Post,
                    Endpoint = $"{merchantUrl}/transactions/{builder.TransactionId}/adjustment",
                    RequestBody = payload.ToString(),
                });
            }
            else if (builder.TransactionType == TransactionType.PayLinkUpdate)
            {
                var payLinkData = builder.PayLinkData;

                var payload = new JsonDoc()
                              .Set("usage_mode", EnumConverter.GetMapping(Target.GP_API, payLinkData.UsageMode) ?? null)
                              .Set("usage_limit", payLinkData.UsageLimit ?? null)
                              .Set("name", payLinkData.Name ?? null)
                              .Set("description", builder.Description ?? null)
                              .Set("type", payLinkData.Type.ToString() ?? null)
                              .Set("status", payLinkData.Status.ToString() ?? null)
                              .Set("shippable", payLinkData.IsShippable?.ToString() ?? null)
                              .Set("shipping_amount", payLinkData.ShippingAmount.ToNumericCurrencyString());

                var transaction = new JsonDoc()
                                  .Set("amount", builder.Amount.ToNumericCurrencyString() ?? null);

                payload.Set("transactions", transaction)
                .Set("expiration_date", payLinkData.ExpirationDate ?? null)
                .Set("images", payLinkData.Images ?? null);

                return(new GpApiRequest
                {
                    Verb = new HttpMethod("PATCH"),
                    Endpoint = $"{merchantUrl}/links/{builder.PaymentLinkId}",
                    RequestBody = payload.ToString(),
                });
            }
            return(null);
        }
        internal static GpApiRequest BuildRequest <T>(ReportBuilder <T> builder, GpApiConnector gateway) where T : class
        {
            var merchantUrl = !string.IsNullOrEmpty(gateway.GpApiConfig.MerchantId) ? $"/merchants/{gateway.GpApiConfig.MerchantId}" : string.Empty;

            if (builder is TransactionReportBuilder <T> trb)
            {
                var request = new GpApiRequest();
                switch (builder.ReportType)
                {
                case ReportType.TransactionDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/transactions/{trb.TransactionId}",
                    });

                case ReportType.FindTransactionsPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/transactions",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.TransactionOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("id", trb.TransactionId);
                    request.AddQueryStringParam("type", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.PaymentType));
                    request.AddQueryStringParam("channel", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.Channel));
                    request.AddQueryStringParam("amount", trb.SearchBuilder.Amount.ToNumericCurrencyString());
                    request.AddQueryStringParam("currency", trb.SearchBuilder.Currency);
                    request.AddQueryStringParam("number_first6", trb.SearchBuilder.CardNumberFirstSix);
                    request.AddQueryStringParam("number_last4", trb.SearchBuilder.CardNumberLastFour);
                    request.AddQueryStringParam("token_first6", trb.SearchBuilder.TokenFirstSix);
                    request.AddQueryStringParam("token_last4", trb.SearchBuilder.TokenLastFour);
                    request.AddQueryStringParam("account_name", trb.SearchBuilder.AccountName);
                    request.AddQueryStringParam("brand", trb.SearchBuilder.CardBrand);
                    request.AddQueryStringParam("brand_reference", trb.SearchBuilder.BrandReference);
                    request.AddQueryStringParam("authcode", trb.SearchBuilder.AuthCode);
                    request.AddQueryStringParam("reference", trb.SearchBuilder.ReferenceNumber);
                    request.AddQueryStringParam("status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.TransactionStatus));
                    request.AddQueryStringParam("from_time_created", trb.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("country", trb.SearchBuilder.Country);
                    request.AddQueryStringParam("batch_id", trb.SearchBuilder.BatchId);
                    request.AddQueryStringParam("entry_mode", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.PaymentEntryMode));
                    request.AddQueryStringParam("name", trb.SearchBuilder.Name);
                    request.AddQueryStringParam("payment_method", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.PaymentMethodName));

                    return(request);

                case ReportType.FindSettlementTransactionsPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/settlement/transactions",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.TransactionOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("number_first6", trb.SearchBuilder.CardNumberFirstSix);
                    request.AddQueryStringParam("number_last4", trb.SearchBuilder.CardNumberLastFour);
                    request.AddQueryStringParam("deposit_status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DepositStatus));
                    request.AddQueryStringParam("account_name", gateway.GpApiConfig.AccessTokenInfo.DataAccountName);
                    request.AddQueryStringParam("brand", trb.SearchBuilder.CardBrand);
                    request.AddQueryStringParam("arn", trb.SearchBuilder.AquirerReferenceNumber);
                    request.AddQueryStringParam("brand_reference", trb.SearchBuilder.BrandReference);
                    request.AddQueryStringParam("authcode", trb.SearchBuilder.AuthCode);
                    request.AddQueryStringParam("reference", trb.SearchBuilder.ReferenceNumber);
                    request.AddQueryStringParam("status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.TransactionStatus));
                    request.AddQueryStringParam("from_time_created", trb.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("deposit_id", trb.SearchBuilder.DepositReference);
                    request.AddQueryStringParam("from_deposit_time_created", trb.SearchBuilder.StartDepositDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_deposit_time_created", trb.SearchBuilder.EndDepositDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("from_batch_time_created", trb.SearchBuilder.StartBatchDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_batch_time_created", trb.SearchBuilder.EndBatchDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("system.mid", trb.SearchBuilder.MerchantId);
                    request.AddQueryStringParam("system.hierarchy", trb.SearchBuilder.SystemHierarchy);

                    return(request);

                case ReportType.DepositDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/settlement/deposits/{trb.SearchBuilder.DepositReference}",
                    });

                case ReportType.FindDepositsPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/settlement/deposits",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.DepositOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("account_name", gateway.GpApiConfig.AccessTokenInfo.DataAccountName);
                    request.AddQueryStringParam("from_time_created", trb.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("id", trb.SearchBuilder.DepositReference);
                    request.AddQueryStringParam("status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DepositStatus));
                    request.AddQueryStringParam("amount", trb.SearchBuilder.Amount.ToNumericCurrencyString());
                    request.AddQueryStringParam("masked_account_number_last4", trb.SearchBuilder.AccountNumberLastFour);
                    request.AddQueryStringParam("system.mid", trb.SearchBuilder.MerchantId);
                    request.AddQueryStringParam("system.hierarchy", trb.SearchBuilder.SystemHierarchy);

                    return(request);

                case ReportType.DisputeDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/disputes/{trb.SearchBuilder.DisputeId}",
                    });

                case ReportType.DocumentDisputeDetail:
                    var apiRequest = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/disputes/{trb.SearchBuilder.DisputeId}/documents/{trb.SearchBuilder.DisputeDocumentId}",
                    };
                    return(apiRequest);

                case ReportType.FindDisputesPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/disputes",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.DisputeOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("arn", trb.SearchBuilder.AquirerReferenceNumber);
                    request.AddQueryStringParam("brand", trb.SearchBuilder.CardBrand);
                    request.AddQueryStringParam("status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DisputeStatus));
                    request.AddQueryStringParam("stage", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DisputeStage));
                    request.AddQueryStringParam("from_stage_time_created", trb.SearchBuilder.StartStageDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_stage_time_created", trb.SearchBuilder.EndStageDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("system.mid", trb.SearchBuilder.MerchantId);
                    request.AddQueryStringParam("system.hierarchy", trb.SearchBuilder.SystemHierarchy);

                    return(request);

                case ReportType.SettlementDisputeDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/settlement/disputes/{trb.SearchBuilder.SettlementDisputeId}",
                    });

                case ReportType.FindSettlementDisputesPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/settlement/disputes",
                    };
                    request.AddQueryStringParam("account_name", gateway.GpApiConfig.AccessTokenInfo.DataAccountName);
                    request.AddQueryStringParam("deposit_id", trb.SearchBuilder.DepositReference);
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.DisputeOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("arn", trb.SearchBuilder.AquirerReferenceNumber);
                    request.AddQueryStringParam("brand", trb.SearchBuilder.CardBrand);
                    request.AddQueryStringParam("STATUS", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DisputeStatus));
                    request.AddQueryStringParam("stage", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.DisputeStage));
                    request.AddQueryStringParam("from_stage_time_created", trb.SearchBuilder.StartStageDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_stage_time_created", trb.SearchBuilder.EndStageDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("from_deposit_time_created", trb.SearchBuilder.StartDepositDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_deposit_time_created", trb.SearchBuilder.EndDepositDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("system.mid", trb.SearchBuilder.MerchantId);
                    request.AddQueryStringParam("system.hierarchy", trb.SearchBuilder.SystemHierarchy);

                    return(request);

                case ReportType.StoredPaymentMethodDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/payment-methods/{trb.SearchBuilder.StoredPaymentMethodId}",
                    });

                case ReportType.FindStoredPaymentMethodsPaged:
                    if (trb.SearchBuilder.PaymentMethod is CreditCardData)
                    {
                        var creditCardData = trb.SearchBuilder.PaymentMethod as CreditCardData;

                        var card = new JsonDoc()
                                   .Set("number", creditCardData.Number)
                                   .Set("expiry_month", creditCardData.ExpMonth.HasValue ? creditCardData.ExpMonth.ToString().PadLeft(2, '0') : null)
                                   .Set("expiry_year", creditCardData.ExpYear.HasValue ? creditCardData.ExpYear.ToString().PadLeft(4, '0').Substring(2, 2) : null);

                        var payload = new JsonDoc()
                                      .Set("account_name", gateway.GpApiConfig.AccessTokenInfo.TokenizationAccountName)
                                      .Set("reference", trb.SearchBuilder.ReferenceNumber)
                                      .Set("card", card != null ? card : null);

                        request = new GpApiRequest {
                            Verb        = HttpMethod.Post,
                            Endpoint    = $"{merchantUrl}/payment-methods/search",
                            RequestBody = payload.ToString()
                        };
                        return(request);
                    }
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/payment-methods",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.StoredPaymentMethodOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("id", trb.SearchBuilder.StoredPaymentMethodId);
                    request.AddQueryStringParam("number_last4", trb.SearchBuilder.CardNumberLastFour);
                    request.AddQueryStringParam("reference", trb.SearchBuilder.ReferenceNumber);
                    request.AddQueryStringParam("status", EnumConverter.GetMapping(Target.GP_API, trb.SearchBuilder.StoredPaymentMethodStatus));
                    request.AddQueryStringParam("from_time_created", trb.SearchBuilder.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.SearchBuilder.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("from_time_last_updated", trb.SearchBuilder.StartLastUpdatedDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_last_updated", trb.SearchBuilder.EndLastUpdatedDate?.ToString("yyyy-MM-dd"));

                    return(request);

                case ReportType.ActionDetail:
                    return(new GpApiRequest {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/actions/{trb.SearchBuilder.ActionId}",
                    });

                case ReportType.FindActionsPaged:
                    request = new GpApiRequest {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/actions",
                    };
                    request.AddQueryStringParam("page", trb.Page?.ToString());
                    request.AddQueryStringParam("page_size", trb.PageSize?.ToString());
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.ActionOrderBy));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("id", trb.SearchBuilder.ActionId);
                    request.AddQueryStringParam("type", trb.SearchBuilder.ActionType);
                    request.AddQueryStringParam("resource", trb.SearchBuilder.Resource);
                    request.AddQueryStringParam("resource_status", trb.SearchBuilder.ResourceStatus);
                    request.AddQueryStringParam("resource_id", trb.SearchBuilder.ResourceId);
                    request.AddQueryStringParam("from_time_created", trb.SearchBuilder.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.SearchBuilder.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("merchant_name", trb.SearchBuilder.MerchantName);
                    request.AddQueryStringParam("account_name", trb.SearchBuilder.AccountName);
                    request.AddQueryStringParam("app_name", trb.SearchBuilder.AppName);
                    request.AddQueryStringParam("version", trb.SearchBuilder.Version);
                    request.AddQueryStringParam("response_code", trb.SearchBuilder.ResponseCode);
                    request.AddQueryStringParam("http_response_code", trb.SearchBuilder.HttpResponseCode);

                    return(request);

                case ReportType.PayLinkDetail:
                    return(new GpApiRequest
                    {
                        Verb = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/links/{trb.SearchBuilder.PayLinkId}",
                    });


                case ReportType.FindPayLinkPaged:
                    request = new GpApiRequest
                    {
                        Verb     = HttpMethod.Get,
                        Endpoint = $"{merchantUrl}/links",
                    };

                    request.AddQueryStringParam("from_time_created", trb.SearchBuilder.StartDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("to_time_created", trb.SearchBuilder.EndDate?.ToString("yyyy-MM-dd"));
                    request.AddQueryStringParam("order", EnumConverter.GetMapping(Target.GP_API, trb.Order));
                    request.AddQueryStringParam("order_by", EnumConverter.GetMapping(Target.GP_API, trb.ActionOrderBy));

                    return(request);
                }
            }
            return(null);
        }