Appy Pie Payment Gateways Plugin - Integrate a Payment Gateway

Integrating Payment Gateways in Appy Pie

Introduction

Whether it’s a startup or a global enterprise, it becomes essential to integrate payment gateways to accept payments and manage a business online. Some payment gateways are readily available worldwide whereas some are confined to specific countries. This is where Appy Pie allows you to integrate the payment gateways in Appy Pie irrespective of the location. But before jumping to the procedure, let’s take a quick glance as to why AppyPie App Builder is the fastest-growing cloud-based Mobile Apps Builder Software.  With millions of users and presence all over the world is itself an explanation to the question. Besides this, the following salient features make the Appy Pie App Builder the best in the world:

  • Instant app creation: Appy Pie App Builder allows its user to create an application within a few minutes.

  • 70+ features or pages: Appy Pie App Builder houses more than 70 features that can be customized as per the need of the user.

  • Real-Time Changes: Appy Pie App Builder ensures that any changes made are visible in real-time.

 

What is a Payment Gateway?

A payment gateway is a service that processes online payments and facilitates transaction flow between the customers and merchants. It transfers information between the websites/mobile devices and payment processors/banks, and vice versa. The transaction data is safely passed using security protocols and encryption. 

How to create SDK for Appy Pie to integrate the payment gateways?

This document guides you to create SDK to integrate payment gateways. It’s a three-step procedure:

  1. Define the folder structure. 

  2. Create a View Page

  3. Create a process file.

 

Step1: Define Folder Structure 

Define the folder structure similar to the one as shown in the above screenshot. The following are the key points to be considered while defining the folder structure:

  1. Name the folder using lowercase letters. For instance; the SDK is named “pesapal” as shown in the above screenshot and all the work will be carried out in this directory only. Note: All the keys used later on must begin with this name only.

  2. Name the “img” folder as “img”. The “img” folder includes an icon image with a transparent background.

  3. Name the icon image the same as the parent directory itself. For example;  If the parent directory is “pesapal”, then name the icon image as “pesapal.png”.

 

The parent directory contains four major files:

  1. “pesapal-page.html” file will contain the payment form as per the payment gateway requirement.

  2. “pesapal.php” file will include the payment process and must be written in php. 

  3. “pesapal.phtml” file will only include the admin view where the end-user will insert its credentials for the respective payment gateway.

  4. “response.php” file will include the following functions:

    • Success function

    • Cancel function

    • Failure function

    • Notify function

 

Step 2: Create a View Page to display on the Admin Dashboard

Create a view page as shown in the above screenshot that will be displayed on the Admin dashboard. Save the file name with the same name used to create a parent directory and ensure the extension is .phtml. 

Making Credential Boxes visible when the Checkbox is Checked

The credential boxes (marked as 2) in the above screenshot will only be visible when the checkbox (marked as 1) is checked. The following code is written in HTML, PHP, and Angular. For angular, the checkbox must have an id, name, and model. 

 

<div class="row offsetbottom15" ng-init="sResetAllPesapal()">
    <div class="col-md-12">
        <div class="input-group">
            <span class="input-group-addon">
                <input type="checkbox" id="pesapal_label_cb" name="payment.pesapal_label_cb" ng-model="payment.pesapal_label_cb">
            </span>
            <input type="text" name="payment.pesapal_label" ng-model="payment.pesapal_label" class="form-control" placeholder="<?php print $this->translate('CREDIT_CARD_GATEWAY_PESAPAL');?>">
        </div>
        <span class="font-11"><?php echo $this->translate('PESAPAL_PRO_TEXT');?></span>
    </div>
</div>


The function sResetAllPesapal() in ng-init will be discussed later.

 

Creating Checkbox on the View Page

Create a checkbox on the view page to display the credential boxes. 

 

<input type="checkbox" id="pesapal_label_cb" name="payment.pesapal_label_cb" ng-model="payment.pesapal_label_cb">

 

The key points to be considered:

  • id must be similar to the one depicted in the above code i.e, “pesapal_label_cb” and must end with “_label_cb”

  • name must be similar to "payment.pesapal_label_cb" and must begin with “payment.” and must end similar to id “_label_cb”

  • model must be exactly similar to the name.

  • All classes and enclosures should be the same as in the code provided above.
     

Adding Input Field for the Checkbox

 

<div ng-show="payment.pesapal_label_cb">
<input type="text" name="payment.pesapal_label" ng-model="payment.pesapal_label" class="form-control" placeholder="<?php print $this->translate('CREDIT_CARD_GATEWAY_PESAPAL');?>">
</div>

 

The key points to be considered:

  • type must be text.

  • name must start with “payment.” and end with “_label”

  • model must be exactly similar to the name.

  • placeholder must be a php code with the translator as shown in the above code.


Note: Since the translator is being used as a helper in our project so the key ('CREDIT_CARD_GATEWAY_PESAPAL') must be provided separately in a text file as shown below:
CREDIT_CARD_GATEWAY_PESAPAL;"Pesapal Mobile Money"

This will be used in our translator file for multiple language engagements.
All the class and enclosure in this will be similar to that of the code provided at the beginning of this topic.

 

Adding Description Text (Optional)

The description text (marked as 3) in the above screenshot describes the payment gateway. It is non-mandatory and can be removed. Similar to the checkbox, the text must be defined using a translator and the key-value pair must be provided separately.

<div class="row">
        <div class="col-md-6 offsetbottom15">
            <strong class="font-12"><?php echo $this->translate('PESAPAL_ENABLE_PROVIDE');?>:</strong>
        </div>   
  </div>

 

Credential Input Field and its error div

The below code illustrates how to get one single input field which will be rendered below the checkbox input field. This credential input field will be controlled by the checkbox model (“payment.pesapal_label_cb”) i.e., this will only show when the gateway checkbox is checked. If you want to use multiple credentials you must repeat the whole block again and again for the required number of times.

 

<div ng-show="payment.pesapal_label_cb">
<div class="row offsetbottom15">
        <div class="col-md-6">
            <div class="input-group">
                <span class="input-group-addon min-box-wid2">
                    <?php echo $this->translate('PESAPAL_CONSUMER_KEY');?>
                    <span style="color:red;">*</span>
                </span>
                <input type="text" name="payment.pesapal_consumer_key" ng-model="payment.pesapal_consumer_key" placeholder="<?php echo $this->translate('PESAPAL_CONSUMER_KEY');?>" class="form-control" ng-blur="sIsEmptyField('payment.pesapal_label_cb','payment.pesapal_consumer_key','payment.pesapal_consumer_error','payment.pesapal_consumer_errorMSG','<?php echo $this->translate('PESAPAL_CONSUMER_KEY');?>')">
                <div class="addMoreAlert" ng-show="payment.pesapal_consumer_error" data-error="payment.pesapal_consumer_error">
                    <a class="f-right icon-cancel" href="javascript:void(0);" ng-click="sRemoveErrorMsg('payment.pesapal_consumer_error')"></a>
                    <span ng-bind-html="payment.pesapal_consumer_errorMSG"></span>
                </div>
            </div>
        </div>
</div>
</div>

 

Step 3: Create a Process File

The process file will be a php file that will be used to create a payment form for the processing of payment. This file must begin with including a file as shown below:
require_once('../include.php');
The file must be written following the oops concept and must extend the class Database. The following steps are involved:

 

Initialization

  1. Use the constructor as defined below at the beginning of this file to create an instance of the Mongo database.
    function __construct(){

$this->mongoObj = new MongoConnect();

}

  1. Use a function with params as shown below:
    function getPesapalForm($appId,$pagename,$orderId,$amount,$currency,$pinfo,$cemail,$vendorId,$pname,$userId,$pageId,$fname){

}

 

This function will accept the following parameters:
appId: This is the appId you’ll receive from the consumer end.

pagename: This is the feature name that you’ll receive from the consumer end.

orderId: This is the orderId generated and sent to you by the consumer.
amount: This is the total amount you’ll receive from the consumer end.

currency: This is the currency you’ll receive as specified by the consumer.

pinfo: This will receive short info about the product.
cemail: This will receive the consumer’s email.

vendorId: This will receive vendorId from the consumer end.

pname: This will receive a product name from the consumer end.

userId: This will receive consumer id.

pageId: This will receive the pageId from consumer end

fname: This will receive the full name of the consumer

Note: You’ll use these as variables in your code.
 

Checking the Received Parameters

Check the received parameters before using them in your code for empty values and return the error message with respect to the params received. This will ensure that no data is missed.
For instance:

$iError = array();
if(empty($appId)) $iError = array('error_code' => 1, 'error_message' => 'App Id missing');
if(!empty($iError)) return $iError;

 

Processing the pageId

Since our system uses multiple features inside a single application, thus it becomes essential to process the pageId.
 

$search = '--';
$tempArray = array();
if(preg_match("/{$search}/i", $pageId)) {
    $tempArray = explode($search, $pageId);
    $pageId = $tempArray[0];
}

 

Fetching the Saved Credentials

 

$sResult = PaymentForm::getAppPaymentConfig($this->mongoObj,$appId,$pagename,$pageId);

 

This will return you your saved credentials in the following array:
$sResult['config']

This array will have your credentials with the same key you used while creating your admin dashboard file.

For instance: If you saved pesapal_label_cb, pesapal_consumer_key, etc. while creating your admin dashboard file, then you will have
pesapal_label_cb in $sResult[‘config’][‘pesapal_label_cb’]

pesapal_consumer_key in $sResult[‘config’][‘pesapal_consumer_key’] as the credentials stored in the array.
 

Store these in a variable and use. For example:
$merchantKey = $sResult['config'][‘pesapal_consumer_key’];
 

Following Instruction from the Payment Gateway

Follow the remaining instructions from the payment gateway to create the payment form. The payment form is the third file which is entirely written in html and jquery (in some cases).
The following sample code is for a paypal form:
 

<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="__SERVER__/js/jquery-1.7.2.min.js"></script>
</head>
<body>
<form action='__URLPRE__paypal.com/cgi-bin/webscr' method='post'>
<input type='hidden' name='business' value='__KEY__'>
<input type='hidden' name='cmd' value='_xclick__CLICK__'>
<input type='hidden' name='lc' value="__LOCALE__">
<input type='hidden' name='item_name' value="__ITEMNAME__">
<input type='hidden' name='amount' value="__AMOUNT__">
<input type='hidden' name='a3' value="__AMOUNT__">
<input type='hidden' name='p3' value='1'>
<input type='hidden' name='t3' value="__TYPE__">
<input type='hidden' name='src' value='1'>
<input type='hidden' name='currency_code' value="__CURRENCY__">
<input type='hidden' name='quantity' value='1'>
<input type='hidden' name='custom' value="__ORDERID__">
<input type='hidden' name='return' value='__RURL__' />
<input type='hidden' name='cancel_return' value='__CURL__' />
<input type='hidden' name='notify_url' value='__NURL__' />
<input type='image' src='/images/subscribe_btn.png' name='submit' id='submit' alt='PayPal - The safer, easier way to pay online!' class="cstm-btn">
</form>
<script type="text/javascript">
            $(document).ready(function(){
                $('.cstm-btn').trigger('click');
            })
        </script>
</body>
</html>

 

Note: All the value in all the field must be replaced in the processing file as shown below:

 

$iHaystack = array($serverurl,$url_prefix,$sResult["config"]["paypal_client_business"],$click,$localeArray['locale'],$itemName,$amount,$type,$currency,$orderId,$rurl,$curl,$nurl);
    $iNeedle = array('__SERVER__','__URLPRE__','__KEY__','__CLICK__','__LOCALE__','__ITEMNAME__','__AMOUNT__','__TYPE__','__CURRENCY__','__ORDERID__','__RURL__','__CURL__','__NURL__');
$html = str_replace($iNeedle, $iHaystack, file_get_contents('paypal-express-page.html'));

 

Storing Values For Future References

Use the following code to store the transactions in the MongoDB of our servers.

$iInsert = PaymentForm::getInitialInsert($this->mongoObj,$appId,$pagename,$pageId,$orderId,$userId,$currency,'PESAPAL’,$amount,$paymentObject,'PENDING');
if(!$iInsert){
$duplicateEntryErrorMsg = PaymentMessage::getErrorMessage($this->mongoObj,$appId,'duplicate');
return array('error_code'=>1,'error_message'=>$duplicateEntryErrorMsg);
}

 

This function receives params in the following way:
$this->mongoObj: The mongo object instantiated in the constructor.
$appId: The appId received in your function.
$pagename: The pagename received in your function.
$pageId: The pageId received in your function.
$orderId: The orderId received in your function.
$userId: The userId received in your function.
$currency: The currency received in your function.
'PESAPAL’: This is the name of the payment Gateway you are creating and can be the same as the parent directory created in your SDK. Ensure the name is in uppercase letters.
$amount: This is the amount you received in your function.
$paymentObject: This is where you can store your metadata in the form of an array.
‘PENDING’: This is the status and must be PENDING only at this time.
 

Rendering Payment Form from the Processing File

After the values have been stored, you can render the payment form from your processing file. For example:

 

$currentTime = time();
$filename = ABS_PUBLIC_PATH.'/tmp/stripeconnect'.$currentTime.'.html';
$file = fopen($filename,"w");
chmod($filename, 0777);
fwrite($file,$html);
fclose($file);
$html = BASE_URL.'/tmp/pesapal'.$currentTime.'.html';
return array('error_code'=>0,'error_message'=>'Success','html_form'=>$html);

 
Note: Use the exact same code as defined above. The $html variable is the same that you used when replacing the values from the paypal.html file shown above.


Calling Class

At the end, you must call your class as shown below:

$request = file_get_contents('php://input');
$request = json_decode($request);
if(empty($request->method)){
    $request = (object)$_POST;
}
try{
$responseData=array(); 
$method = $request->method;
$objModel = new PesapalWebservice();
switch ($method) {
case 'getPesapalForm':
$appId = isset($request->appId)?$request->appId:"";
$orderId = isset($request->orderId)?$request->orderId:"";
$pagename = isset($request->pagename)?$request->pagename:"";
$amount = isset($request->amount)?$request->amount:"";
$pinfo = isset($request->orderDesc)?$request->orderDesc:"";
$fname = isset($request->fName)?$request->fName:$request->fname;
$email = isset($request->email)?$request->email:"";
$currency = isset($request->currency)?$request->currency:"";
$userId = isset($request->userId)?$request->userId:"";
$pageId = isset($request->pageId)?$request->pageId:"";
$responseData = $objModel->getPesapalForm($appId,$pagename,$amount,$pinfo,$orderId,$fname,$email,$currency,$userId,$pageId);
break;
default:
return;
break;
}
}catch(Exception $e){
$responseData = array('status'=>1,'error_message'=>$e->getMessage());
}
echo json_encode($responseData);
exit;

 

Response File

The response file is written on the concept of OOPs and must include the following functions to obtain a response from the payment gateway:

  • Success function

  • Failure function

  • Cancel function

  • Notify function

Success Function

This function will be your success response from the payment gateway. The following are the key points to be considered:

  • Ensure that you receive the similar parameters from your payment gateway that you are using in your processing function.

  • Ensure that the name of the function is ‘success’.

  • The function must receive all the post param set by the payment gateway.

  • The class begins similarly to the processing file. 

 

include_once(‘../include.php’);
class ResponseWebservice extends Database
{
function __construct(){
$this->mongoObj() = new MOngoConnect();
}
}

 

  • The class ends similarly to the processing file.

 

$request = file_get_contents('php://input');
$request = json_decode($request);
if(empty($request->method)){
    $request = (object)$_POST;
}
try{
$responseData=array(); 
$method = $request->method;
$objModel = new ResponseWebservice ();
switch ($method) {
case ‘success’:
$responseData = $objModel->success($request);
break;
default:
return;
break;
}
}catch(Exception $e){
$responseData = array('status'=>1,'error_message'=>$e->getMessage());
}
echo json_encode($responseData);
exit;

 

  • You will verify the transaction data from the payment gateway in the success function. For updating the transaction information in our database, you must use the following code:

 

$uUpdate = PaymentForm::getFinalUpdate($this->mongoObj,$appId,$pagename,$pageId,$orderId,$userId,'PESAPAL',$amount,$transId,$status,$request);

 

The function will accept the following parameters:

$this->mongoObj: The mongo object instantiated in constructor.
$appId: The appId received in your function.
$pagename: The pagename received in your function.
$pageId: The pageId received in your function.
$orderId: The orderId received in your function.
$userId: The userId received in your function.
'PESAPAL’: This is the name of the payment Gateway you are creating and can be the same as the parent directory created in your SDK. Ensure the name is in uppercase letters.
$amount: This is the amount you received in your function.
$transId: This is the transaction Id received from the payment gateway.
$status: This is the status received from the payment gateway.

$request: This is the complete request received from the payment gateway.

 

Failure Function

The failure function is exactly similar to the success function and the only change is of status.

 

Cancel Function

The cancel function is also similar to the success function but will be called by the payment gateway in case the consumer cancels the payment process.

 

Notify Function

The notify function is used when the payment is pending and the payment gateway holds the payment for a few seconds. This is the IPN of your payment gateway. The rest of the processing must be carried out as directed by the payment gateway and then the update code must be called.

 

Please click here to download the sample code and test the plugin. Once this is tested please contact us at support@appypie.com and share the developed plugin code in ZIP file format with us.