Payment Gateway API

Restrict Content Pro includes a complete payment gateway API that permits developers to integrate Restrict Content Pro with additional payment processors.

Building a payment gateway includes two primary components:

  1. Registering the gateway
  2. Providing an extension of the RCP_Payment_Gateway class

Payment gateways are registered through the  rcp_payment_gateways filter. This receives one parameter, $gateways, that is an array of all currently registered gateways.

Each gateway in the array is an array with the following keys:

  • label - The payment method label shown to customers
  • admin_label - The label used to describe the gateway in the settings screen
  • class - The name of the class that extensions the RCP_Payment_Gateway base class

The ID of the gateway is determined by the key in the main array.

Registering a gateway looks like this:

Once you have registered the gateway, you will write out the gateway class. The class provided should be an extension of the base payment gateway class, which looks like this:

There are several foundational methods provided by the base class:

  • init() - (required) This is used to setup a few gateway properties
  • process_signup() - (required) This is the method that is run when the registration form is submitted and all validation passes
  • process_webhooks() - (optional) This is the method that is used to detect webhooks from the payment processor
  • scripts() - (optional) This method allows you to enqueue or output any JS/CSS needed for the payment gateway
  • fields() - (optional) This method allows you to output gateway-specific fields on the registration form
  • validate_fields() - (optional) This method allows you to validate the custom fields you have added to the registration form for the gateway

A gateway is only required to provide the init() and process_signup() methods, but the other methods will likely be used as well for many payment gateways.

The init() method is primarily used for declaring which features the gateway supports and checking for sandbox mode. A common init() method looks like this:

The process_signup() method is where most of magic happens. This is the method that handles calling the payment processor's API or redirecting to an external payment page. For this example, let's assume we are going to redirect to an external payment page.

Before adding our processing logic to process_signup(), our class looks something like this:

We now write our redirection logic in process_signup():

This shows some basic logic for subscriptions but there are numerous additional variables for you to work with. Restrict Content Pro will provide the following properties for the class:

  • $supports 
  • $user_name 
  • $currency 
  • $amount
  • $discount
  • $length
  • $length_unit
  • $signup_fee
  • $subscription_key
  • $subscription_id
  • $subscription_name
  • $auto_renew
  • $return_url
  • $test_mode
  • $user_id
  • $email

Processing the signup is a major part of building a payment gateway, but there are several other components as well, which we will continue below.

Adding Registration Fields

If your gateway needs to add fields to the registration for, you can use the fields() method. Restrict Content Pro will automatically append the return value for this method to the registration form when the gateway is selected.

For example, many payment gateways need to add a credit / debit card form to the registration form. If you need to do that, this example will be helpful:

public function fields() {
	ob_start();
	rcp_get_template_part( 'card-form' );
	return ob_get_clean();
}

You can read about  rcp_get_template_part() here. "card-form" is a template file provided by Restrict Content Pro that includes a standard credit / debit card template.

If you need any other fields, simply add your HTMl to the fields() method.

Note: this method should be used for adding general fields to the registration form, this is for gateway-specific fields only.

Validating Fields

If you need to validate fields that you have added to the registration form, you can use the validate_fields() method to do this.

When validating a field, you will use the add_error() method to register an error message that is then displayed on the registration form.

public function validate_fields() {
	if( empty( $_POST['rcp_card_number'] ) ) {
		$this->add_error( 'missing_card_number', __( 'The card number you have entered is invalid', 'rcp' ) );
	}
	if( empty( $_POST['rcp_card_cvc'] ) ) {
		$this->add_error( 'missing_card_code', __( 'The security code you have entered is invalid', 'rcp' ) );
	}
	if( empty( $_POST['rcp_card_zip'] ) ) {
		$this->add_error( 'missing_card_zip', __( 'The zip / postal code you have entered is invalid', 'rcp' ) );
	}
	if( empty( $_POST['rcp_card_name'] ) ) {
		$this->add_error( 'missing_card_name', __( 'The card holder name you have entered is invalid', 'rcp' ) );
	}
	if( empty( $_POST['rcp_card_exp_month'] ) ) {
		$this->add_error( 'missing_card_exp_month', __( 'The card expiration month you have entered is invalid', 'rcp' ) );
	}
	if( empty( $_POST['rcp_card_exp_year'] ) ) {
		$this->add_error( 'missing_card_exp_year', __( 'The card expiration year you have entered is invalid', 'rcp' ) );
	}
}

These error messages will be displayed on the registration form and will prevent the form from being submitted.

Processing Webhooks

Webhooks are an integral part of payment processor integrations. They are what allow you to detect when a subscription payment has been made or a customer's subscription has been modified in some way from the merchant account.

There are two parts to processing webhooks:

  1. Telling your payment processor the URL to which webhooks should be sent
  2. Processing the webhooks in Restrict Content Pro after they are sent by the payment processor

Instructing the payment process where to send the webhook is different for every merchant processor, but often involves passing a URL to the parameters included in the API request when a subscription is created.

For example, PayPal uses a parameter called "notify_url", so we will use that.

We can include the webhook URL in the API call during process_signup():

public function process_signup() {
	// Set up the query args
	$args = array(
		'price'        => $this->amount,
		'description'  => $this->subscription_name,
		'custom'       => $this->user_id,
		'email'        => $this->email,
		'notify_url'   => add_query_arg( 'listener', '2checkout', home_url( 'index.php' ) )
	);
	if( $this->auto_renew ) {
		$args['interval']       = $this->length_unit; // month, day, year
		$args['interval_count'] = $this->length; // 1, 2, 3, 4 . . . 
	}
	if( ! empty( $this->signup_fee ) ) {
		$args['one_time_fee']   = $this->signup_fee;
	}
	// Redirect to the external payment page
	wp_redirect( add_query_arg( $args, 'http://paymentpage.com/api/' ) );
	exit;
}

The URL is nothing more than the site's home URL with a special query arg attached to it. This query arg allows us to tell the difference between a webhook and a standard page request on the site.

Processing the webhooks is simple. All you need to do is place the logic for processing the request from your payment processor in the process_webhooks() method, like this:

public function process_webhooks() {
	// Determine if this is a webhook
	if( ! isset( $_GET['listener'] ) || strtoupper( $_GET['listener'] ) != '2checkout' ) {
		return;
	}
	// Now retrieve the webhook data from the $_POST super global
}

During the webhook, you will need to perform data validation and sanitization and then also make changes to the customer's account as appropriate. Here are common actions performs during a webhook:

  • Activating an account
  • Renewing a subscription
  • Recording a payment
  • Canceling a subscription

For these actions, you need to know how to modify user accounts and how to create subscription payments, both of which are described below in their appropriate sections.

To assist you in building your webhook processor, here is an example of how it works in PayPal Express:

Modifying Member Accounts

Since building a payment gateway means manipulating user accounts (for cancellations, activations, payments, etc), it is important that you know how to adjust a member's subscription.

Restrict Content Pro includes a class called  RCP_Member that will help you significantly in this area.

When using the class, you first need to instantiate it, like this:

$member = new RCP_Member( $user_id );

Once instantiated, you can call any of the public methods available.

For example, when you need to renew a member (such as when a payment is process), you will do this:

$member->renew( true );

The true parameter refers to whether the account is recurring. If the member has a recurring subscription, pass true, otherwise pass false.

When you need to cancel a member's account, you can use the set_status() method:

$member->cancel();

To activate a members account:

$member->set_status( 'active' );<br>$member->set_expiration_date( $new_date ); // Pass date as Y-n-d H:i:s

You can also use the renew() method for activating an account:

$member->renew();

The renew() method will automatically calculate and set the expiration date based on the subscription level assigned to the user.

For additional examples, see the RCP_Member class documentation.

Recording Payments for Members

Payments need to be recorded from the payment gateways in order to be displayed in the Restrict > Payments menu. Payments are usually recording during signup (for initial payments) and during webhook processing (for subscription payments).

The  RCP_Payments class will be helpful for creating payment records in Restrict Content Pro.

Creating a payment looks like this:

$member   = new RCP_Member( $user_id );
$payments = new RCP_Payments();
$args = array(
	'date'             => date( 'Y-m-d g:i:s' ),
	'subscription'     => $member->get_subscription_name(),
	'payment_type'     => '2Checkout',
	'subscription_key' => $member->get_subscription_key(),
	'amount'           => $amount,
	'user_id'          => $member->ID,
	'transaction_id'   => $transaction_id
);
$payments->insert( $args );

It is up to you to specify each of the necessary parameters. These are usually obtained from the POST data in the webhook or from the API response in the signup processing.

Complete PayPal Pro Gateway

To better assist you in creating your own payment gateway, here is the complete gateway for PayPal Pro that is included in Restrict Content Pro: