Payment Gateway Plugin API

CartThrob has a payment gateway interface and several helper functions that simplify the creation of payment gateways. Review the gateways that come with CartThrob for examples. The Cartthrob_dev_template.php contains detailed notes and documentation within the file itself. It should serve as a good guide for building additional gateways. Cartthrob_cartthrob_direct.php, and Cartthrob_sage_s.php are also good reference examples. You can find existing CartThrob gateways in the cartthrob/payment_gateways folder.

It's important to note that the most critical element of building a gateway is understanding your processor's system. You'll need to have an account with your processor to test with, and you'll need their developer documentation, and code samples as well if they're available. If code samples are not available, you may try to refer to gateways for other shopping carts that have already been developed.

We have several functions that exist to simplify integration with off-site gateways, but some gateways are just complex to deal with, and there's no getting around it. Rather than make the process of building a custom integrated gateway even more complicated we've tried to simplify the process as much as possible through the use of helper functions that simplify integration with many different types of gateways. Review the cartthrob/libraries/Cartthrob_payments.php file to see the full list of payment gateway helper functions.

There are several types of gateways that we've discovered over the years. CartThrob can integrate with each type, but some are more difficult than others. Gateways are classified in the following groups:

  • Direct. All payment details are taken on your site, the customer never leaves your site. Authorization is immediate.
  • Hosted/redirect. The customer is taken off of your site to the processor's site. All payment details are taken on the processor's site. When the transaction is complete, the customer is redirected back to your site. (see gateway_offsite_redirect and gateway_order_update functions below)
  • Hosted/cul-de-sac. The customer is taken off site. All payment details are taken on the processor's site, and the authorization is immediate. At the end of the process, the customer is left at the processor's site, but the processor dynamically pulls in a page from your website. (see reference to get_notify_url and relaunch_session below)
  • Hosted/dead end. The customer is taken off site, and makes the payment at the processor's site. At the end of the process, the customer is not directed back to your site, no pages are pulled from your site, and your site is not notified of the success or failure of a transaction. At best, they may allow you to upload a plain HTML template to display when a transaction is successful or fails. We do not recommend any company that only offers this limited service.
  • Hosted/delayed-response (PayPal, Google Checkout are the most well-known). The customer is taken offsite. All payment details are taken on the processor's site. Authorization may take as long as a week. At the end of the process the customer may or may not be redirected back to your site. The transaction is not completed in real-time, and your site may not be notified of a successful completion for days. It's like taking an IOU that will probably be paid in a few days. These types of merchant accounts are generally inexpensive to set up and maintain, but integration is much more time consuming, and the process is inefficient and confusing. Many times if customers purchase items or software, they expect shipping or downloads to be immediate. Using one of these methods, you need to wait until the funding is authorized. Integrating these gateways is difficult because you need to set up the system to relaunch orders securely. PayPal standard is a fairly typical example of this type of gateway (see relaunch_session function below.).

Getting Started

When you begin, follow the following requirements.

  • All gateways should be named Cartthrob_your_gateway_name.php and should be stored in the cartthrob/third_party/payment_gateways folder.
  • You may also want to create a language file to go with your gateway. You can refer to existing language files (cartthrob/language/english) for structure, but at a minimum, language files need to be named cartthrob_your_gateway_name_lang.php, and should be added to the appropriate language folder.
  • The classname of your gateway needs to match the filename. A file called Cartthrob_my_gateway.php will have a classname like so: "Cartthrob_my_gateway extends Cartthrob_payment_gateway"
  • public $title is the descriptive name of your gateway
  • public $overview is the overview or special instructions for this gateway
  • public $settings is an array of settings (more on that below)
  • public $fields is an array containing fields that will be output as part of the gateway_fields variable in the checkout form. Adding fields here handles nearly all of the formatting and basic form generation. Please see cartthrob/libraries/API/API_cartthrob_payment_gateways gateway_fields function for a list of acceptable field names. Only fields listed in the API should be used, all other field names are ignored. If it is absolutely impossible to integrate with your gateway without additional field names, please contact us.
  • public $required_fields is an array containing form fields that are required. Any field set in this array will cause the checkout process to fail if that field is empty.
  • public $hidden states which fields should be hidden fields not editable by the user. When a user checks out hidden fields are filled automatically if appropriate data is found in the user's session.
  • public $card_types is an array containing the gateway's acceptable credit card types. If this is not set, visa => Visa, mc => MasterCard, amex => American Express, and discover => Discover are used. Your particular processor might also take additional cards like Laser and Solo, or might use different key names like MC, Master, MasterCard, in which case you'll need to provide an array of credit card types containing the required gateway code as the key, and the descriptive name the customer will see as the value.
  • There is only ONE required function: charge. This function is required of all gateways to do the bare minimum of processing. More details on it are listed below.

Plugin Settings

Plugin settings are shown in the payment gateway configuration page. Generally they're used to store merchant ids and passwords, and other information required to integrate with your gateway. You'll find an example of the different types of settings below.

    'settings' => array(
        array(
            'name' => 'Settings Example', // descriptive name
            'short_name' => 'settings_example', // you will use this to access this setting your code.
            'type' => 'text', // or textarea
            'default' => 'Default Text', // optional
        ),
        array(
            'name' => 'Settings Example 2', 
            'short_name' => 'settings_example_2', 
            'type' => 'radio',
            'default' => 'no', // will auto-select "no" as the default
            'options' => array(
                'yes' => 'Yes',
                'no' => 'No',
            ),
        ),
        array(
            'name' => 'Settings Example 3',
            'short_name' => 'settings_example3',
            'type' => 'matrix',
            'settings' => array(
                array(
                    'name' => 'Matrix Settings',
                    'short_name' => 'matrix_settings',
                    'type' => 'checkbox',
                    'options' => array(
                        'option1' => 'Option1'
                    )
                )
                array(
                    'name' => 'Other Setting',
                    'short_name' => 'other_setting',
                    'type' => 'text',
                    'default' => "More default text"
                )
            ),
        ),
    )

Using the "settings" array, you can create multiple setting fields that will display in the gateways settings when it is selected. Name, short_name, and type are required for each settings group. You may optionally provide a default value. The available types include "text", "textarea", "radio", "checkbox" and "matrix". Find examples of each are shown above.

Processing Overview

By the time $this->order() data makes it to your gateway, the data has already been cleaned and formatted. Any data will have already been saved as an order, so all you need to do is pass the data off to your gateway in their required format. Though it's really dependant on your processor's requirements, our typical methodology is this:

  1. create an array containing the processor's required variable names as array keys (eg. z_firstName) and CartThrob data (eg. $this->order('first_name')) as array values. (see $post_array in our example below)
  2. convert that array into a query string (if needed)
  3. curl the data to the gateway for direct integration, or use gateway_exit offsite to send the customer to the hosted processing page.
  4. handle the response, either by reading the curl data, or in a function that will be called by the processor (see get_notify_url function below)

Order Data Variables

You can access all order data using $this->order('variable'); You do not need to test whether or not the particular variable is set. If it's not set NULL will be returned.

'first_name',
'last_name',
'address',
'address2',
'city',
'state',
'zip',
'description',
'company',
'phone',
'email_address',
'shipping_first_name',
'shipping_last_name',
'shipping_address',
'shipping_address2',
'shipping_city',
'shipping_state',
'shipping_zip',
'expiration_month',
'expiration_year',
'begin_month',
'begin_year',
'bday_month',
'bday_day',
'bday_year',
'CVV2',
'card_code',
'issue_number',
'card_type',
'currency_code',
'country_code',
'shipping_option',
'credit_card_number'
'entry_id'
'total'

function charge($credit_card_number)

The charge function is the only required function in your payment gateway. The $credit_card_number is the only parameter, and can be set to NULL. Any other information can be accessed using $this->order('variable_name');

In the very end of the process you should generally return an array containing the following keys:

$auth= array(
            "authorized"    => (boolean) FALSE, // if successful send true. otherwise false
            "failed"        => (boolean) TRUE, // if unable to understand error, or complete failure send TRUE
            "declined"      => (boolean) FALSE, // if transaction is declined send TRUE
            "processing"    => (boolean) FALSE, // only used for gateways like PayPal that take a long time to authorize
            "error_message" => (string) "Your error message",
            "transaction_id"    => (string) "123456", // the transaction id returned from the processor. 
        ); 


This returned data is also used in the templates to evaluate conditionals and output authorization and error messages. Default values are not necessary, if you return an empty array, CartThrob will automatically set the transaction to "failed", and will output a generic error.

If 'authorized' is TRUE, the transaction will be considered successful. Declined & failed conditions will be ignored.

function success()

You can add other functions as necessary. They are not used by CartThrob in anyway. You can call them from outside the system however (see get_notify_url below)

Helper Functions

$this->data_array_to_string

$data = $this->data_array_to_string($array);

Converts an array to a urlencoded string of name / value pairs, ex. var1=cart&var2=throb

$this->split_url_string

$transaction =  $this->split_url_string($connect);

Splits a URL encoded string of name / value pairs into an array, ex. $transaction['var1']='cart'; $transaction['var2']='throb';

$this->curl_transaction

$connect = $this->curl_transaction($host_url,$data);

Uses cURL to send and receive data to another server. Pass in the curl server address as a string, and send additional data as an array or query string as required by your processor. Most of the processor documentation does not specifiy whether a query string is required or not, some trial and error may be needed.

$this->gateway_exit_offsite

$this->gateway_exit_offsite($post_array, $host_url); exit; 

If you are going to be sending the user off-site for handling the rest of the transaction, add this function at the bottom of your charge function. This function basically converts an array of key=>values to a URL string, and redirects the user to the off-site gateway using this data. Take a look at the post array used in the Authorize.net payment gateway as an example… each gateway requires different data, which you must gather, format as necessary and send.

$this->gateway_order_update

$this->gateway_order_update($auth_array,$this->order('order_id'), $this->order('return'));

This function is useful for completing an order, after being returned from a hosted gateway. Use this regardless of whether your transaction was successful or not, as it updates the status of transactions based on the $auth array (see charge above for more information about the $auth array). The auth array and order id are required. If the return URL is empty the customer will not be redirected. Generally you should only leave the return URL parameter empty if your system is being notified in the background by a payment processor… many times they require that there are no redirects in your notification system. If the customer is redirected to the function calling gateway_order_update, you should generally supply a return url.

This function does the following:

  • Updates the transaction data for an order (adds transaction numbers, or error messages to the order data)
  • Updates order status. This will set the complete, failed, declined, processing status as dictated by the contents of the $auth array
  • Updates purchased items status
  • Executes the on_fail, on_authorize, and on_decline extension hooks.
  • Sends notification emails

$this->get_notify_url

$success_url = $this->_get_notify_url(ucfirst(get_class($this)),'my_success_function');

This function will generate something like this:

http://yoursite.com/index.php?ACT=57gateway=my_selected_gateway&method=my_success_function

Many hosted payment processing systems will return your customers to a different URL for success, failed, declined transactions. You can usually use the same notification url for each of these statuses… if the gateay also posts transaction data you will be able to parse this information and update cartthrob using the gateway_order_update function. The dynamic URLs generated by this function makes it possible to update CartThrob with order data, transaction information and status. If you use a hard-coded URL, you will not get the benefit of this additional order processing.

NOTE: Some payment processors WILL NOT use URLs containing a query string (?ACT=etc). IF that's the case with your processor, please contact us for some sample methodology and code.

$this->plugin_settings

$merchant_id = $this->plugin_settings('your_variable')

Allows you to access plugin settings data.
### $this->alpha2_country_code

$two_character_country_code = $this->alpha2_country_code($this->order('country_code'))); 

This will convert CartThrob's standard 3 character country codes to 2 character codes.

$this->year2

$year = $this->year2($this->order('expiration_year'))); 

This converts 4 character years to 2 character years (2004 -> 04)

$this->year4

$year = $this->year4($this->order('expiration_year')));


This ensures a year date is sent as 4 characters (2004)

$this->update_order

$this->update_order(array('status'=>'closed', 'first_name'=>'Joe')); 

Allows you to update order data by sending an array containing key => value pairs.

$this->relaunch_session

$this->relaunch_session($session_id);

This will relaunch a dead session, and allow you to access order data from the session using $this->order('var'); This is only needed when a gateway needs to communicate with your site in the background, or after your customer is no longer present. Generally you will have to get the session from a $post variable or other method. Be careful when using this, as the entire order data is stored. This is best used when you can dynamically validate that the message is coming from your payment processor.

$this->fetch_template

$template_code = $this->fetch_template('cart/complete'); 

Fetches the contents of an existing template.

$this->parse_template

echo $this->parse_template($template_code, array('{my_variable}'=> "123")); 

Will parse ExpressionEngine template code. You can optionally send and array of variables to parse as well.