Signature

Request

Request Payment Data

Callback

Payment Method

Changelog

Introduction

Welcome to Platform API, you can use this API to integrate with your website.

Signature

Request

  1. Sort all non-empty parameter fields in ascending ASCII order. Concatenate the values in the order of the keys to generate string StringA.

  2. Encrypt StringA using the merchant's private key (queryString) with RSA to obtain the signature value sign.

Response

  1. 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).

  2. Decrypt sign using RSA with the platform's public key to obtain the original data, then compare it with StringA.

Callback

  1. 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).

  2. Decrypt sign using RSA with the platform's public key to obtain the original data, then compare it with StringA.


Example

SignDataExample

JavaCodeExample

Request

Request Payment Data

HTTP Request

Production: POST https://open.clickpay.click/gateway/pay

Parameters

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
email 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

Example JSON Request Body

{
  "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"
}

Important Notes

JSON Response Structure

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 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.

Example JSON Response Body

{
	"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;
}
?>

Callback

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

Callback Parameters

HTTP Request

Parameters

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
email 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"
}

Notes

PHP Callback Handler

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;
}
?>

Payment Method

Here is the table describing the available payment methods on the platform:

CASHIER MODE

Payment Method Description
CASHIER Cashier
CASHIER-OVO Cashier OVO

API MODE

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.

Inquiry Status

HTTP Request

To query the order status, send an HTTP POST request to the following endpoint:

Production: https://open.clickpay.click/gateway/query

Parameters

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

JSON Response Structure

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.
}

Example PHP Code

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.

Explanation:

  1. Setup Parameters:

    • Replace YOUR_PRIVATE_KEY and YOUR_MERCHANT_CODE_HERE with your actual private key and merchant code.
    • Set queryType to ORDER_QUERY.
    • Set orderNum to the merchant system unique order number you want to inquire about.
    • Set dateTime to the date and time of the transaction in yyyyMMddHHmmss format.
  2. Construct Parameters:

    • Construct an array $params with the required parameters.
    • Sort the parameters alphabetically by key and concatenate their values into a single string $params_str.
  3. Encrypt Signature:

    • Encrypt the concatenated parameters string $params_str using the private key.
    • Base64 encode the resulting encrypted signature and add it to the $params array.
  4. HTTP POST Request:

    • Convert the $params array to JSON format.
    • Set up a cURL request to send a POST request to the API endpoint (https://open.clickpay.click/gateway/query).
    • Include headers specifying the content type and content length.
    • Disable SSL verification for simplicity (CURLOPT_SSL_VERIFYPEER set to FALSE).
  5. Handle Response:

    • Execute the cURL request and capture the HTTP response.
    • If the HTTP response code is 200 (OK), decode the JSON response and print the result.
    • If the HTTP response code is not 200, print the HTTP status code.

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.

Status Codes

Here is a detailed explanation of the status codes for querying payment and refund orders via the API.

When 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.

When 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.

Example

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.

Changelog

Version 1.0