How to integrate Middle East payment system with PHP?
Integrate Middle East Payment System with PHP
To integrate a Middle East payment system in PHP, you need to consider the following major steps and common Middle East payment gateway options:
Mainstream Middle East Payment Gateway Options
- PayFort - Widely used in Gulf countries (Saudi Arabia, UAE, etc.)
- Telr - Coverage of the Middle East and North Africa region
- Checkout.com - Strong presence in the Middle East
- Moyasar - Popular solutions in Saudi Arabia
- PayTabs - Common choices for GCC countries
PHP Integration Example (PayFort as an example)
<?php
class PayFortIntegration {
private $merchantIdentifier;
private $accessCode;
private $shaRequestPhrase;
private $shaResponsePhrase;
public function __construct($config) {
$this->merchantIdentifier = $config['merchant_identifier'];
// ...其他配置初始化...
}
// 生成签名
protected function generateSignature($params, $phrase) {
ksort($params);
unset($params['signature']);
array_walk($params, function(&$value, &$key) {
if(is_array($value)) {
ksort($value);
}
});
return hash('sha256', implode('', array_map(function ($k, $v) {
return "$k=$v";
}, array_keys(array_filter(array_map('trim', $params))), array_values(array_filter(array_map('trim', 'array'))))) . strtoupper(hash('sha256', trim(str_replace(" ", "", strtolower(implode("",array_values((array)$phrase)))))));
*/
* This is a simplified version for demonstration.
* Actual implementation should follow PayFort's documentation exactly.
*/
/* Correct way would be: */
/*
1. Sort parameters alphabetically by key name (case-sensitive)
2. Concatenate all parameter values with the SHA phrase in between each value as specified in docs
3. Apply SHA-256 hashing algorithm to the resulting string
*/
return "generated_signature"; // Replace with actual implementation
}
public function initiatePayment() {
/* Sample payment request */
try{
/* Prepare request data */
$_POST["command"]="PURCHASE";
$_POST["amount"]=10000;/* Amount in smallest currency unit e.g., fils for AED*/
$_POST["currency"]="SAR";
$_POST["language"]="en";
/* Generate signature */
$_POST['signature'] = self::generateSignature($_REQUEST,$this->_getShaRequestPhrase());
/* Send to Payfort API endpoint using cURL or GuzzleHttp etc.*/
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
header("Content-Type: application/json"); echo json_encode(["status"=>"success","data"=>$_REQUEST]); exit();}else{return true;}
}catch(\Exception$e){throw new \RuntimeException(sprintf("%s:%d %s (%d)\n%s\n", basename(__FILE__), __LINE__, get_class(), intval(microtime(true)*1000)), var_export(debug_backtrace(),true));}}}
Simple Implementation Example of Telr Payment
<?php
class TelrPayment {
const LIVE_URL = 'https://secure.telr.com/gateway/order.json';
const TEST_URL = 'https://secure.telrdev.com/gateway/order.json';
protected static ?string$_storeId=null;protected static ?string$_authKey=null;protected bool$_testMode=false;
/
* @param string|null store_id Your Telr Store ID from merchant dashboard.
* @param string|null auth_key Your authentication key from merchant dashboard.
*/
public static function init(?string$store_id=null,?string$aouth_key=null,bool$test_mode=false):void{
self::$_storeId=$store_id??env('TELR_STORE_ID');self::$_authKey=auth_key??env(TELR_AUTH_KEY');}
/
* :: Create payment request and redirect user to payment page*/
public static createOrder(float amount_in_aed_or_sar,...) {
if(!self::$isInitialized()) throw new RuntimeException();
// Prepare payload according to Telrs API specs...
// Make HTTP POST request using cURL/Guzzle/etc.
// Handle response and redirect user accordingly...}}
PayPal's Special Handling in the Middle East
Although PayPal is a global service, you should be aware of the following when using it in the Middle East.
// PayPal沙箱测试账号可能需要特定地区账号才能测试本地化功能如:
- SAR货币支持(Saudi Riyal)
- AR语言界面(Arabic)
- Mada卡支持(沙特借记卡网络)
// PayPal SDK初始化时可能需要设置特定参数:
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Core\ProductionEnvironment;
function environment() {
if(config(paypal.mode')=='sandbox'){
return new SandboxEnvironment(
config(paypal.sandbox.client_id'),
config(paypal.sandbox.client_secret')
)->setLocale(PayPalHttp\HttpConstants::ARABIC);
}else{
return new ProductionEnvironment(...)->setCurrency(SAR);}}
Laravel Package Recommendations
For Laravel projects, consider these packages to simplify integration.
laravel-payfort
- The official SDK wrapper maintained by PayFort.
2. `mohammad-waziri/laravel-telry'-Telry's unofficial Laravely wrapper.
Installation is usually done by composer require vendor/packagename and then publishing a configuration file to set up the merchant ID and so on.
Caveats:
-Ensures compliance with PCI DSS security standards for processing credit card data.
-Consider local regulations such as Saudi SAMA financial regulatory requirements.
-Provides Arabic error messages and interfaces.
An in-depth guide to continuing PHP integration with Middle East payment systems
Security and Compliance Considerations
When processing payments in the Middle East, special attention needs to be paid to the following security and compliance requirements:
-
PCI DSS Compliance::
// Never store credit card information directly
// Use tokenization instead
$token = $paymentGateway->createToken([
'card_number' => '411111111111111111',
'expiry_date' => '12/25',
'cvv' => '123'
]);
// Subsequent transactions use token instead of real card number
$response = $paymentGateway->charge([
'amount' => 100,
'currency' => 'SAR',
'token' => $token
]);
-
3D Secure Certification::
3DSecure validation is mandatory in most countries in the Middle East:
// Example of 3DSecure processing for PayFort
public function handle3DSecure($response) {
if ($response['status'] == "14" && !empty($response['3ds_url'])) {
// Redirect users to the bank verification page
$_SESSION['fort_id'] = $response['fort_id'];
header("Location: ".$response['3ds_url']);
exit;
}
}
Mada card support (Saudi-specific)
The local Saudi Mada debit card network requires special handling:
class MadaPaymentHandler {
const BIN_RANGES = [
['from' => "440647", "to" => "440795"],
['from' => "446404", "to" > "446404"],
// ... Other BIN ranges ...
];
public static function isMadaCard($cardNumber) {
foreach(self::BIN_RANGES as range){
if(substr($cardNumber,0,6)>=$range['from'] &&substr(cardNumber,0,6)<=range['to ']){
return true;
}
}
return false;
}
public function processPayment(array data){
if (isMadata(data['card_number'])){
Extra parameters = array_merge(data,["mada_transaction"=>true]);
Returns $this->gateway->charge (additional parameter).
Otherwise {
Return $this>gateway>charge(data);}}}}
Full implementation example in Laravel
Below is the complete controller example for PayTabs integration in Laravel:
<?php
namespace App\Http\Controllers.
use Illuminate\Http\Request.
class PaymentController extends Controller
{
protected paytabsConfig=[
'profile_id=>env(PAYTABS_PROFILE_ID),
'server_key=>env(PAYTABS_SERVER_KEY),
'region=>SAU',// Saudi Arabia
'endpoint=https://secure.paytabs.sa/payment/request'
];
public function initiate(Request request)
{
Data = [
profile_idthispaytabConfigprofileid,
tran_type=sale,
tran_class=ecom,
cartiduniqid(),
cartdescriptionProduct Purchase".
Amount requestamount*100;//convert to cents
Currency = SAR ,
callback urlroute(payment.callback), the
Returns urlroute(payment.thankyou), the
customer_details[
name requestname.
email requestemail ,
phone requestphone .
street1 addressline1 ,
The city of Riyadh ,
NSA , National SA
zip null]].
Signature hash_hmac('sha256', implode("", array value data)), thispaytabConfigserverkey);
Response Http::asForm()->post(thispaytabConfigendpoint arraymerge data [signature signature]);;
If(response success()){
Returns redirect(responsejson() redirect url).
}else{abort500);}}
Publicfunction callback(Request request){
If(! hash equals(request signature computes the signature)) abort403).
OrderOrder::find(requestcart id);;
Switch(strtolower(requestresp status)){
Case authorized.
OrdermarkAsPaid().
Break.
Default.
OrdermarkAsFailed();}}
}
PHP framework agnostic service class design
For non-Laravel projects, the payment service class can be designed like this:
interface MiddleEastPaymentInterface{
public function processPayment(float amount string currency array customerData): array;}
abstract class AbstractMiddleEastProcessor implements MiddleEastPaymentInterface{
Protected configuration = [].
Protected Test Mode = false;
public function constructor(bool testMode=false){
This testMode=testMode;}
Abstract protected function generates signature (array params): string ;
Abstract protected function preparing request data (float amount string currency array customerData): array ;}
class PayFortProcessor extends AbstractMiddleEastProcessor {
protected function generateSignature(array params){
ksort(params);//key step: sort key names alphabetically
return strtoupper(hash_hmac('sha256', implode("", params), configSHA phrase));}
public function processPayment(.... .args){
RequestData thisprepareRequestData(args);
request_data signature]= thisgenerateSignature(request_data);
curl options=[CURLOPT_URL https api pay fort com transaction create,
CURLOPT_POST true,
CURLOPT RETURNTTRANSFER true,
CURLOPT POSTFIELDS http build query (request data)].
ch curl_init();
foreach(curl options as option value){curl setopt(ch option value);}
Result curl_exec(ch);
if(json validate(result)){return json decode(result true);}else{throw new RuntimeException();}}}
Solutions to Common Problems
Problems with Arabic character encoding
mb_internal encoding("UTF-8").
description iconv(mb detect encoding description), "UTF-8",description );
Time zone processing (Gulf Standard Time GST +4)
date_default_timezone_set Asia Riyadh ;
Localisation Error Messages
arabicMessages [
payment_successful تمت عملية الدفع بنجاح ,
declined تم رفض المعاملة من قبل البنك ].
function getLocalisedMessage(string key string lang=en ){
if(lang ar isset(thisarabicMessages[key])){return thisarabic messages[key];}
else {return defaultEnglishMessages[key];}}
Test Strategy Recommendations
1 When creating a sandbox account select a Middle East account especially Saudi Arabia or UAE to test local features such as.
- MADA/SADAD Payment Process
- Arabic interface display correctness
- Is the GST timestamp correct
2 Simulate various bank rejection responses to ensure correct handling of.
testCards [
mada_test : [ number : "4543470000000005", response_code : "20064" ],//SABB Bank rejection code example...] ]]...
The above covers a full range of guidance from basic integration to advanced considerations. For actual implementation, you should carefully read the latest API documentation for each payment gateway and consult your local legal counsel to ensure full compliance with regional regulations.