Creating an Authorize.net Subscription Using a CIM Profile

Published by John on July 12, 2017 Under PHP

Recently, while working on a site that manages user profiles, I needed to create a subscription using Authorize.net’s Automated Recurring Billing(ARB.)

Since we already have the user’s credit card information stored using the Customer Information Manager(CIM) in order to be able to charge them for one-off purchases, I wanted to create the subscription using their CIM profile, so as not to require them to re-enter their credit card information.

After some research, I determined that this was a current feature of their API, however the PHP API does not appear to offer it as an option. Fortunately, it is a fairly quick fix(provided you don’t mind editing their PHP API.)

To add support for this, first you need to modify the following file: lib/shared/AuthorizeNetTypes.php

Replace the entire AuthorizeNet_Subscription class with the following:

/**
 * A class that contains all fields for an AuthorizeNet ARB Subscription.
 *
 * @package    AuthorizeNet
 * @subpackage AuthorizeNetARB
 */
class AuthorizeNet_Subscription
{

    public $name;
    public $intervalLength;
    public $intervalUnit;
    public $startDate;
    public $totalOccurrences;
    public $trialOccurrences;
    public $amount;
    public $trialAmount;
    public $creditCardCardNumber;
    public $creditCardExpirationDate;
    public $creditCardCardCode;
    public $bankAccountAccountType;
    public $bankAccountRoutingNumber;
    public $bankAccountAccountNumber;
    public $bankAccountNameOnAccount;
    public $bankAccountEcheckType;
    public $bankAccountBankName;
    public $orderInvoiceNumber;
    public $orderDescription;
    public $customerId;
    public $customerEmail;
    public $customerPhoneNumber;
    public $customerFaxNumber;
    public $billToFirstName;
    public $billToLastName;
    public $billToCompany;
    public $billToAddress;
    public $billToCity;
    public $billToState;
    public $billToZip;
    public $billToCountry;
    public $shipToFirstName;
    public $shipToLastName;
    public $shipToCompany;
    public $shipToAddress;
    public $shipToCity;
    public $shipToState;
    public $shipToZip;
    public $shipToCountry;
    
    public function getXml()
    {
        $xml = "<subscription>
    <name>{$this->name}</name>
    <paymentSchedule>
        <interval>
            <length>{$this->intervalLength}</length>
            <unit>{$this->intervalUnit}</unit>
        </interval>
        <startDate>{$this->startDate}</startDate>
        <totalOccurrences>{$this->totalOccurrences}</totalOccurrences>
        <trialOccurrences>{$this->trialOccurrences}</trialOccurrences>
    </paymentSchedule>
    <amount>{$this->amount}</amount>
    <trialAmount>{$this->trialAmount}</trialAmount>
    <payment>
        <creditCard>
            <cardNumber>{$this->creditCardCardNumber}</cardNumber>
            <expirationDate>{$this->creditCardExpirationDate}</expirationDate>
            <cardCode>{$this->creditCardCardCode}</cardCode>
        </creditCard>
        <bankAccount>
            <accountType>{$this->bankAccountAccountType}</accountType>
            <routingNumber>{$this->bankAccountRoutingNumber}</routingNumber>
            <accountNumber>{$this->bankAccountAccountNumber}</accountNumber>
            <nameOnAccount>{$this->bankAccountNameOnAccount}</nameOnAccount>
            <echeckType>{$this->bankAccountEcheckType}</echeckType>
            <bankName>{$this->bankAccountBankName}</bankName>
        </bankAccount>
    </payment>
    <order>
        <invoiceNumber>{$this->orderInvoiceNumber}</invoiceNumber>
        <description>{$this->orderDescription}</description>
    </order>
    <customer>
        <id>{$this->customerId}</id>
        <email>{$this->customerEmail}</email>
        <phoneNumber>{$this->customerPhoneNumber}</phoneNumber>
        <faxNumber>{$this->customerFaxNumber}</faxNumber>
    </customer>
    <billTo>
        <firstName>{$this->billToFirstName}</firstName>
        <lastName>{$this->billToLastName}</lastName>
        <company>{$this->billToCompany}</company>
        <address>{$this->billToAddress}</address>
        <city>{$this->billToCity}</city>
        <state>{$this->billToState}</state>
        <zip>{$this->billToZip}</zip>
        <country>{$this->billToCountry}</country>
    </billTo>
    <shipTo>
        <firstName>{$this->shipToFirstName}</firstName>
        <lastName>{$this->shipToLastName}</lastName>
        <company>{$this->shipToCompany}</company>
        <address>{$this->shipToAddress}</address>
        <city>{$this->shipToCity}</city>
        <state>{$this->shipToState}</state>
        <zip>{$this->shipToZip}</zip>
        <country>{$this->shipToCountry}</country>
    </shipTo>
</subscription>";
        
        $xml_clean = "";
        // Remove any blank child elements
        foreach (preg_split("/(\r?\n)/", $xml) as $key => $line) {
            if (!preg_match('/><\//', $line)) {
                $xml_clean .= $line . "\n";
            }
        }
        
        // Remove any blank parent elements
        $element_removed = 1;
        // Recursively repeat if a change is made
        while ($element_removed) {
            $element_removed = 0;
            if (preg_match('/<[a-z]+>[\r?\n]+\s*<\/[a-z]+>/i', $xml_clean)) {
                $xml_clean = preg_replace('/<[a-z]+>[\r?\n]+\s*<\/[a-z]+>/i', '', $xml_clean);
                $element_removed = 1;
            }
        }
        
        // Remove any blank lines
        // $xml_clean = preg_replace('/\r\n[\s]+\r\n/','',$xml_clean);
        return $xml_clean;
    }
}

Now, when you are creating a subscription, instead of adding a credit card, set a customer profile ID and customer payment profile ID, in order to create the subscription using the CIM profile(as opposed to using a credit card.) In the event that you have not added both a customerPaymentProfileId and a customerProfileId to the subscription, it should default to attempting to create it using a credit card or bank account.

Basic Example:


	$subscription = new AuthorizeNet_Subscription;
	$subscription->name = $subscription_name;
	$subscription->intervalLength = 1;
	$subscription->intervalUnit = 'months';
			
	$subscription->startDate = $start_date;
	$subscription->totalOccurrences = 24;
			
	$subscription->amount = $this->get_subscription_cost();
	$subscription->orderInvoiceNumber = $invoice_number;
	$subscription->orderDescription = $order_description;
			
	$subscription->customerPaymentProfileId = $payment_profile_id;
	$subscription->customerProfileId = $customer_profile_id;


No Comments |

Add a Comment