public Transaction ManageTransaction(ManagementBuilder builder)
        {
            var request = new TransitRequestBuilder(MapTransactionType(builder))
                          .Set("developerID", DeveloperId)
                          .Set("deviceID", DeviceId)
                          .Set("transactionKey", TransactionKey)
                          .Set("transactionAmount", builder.Amount.ToCurrencyString())
                          .Set("tip", builder.Gratuity.ToCurrencyString())
                          .Set("transactionID", builder.TransactionId)
                          .Set("isPartialShipment", builder.MultiCapture ? "Y" : null)
                          .SetPartialShipmentData(builder.MultiCaptureSequence, builder.MultiCapturePaymentCount)
                          .Set("externalReferenceID", builder.ClientTransactionId)
                          .Set("voidReason", EnumConverter.GetMapping(Target.Transit, builder.VoidReason));

            string response = DoTransaction(request.BuildRequest(builder));

            return(MapResponse(builder, response));
        }
        public Transaction ProcessAuthorization(AuthorizationBuilder builder)
        {
            var request = new TransitRequestBuilder(MapTransactionType(builder))
                          .Set("developerID", DeveloperId)
                          .Set("deviceID", DeviceId)
                          .Set("transactionKey", TransactionKey)
                          .Set("transactionAmount", builder.Amount.ToCurrencyString())
                          .Set("tokenRequired", builder.RequestMultiUseToken ? "Y" : "N")
                          .Set("externalReferenceID", builder.ClientTransactionId);

            request.Set("cardDataSource", MapCardDataSource(builder));
            if (builder.PaymentMethod is ICardData card)
            {
                string cardNumber        = card.Number;
                string cardDataInputMode = "ELECTRONIC_COMMERCE_NO_SECURITY_CHANNEL_ENCRYPTED_SET_WITHOUT_CARDHOLDER_CERTIFICATE";
                if (card.CardType.Equals("Amex") && !string.IsNullOrEmpty(card.Cvn))
                {
                    cardDataInputMode = "MANUALLY_ENTERED_WITH_KEYED_CID_AMEX_JCB";
                }

                if (card is ITokenizable token && token.Token != null)
                {
                    cardNumber = token.Token;
                    //cardDataInputMode = "MERCHANT_INITIATED_TRANSACTION_CARD_CREDENTIAL_STORED_ON_FILE";
                }

                request.Set("cardNumber", cardNumber)
                .Set("expirationDate", card.ShortExpiry)
                .Set("cvv2", card.Cvn)
                .Set("cardPresentDetail", card.CardPresent ? "CARD_PRESENT" : "CARD_NOT_PRESENT")
                .Set("cardholderPresentDetail", card.CardPresent ? "CARDHOLDER_PRESENT" : "CARDHOLDER_NOT_PRESENT_ELECTRONIC_COMMERCE")
                .Set("cardDataInputMode", cardDataInputMode)
                .Set("cardholderAuthenticationMethod", "NOT_AUTHENTICATED")
                .Set("authorizationIndicator", builder.AmountEstimated ? "PREAUTH" : "FINAL");
            }
            else if (builder.PaymentMethod is ITrackData track)
            {
                request.Set(track.TrackNumber.Equals(TrackNumber.TrackTwo) ? "track2Data" : "track1Data", track.TrackData);
                request.Set("cardPresentDetail", "CARD_PRESENT")
                .Set("cardholderPresentDetail", "CARDHOLDER_PRESENT")
                .Set("cardDataInputMode", "MAGNETIC_STRIPE_READER_INPUT")
                .Set("cardholderAuthenticationMethod", "NOT_AUTHENTICATED");

                if (builder.HasEmvFallbackData)
                {
                    request.Set("emvFallbackCondition", EnumConverter.GetMapping(Target.Transit, builder.EmvFallbackCondition))
                    .Set("lastChipRead", EnumConverter.GetMapping(Target.Transit, builder.EmvLastChipRead))
                    .Set("paymentAppVersion", builder.PaymentApplicationVersion ?? "unspecified");
                }
            }

            // AVS
            if (builder.BillingAddress != null)
            {
                request.Set("addressLine1", builder.BillingAddress.StreetAddress1)
                .Set("zip", builder.BillingAddress.PostalCode);
            }

            // PIN Debit
            if (builder.PaymentMethod is IPinProtected pinProtected)
            {
                request.Set("pin", pinProtected.PinBlock.Substring(0, 16))
                .Set("pinKsn", pinProtected.PinBlock.Substring(16));
            }

            #region 3DS 1/2
            if (builder.PaymentMethod is ISecure3d secure && secure.ThreeDSecure != null)
            {
                if (secure.ThreeDSecure.Version.Equals(Secure3dVersion.One))
                {
                    request.Set("programProtocol", "1");
                }
                else
                {
                    request.Set("programProtocol", "2")
                    .Set("directoryServerTransactionID", secure.ThreeDSecure.DirectoryServerTransactionId);
                }

                request.Set("eciIndicator", secure.ThreeDSecure.Eci)
                .Set("secureCode", secure.ThreeDSecure.SecureCode)
                .Set("digitalPaymentCryptogram", secure.ThreeDSecure.AuthenticationValue)
                .Set("securityProtocol", secure.ThreeDSecure.AuthenticationType)
                .Set("ucafCollectionIndicator", EnumConverter.GetMapping(Target.Transit, secure.ThreeDSecure.UCAFIndicator));
            }
            #endregion

            #region Commercial Card Requests
            if (builder.CommercialData != null)
            {
                var cd = builder.CommercialData;

                if (cd.CommercialIndicator.Equals(CommercialIndicator.Level_II))
                {
                    request.Set("commercialCardLevel", "LEVEL2");
                }
                else
                {
                    request.Set("commercialCardLevel", "LEVEL3");
                    request.SetProductDetails(cd.LineItems);
                }

                request.Set("salesTax", cd.TaxAmount.ToCurrencyString())
                .Set("chargeDescriptor", cd.Description)
                .Set("customerRefID", cd.CustomerReferenceId)
                .Set("purchaseOrder", cd.PoNumber)
                .Set("shipToZip", cd.DestinationPostalCode)
                .Set("shipFromZip", cd.OriginPostalCode)
                .Set("supplierReferenceNumber", cd.SupplierReferenceNumber)
                .Set("customerVATNumber", cd.CustomerVAT_Number)
                .Set("summaryCommodityCode", cd.SummaryCommodityCode)
                .Set("shippingCharges", cd.FreightAmount.ToCurrencyString())
                .Set("dutyCharges", cd.DutyAmount.ToCurrencyString())
                .Set("destinationCountryCode", cd.DestinationCountryCode)
                .Set("vatInvoice", cd.VAT_InvoiceNumber)
                .Set("orderDate", cd.OrderDate?.ToString("dd/MM/yyyy"))
                .SetAdditionalTaxDetails(cd.AdditionalTaxDetails);
            }
            #endregion

            // Acceptor Config
            request.Set("terminalCapability", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.CardDataInputCapability))
            .Set("terminalCardCaptureCapability", AcceptorConfig.CardCaptureCapability ? "CARD_CAPTURE_CAPABILITY" : "NO_CAPABILITY")
            .Set("terminalOperatingEnvironment", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.OperatingEnvironment))
            .Set("cardholderAuthenticationEntity", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.CardHolderAuthenticationEntity))
            .Set("cardDataOutputCapability", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.CardDataOutputCapability))
            .Set("terminalAuthenticationCapability", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.CardHolderAuthenticationCapability))
            .Set("terminalOutputCapability", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.TerminalOutputCapability))
            .Set("maxPinLength", EnumConverter.GetMapping(Target.Transit, AcceptorConfig.PinCaptureCapability));

            string response = DoTransaction(request.BuildRequest(builder));
            return(MapResponse(builder, response));
        }