Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Bank Accounts With Authorize.Net C# SDK

After playing around with the Authorize.Net CIM XML API C# sample code, I started using the Authorize.Net C# SDK. I am able to add credit cards and bank accounts to customer profiles using the CIM XML API sample code. I don't see how to add bank accounts using the SDK though.

Adding bank account with CIM XML API:

... customerPaymentProfileType new_payment_profile = new customerPaymentProfileType(); paymentType new_payment = new paymentType();  bankAccountType new_bank = new bankAccountType(); new_bank.nameOnAccount = "xyz"; new_bank.accountNumber = "4111111"; new_bank.routingNumber = "325070760"; new_payment.Item = new_bank;  new_payment_profile.payment = new_payment;  createCustomerPaymentProfileRequest request = new createCustomerPaymentProfileRequest(); XmlAPIUtilities.PopulateMerchantAuthentication((ANetApiRequest)request);  request.customerProfileId = profile_id.ToString(); request.paymentProfile = new_payment_profile; request.validationMode = validationModeEnum.testMode; ... 

Using the SDK I only see a .AddCreditCard() method, but no way to add a bank account. When I loop through all my PaymentProfiles It throws an exception when it comes across a bank account too:

CustomerGateway cg = new CustomerGateway("xxx", "yyy");  foreach (string cid in cg.GetCustomerIDs()) {     Customer c = cg.GetCustomer(cid);     foreach (PaymentProfile pp in c.PaymentProfiles)     {         Console.WriteLine(pp.ToString());     } } 

Exception:

Unable to cast object of type 'AuthorizeNet.APICore.bankAccountMaskedType' to type 'AuthorizeNet.APICore.creditCardMaskedType'. 

enter image description here

How do I add a bank account to a CIM profile using the Authorize.Net C# SDK?

Update:

Proof that CIM can store bank account information:

enter image description here

like image 435
Greg Avatar asked Jun 11 '12 13:06

Greg


People also ask

Does Authorize.net accept debit cards?

Offer your customers a variety of payment options ranging from debit cards, credit cards and eChecks to digital payments like Apple Pay and PayPal. Questions? Call 1-888-323-4289.

Does Authorize.net accept ACH payments?

Authorize.net allows you to accept eChecks, also known as ACH Payments directly through your Virtual Terminal! In addition, when accepting eChecks, you can also setup recurring payments using this payment method – so you can offer easy monthly/quarterly payments to your customers or members.

What bank does Authorize.net use?

Bank of America Merchant Services.

Does Authorize.net need a merchant account?

For a business like yours that wants to accept payments—online, in person or both—a payment gateway (such as Authorize.net) is a must-have, along with a merchant bank account.


1 Answers

The following is tested, but only so far as what the original question brought up (Test it more for me?), I wrote it using the provided XML example and by copying the code for the AddCreditCard code.

When you are all done updating the following code will work:

        var cg = new CustomerGateway("login", "transkey", ServiceMode.Test);         var c = cg.CreateCustomer("[email protected]", "test customer");         //just to show that we didn't break CC         cg.AddCreditCard(c.ProfileID, "cc#", 07, 2011);         cg.AddBankAccount(c.ProfileID, "Peter", "bankaccoung#", "routing#");         //tostring doesn't actually do much... but if you break on it you can see the details for both the CC and the bank info.         foreach (PaymentProfile pp in cg.GetCustomer(c.ProfileID).PaymentProfiles)         {             Console.WriteLine(pp.ToString());         } 

First, download the C# source code for the API from http://developer.authorize.net/downloads/.

In reviewing the code I can see 4 files that use "creditCardType", these are SubscriptionRequest.cs, CustomerGateway.cs, PaymentProfile.cs and AnetApiSchema.cs (this last one we don't have to touch). We also need to watch out for 'creditCardMaskedType', which is used in PaymentProfile.cs, Transaction.cs and AnetApiSchema.cs. Any place these files show up we need to make sure we support the bankAccount equivelants as well.

Open the AuthorizeNET solution. We'll be jumping around a bit through the files listed above.

In CustomerGateway.cs add the following block of code:

    /// <summary>     /// Adds a bank account profile to the user and returns the profile ID     /// </summary>     /// <returns></returns>     public string AddBankAccount(string profileID, string nameOnAccount, string accountNumber, string routingNumber)     {         var req = new createCustomerPaymentProfileRequest();         req.customerProfileId = profileID;         req.paymentProfile = new customerPaymentProfileType();         req.paymentProfile.payment = new paymentType();          bankAccountType new_bank = new bankAccountType();         new_bank.nameOnAccount = nameOnAccount;         new_bank.accountNumber = accountNumber;         new_bank.routingNumber = routingNumber;          req.paymentProfile.payment.Item = new_bank;          var response = (createCustomerPaymentProfileResponse)_gateway.Send(req);          return response.customerPaymentProfileId;     } 

In PaymentProfile.cs add some public properties

    public string BankNameOnAccount {get; set; }     public string BankAccountNumber { get; set; }     public string BankRoutingNumber { get; set; } 

Modify the the following block of the PaymentProfile(customerPaymentProfileMaskedType apiType) constructor:

        if (apiType.payment != null) {             if(apiType.payment.Item is bankAccountMaskedType) {                 var bankAccount = (bankAccountMaskedType)apiType.payment.Item;                 this.BankNameOnAccount = bankAccount.nameOnAccount;                 this.BankAccountNumber = bankAccount.accountNumber;                 this.BankRoutingNumber = bankAccount.routingNumber;             }             else if (apiType.payment.Item is creditCardMaskedType)             {                 var card = (creditCardMaskedType)apiType.payment.Item;                 this.CardType = card.cardType;                 this.CardNumber = card.cardNumber;                 this.CardExpiration = card.expirationDate;             }         } 

Add this block to the PaymentProfile.ToAPI() method:

        if (!string.IsNullOrEmpty(this.BankAccountNumber))         {             bankAccountType new_bank = new bankAccountType();             new_bank.nameOnAccount = BankNameOnAccount;             new_bank.accountNumber = BankAccountNumber;             new_bank.routingNumber = BankRoutingNumber;              result.payment.Item = new_bank;         } 

Add the following public properties to SubscriptionRequest.cs > SubscriptionRequest class (around line 187)

    public string BankNameOnAccount {get; set; }     public string BankAccountNumber { get; set; }     public string BankRoutingNumber { get; set; } 

Add the following else if block TWICE to SubscriptionRequest. The first time is in the ToAPI method, the second is in the ToUpdateableAPI method, in both cases it goes after the CC number null check.

        else if (!String.IsNullOrEmpty(this.BankAccountNumber))         {             bankAccountType new_bank = new bankAccountType();             new_bank.nameOnAccount = BankNameOnAccount;             new_bank.accountNumber = BankAccountNumber;             new_bank.routingNumber = BankRoutingNumber;              sub.payment = new paymentType();             sub.payment.Item = new_bank;         } 

Add the following public properties to Transaction.cs

    public string BankNameOnAccount { get; set; }     public string BankAccountNumber { get; set; }     public string BankRoutingNumber { get; set; } 

In Transaction.cs in the static NewFromResponse(transactionDetailsType trans) method, find the block that checks for trans.payment != null and tweak as shown:

        if (trans.payment != null) {             if (trans.payment.Item.GetType() == typeof(creditCardMaskedType))             {                 var cc = (creditCardMaskedType)trans.payment.Item;                 result.CardNumber = cc.cardNumber;                 result.CardExpiration = cc.expirationDate;                 result.CardType = cc.cardType;             }              else if (trans.payment.Item.GetType() == typeof(bankAccountMaskedType))             {                 var bankAccount = (bankAccountMaskedType)trans.payment.Item;                 result.BankNameOnAccount = bankAccount.nameOnAccount;                 result.BankAccountNumber = bankAccount.accountNumber;                 result.BankRoutingNumber = bankAccount.routingNumber;             }         } 
like image 136
Peter Avatar answered Oct 04 '22 09:10

Peter