2013-03-27 83 views
3

我正在使用ASP.NET MVC 4,.NET Braintree Payments API和Braintree.js。Braintree API在Sandbox的CreateCard.Create中抛出Braintree.Exceptions.AuthorizationException

下面是一个简单的包装我建立布伦特里:

public class PaymentBL 
{ 
    private static BraintreeGateway _braintreeGateway = new BraintreeGateway 
     { 
      Environment = Braintree.Environment.SANDBOX, 
      MerchantId = "xxxxxxx", 
      PublicKey = "xxxxxxxxxxxx", 
      PrivateKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
     }; 

    public Result<Transaction> ChargeCardOnce(decimal amount, string cardholderName, string cardNumber, string expiration, 
     string cvv) 
    { 
     TransactionCreditCardRequest creditCardRequest = new TransactionCreditCardRequest(); 
     creditCardRequest.CardholderName = cardholderName; 
     creditCardRequest.Number = cardNumber; 
     creditCardRequest.ExpirationDate = expiration; 
     creditCardRequest.CVV = cvv; 

     TransactionOptionsRequest optionsRequest = new TransactionOptionsRequest(); 
     optionsRequest.SubmitForSettlement = true; 

     TransactionRequest transactionRequest = new TransactionRequest(); 
     transactionRequest.Amount = amount; 
     transactionRequest.CreditCard = creditCardRequest; 
     transactionRequest.Options = optionsRequest; 

     return _braintreeGateway.Transaction.Sale(transactionRequest); 
    } 

    /// <summary> 
    /// Stores a credit card in the Braintree vault. In some cases, will put a $1 temporary charge 
    /// on the credit card that will come off a few days later. 
    /// 
    /// From BrainTree: Regardless of card type, any instance where a $1 authorization returns a successful result, 
    /// we immediately follow-up with an automatic void request to ensure that the transaction will fall off 
    /// of the cardholder's statement as soon as possible. 
    /// </summary> 
    public Result<CreditCard> StoreCustomer(int customerId, string cardholderName, string cardNumber, string expiration, string cvv) 
    { 
     //CreditCardAddressRequest addressRequest = new CreditCardAddressRequest(); 
     //addressRequest.PostalCode = postalCode; 

     CreditCardOptionsRequest optionsRequest = new CreditCardOptionsRequest(); 
     optionsRequest.VerifyCard = true; 
     optionsRequest.VerificationMerchantAccountId = _braintreeGateway.MerchantId; 

     CreditCardRequest creditCard = new CreditCardRequest(); 
     creditCard.CustomerId = customerId.ToString(); 
     creditCard.Token = customerId.ToString(); // Use same token to ensure overwrite 
     creditCard.CardholderName = cardholderName; 
     creditCard.Number = cardNumber; 
     creditCard.ExpirationDate = expiration; 
     creditCard.CVV = cvv; 
     creditCard.Options = optionsRequest; 

     return _braintreeGateway.CreditCard.Create(creditCard); 
    } 

    /// <summary> 
    /// Search BrainTree vault to retrieve credit card 
    /// </summary> 
    /// <param name="customerId"></param> 
    public CreditCard GetCreditCardOnFile(int customerId) 
    { 
     Customer customer = null; 

     try 
     { 
      customer = _braintreeGateway.Customer.Find(customerId.ToString()); 
     } 
     catch (Braintree.Exceptions.NotFoundException) 
     { 
      return null; 
     } 

     if (customer.CreditCards == null || customer.CreditCards.Length == 0) 
     { 
      return null; 
     } 

     if (customer.CreditCards.Length >= 2) 
     { 
      throw new Exception(string.Format("Customer {0} has {1} credit cards", 
       customerId, customer.CreditCards.Length)); 
     } 

     return customer.CreditCards[0]; 
    } 
} 

当我调用这个方法,它的工作原理:

  Result<Transaction> result = paymentBL.ChargeCardOnce(
       2.34m 
       , formCollection["name"] 
       , formCollection["number"] 
       , formCollection["exp"] 
       , formCollection["cvv"] 
      ); 

随后,我可以在布伦特里查看已完成测试交易仪表板。因此,我知道Braintree.js的加密表单值正确地到达我的控制器操作,并且我的密钥和商家帐户ID都已正确设置。

当我更换上面的调用与以下调用StoreCustomer到ChargeCardOnce,我收到一个Braintree.Exceptions.AuthorizationException在该行return _braintreeGateway.CreditCard.Create(creditCard);

  Result<CreditCard> result = paymentBL.StoreCustomer(
       systemHost.Customer.CustomerId 
       , formCollection["name"] 
       , formCollection["number"] 
       , formCollection["exp"] 
       , formCollection["cvv"] 
      ); 

从布伦特里支持:“你能创建一个客户以及沙盒中的信用卡,因为它的制作完全反映了生产环境的外观。“

有没有人体验过这个呢?我指的是Braintree对这个问题的支持,但是如果SO上的任何人已经看到了这一点,并且知道解决方案或解决方法,我会放心的。

回答

13

我在布伦特里工作。看起来我们已经回答了你的问题的答案,但我会在这里回答任何有未来相同问题的人。

在这种情况下,问题是:

optionsRequest.VerificationMerchantAccountId = _braintreeGateway.MerchantId; 

商家ID标识您的支付网关帐户,而您的商家帐户ID标识要用于验证的银行帐户。 An article in our support center explains the difference

MerchantAccountId

随着布伦特里,你可以有多个商户 通过同一个网关帐户占所有处理。这 意味着你可以有多个地点,多个业务,多种货币等所有设置和处理在一个单一的 帐户。通过统一报告和访问,您可以轻松跟踪所有的处理过程,甚至可以为您节省开支。

您可以通过以下步骤找到所有商家帐户的ID在你的网关 帐户:在您的帐户名

  • 登录到您的帐户

  • 悬停,然后单击“处理”

  • 滚动至页面底部至 标为“商家帐户”的部分。

AuthorizationExceptionHTTP Status Code 403 Forbidden。这意味着服务器正在拒绝您的请求,因为您无权访问资源(即使您可能已通过身份验证)。

由于没有商户帐户可供您的用户使用您指定的ID(因为它根本不是商家帐户ID),您可以获得AuthorizationException

如果您的商家经常只有一个商家帐户,或者您想使用默认帐户,则无需指定VerificationMerchantAccountId

+0

感谢您的回答和澄清,它已经解决了这个问题。 – 2013-03-29 16:48:44