When building a secure online donation platform in the UAE, choosing a trusted government backed payment gateway is critical. Dubai Pay provides a reliable and compliant infrastructure that enables organisations to collect payments safely while meeting regulatory standards.
In this guide, we walk through the complete process of integrating Dubai Pay into a PHP application. The implementation is demonstrated in the context of developing an online donation system for Dubai Cares, covering authentication, payment creation, signature validation, and transaction confirmation. The aim is to clearly explain each step so developers can understand both the technical flow and the security principles behind the integration.

Results
QA credential requirements
OAuth authentication
Required keys for authorisation
HMAC SHA512 signature generation
Payment registration and redirect handling
Token verification and confirmation
Hosted versus self managed checkout
Understanding the Dubai Pay Architecture
Dubai Pay uses:
OAuth 2 client credentials flow for authentication Bearer token based API authorisation HMAC SHA512 signature validation for request integrity Batch based transaction processing Hosted redirection checkout model
The gateway is designed to ensure:
Payload integrity Non tampering of transaction data Secure government compliant processing Clear batch reconciliation
Required QA Credentials
Before integration begins, you must obtain QA environment credentials from Dubai Pay.
Required QA Credentials
Before integration begins, you must obtain QA environment credentials from Dubai Pay.
Typically, you will receive:
php:
$CLIENT_ID = “XXXX-XXXX-XXX”;
$CLIENT_SECRET = “XXXX-XXXX-XXX”;
$ENTITY_CODE = “XXXX”;
$SP_CODE = “XXXX”;
$SERV_CODE = “XXXX”;
$CHECKSUM_KEY = “XXXXXXXXXXXXXXXXXXX”;
$BASE_URL = “https://api.qa.dubai.gov.ae”;
$RETURN_URL = “https://your-domain.com/return.php“;
What Each Key Is Used For
| Key | Purpose |
| Client ID | OAuth authentication |
| Client Secret | OAuth authentication |
| Access Token | API authorisation |
| Entity Code | Identifies organisation |
| SP Code | Service provider reference |
| Service Code | Specific service mapping |
| Checksum Key | HMAC signature generation |
You may be required to provide:
Official onboarding request Technical contact details Callback and return URLs Whitelisted IP addresses Organisation authorisation documents
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (!isset($data[‘access_token’])) {
die(“OAuth authentication failed.”);
}
return $data[‘access_token’];
} This token must be included in every subsequent API request:
Authorization: Bearer {access_token}
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
}
Step 2: Generating HMAC SHA512 Signature
Every Dubai Pay API request requires a signature header called:
dubaiPaySignature
The signature is created from:
The exact JSON payload SHA512 hashing The Checksum Key Uppercase output
Signature Example
$jsonPayload = json_encode($jsonPayload = json_encode(
$jsonPayload = json_encode(
$payload,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
$jsonPayload = mb_convert_encoding($jsonPayload, ‘UTF-8’);
$signature = strtoupper(
hash_hmac(‘sha512’, $jsonPayload, $CHECKSUM_KEY)
);
$payload,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
$jsonPayload = mb_convert_encoding($jsonPayload, ‘UTF-8’);
$signature = strtoupper(
hash_hmac(‘sha512’, $jsonPayload, $CHECKSUM_KEY)
);
This ensures:
Payload integrity Tamper prevention Government grade request validation
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
}
Step 3: Creating the Payment and Getting Redirect URL
Dubai Pay follows a hosted redirection model. You register a batch transaction, and the response contains a uri for redirection.
callAPI Helper Function
function callAPI($endpoint, $payload, $token, $baseUrl, $checksumKey)
{
$jsonPayload = json_encode(
$payload,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
$jsonPayload = mb_convert_encoding($jsonPayload, ‘UTF-8’);
$signature = strtoupper(
hash_hmac(‘sha512’, $jsonPayload, $checksumKey)
);
$ch = curl_init($baseUrl . $endpoint);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Bearer $token”,
“Content-Type: application/json”,
“dubaiPaySignature: $signature”
],
CURLOPT_POSTFIELDS => $jsonPayload
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
Creating the Payment
$accessToken = getAccessToken($CLIENT_ID, $CLIENT_SECRET);
$payload = [
“entityCode” => $ENTITY_CODE,
“batchId” => “batch_” . time(),
“totalAmount” => 10.00,
“totalTransactions” => 1,
“returnUrl” => $RETURN_URL,
“transactions” => [[
“spCode” => $SP_CODE,
“servCode” => $SERV_CODE,
“spTrn” => uniqid(“DONATION_”),
“amount” => 10.00,
“currency” => “AED”,
“timestamp” => date(“d-m-Y H:i:s”),
“channel” => “100”,
“description” => “Online Donation”,
“type” => “sale”,
“version” => “2.1”,
“settlementType” => “gov”
]]
]; Calling Register Endpoint
$response = callAPI(
“/secure/dubaipay/batch/1.0.0/register”,
$payload,
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
);
Redirecting the Donor
if (!isset($response[‘uri’])) {
die(“Payment registration failed.”);
}
header(“Location: ” . $response[‘uri’]);
exit; The donor is redirected to Dubai Pay secure hosted checkout.
Hosted Checkout Versus Self Managed Checkout
Dubai Pay primarily supports hosted redirection checkout.
This means:
Card data is entered on Dubai Pay servers Your server does not handle card details PCI scope is reduced Security responsibility is simplified
Direct self managed card form processing is not the standard model.
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
}
Step 4: Handling Payment Confirmation
After payment completion, Dubai Pay posts a TOKEN to your return URL.
Retrieve Token
$responseToken = $_POST[‘TOKEN’];
Verify Using tokenDetails API
$verification = callAPI(
“/secure/dubaipay/batch/1.0.0/tokenDetails”,
[
“token” => $responseToken,
“entityCode” => $ENTITY_CODE
],
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
);
Validate Transaction
if (
$verification[‘batchStatus’] == ‘completed’ &&
$verification[‘transactions’][0][‘message’][‘code’] == 0
) {
Only when both conditions are satisfied should the transaction be considered successful.
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
}
Step 5: Confirm API Call
Dubai Pay recommends confirming transactions after successful verification.
$confirmPayload = [
“entityCode” => $ENTITY_CODE,
“batchId” => $verification[‘batchId’],
“confirmAll” => true,
“message” => [
“code” => “0”,
“text” => “confirmed”
]
];
$confirmResponse = callAPI(
“/secure/dubaipay/batch/1.0.0/confirm”,
$confirmPayload,
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
); Only after confirmation should you:
Update the donation record Store the gateway reference Trigger receipt email Mark transaction as settled
Security and Production Best Practices
When moving from QA to production:
Replace QA endpoints with production URLs Update Client ID and Client Secret Replace Checksum Key Validate return URL handling Log all API responses Use idempotent transaction references Implement server side validation
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
}
Conclusion
Dubai Pay integration in PHP requires structured implementation of OAuth authentication, HMAC SHA512 request signing and strict transaction verification.
For organisations such as Dubai Cares, this integration provides:
Government compliant payment processing Hosted secure checkout Strong request integrity validation Clear batch reconciliation
When implemented correctly, Dubai Pay offers a reliable and scalable solution for secure online donation platforms in the UAE.
When building a secure online donation platform in the UAE, choosing a trusted government backed payment gateway is critical. Dubai Pay provides a reliable and compliant infrastructure that enables organisations to collect payments safely while meeting regulatory standards.
In this guide, we walk through the complete process of integrating Dubai Pay into a PHP application. The implementation is demonstrated in the context of developing an online donation system for Dubai Cares, covering authentication, payment creation, signature validation, and transaction confirmation. The aim is to clearly explain each step so developers can understand both the technical flow and the security principles behind the integration.
This guide covers:
- QA credential requirements
- OAuth authentication
- Required keys for authorisation
- HMAC SHA512 signature generation
- Payment registration and redirect handling
- Token verification and confirmation
- Hosted versus self managed checkout
Understanding the Dubai Pay Architecture
Dubai Pay uses:
- OAuth 2 client credentials flow for authentication
- Bearer token based API authorisation
- HMAC SHA512 signature validation for request integrity
- Batch based transaction processing
- Hosted redirection checkout model
The gateway is designed to ensure:
- Payload integrity
- Non tampering of transaction data
- Secure government compliant processing
- Clear batch reconciliation
Required QA Credentials
Before integration begins, you must obtain QA environment credentials from Dubai Pay.
Typically, you will receive:
$CLIENT_ID = “XXXX-XXXX-XXX”;
$CLIENT_SECRET = “XXXX-XXXX-XXX”;
$ENTITY_CODE = “XXXX”;
$SP_CODE = “XXXX”;
$SERV_CODE = “XXXX”;
$CHECKSUM_KEY = “XXXXXXXXXXXXXXXXXXX”;
$BASE_URL = “https://api.qa.dubai.gov.ae”;
$RETURN_URL = “https://your-domain.com/return.php“;
What Each Key Is Used For
| Key | Purpose |
| Client ID | OAuth authentication |
| Client Secret | OAuth authentication |
| Access Token | API authorisation |
| Entity Code | Identifies organisation |
| SP Code | Service provider reference |
| Service Code | Specific service mapping |
| Checksum Key | HMAC signature generation |
You may be required to provide:
- Official onboarding request
- Technical contact details
- Callback and return URLs
- Whitelisted IP addresses
- Organisation authorisation documents
Step 1: OAuth Authentication
Dubai Pay requires a Bearer access token before any API call can be made.
Generating Access Token
function getAccessToken($clientId, $clientSecret)
{
$url = “https://ids.qa.dubai.gov.ae/oauth2/token”;
$credentials = base64_encode($clientId . “:” . $clientSecret);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Basic ” . $credentials,
“Content-Type: application/x-www-form-urlencoded”
],
CURLOPT_POSTFIELDS => http_build_query([
“grant_type” => “client_credentials”,
“scope” => “openid”
])
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if (!isset($data[‘access_token’])) {
die(“OAuth authentication failed.”);
}
return $data[‘access_token’];
}
This token must be included in every subsequent API request:
Authorization: Bearer {access_token}
Step 2: Generating HMAC SHA512 Signature
Every Dubai Pay API request requires a signature header called:
dubaiPaySignature
The signature is created from:
- The exact JSON payload
- SHA512 hashing
- The Checksum Key
- Uppercase output
Signature Example
$jsonPayload = json_encode(
$payload,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
$jsonPayload = mb_convert_encoding($jsonPayload, ‘UTF-8’);
$signature = strtoupper(
hash_hmac(‘sha512’, $jsonPayload, $CHECKSUM_KEY)
);
This ensures:
- Payload integrity
- Tamper prevention
- Government grade request validation
Step 3: Creating the Payment and Getting Redirect URL
Dubai Pay follows a hosted redirection model. You register a batch transaction, and the response contains a uri for redirection.
callAPI Helper Function
function callAPI($endpoint, $payload, $token, $baseUrl, $checksumKey)
{
$jsonPayload = json_encode(
$payload,
JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);
$jsonPayload = mb_convert_encoding($jsonPayload, ‘UTF-8’);
$signature = strtoupper(
hash_hmac(‘sha512’, $jsonPayload, $checksumKey)
);
$ch = curl_init($baseUrl . $endpoint);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
“Authorization: Bearer $token”,
“Content-Type: application/json”,
“dubaiPaySignature: $signature”
],
CURLOPT_POSTFIELDS => $jsonPayload
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
Creating the Payment
$accessToken = getAccessToken($CLIENT_ID, $CLIENT_SECRET);
$payload = [
“entityCode” => $ENTITY_CODE,
“batchId” => “batch_” . time(),
“totalAmount” => 10.00,
“totalTransactions” => 1,
“returnUrl” => $RETURN_URL,
“transactions” => [[
“spCode” => $SP_CODE,
“servCode” => $SERV_CODE,
“spTrn” => uniqid(“DONATION_”),
“amount” => 10.00,
“currency” => “AED”,
“timestamp” => date(“d-m-Y H:i:s”),
“channel” => “100”,
“description” => “Online Donation”,
“type” => “sale”,
“version” => “2.1”,
“settlementType” => “gov”
]]
];
Calling Register Endpoint
$response = callAPI(
“/secure/dubaipay/batch/1.0.0/register”,
$payload,
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
);
Redirecting the Donor
if (!isset($response[‘uri’])) {
die(“Payment registration failed.”);
}
header(“Location: ” . $response[‘uri’]);
exit;
The donor is redirected to Dubai Pay secure hosted checkout.
Hosted Checkout Versus Self Managed Checkout
Dubai Pay primarily supports hosted redirection checkout.
This means:
- Card data is entered on Dubai Pay servers
- Your server does not handle card details
- PCI scope is reduced
- Security responsibility is simplified
Direct self managed card form processing is not the standard model.
Step 4: Handling Payment Confirmation
After payment completion, Dubai Pay posts a TOKEN to your return URL.
Retrieve Token
$responseToken = $_POST[‘TOKEN’];
Verify Using tokenDetails API
$verification = callAPI(
“/secure/dubaipay/batch/1.0.0/tokenDetails”,
[
“token” => $responseToken,
“entityCode” => $ENTITY_CODE
],
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
);
Validate Transaction
if (
$verification[‘batchStatus’] == ‘completed’ &&
$verification[‘transactions’][0][‘message’][‘code’] == 0
) {
Only when both conditions are satisfied should the transaction be considered successful.
Step 5: Confirm API Call
Dubai Pay recommends confirming transactions after successful verification.
$confirmPayload = [
“entityCode” => $ENTITY_CODE,
“batchId” => $verification[‘batchId’],
“confirmAll” => true,
“message” => [
“code” => “0”,
“text” => “confirmed”
]
];
$confirmResponse = callAPI(
“/secure/dubaipay/batch/1.0.0/confirm”,
$confirmPayload,
$accessToken,
$BASE_URL,
$CHECKSUM_KEY
);
Only after confirmation should you:
- Update the donation record
- Store the gateway reference
- Trigger receipt email
- Mark transaction as settled
Security and Production Best Practices
When moving from QA to production:
- Replace QA endpoints with production URLs
- Update Client ID and Client Secret
- Replace Checksum Key
- Validate return URL handling
- Log all API responses
- Use idempotent transaction references
- Implement server side validation
Conclusion
Dubai Pay integration in PHP requires structured implementation of OAuth authentication, HMAC SHA512 request signing and strict transaction verification.
For organisations such as Dubai Cares, this integration provides:
- Government compliant payment processing
- Hosted secure checkout
- Strong request integrity validation
- Clear batch reconciliation
When implemented correctly, Dubai Pay offers a reliable and scalable solution for secure online donation platforms in the UAE.





