Today, we are going to make a payment gateway plugin for WooCommerce in WordPress.
For the sake of simplicity, we will redirect user to another page, which is provided by payment gateway for transactions to be completed.
For this example, we are going to use Raast payment gateway. Raast payment gateway provides an api to, first initiate a payment and then redirect user to Raast payment page.
Making Plugin File
First of all, we need to make our plugin file. WordPress provides a really simple method to make a plugin file.
- Make a file with any name, with php extention. For example, in this case, raast.php
- Copy the code below
<?php
/*
* Plugin Name: Raast Payment Gateway for Woocommerce
* Plugin URI: https://husnaincodes.com/wp-plugins/raast-payment-gateway-for-woocommerce/
* Description: This plugin helps you integrate Raast Payment Gateway for Woocommerce.
* Author: Husnain Mustafa
* Author URI: https://husnaincodes.com
* Version: 1.0.3
*/
By adding only the above content, wordpress recognizes our plugin and shows it in plugins section of wordpress admin panel. Below is the pictures that describes above written code.
So now, our plugin file is ready.
Integrating our plugin with WooCommerce
WooCommerce provides a very easy way to integrate plugins with it. As our goal is to make payment gateway plugin, we need to make a class which extends WC_Payment_Gateway class that woocommerce provides.
class Raast_Payment_Gateway extends WC_Payment_Gateway
WC_Payment_Gateway provides different methods which we can override and make use of those.
Below is the structure that we are going to use in our plugin:
function initiate_raast_class() {
class Raast_Payment_Gateway extends WC_Payment_Gateway {
public function __construct() {
}
public function init_form_fields() {
}
public function payment_fields() {
}
public function validate_fields() {
}
public function process_payment( $order_id ) {
}
}
}
}
add_filter( 'woocommerce_payment_gateways', 'add_raast_class' );
function add_raast_class( $gateways ) {
$gateways[] = 'Raast_Payment_Gateway';
return $gateways;
}
add_action( 'plugins_loaded', 'initiate_raast_class' );
Description of above code
__construct is basically our class constructor which is executed at the time when object of class is made. Here, we will define multiple fields which are associated with our plugin. I will explain those later.
init_form_fields is where we define fields, so that we can get different variable from the woocommerce -> settings -> payments -> -> manage.
payment_fields is where we define fields which are visible to the customer at the checkout page. This is used if we do not want to redirect our customer to our payment gateway transaction page, rather we want to ask details right on checkout page. Mostly used in the case of payments cards.
As we are redirecting customer to our payment gateway transaction page, we do not need this method.validate_fields is used to validate the input fields by the customer. Again we are not going to use this in our example.
process_payment is the most important method. Because, this method is called when customer clicks on place order. This method is where we define what and how payment happens. In our case, we are going to post a request to Raast. Raast will return us a redirect url, then we are going to redirect our customer to that url so that Raast can handle transaction by itself on its transaction page.
Raast Transaction flow
- So Raast provide us the api where we can post request with required parameters
- If request is successful, Raast respond with redirect url.
- We will redirect our customer to that url.
- Our customer fulfills the transaction on Raast transaction page.
- If transaction is successful, Raast will post a request on given IPN url which we provide to Raast in first request that we made.
- We can further handle the request by Raast by however we want. Usually, we just complete the order by either:
$order->update_status( 'processing' );
OR$order->$order->payment_complete();
Inside of the above methods
public function __construct() {
$this->id = 'raast';
$this->icon = 'https://www.raastid.com/assets/images/logoIcon/light_logo.png';
$this->has_fields = false;
$this->method_title = 'Raast Payment Gateway';
$this->method_description = 'Let Your Customers Pay with Raast ID';
$this->supports = array(
'products'
);
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option( 'title' );
$this->description = $this->get_option( 'description' );
$this->success_url = $this->get_option( 'success_url' );
$this->cancel_url = $this->get_option( 'cancel_url' );
$this->logo_url = $this->get_option( 'logo_url' );
$this->ipn_url = plugin_dir_url( __FILE__ ) . 'ipn.php';
$this->testmode = 'yes' === $this->get_option( 'testmode' );
$this->private_key = $this->get_option( 'private_key' );
$this->publishable_key = $this->get_option( 'publishable_key' );
if( empty($this->success_url) || $this->success_url == null ){
$this->success_url = get_site_url();
}
if( empty($this->cancel_url) || $this->cancel_url == null ){
$this->cancel_url = get_site_url();
}
if( empty($this->logo_url) || $this->logo_url == null ){
$this->logo_url = 'https://www.raastid.com/assets/images/logoIcon/light_logo.png';
}
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) );
}
public function init_form_fields(){
$this->form_fields = array(
'title' => array(
'title' => 'Title',
'type' => 'text',
'description' => 'This controls the title which the user sees during checkout.',
'default' => 'Raast',
'desc_tip' => true,
),
'description' => array(
'title' => 'Description',
'type' => 'textarea',
'description' => 'This controls the description which the user sees during checkout.',
'default' => 'Pay with your Raast ID',
),
'testmode' => array(
'title' => 'Test mode',
'label' => 'Enable Test Mode',
'type' => 'checkbox',
'description' => 'Tick this to enable sandbox/test mode. According to RAAST documentaion, test mail is: test_mode@mail.com and test verification code is: 222666',
'default' => 'yes',
),
'success_url' => array(
'title' => 'Success URL',
'description' => 'This is the URL where Raast will redirect after payment was SUCCESSFUL. If you leave this field empty, it will be redirected to your site. Example: https://www.example.com/',
'type' => 'text',
'default' => ''
),
'cancel_url' => array(
'title' => 'Cancel URL',
'description' => 'This is the URL where Raast will redirect if payment was CANCELLED. If you leave this field empty, it will be redirected to your site. Example: https://www.example.com/',
'type' => 'text',
'default' => ''
),
'logo_url' => array(
'title' => 'Logo Url',
'description' => 'Your Site Logo URL. If you leave this field empty, it will use RAAST icon. Example: https://www.example.com/image.png',
'type' => 'text',
'default' => ''
),
'publishable_key' => array(
'title' => 'Your Raast Public Key',
'type' => 'text',
'default' => ''
),
'private_key' => array(
'title' => 'Your Raast Private Key',
'type' => 'password',
'default' => ''
)
);
}
public function process_payment( $order_id ) {
global $woocommerce;
$order = wc_get_order( $order_id );
$amount = $order->get_total();
$name = $order->get_billing_first_name() . $order->get_billing_first_name();
$email = $order->get_billing_email();
///live end point
$url = 'https://www.raastid.com/payment/initiate';
if($this->testmode){
//test end point
$url = 'https://www.raastid.com/sandbox/payment/initiate';
}
// Paramenters to API Call
$parameters = [
'identifier' => $order_id,
'currency' => 'USD',
'amount' => $amount,
'details' => 'Order Placed',
'ipn_url' => $this->ipn_url,
'cancel_url' => $this->cancel_url,
'success_url' => $this->success_url,
'public_key' => $this->publishable_key,
'site_logo' => $this->logo_url,
'checkout_theme' => 'dark',
'customer_name' => $name,
'customer_email' => $email,
];
//live end point
$url = 'https://www.raastid.com/payment/initiate';
if($this->testmode){
//test end point
$url = 'https://www.raastid.com/sandbox/payment/initiate';
}
// API Call
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$result = json_decode($result, true);
if($result['success'] == 'ok'){
$woocommerce->cart->empty_cart();
wc_add_notice('Order is Placed Successfully!');
return array(
'result' => 'success',
'redirect' => $result['url']
);
}
else{
// To debug result
/*
if (is_array($result) || is_object($result)) {
error_log(print_r($result, true));
}
else {
error_log($result);
}
*/
}
}
Understanding the above code
__construct()
$this->id
is used to define id, we can use this to get reference of our class anywhere outside the file. Like in IPN, I used$raast = WC()->payment_gateways->payment_gateways()['raast'];
and further used$raast
to get private key in IPN file.$this->icon
is used to set url of icon which will be used at checkout page.
$this->has_fields
is a boolean. Used if we want to use fields at checkout page, mostly used for custom credit card form. In our case, it is going to be false.$this->method_title
used to define name of our plugin at WooCommerce -> Settings -> Payments$this->method_description
used to define description of our plugin at WooCommerce -> Settings -> Payments.
$this->init_settings();
to load previous settings$this->title
Title at checkout page$this->description
Description at checkout page
Other variables are custom variable used in api call.
To get value of any field, at plugin's settings in WooCommerce, we can use $this->get_option( <name of field> )
init_form_fields()
Here, we define the fields that we require from the admin, like title, description and other fields that could be used to integrate payment gateway.
In this method, we defined $this->form_fields
which is an array.
We can also assign $this->form_fields
in constructor rather than having separate method and then calling it from constructor. But for cleaner code, a separate method is better.
To get values from these fields we can use $this->get_option( <name of field> )
.
process_payment( $order_id )
It is used to process the payments. This is called after customer places order. This method is customized according to the need of payment gateway that we are integrating.
Our plugin is good to go now.
Hope this article was helpful. If you have any queries, ask in comments. You can get full code at Github for reference.
Top comments (0)