Welcome to Platform API, you can use this API to integrate with your website.
Sort all non-empty parameter fields in ascending ASCII order. Concatenate the values in the order of the keys to generate string StringA
.
Encrypt StringA
using the merchant's private key (queryString
) with RSA to obtain the signature value sign
.
Sort all non-empty parameter fields in ascending ASCII order. Concatenate the values in the order of the keys to generate string StringA
(excluding sign
).
Decrypt sign
using RSA with the platform's public key to obtain the original data, then compare it with StringA
.
Sort all non-empty parameter fields in ascending ASCII order. Concatenate the values in the order of the keys to generate string StringA
(excluding sign
).
Decrypt sign
using RSA with the platform's public key to obtain the original data, then compare it with StringA
.
Production: POST https://open.clickpay.click/gateway/pay
Parameter | Type | Required | Description | Example |
---|---|---|---|---|
merchantCode | string(32) | Y | Merchant number opened by the merchant on the platform | S820190712000002 |
method | string(10) | Y | BNI / BRI / CIMB / MANDIRI / PERMATA / QRIS | BNI |
orderNum | string(32) | Y | Merchant system unique order number | T1231511321515 |
payMoney | double(15,2) | Y | Order payment amount | 100000 |
productDetail | string(32) | Y | Product description | Test Pay |
name | string(32) | Y | The name displayed on the bank payment confirmation page | Neo |
string(64) | Y | Customer's email address | [email protected] | |
currency | string(64) | Y | Currency | IDR |
notifyUrl | string(100) | Y | Asynchronous notification address, used to receive asynchronous notification of successful order payment | https://www.example.com/notify |
redirectUrl | string(100) | Y | Synchronous redirect address, the page that jumps after the order payment is successful | https://www.example.com/redirect |
phone | string(16) | N | Customer's mobile number | 082113086611 |
expiryPeriod | int(5) | N | Order expiration time in minutes (5, 10 or 60) | 10 |
dateTime | string(14) | Y | Request timestamp in yyyyMMddHHmmss format | 20191018105510 |
sign | string(512) | Y | RSA encrypted string | ja6R8eukQY9jc8z....bqzRGxV4Z3y-EZOs |
{
"merchantCode": "S820190712000002",
"method": "BNI",
"orderNum": "T1231511321515",
"payMoney": 100000,
"productDetail": "Test Pay",
"name": "Neo",
"email": "[email protected]",
"currency": "IDR",
"notifyUrl": "https://www.example.com/notify",
"redirectUrl": "https://www.example.com/redirect",
"phone": "082113086611",
"expiryPeriod": 10,
"dateTime": "20191018105510",
"sign": "ja6R8eukQY9jc8z....bqzRGxV4Z3y-EZOs"
}
sign
field must contain a valid RSA encrypted string for security purposes.notifyUrl
and redirectUrl
must be accessible URLs for handling asynchronous notifications and redirects after payment success.Field | Description |
---|---|
platRespCode | SUCCESS (request successful), FAIL (request failed), UNKNOWN (status unknown, requires manual processing), NOTEXIST (order does not exist), ERROR (error occurred) |
platRespMessage | Description of the platRespCode. |
platOrderNum | Order number generated by the platform. |
orderNum | Merchant system unique order number. |
method | Payment method |
name | Name of the customer. |
Email of the customer. | |
payData | Payment URL or data. |
originData | Unhandler Payment data. |
payMoney | Amount paid. |
payFee | Fee charged for the payment. |
productDetail | Details of the product or payment purpose. |
sourcePartnerName | Name of the partner (e.g., Speedy). |
platSign | Platform signature for verification. |
{
"method": "BNI",
"productDetail": "Test",
"orderNum": "T1720169959704",
"platRespCode": "SUCCESS",
"platOrderNum": "BNI_564241648432906240",
"payMoney": "50000",
"payFee": "1250",
"name": "12222",
"platSign": "EX9Nl226+78GHeSDAXW9Zc5Hf38NT82574VVCaFfZdtX7wwQ7WNxMVCJBFpPpNGvPbyygGmsNWZsC1358dIX5XUe3QSupcZtNl5gVDhQ4jmJ06KQRT9zvJH8V+zgCLa2QZ0Nw52JuocNUv0ZRU+x7LzE96BKaSF3wc9oc8sI1qwSmcqWIaAGupQSGpWPClw/45sKxFdPcIukQhTj8GkcNib4RNLX5Mq3gXANuKtvDlhYj4ZpmavryJQ93DwM/HvvMORp0NVTwkqVTWMaVS14m+rWv0KCgn1ak/DqQGdfJtRRGAsTx525Vw/JF6h/RNmVuZP6b5906XH46jyXuK4W9w==",
"originData": "9887387560967075",
"platRespMessage": "Success",
"payData": "https://open.clickpay.click/cashier/BNI?order=BNI_564241648432906240",
"email": "[email protected]"
}
<?php
$privateKey = 'YOUR_PRIVATE_KEY'; // from Platform
$merchantCode = 'YOUR_MERCHANT_CODE_HERE'; // from Platform
$payMoney = '10000';
$method = 'CASHIER'; // Payment method of your choice
$orderNum = 'T1231511321515'; // Merchant system unique order number
$productDetail = 'Test Pay'; // The virtual account description
$dateTime = date("YmdHis",time());
$email = '[email protected]'; // Customer's email address
$phone = '082113086611'; // Customer's mobile number
$name = 'Neo'; // Display name on bank confirmation display
$currency = 'IDR'; // Display name on bank confirmation display
$notifyUrl = 'http://example.com/callback'; // url for callback
$redirectUrl = 'http://example.com/redirect'; // url for redirect
$expiryPeriod = '10'; // Order expiration time
$params = array(
'merchantCode' => $merchantCode,
'payMoney' => $payMoney,
'method' => $method,
'orderNum' => $orderNum,
'productDetail' => $productDetail,
'name' => $name,
'email' => $email,
'phone' => $phone,
'currency' => $currency,
'notifyUrl' => $notifyUrl,
'redirectUrl' => $redirectUrl,
'dateTime' => $dateTime,
'expiryPeriod' => $expiryPeriod
);
ksort($params);
$params_str = '';
foreach ($params as $key => $val) {
$params_str = $params_str . $val;
}
$sign = private_key_encrypt($params_str, $privateKey);
$params['sign'] = $sign;
$params_string = json_encode($params);
// $url = 'https://open.clickpay.click/gateway/pay'; // Production
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $params_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($params_string))
);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
//execute post
$request = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 200)
{
$result = json_decode($request, true);
echo "platRespCode :" . $result['platRespCode'] . "<br />";
echo "platRespMessage :" . $result['platRespMessage'] . "<br />";
echo "platOrderNum :" . $result['platOrderNum'] . "<br />";
echo "orderNum :" . $result['orderNum'] . "<br />";
echo "method :" . $result['method'] . "<br />";
echo "name :" . $result['name'] . "<br />";
echo "email :" . $result['email'] . "<br />";
echo "payData :" . $result['payData'] . "<br />";
echo "originData :" . $result['originData'] . "<br />";
echo "payMoney :" . $result['payMoney'] . "<br />";
echo "payFee :" . $result['payFee'] . "<br />";
echo "productDetail :" . $result['productDetail'] . "<br />";
echo "platSign :" . $result['platSign'] . "<br />";
}
else
echo $httpCode;
function private_key_encrypt($data, $private_key)
{
$private_key = '-----BEGIN PRIVATE KEY-----'."\n".$private_key."\n".'-----END PRIVATE KEY-----';
$pi_key = openssl_pkey_get_private($private_key);
$crypto = '';
foreach (str_split($data, 117) as $chunk) {
openssl_private_encrypt($chunk, $encryptData, $pi_key);
$crypto .= $encryptData;
}
return base64_encode($crypto);
}
function public_key_decrypt($data, $public_key)
{
$public_key = '-----BEGIN PUBLIC KEY-----'."\n".$public_key."\n".'-----END PUBLIC KEY-----';
$data = base64_decode($data);
$pu_key = openssl_pkey_get_public($public_key);
$crypto = '';
foreach (str_split($data, 128) as $chunk) {
openssl_public_decrypt($chunk, $decryptData, $pu_key);
$crypto .= $decryptData;
}
return $crypto;
}
?>
Return values are returned as HTTP POST, Merchant will need to provide a call-back page to catch the result. After receiving the notification and processing is successful, please return the string SUCCESS
Parameter | Description | Example |
---|---|---|
code | Status of the request (00 indicates success) |
00 |
msg | Asynchronous return status of the order request in the msg field |
SUCCESS |
platOrderNum | Payment platform order number | BK_1563278763273 |
orderNum | Merchant request serial number | T1231511321515 |
method | Payment method requested (BNI , BRI , CIMB , etc.) |
BNI |
name | The name displayed on the bank payment confirmation page | Neo |
payData | Payment data | https://open.clickpay.click/zalo |
payMoney | Request order amount | 100000 |
payFee | Order handling fee amount | 500 |
Customer's email address | [email protected] | |
platSign | RSA encrypted string | ja6R8eukQY9jc8z....bqzRGxV4Z3y-EZOs |
{
"code": "00",
"email": "[email protected]",
"method": "DANA",
"msg": "SUCCESS",
"name": "724424035",
"orderNum": "21161500247208",
"payData": "https://link.dana.id/pay",
"payFee": "250.00",
"payMoney": "10000.00",
"platOrderNum": "552538080348274688",
"platSign": "oo60qPYtJw/7lem/bTqYhZigW8KzhXD6+woI8EXJlG/2z6IE1G9Hr0M/W/2tUBSdMJfkOsUgpDF4MgI9eTABFR80RFVPfZxo60UTc147ISQSkoFj1CxkPar3HVfQld892o9JEg0NtF4VlK59//6skfg12uuH0u5TDV5ty1Btspd+J3E90rA7nQi+UHn6hrI9AUbZrNYSxh7LolKpKnFVFxFN6spY+RCKx6NKMTirS0Z9ZnIXyAoTMbmmJIOiAoKuq6gYshi/2YBxUy8SteiClezy0Rk/7BvDEzdYJM0sg0Vkjt/HzQRlJ41wuTDAJUxyy2ZJleuEH6u9qFkJXXYVY5gNZlGmYHvW4koWk4dngSY88HpB/aPuim7iGnOEWBpNngeR4l0TADRC0XA54762v+nI91CPn1Xh45exim+R1N7ZFHO2jXCihcyV/jKUcA2+2pUa/TFGsY4gojWtRVLjUrrRkGmmHgBaoWZpF/+3U/fWNho8Px+M3EcHFJ8VIANGgqTVT8MLZ3x6Tvf8SD7C//N8BqQLHRXqnIYGnReaC9xzF1ADfQehBOubUUN3qRWloho83HkVQiVUzkc/JEdX10g0iHyBd2UaXBIIU02EQbXsKina3/64jjyF/xK5Z9v5v4hikLVicP/Yo36AUpTg1ObOnoA8MlPatDHF+GjBcTlfbUEP4MFzqaCrWv1qdw04kjB1vDNF9nxGpUfE8/VK1YRdRyXDukHzhibUJULpbbTr7XUOWDaNw5DDTtHFl09zymKY0Ri9TU8eN+d8TLmxBovyrJjGCnX0yUnaOhaFaFSt8SWimwWoDzPnNAsKeo6BuNVUS8VMDzOuwZES0y1SwhWZJHk/fYZ7j/PLD4ZEFgVdJyb/Zpc0vlaBBvEoiOvfruh/WkOR/4t2tDIWdOUbivkMHy98GjJJwExH2v1etsLhMdBIyZDJsVavJ9TTTeRvjZjZRnAwIR90dwKlgznTQQrbJc9D9pK0ZcJ+CGLKdJvM5eDTdTugEQLbZCppNy4x"
}
public_key_decrypt
function correctly handles RSA decryption using your public key.Here is the PHP callback handler for processing the JSON response from the payment gateway. This script verifies the integrity of the data using RSA encryption and checks the response status.
<?php
$res = json_decode(file_get_contents('php://input'), true);
$platSign = $res['platSign'];
unset($res['platSign']);
// Public Key for decryption
$public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFJ/AmUV4Z8udG8aOBUt/kEwc/DbxF5Gtfw6Y00NHQ4Pz2X2x9IxjUZxn2dnFxmrmhqKNlfwXOqyejhBzi0pSHyGoI4XP9IEfZGO6YkSb9DCY1ZxX8fDl2G+tPCbWYTVO4JutFmzTWgk1Uhhu6L9dlOMUHvZf3/6czA/a9C7azXwIDAQAB';
// Decrypt platSign
$decryptSign = public_key_decrypt($platSign, $public_key);
// Sort and concatenate parameters
$params = $res;
ksort($params);
$params_str = '';
foreach ($params as $key => $val) {
$params_str .= $val;
}
// Verify signature
if ($params_str == $decryptSign) {
// Check if payment was successful
if ($res['code'] == '00' && $res['msg'] == 'SUCCESS') {
echo 'SUCCESS';
} else {
echo 'FAIL';
}
} else {
echo 'FAIL';
}
function public_key_decrypt($data, $public_key)
{
$public_key = '-----BEGIN PUBLIC KEY-----'."\n".$public_key."\n".'-----END PUBLIC KEY-----';
$data = base64_decode($data);
$pu_key = openssl_pkey_get_public($public_key);
$crypto = '';
foreach (str_split($data, 128) as $chunk) {
openssl_public_decrypt($chunk, $decryptData, $pu_key);
$crypto .= $decryptData;
}
return $crypto;
}
?>
Here is the table describing the available payment methods on the platform:
Payment Method | Description |
---|---|
CASHIER | Cashier |
CASHIER-OVO | Cashier OVO |
Payment Method | Description | Type |
---|---|---|
BNI | BNI Payment | VA |
BRI | BRI Payment | VA |
CIMB | CIMB Payment | VA |
MANDIRI | MANDIRI Payment | VA |
PERMATA | PERMATA Payment | VA |
QRIS | QRIS Payment | QRIS |
BCA | BCA Payment | VA |
DANAMON | DANAMON Payment | VA |
BSI | BSI Payment | VA |
BNC | BNC Payment | VA |
DANA | DANA Payment | Ewallet |
OVO | OVO Payment | Ewallet |
LINKAJA | LINKAJA Payment | Ewallet |
SHOPEEPAY | SHOPEEPAY Payment | Ewallet |
These are the supported payment methods you can use with the platform.
To query the order status, send an HTTP POST request to the following endpoint:
Production: https://open.clickpay.click/gateway/query
When sending the POST request, include the following parameters in the JSON body:
Parameter | Description | Example |
---|---|---|
merchantCode |
Merchant number opened by the merchant on the platform | S820190712000002 |
queryType |
Type of query. Use ORDER_QUERY for payment orders or REFUND_QUERY for refund orders |
ORDER_QUERY |
orderNum |
Merchant system unique order number | T1231511321515 |
dateTime |
Date and time of the transaction in yyyyMMddHHmmss format |
20191018105510 |
appId |
Application ID. Ignore if you didn't create an application | 9039094726 |
sign |
RSA encrypted string | ja6R8eukQY9jc8z....bqzRGxV4Z3y-EZOs |
Here’s a detailed explanation of the JSON response structure and parameters for querying the order status via the provided API endpoint.
Here is the field explanation table for the provided JSON object:
Field | Description | Example Value |
---|---|---|
platRespCode | Indicates if the request was successful. | SUCCESS (request successful), FAIL (request failed), UNKNOWN (status unknown, requires manual processing), NOTEXIST (order does not exist), ERROR (error occurred) |
platRespMessage | Description of platRespCode . |
"success" |
platOrderNum | Order number on the platform. | "FT_1565066064716" |
orderNum | Merchant system unique order number. | "T20190806000001" |
amount | Amount involved in the transaction. | 20000.00 |
fee | Charged fee. | 6000.00 |
status | Status of the order (refer to Status Code). | "NO_PAY" |
msg | Description of the status. | "Unpaid" |
platSign | RSA encrypted signature for verification. | "YTO7eBFIgpQRDg6iKUz3GDggg1H8e5vuPDqgCrWkoO08VixtocMB1gUyDdUaMwEfm5-Iv337ZmHOMJWO7B_2YAIabVOUUaEzE9nJfFIwZYxYXNCJwswXGEtEt8qah4oXTjOOIkiuetgORGxATclKHIvgD-Wm-eZ2DvhrgrRwdUI" |
When you query the order status, the response will be a JSON object structured as follows:
{
"platRespCode": "SUCCESS", // Indicates if the request was successful.
"platRespMessage": "success", // Description of platRespCode.
"platOrderNum": "FT_1565066064716", // Order number on the platform.
"orderNum": "T20190806000001", // Merchant system unique order number.
"amount": 20000.00, // Amount involved in the transaction.
"fee": 6000.00, // Charged fee.
"status": "NO_PAY", // Status of the order (refer to Status Code).
"msg": "Unpaid", // Description of the status.
"platSign": "YTO7eBFIgpQRDg6iKUz3GDggg1H8e5vuPDqgCrWkoO08VixtocMB1gUyDdUaMwEfm5-Iv337ZmHOMJWO7B_2YAIabVOUUaEzE9nJfFIwZYxYXNCJwswXGEtEt8qah4oXTjOOIkiuetgORGxATclKHIvgD-Wm-eZ2DvhrgrRwdUI" // RSA encrypted signature.
}
Below is a PHP code snippet to send the request and handle the response:
<?php
$privateKey = 'YOUR_PRIVATE_KEY';
$merchantCode = 'S820190712000002'; // Your merchant code
$queryType = 'ORDER_QUERY';
$orderNum = 'T1231511321515'; // Your order number
$dateTime = '20191018105510'; // Date and time in yyyyMMddHHmmss format
$appId = '9039094726'; // Your application ID (if any)
$params = array(
'merchantCode' => $merchantCode,
'queryType' => $queryType,
'orderNum' => $orderNum,
'dateTime' => $dateTime,
'appId' => $appId
);
ksort($params);
$params_str = '';
foreach ($params as $key => $val) {
$params_str .= $val;
}
$pi_key = openssl_pkey_get_private($privateKey);
openssl_private_encrypt($params_str, $sign, $pi_key);
$sign = base64_encode($sign);
$params['sign'] = $sign;
$params_string = json_encode($params);
$url = 'https://open.clickpay.click/gateway/query';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $params_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($params_string)
));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$request = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode == 200) {
$result = json_decode($request, true);
print_r($result);
} else {
echo "HTTP Error Code: $httpCode";
}
?>
This script sends a POST request to the specified URL with the necessary parameters to query the order status and handles the response by printing it. Make sure to replace the placeholders with actual values specific to your integration.
Setup Parameters:
YOUR_PRIVATE_KEY
and YOUR_MERCHANT_CODE_HERE
with your actual private key and merchant code.queryType
to ORDER_QUERY
.orderNum
to the merchant system unique order number you want to inquire about.dateTime
to the date and time of the transaction in yyyyMMddHHmmss
format.Construct Parameters:
$params
with the required parameters.$params_str
.Encrypt Signature:
$params_str
using the private key.$params
array.HTTP POST Request:
$params
array to JSON format.https://open.clickpay.click/gateway/query
).CURLOPT_SSL_VERIFYPEER
set to FALSE
).Handle Response:
Make sure to replace placeholders with actual values specific to your integration. This script will help you inquire about the status of a transaction on the platform. Adjustments may be needed based on specific API requirements or additional security configurations.
Here is a detailed explanation of the status codes for querying payment and refund orders via the API.
queryType
is ORDER_QUERY
: Status Code | Description | Order State |
---|---|---|
INIT_ORDER | Create order | Order is created |
NO_PAY | Paying | Payment is ongoing |
OPEN_PAY_URL | Paying | Payment is ongoing |
SUCCESS | Payment successful | Order is successful |
PAY_CANCEL | Cancel payment | Order failed |
PAY_ERROR | Payment failed | Order failed |
Note: For ORDER_QUERY
, an order is considered successful only when the status value is SUCCESS
. It fails when the status value is PAY_CANCEL
or PAY_ERROR
.
queryType
is REFUND_QUERY
: Status Code | Description | Order State |
---|---|---|
0 | INIT (create order) | Order is created |
2 | Handle refund successful | Order is successful |
4 | Handle refund failed | Order failed |
Note: For REFUND_QUERY
, an order is considered successful only when the status value is 2
. It fails when the status value is 4
.
To better understand how to interpret the response, consider the following example of a response JSON:
{
"platRespCode": "SUCCESS",
"platRespMessage": "success",
"platOrderNum": "FT_1565066064716",
"orderNum": "T20190806000001",
"amount": 20000.00,
"fee": 6000.00,
"status": "NO_PAY",
"msg": "Unpaid",
"platSign": "YTO7eBFIgpQRDg6iKUz3GDggg1H8e5vuPDqgCrWkoO08VixtocMB1gUyDdUaMwEfm5-Iv337ZmHOMJWO7B_2YAIabVOUUaEzE9nJfFIwZYxYXNCJwswXGEtEt8qah4oXTjOOIkiuetgORGxATclKHIvgD-Wm-eZ2DvhrgrRwdUI"
}
In this example, the status
is NO_PAY
, which means the payment is ongoing. If the status were SUCCESS
, it would indicate that the payment was successful.