【问题标题】:Using Bank Accounts With Authorize.Net C# SDK通过 Authorize.Net C# SDK 使用银行账户
【发布时间】:2012-06-14 10:37:42
【问题描述】:

在玩过Authorize.Net CIM XML API C# sample code 之后,我开始使用Authorize.Net C# SDK。我可以使用 CIM XML API 示例代码将信用卡和银行帐户添加到客户资料中。不过,我看不到如何使用 SDK 添加银行帐户。

使用 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;
...

使用 SDK 我只看到.AddCreditCard() 方法,但无法添加银行帐户。当我遍历我所有的 PaymentProfiles 时,它也会在遇到银行账户时引发异常:

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());
    }
}

例外:

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

如何使用 Authorize.Net C# SDK 将银行帐户添加到 CIM 配置文件?

更新:

CIM 可以存储银行账户信息的证明:

【问题讨论】:

  • @Ramhound 解释一下然后dl.dropbox.com/u/3115379/…
  • @Rup - 他们可能知道自己在做什么,但他们的代码和社区本身并没有给我留下深刻印象。
  • @Greg - 我不知道该告诉你什么。我查看了他们的整个 API。我下载的 API 让我相信 PaymentProfile 不支持将支票账户添加到客户的 PaymentProfile。所以我建议你联系 Authorize.NET 并简单地询问。 我继续删除我制作的 cmets,因为它们不正确。
  • @Rup 是的,developer@authorize.net 没有回应
  • 截至 2012 年 6 月 15 日,Authorize.NET 开发者论坛上的帖子称他们正在“调查”...community.developer.authorize.net/t5/Integration-and-Testing/…

标签: c# payment-gateway authorize.net


【解决方案1】:

以下内容已经过测试,但仅就原始问题提出的问题(为我测试更多?)而言,我使用提供的 XML 示例并通过复制 AddCreditCard 代码的代码来编写它。

当您完成更新后,以下代码将起作用:

        var cg = new CustomerGateway("login", "transkey", ServiceMode.Test);
        var c = cg.CreateCustomer("peter@example.com", "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());
        }

首先,从http://developer.authorize.net/downloads/下载API的C#源代码。

在查看代码时,我可以看到 4 个使用“creditCardType”的文件,它们是 SubscriptionRequest.cs、CustomerGateway.cs、PaymentProfile.cs 和 AnetApiSchema.cs(这是我们不必触及的最后一个)。我们还需要注意在 PaymentProfile.cs、Transaction.cs 和 AnetApiSchema.cs 中使用的“creditCardMaskedType”。这些文件出现在任何地方,我们都需要确保我们也支持 bankAccount 等价物。

打开 AuthorizeNET 解决方案。我们将浏览一下上面列出的文件。

在 CustomerGateway.cs 中添加以下代码块:

    /// <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;
    }

在 PaymentProfile.cs 添加一些公共属性

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

修改PaymentProfile(customerPaymentProfileMaskedType apiType)构造函数的如下块:

        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;
            }
        }

将此块添加到PaymentProfile.ToAPI() 方法中:

        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;
        }

将以下公共属性添加到 SubscriptionRequest.cs > SubscriptionRequest 类(大约第 187 行)

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

添加以下 else if block TWICE 到 SubscriptionRequest。第一次是在 ToAPI 方法中,第二次是在 ToUpdateableAPI 方法中,在这两种情况下都在 CC 编号 null 检查之后。

        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;
        }

将以下公共属性添加到 Transaction.cs

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

在静态 NewFromResponse(transactionDetailsType trans) 方法中的 Transaction.cs 中,找到检查 trans.payment != null 的块并进行调整,如下所示:

        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;
            }
        }

【讨论】:

  • 不错!我完全错过了有源下载:-/
  • 非常感谢您提供此示例代码。我在 authorize.net 获得了支持,告诉我 C# SDK 不能使用 CIM,除非它是通过 SOAP/XML 完成的,尽管我向他们指出 SDK 中有明确的方法可以实现 CIM。
  • @Ricky 很遗憾,在我编写这段代码将近两年后,他们仍然没有将这个功能添加到他们的 .Net SDK 中。很高兴听到它对您有所帮助。
  • @Peter 对于信用卡,它可以完美运行,但它不在 SDK 或 CIM 文档中。我使用了您的第一个代码块,并且能够成功设置 CIM 配置文件并对其进行验证,而无需使用您的任何其他代码。我已经在努力实现它,这样我们就可以摆脱在我们的系统中存储信用卡详细信息,以符合 PCI 的要求。再次感谢。
  • 谢谢。确实需要一点时间来了解将项目添加到 SubscriptionRequest 类的位置。
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 2018-04-26
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多