示例#1
0
        private Transaction createPayoutTransaction(PaySession session, ITransactionContext context, JSONDataMap response, Account to, Amount amount, string description = null)
        {
            var    batchID = response.GetNodeByPath(RESPONSE_BATCH_HEADER, RESPONSE_BATCH_ID);
            object itemID  = null;
            var    items   = response.GetNodeByPath(RESPONSE_ITEMS) as JSONDataArray;

            if (items != null && items.Count > 0)
            {
                // for the moment there is only one possible payment in a batch
                itemID = ((JSONDataMap)items[0]).GetNodeByPath(RESPONSE_ITEMS_ITEMID);
            }

            var processorToken  = new { batchID = batchID.AsString(), itemID = itemID.AsString() };
            var transactionDate = response.GetNodeByPath(RESPONSE_BATCH_HEADER, RESPONSE_TIME_COMPLETED)
                                  .AsDateTime(App.TimeSource.UTCNow);

            var transactionID = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Transfer);

            return(Transaction.Transfer(transactionID,
                                        this.Name, processorToken,
                                        Account.EmptyInstance,
                                        to,
                                        amount,
                                        transactionDate,
                                        description));
        }
示例#2
0
        /// <summary>
        /// Overload of Charge method with Stripe-typed session parameter
        /// </summary>
        public Transaction Charge(StripeSession session, ITransactionContext context, Account from, Account to, Amount amount, bool capture = true, string description = null, object extraData = null)
        {
            var fromActualData = PaySystemHost.AccountToActualData(context, from);

            try
            {
                var bodyPrms = new Dictionary <string, string>()
                {
                    { PRM_AMOUNT, ((int)((amount.Value * 100))).ToString() },
                    { PRM_CURRENCY, amount.CurrencyISO.ToString().ToLower() },
                    { PRM_DESCRIPTION, description },
                    { PRM_CAPTURE, capture.ToString() }
                };

                fillBodyParametersFromAccount(bodyPrms, fromActualData);

                var prms = new WebClient.RequestParams()
                {
                    Uri            = new Uri(CHARGE_URI),
                    Caller         = this,
                    UName          = session.SecretKey,
                    Method         = HTTPRequestMethod.POST,
                    BodyParameters = bodyPrms
                };

                dynamic obj = WebClient.GetJson(prms);

                var created = ((long)obj.created).FromSecondsSinceUnixEpochStart();

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Charge);

                var ta = new Transaction(taId, TransactionType.Charge, from, to, this.Name, obj.id, amount, created, description);

                StatCharge(amount);

                return(ta);
            }
            catch (Exception ex)
            {
                var wex = ex as System.Net.WebException;

                if (wex != null)
                {
                    var response = wex.Response as System.Net.HttpWebResponse;
                    if (response != null)
                    {
                        string errorMessage = this.GetType().Name +
                                              ".Charge(money: {0}, card: {1}, amount: '{2}')".Args(amount.Value, fromActualData.AccountNumber, amount);
                        var stripeEx = PaymentStripeException.Compose(response, errorMessage, wex);
                        throw stripeEx;
                    }
                }

                StatChargeError();

                throw new PaymentStripeException(StringConsts.PAYMENT_CANNOT_CHARGE_PAYMENT_ERROR + this.GetType()
                                                 + " .Capture(session='{0}', card='{1}', amount='{2}')".Args(session, from, amount), ex);
            }
        }
示例#3
0
        /// <summary>
        /// Transfers funds to customerAccount from current stripe account
        /// (which credentials is supplied in current session)
        /// </summary>
        private Transaction transfer(StripeSession stripeSession, ITransactionContext context, string recipientID, Account customerAccount, Amount amount, string description)
        {
            var actualAccountData = PaySystemHost.AccountToActualData(context, customerAccount);

            try
            {
                var prms = new WebClient.RequestParams()
                {
                    Uri            = new Uri(TRANSFER_URI),
                    Caller         = this,
                    UName          = stripeSession.SecretKey,
                    Method         = HTTPRequestMethod.POST,
                    BodyParameters = new Dictionary <string, string>()
                    {
                        { PRM_RECIPIENT, recipientID },
                        { PRM_AMOUNT, ((int)((amount.Value * 100))).ToString() },
                        { PRM_CURRENCY, amount.CurrencyISO.ToLower() },
                        { PRM_DESCRIPTION, description }
                    }
                };

                dynamic obj = WebClient.GetJson(prms);

                var created = ((long)obj.created).FromSecondsSinceUnixEpochStart();

                var taId = PaySystemHost.GenerateTransactionID(stripeSession, context, TransactionType.Transfer);

                var ta = new Transaction(taId, TransactionType.Transfer, Account.EmptyInstance, customerAccount, this.Name, obj.id, amount, created, description);

                StatTransfer(amount);

                return(ta);
            }
            catch (Exception ex)
            {
                var wex = ex as System.Net.WebException;
                if (wex == null)
                {
                    var response = wex.Response as System.Net.HttpWebResponse;
                    if (response != null)
                    {
                        string errorMessage = this.GetType().Name +
                                              ".transfer(recipientID='{0}', customerAccount='{1}', amount='{2}')".Args(recipientID, actualAccountData, amount);
                        PaymentStripeException stripeEx = PaymentStripeException.Compose(response, errorMessage, wex);
                        if (stripeEx != null)
                        {
                            throw stripeEx;
                        }
                    }
                }

                StatTransferError();

                throw new PaymentStripeException(StringConsts.PAYMENT_CANNOT_TRANSFER_ERROR + this.GetType()
                                                 + " .transfer(customerAccout='{0}')".Args(actualAccountData), ex);
            }
        }
示例#4
0
        public override Transaction Refund(PaySession session, ITransactionContext context, ref Transaction charge, Financial.Amount?amount = null, string description = null, object extraData = null)
        {
            var refundAmount = amount ?? charge.Amount;

            var created = DateTime.UtcNow;

            var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Refund);

            var refundTA = Transaction.Refund(taId, this.Name, taId, Account.EmptyInstance, charge.From, refundAmount, created, description, relatedTransactionID: charge.ID);

            StatRefund(charge, amount);

            return(refundTA);
        }
示例#5
0
        /// <summary>
        /// Overload of Refund method with Stripe-typed session parameter
        /// Developers, don't call this method directly. Call Transaction.Refund instead.
        /// </summary>
        public Transaction Refund(StripeSession session, ITransactionContext context, ref Transaction charge, Amount?amount = null, string description = null, object extraData = null)
        {
            var fromActualData = PaySystemHost.AccountToActualData(context, charge.From);

            var refundAmount = amount ?? charge.Amount;

            try
            {
                var bodyPrms = new Dictionary <string, string>()
                {
                    { PRM_AMOUNT, ((int)((refundAmount.Value * 100))).ToString() }
                };

                if (description.IsNotNullOrWhiteSpace())
                {
                    bodyPrms.Add(PRM_REASON, description);
                }

                var prms = new WebClient.RequestParams()
                {
                    Uri            = new Uri(REFUND_URI.Args(charge.ProcessorToken)),
                    Caller         = this,
                    UName          = session.SecretKey,
                    Method         = HTTPRequestMethod.POST,
                    BodyParameters = bodyPrms
                };

                dynamic obj = WebClient.GetJson(prms);

                dynamic lastRefund = ((NFX.Serialization.JSON.JSONDataArray)obj.refunds.Data).First();

                var created = ((long)obj.created).FromSecondsSinceUnixEpochStart();

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Refund);

                var refundTA = new Transaction(taId, TransactionType.Refund, Account.EmptyInstance, charge.From, this.Name,
                                               lastRefund["id"], refundAmount, created, description,
                                               isCaptured: true, canRefund: false);

                StatRefund(charge, amount);

                return(refundTA);
            }
            catch (Exception ex)
            {
                var wex = ex as System.Net.WebException;
                if (wex != null)
                {
                    var response = wex.Response as System.Net.HttpWebResponse;
                    if (response != null)
                    {
                        string errorMessage = this.GetType().Name +
                                              ".Refund(money: {0}, card: {1}, description: '{2}')"
                                              .Args(charge.Amount, fromActualData.AccountNumber, description);
                        PaymentStripeException stripeEx = PaymentStripeException.Compose(response, errorMessage, wex);
                        if (stripeEx != null)
                        {
                            throw stripeEx;
                        }
                    }
                }

                StatRefundError();

                throw new PaymentStripeException(StringConsts.PAYMENT_CANNOT_CAPTURE_CAPTURED_PAYMENT_ERROR + this.GetType()
                                                 + " .Refund(session='{0}', charge='{1}')".Args(session, charge), ex);
            }
        }
示例#6
0
文件: MockSystem.cs 项目: ame89/nfx
        public override Transaction Transfer(PaySession session, ITransactionContext context, Account from, Account to, Financial.Amount amount, string description = null, object extraData = null)
        {
            var actualAccountData = PaySystemHost.AccountToActualData(context, to);

            if (actualAccountData == null)
            {
                StatTransferError();
                throw new PaymentMockException(StringConsts.PAYMENT_UNKNOWN_ACCOUNT_ERROR.Args(from) + this.GetType().Name + ".Transfer");
            }

            AccountData accountData = null;

            accountData = m_Accounts.DebitBankCorrect.FirstOrDefault(c => c.AccountNumber == actualAccountData.AccountNumber &&
                                                                     c.CardExpirationYear == actualAccountData.CardExpirationYear &&
                                                                     c.CardExpirationMonth == actualAccountData.CardExpirationMonth &&
                                                                     c.CardVC == actualAccountData.CardVC);

            if (accountData != null)
            {
                var created = DateTime.Now;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Transfer);

                var ta = new Transaction(taId, TransactionType.Transfer, Account.EmptyInstance, to, this.Name, taId, amount, created, description);

                StatTransfer(amount);

                return(ta);
            }

            accountData = m_Accounts.DebitCardCorrect.FirstOrDefault(c => c.AccountNumber == actualAccountData.AccountNumber &&
                                                                     c.CardExpirationYear == actualAccountData.CardExpirationYear &&
                                                                     c.CardExpirationMonth == actualAccountData.CardExpirationMonth &&
                                                                     c.CardVC == actualAccountData.CardVC);

            if (accountData != null)
            {
                var created = DateTime.Now;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Transfer);

                var ta = new Transaction(taId, TransactionType.Transfer, Account.EmptyInstance, to, this.Name, taId, amount, created, description);

                StatTransfer(amount);

                return(ta);
            }

            accountData = m_Accounts.DebitCardCorrectWithAddr.FirstOrDefault(c => c.AccountNumber == actualAccountData.AccountNumber &&
                                                                             c.CardExpirationYear == actualAccountData.CardExpirationYear &&
                                                                             c.CardExpirationMonth == actualAccountData.CardExpirationMonth &&
                                                                             c.CardVC == actualAccountData.CardVC &&
                                                                             c.BillingAddress1 != actualAccountData.BillingAddress1 &&
                                                                             c.BillingAddress2 != actualAccountData.BillingAddress2 &&
                                                                             c.BillingCountry != actualAccountData.BillingCountry &&
                                                                             c.BillingCity != actualAccountData.BillingCity &&
                                                                             c.BillingPostalCode != actualAccountData.BillingPostalCode &&
                                                                             c.BillingRegion != actualAccountData.BillingRegion &&
                                                                             c.BillingEmail != actualAccountData.BillingEmail &&
                                                                             c.BillingPhone != actualAccountData.BillingPhone);

            if (accountData != null)
            {
                var created = DateTime.Now;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Transfer);

                var ta = new Transaction(taId, TransactionType.Transfer, Account.EmptyInstance, to, this.Name, taId, amount, created, description);

                StatTransfer(amount);

                return(ta);
            }

            StatTransferError();
            throw new PaymentException(StringConsts.PAYMENT_INVALID_CARD_NUMBER_ERROR + this.GetType().Name + ".Transfer");
        }
示例#7
0
文件: MockSystem.cs 项目: ame89/nfx
        public override Transaction Charge(PaySession session, ITransactionContext context, Account from, Account to, Financial.Amount amount, bool capture = true, string description = null, object extraData = null)
        {
            var fromActualData = PaySystemHost.AccountToActualData(context, from);

            if (fromActualData == null)
            {
                StatChargeError();
                throw new PaymentMockException(StringConsts.PAYMENT_UNKNOWN_ACCOUNT_ERROR.Args(from) + this.GetType().Name + ".Charge");
            }

            if (m_Accounts.CreditCardDeclined.Any(c => c.AccountNumber == fromActualData.AccountNumber))
            {
                StatChargeError();
                throw new PaymentMockException(this.GetType().Name + ".Charge: card '{0}' declined".Args(fromActualData));
            }

            if (m_Accounts.CreditCardLuhnError.Any(c => c.AccountNumber == fromActualData.AccountNumber))
            {
                StatChargeError();
                throw new PaymentMockException(this.GetType().Name + ".Charge: card number '{0}' is incorrect".Args(fromActualData));
            }


            AccountData foundAccount = null;

            foundAccount = m_Accounts.CreditCardsCorrect.FirstOrDefault(c => c.AccountNumber == fromActualData.AccountNumber);

            if (foundAccount != null)
            {
                if (foundAccount.CardExpirationYear != fromActualData.CardExpirationYear)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_EXPIRATION_DATE_ERROR
                                                   .Args(fromActualData.CardExpirationYear, fromActualData.CardExpirationMonth) + this.GetType().Name + ".Charge");
                }

                if (foundAccount.CardExpirationMonth != fromActualData.CardExpirationMonth)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_EXPIRATION_DATE_ERROR
                                                   .Args(fromActualData.CardExpirationYear, fromActualData.CardExpirationMonth) + this.GetType().Name + ".Charge");
                }

                if (foundAccount.CardVC != fromActualData.CardVC)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_CVC_ERROR + this.GetType().Name + ".Charge");
                }

                var created = DateTime.UtcNow;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Charge);

                var ta = new Transaction(taId, TransactionType.Charge, from, to, this.Name, taId, amount, created, description);

                StatCharge(amount);

                return(ta);
            }

            foundAccount = m_Accounts.CreditCardCorrectWithAddr.FirstOrDefault(c => c.AccountNumber == fromActualData.AccountNumber);

            if (foundAccount != null)
            {
                if (foundAccount.CardExpirationYear != fromActualData.CardExpirationYear)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_EXPIRATION_DATE_ERROR
                                                   .Args(fromActualData.CardExpirationYear, fromActualData.CardExpirationMonth) + this.GetType().Name + ".Charge");
                }

                if (foundAccount.CardExpirationMonth != fromActualData.CardExpirationMonth)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_EXPIRATION_DATE_ERROR
                                                   .Args(fromActualData.CardExpirationYear, fromActualData.CardExpirationMonth) + this.GetType().Name + ".Charge");
                }

                if (foundAccount.CardVC != fromActualData.CardVC)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_CVC_ERROR.Args(fromActualData.CardVC) + this.GetType().Name + ".Charge");
                }

                if (foundAccount.BillingAddress1 != fromActualData.BillingAddress1 ||
                    foundAccount.BillingAddress2 != fromActualData.BillingAddress2 ||
                    foundAccount.BillingCountry != fromActualData.BillingCountry ||
                    foundAccount.BillingCity != fromActualData.BillingCity ||
                    foundAccount.BillingPostalCode != fromActualData.BillingPostalCode ||
                    foundAccount.BillingRegion != fromActualData.BillingRegion ||
                    foundAccount.BillingEmail != fromActualData.BillingEmail ||
                    foundAccount.BillingPhone != fromActualData.BillingPhone)
                {
                    StatChargeError();
                    throw new PaymentMockException(StringConsts.PAYMENT_INVALID_ADDR_ERROR + this.GetType().Name + ".Charge");
                }

                var created = DateTime.UtcNow;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Charge);

                var ta = new Transaction(taId, TransactionType.Charge, from, to, this.Name, taId, amount, created, description);

                StatCharge(amount);

                return(ta);
            }

            throw new PaymentException(StringConsts.PAYMENT_INVALID_CARD_NUMBER_ERROR + this.GetType().Name + ".Charge");
        }
示例#8
0
        public Transaction Charge(BraintreeSession session, ITransactionContext context, Account from, Account to, Amount amount, bool capture = true, string description = null, object extraData = null)
        {
            var orderContex = context as IOrderTransactionContext;

            var fromActualData = PaySystemHost.AccountToActualData(context, from);

            try
            {
                var isWeb   = fromActualData.Account.IsWebTerminalToken;
                var request = new JSONDataMap();

                var transaction = (JSONDataMap)(request["transaction"] = new JSONDataMap());
                transaction["type"]   = "sale";
                transaction["amount"] = amount.Value;
                transaction[isWeb ? "payment_method_nonce" : "payment_method_token"] = fromActualData.Account.AccountID;
                if (orderContex != null)
                {
                    transaction["order_id"] = orderContex.OrderId;
                    if (orderContex.IsNewCustomer)
                    {
                        var customer = (JSONDataMap)(transaction["customer"] = new JSONDataMap());
                        customer["id"] = orderContex.CustomerId;
                    }
                    else
                    {
                        transaction["customer_id"] = orderContex.CustomerId;
                    }
                }

                var billing = (JSONDataMap)(transaction["billing"] = new JSONDataMap());
                if (fromActualData.FirstName.IsNotNullOrWhiteSpace())
                {
                    billing["first_name"] = fromActualData.FirstName;
                }
                if (fromActualData.LastName.IsNotNullOrWhiteSpace())
                {
                    billing["last_name"] = fromActualData.LastName;
                }
                if (fromActualData.BillingAddress.Address1.IsNotNullOrWhiteSpace())
                {
                    billing["street_address"] = fromActualData.BillingAddress.Address1;
                }
                if (fromActualData.BillingAddress.Address2.IsNotNullOrWhiteSpace())
                {
                    billing["extended_address"] = fromActualData.BillingAddress.Address2;
                }
                if (fromActualData.BillingAddress.City.IsNotNullOrWhiteSpace())
                {
                    billing["locality"] = fromActualData.BillingAddress.City;
                }
                if (fromActualData.BillingAddress.Country.IsNotNullOrWhiteSpace())
                {
                    billing["country_code_alpha3"] = fromActualData.BillingAddress.Country;
                }
                if (fromActualData.BillingAddress.Region.IsNotNullOrWhiteSpace())
                {
                    billing["region"] = fromActualData.BillingAddress.Region;
                }
                if (fromActualData.BillingAddress.PostalCode.IsNotNullOrWhiteSpace())
                {
                    billing["postal_code"] = fromActualData.BillingAddress.PostalCode;
                }
                if (fromActualData.BillingAddress.Company.IsNotNullOrWhiteSpace())
                {
                    billing["company"] = fromActualData.BillingAddress.Company;
                }

                var options = (JSONDataMap)(transaction["options"] = new JSONDataMap());
                options["submit_for_settlement"] = capture;
                if (orderContex != null)
                {
                    options["store_in_vault_on_success"] = isWeb;
                }

                dynamic obj = getResponse(session, URI_Transactions(session.MerchantID), HTTPRequestMethod.POST, request);

                string created = obj.transaction.createdAt;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Charge);

                string customerID    = obj.transaction.customer.id;
                string token         = obj.transaction.creditCard.token;
                string transactionID = obj.transaction.id;

                var ta = Transaction.Charge(taId, this.Name, "{0}:{1}:{2}".Args(customerID, token, transactionID), from, to, amount, created.AsDateTime(), description);

                StatCharge(amount);

                return(ta);
            }
            catch (Exception ex)
            {
                StatChargeError();

                var wex = ex as System.Net.WebException;
                if (wex != null)
                {
                    using (var sr = new System.IO.StreamReader(wex.Response.GetResponseStream()))
                    {
                        var respStr = sr.ReadToEnd();
                        var resp    = respStr.IsNotNullOrWhiteSpace() ? respStr.JSONToDynamic() : null;
                        // TODO Exception Handilng
                    }
                }

                throw new PaymentException(StringConsts.PAYMENT_CANNOT_CHARGE_PAYMENT_ERROR + this.GetType()
                                           + " .Capture(session='{0}', card='{1}', amount='{2}')".Args(session, from, amount), ex);
            }
        }
示例#9
0
        public Transaction Charge(BraintreeSession session, ITransactionContext context, Account from, Account to, Amount amount, bool capture = true, string description = null, object extraData = null)
        {
            var orderContex = context as IOrderTransactionContext;

            var fromActualData = PaySystemHost.AccountToActualData(context, from);

            try
            {
                var isWeb       = fromActualData.Account.IsWebTerminalToken;
                var transaction = new XElement("transaction",
                                               new XElement("type", "sale"),
                                               new XElement("amount", amount.Value),
                                               new XElement(isWeb ? "payment-method-nonce" : "payment-method-token", fromActualData.Account.AccountID));
                if (orderContex != null)
                {
                    transaction.Add(new XElement("order-id", orderContex.OrderId));
                    if (isWeb)
                    {
                        if (orderContex.IsNewCustomer)
                        {
                            transaction.Add(new XElement("customer", new XElement("id", orderContex.CustomerId)));
                        }
                        else
                        {
                            try
                            {
                                getResponse(session, URI_Customer(session.MerchantID, orderContex.CustomerId.AsString()), method: HTTPRequestMethod.GET);
                                transaction.Add(new XElement("customer-id", orderContex.CustomerId));
                            }
                            catch
                            {
                                transaction.Add(new XElement("customer", new XElement("id", orderContex.CustomerId)));
                            }
                        }
                    }
                }
                if (isWeb)
                {
                    var billing = new XElement("billing");

                    if (fromActualData.FirstName.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("first-name", fromActualData.FirstName));
                    }
                    if (fromActualData.LastName.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("last-name", fromActualData.LastName));
                    }
                    if (fromActualData.BillingAddress.Address1.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("street-address", fromActualData.BillingAddress.Address1));
                    }
                    if (fromActualData.BillingAddress.Address2.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("extended-address", fromActualData.BillingAddress.Address2));
                    }
                    if (fromActualData.BillingAddress.City.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("locality", fromActualData.BillingAddress.City));
                    }
                    if (fromActualData.BillingAddress.Country.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("country-code-alpha3", fromActualData.BillingAddress.Country));
                    }
                    if (fromActualData.BillingAddress.Region.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("region", fromActualData.BillingAddress.Region));
                    }
                    if (fromActualData.BillingAddress.PostalCode.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("postal-code", fromActualData.BillingAddress.PostalCode));
                    }
                    if (fromActualData.BillingAddress.Company.IsNotNullOrWhiteSpace())
                    {
                        billing.Add(new XElement("company", fromActualData.BillingAddress.Company));
                    }

                    transaction.Add(billing);
                }

                var options = new XElement("options", new XElement("submit-for-settlement", capture));
                if (orderContex != null && isWeb)
                {
                    options.Add(new XElement("store-in-vault-on-success", true));
                }

                transaction.Add(options);

                var response = getResponse(session, URI_Transactions(session.MerchantID), new XDocument(transaction));

                transaction = response.Root;

                var transactionID = transaction.Element("id").Value;
                var status        = transaction.Element("status").Value;
                var captured      = status.EqualsOrdIgnoreCase("submitted_for_settlement");
                var created       = transaction.Element("created-at").Value.AsDateTime();
                var customerID    = transaction.Element("customer").Element("id").Value;
                var token         = transaction.Element("credit-card").Element("token").Value;

                var amountAuth     = new Amount(amount.CurrencyISO, transaction.Element("amount").Value.AsDecimal());
                var amountCaptured = captured ? (Amount?)amountAuth : null;

                var taId = PaySystemHost.GenerateTransactionID(session, context, TransactionType.Charge);
                var ta   = Transaction.Charge(taId, Name,
                                              "{0}:{1}:{2}".Args(customerID, token, transactionID),
                                              from, to,
                                              amountAuth, created, description,
                                              amountCaptured: amountCaptured);

                StatCharge(amount);

                return(ta);
            }
            catch (Exception ex)
            {
                StatChargeError();
                if (ex is PaymentException)
                {
                    throw ex;
                }
                throw new PaymentException(StringConsts.PAYMENT_CANNOT_CHARGE_PAYMENT_ERROR + GetType().Name
                                           + " .Charge(session='{0}', card='{1}', amount='{2}')".Args(session, from, amount), ex);
            }
        }