NAV Navbar
json php shell

Getting Started

Duitku makes the integration process as easy as possible. Allows the Duitku payment page to appear on your web page/application after checkout, with a very easy integration process. Hand over your payment to Duitku Pop. Provide optional payments and confirmation of payments made by customers on your page. Only by you bring Duitku pop on your page.

Overview

  1. The user performs the checkout operation.
  2. The merchant server makes an API request to the Duitku payment backend to get the DUITKU_REFERENCE.
  3. Duitku payment backend response to the API call with the DUITKU_REFERENCE.
  4. The merchant server constructs the HTML page and sends it back to the browser.
  5. The user verifies the details and clicks the pay button. Merchant's javascript code calls checkout.process(DUITKU_REFERENCE, options).
  6. Duitku payment backend processes the details and responds with the payment status. Then, Duitku JS calls the corresponding callback provided by the merchant's javascript code.
  7. Duitku payment backend notifies the merchant server about the payment status.

Integration Step

Flowchart pop

To connect with Duitku API, There are few things should be known as below.

Merchant Code

Merchant Code is a project code that can be get on dashboard Duitku. This code is used as your project identifier in every transaction. Every projects that have been registered on merchant portal is have a merchant code. See on how to create merchant code here.

API Key

API (Application Programming Interface) is an authentication code to access Duitku API. API key use to prevent dangerous user or malware. As merchant code, API key can be found in every projects that have been registered on merchant portal as pairs.

Supported Browsers

Web

Browser Version
Chrome 26 and above
Firefox 29 and above
Internet Explorer 10 and above
Safari 6 and above

Mobile

Browser Version
Chrome 32 and above
Android 4.4 and above
Safari 8 and above

Library

You can use Duitku Library for integration and to start transaction using Duitku on your web or application. For further step you may see Duitku Library on the package repository at each library. Click the link below.

Backend Integration or Server Side

The backend integration goal is to acquire DUITKU_REFERENCE by providing payment information. We provide an HTTP API to do this.

Create Invoice

Create Invoice API is used to get Duitku's reference by sending requirement parameters to the API. Merchant will get Duitku's reference, payment URL as a response from API.

Basic Authentication

Basic Authentication that Duitku uses is signature, timestamp, and merchant code that are sent within request headers.

The signature is the transaction identification code. Contains transaction parameters that have been hashed using the SHA256 hashing method. The hash parameter is merchant code, timestamp, then API key, and should be in order.

The timestamp is a UNIX timestamp in milliseconds within our timezone (Jakarta). The UNIX timestamp is a way to track time as a running total of seconds.

The merchant code is a project ID that has been created and registered at the Duitku merchant page.

Endpoint

https://api-prod.duitku.com/api/merchant/createInvoice

https://api-sandbox.duitku.com/api/merchant/createInvoice

Request Headers

To create a valid HTTP request, the merchant needs to use headers like in below:

Request Parameter

{
    "paymentAmount": 40000,
    "merchantOrderId": "1648542419",
    "productDetails": "Test Pay with duitku",
    "additionalParam": "",
    "merchantUserInfo": "",
    "customerVaName": "John Doe",
    "email": "[email protected]",
    "phoneNumber": "08123456789",
    "itemDetails": [{
        "name": "Test Item 1",
        "price": 10000,
        "quantity": 1
    }, {
        "name": "Test Item 2",
        "price": 30000,
        "quantity": 3
    }],
    "customerDetail": {
        "firstName": "John",
        "lastName": "Doe",
        "email": "[email protected]",
        "phoneNumber": "08123456789",
        "billingAddress": {
            "firstName": "John",
            "lastName": "Doe",
            "address": "Jl. Kembangan Raya",
            "city": "Jakarta",
            "postalCode": "11530",
            "phone": "08123456789",
            "countryCode": "ID"
        },
        "shippingAddress": {
            "firstName": "John",
            "lastName": "Doe",
            "address": "Jl. Kembangan Raya",
            "city": "Jakarta",
            "postalCode": "11530",
            "phone": "08123456789",
            "countryCode": "ID"
        }
    },
    "callbackUrl": "https:\/\/example.com\/api-pop\/backend\/callback.php",
    "returnUrl": "https:\/\/example.com\/api-pop\/backend\/redirect.php",
    "expiryPeriod": 10
}
<?php
    $merchantCode = 'DXXXXX'; // from duitku
    $merchantKey = 'XXXXXXXCX17XXXX5XX5XXXXXX0X3XXAF'; // from duitku
    $paymentAmount = 40000;
    $merchantOrderId = time() . ''; // from merchant, unique
    $productDetails = 'Test Pay with duitku';
    $email = '[email protected]'; // email customer merchant
    $phoneNumber = '08123456789'; // customer merchant phone number (optional)
    $additionalParam = ''; // optional
    $merchantUserInfo = ''; // optional
    $customerVaName = 'John Doe'; // Show customer name on the bank view
    $callbackUrl = 'http://example.com/callback'; // URL untuk callback
    $returnUrl = 'http://example.com/return'; // URL untuk redirect
    $expiryPeriod = 10; // expire transaction time in minutes
    $signature = hash('sha256', $merchantCode.$timestamp.$merchantKey);
    //$paymentMethod = 'VC'; //use for directional payment

    // Detail Customer
    $firstName = "John";
    $lastName = "Doe";

    // Alamat
    $alamat = "Jl. Kembangan Raya";
    $city = "Jakarta";
    $postalCode = "11530";
    $countryCode = "ID";

    $address = array(
        'firstName' => $firstName,
        'lastName' => $lastName,
        'address' => $alamat,
        'city' => $city,
        'postalCode' => $postalCode,
        'phone' => $phoneNumber,
        'countryCode' => $countryCode
    );

    $customerDetail = array(
        'firstName' => $firstName,
        'lastName' => $lastName,
        'email' => $email,
        'phoneNumber' => $phoneNumber,
        'billingAddress' => $address,
        'shippingAddress' => $address
    );


    $item1 = array(
        'name' => 'Test Item 1',
        'price' => 10000,
        'quantity' => 1);

    $item2 = array(
        'name' => 'Test Item 2',
        'price' => 30000,
        'quantity' => 3);

    $itemDetails = array(
        $item1, $item2
    );

    $params = array(
        'paymentAmount' => $paymentAmount,
        'merchantOrderId' => $merchantOrderId,
        'productDetails' => $productDetails,
        'additionalParam' => $additionalParam,
        'merchantUserInfo' => $merchantUserInfo,
        'customerVaName' => $customerVaName,
        'email' => $email,
        'phoneNumber' => $phoneNumber,
        'itemDetails' => $itemDetails,
        'customerDetail' => $customerDetail,
        'callbackUrl' => $callbackUrl,
        'returnUrl' => $returnUrl,
        'expiryPeriod' => $expiryPeriod
        //'paymentMethod' => $paymentMethod
    );

    $params_string = json_encode($params);
    //echo $params_string;
    $url = 'https://api-sandbox.duitku.com/api/merchant/createinvoice'; // Sandbox
    // $url = 'https://api-prod.duitku.com/api/merchant/createinvoice'; // Production
    $ch = curl_init();

    $timestamp = round(microtime(true) * 1000); //in milisecond

    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),
        'x-duitku-signature:' . $signature ,
        'x-duitku-timestamp:' . $timestamp ,
        'x-duitku-merchantcode:' . $merchantCode    
        )                                                                       
    );   
    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);
        //header('location: '. $result['paymentUrl']);
        echo "paymentUrl :". $result['paymentUrl'] . "<br />";
        echo "merchantCode :". $result['merchantCode'] . "<br />";
        echo "reference :". $result['reference'] . "<br />";
        echo "vaNumber :". $result['vaNumber'] . "<br />";
        echo "amount :". $result['amount'] . "<br />";
        echo "statusCode :". $result['statusCode'] . "<br />";
        echo "statusMessage :". $result['statusMessage'] . "<br />";
    }
    else
    {
        echo $httpCode;
    }
?>
curl --location --request POST 'https://api-sandbox.duitku.com/api/merchant/createInvoice' \
--header 'x-duitku-signature: sample string' \
--header 'x-duitku-timestamp: 1629219840000' \
--header 'x-duitku-merchantcode: D0001' \
--header 'Content-Type: application/json' \
--data-raw
{ 
   "paymentAmount":40000,
   "merchantOrderId":"1579838431",
   "productDetails":"Test Pay with duitku",
   "additionalParam":"",
   "merchantUserInfo":"",
   "customerVaName":"John Doe",
   "email":"[email protected]",
   "phoneNumber":"08123456789",
   "itemDetails":[ 
      { 
         "name":"Test Item 1",
         "price":10000,
         "quantity":1
      },
      { 
         "name":"Test Item 2",
         "price":30000,
         "quantity":3
      }
   ],
   "customerDetail":{ 
      "firstName":"John",
      "lastName":"Doe",
      "email":"[email protected]",
      "phoneNumber":"08123456789",
      "billingAddress":{ 
         "firstName":"John",
         "lastName":"Doe",
         "address":"Jl. Kembangan Raya",
         "city":"Jakarta",
         "postalCode":"11530",
         "phone":"08123456789",
         "countryCode":"ID"
      },
      "shippingAddress":{ 
         "firstName":"John",
         "lastName":"Doe",
         "address":"Jl. Kembangan Raya",
         "city":"Jakarta",
         "postalCode":"11530",
         "phone":"08123456789",
         "countryCode":"ID"
      }
   },
   "callbackUrl":"http:\/\/example.com\/callback",
   "returnUrl":"http:\/\/example.com\/return",
   "expiryPeriod":10
}
Parameter Type Required Description Example
paymentAmount integer

πŸ—Έ

Payment amount. 150000
merchantOrderId string(50)

πŸ—Έ

Order ID from merchant. abcde12345
productDetails string(255)

πŸ—Έ

Product detail. Payment for Example Store
email string(255)

πŸ—Έ

Your customer email. [email protected]
additionalParam string(255)

βœ—

Additional parameter (optional).
merchantUserInfo string(255)

βœ—

Username or email customer (optional). [email protected]
customerVaName string(20)

βœ—

The name will appear on the bank's payment confirmation page. John Doe
phoneNumber string(50)

βœ—

Customer phone number (optional). 08123456789
itemDetails Object

βœ—

Item Details (optional).
customerDetail CustomerDetail

βœ—

Customer Detail.
returnUrl string(255)

πŸ—Έ

URL for redirect when the transaction is finish or canceled. http://www.example.com/return
callbackUrl string(255)

πŸ—Έ

URL for transaction Callback. http://www.example.com/callback
expiryPeriod integer

βœ—

The validity period of the transaction before it expires. For details expiryPeriod can be found here. 5, 10 or 60 (in minutes)
paymentMethod string

βœ—

Payment Method is a payment gateway code. VC

Duitku uses merchantCode and apiKey to allow access to the API. You can register a new merchantCode at our Merchant Portal.

Response Parameters

{
    "merchantCode": "DXXXX",
    "reference": "DXXXXS875LXXXX32IJZ7",
    "paymentUrl": "https://app-sandbox.duitku.com/redirect_checkout?reference=DXXXXS875LXXXX32IJZ7",
    "statusCode": "00",
    "statusMessage": "SUCCESS"
}
Parameter Type Description Example
merchantCode string Merchant code from Duitku. D0001
reference string Reference from Duitku (need to be saved on your system). DXXXXS875LXXXX32IJZ7
paymentUrl string Payment URL if you want to use Duitku payment page. https://app-sandbox.duitku.com/redirect_checkout?reference=DXXXXS875LXXXX32IJZ7
statusCode string Response status code. 00
statusMessage string Response status. Success

JSON Object

Collection of JSON objects.

Item Details

"itemDetails": [{
    "name": "Apel",
    "quantity": 2,
    "price": 50000
}]
Parameter Type Required Description Example
name string(50)

πŸ—Έ

Name of the item. Apel
quantity integer

πŸ—Έ

Quantity of the item bought. 2
price integer

πŸ—Έ

Price of the item.
Note: Don't add decimal.
50000

Customer Detail

"customerDetail": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "[email protected]",
    "phoneNumber": "081234567890",
    "billingAddress": {
      "firstName": "John",
      "lastName": "Doe",
      "address": "St Panjang",
      "city": "Jakarta",
      "postalCode": "41011",
      "phone": "081234567890",
      "countryCode": "ID"
    },
    "shippingAddress": {
      "firstName": "John",
      "lastName": "Doe",
      "address": "St Panjang",
      "city": "Jakarta",
      "postalCode": "41011",
      "phone": "081234567890",
      "countryCode": "ID"
    }
}
Parameter Type Required Description Example
firstName string(50)

βœ—

Customer first name. John
lastName string(50)

βœ—

Customer last name. Doe
email string(50)

βœ—

Customer email. [email protected]
phoneNumber string(50)

βœ—

Customer phone number. 081234567890
billingAddress Address

βœ—

Customer billing address.
shippingAddress Address

βœ—

Customer shipping address.

Address

{
  "firstName": "John",
  "lastName": "Doe",
  "address": "St Panjang",
  "city": "Jakarta",
  "postalCode": "41011",
  "phone": "081234567890",
  "countryCode": "ID"
}
Parameter Type Required Description Example
firstName string(50)

βœ—

Customer first name. John
lastName string(50)

βœ—

Customer last name. Doe
address string(50)

βœ—

Address for billing or shipping. St Panjang
city string(50)

βœ—

City description for the address. Jakarta
postalCode string(50)

βœ—

Postal code for the address. 41011
phone string(50)

βœ—

Phone number for billing or shipping. 081234567890
countryCode string(50)

βœ—

ISO 3166-1 alpha-3. ID - for Indonesia

Callback

<?php
    $apiKey = 'YOUR_MERCHANT_KEY_HERE'; // Your API key
    $merchantCode = isset($_POST['merchantCode']) ? $_POST['merchantCode'] : null; 
    $amount = isset($_POST['amount']) ? $_POST['amount'] : null; 
    $merchantOrderId = isset($_POST['merchantOrderId']) ? $_POST['merchantOrderId'] : null; 
    $productDetail = isset($_POST['productDetail']) ? $_POST['productDetail'] : null; 
    $additionalParam = isset($_POST['additionalParam']) ? $_POST['additionalParam'] : null; 
    $paymentCode = isset($_POST['paymentCode']) ? $_POST['paymentCode'] : null; 
    $resultCode = isset($_POST['resultCode']) ? $_POST['resultCode'] : null; 
    $merchantUserId = isset($_POST['merchantUserId']) ? $_POST['merchantUserId'] : null; 
    $reference = isset($_POST['reference']) ? $_POST['reference'] : null; 
    $signature = isset($_POST['signature']) ? $_POST['signature'] : null; 

    //log callback untuk debug 
    // file_put_contents('callback.txt', "* Callback *\r\n", FILE_APPEND | LOCK_EX);

    if(!empty($merchantCode) && !empty($amount) && !empty($merchantOrderId) && !empty($signature))
    {
        $params = $merchantCode . $amount . $merchantOrderId . $apiKey;
        $calcSignature = md5($params);

        if($signature == $calcSignature)
        {
            //Callback is valid
            //You might update your payment status here
            // file_put_contents('callback.txt', "* Success *\r\n\r\n", FILE_APPEND | LOCK_EX);

        }
        else
        {
            // file_put_contents('callback.txt', "* Bad Signature *\r\n\r\n", FILE_APPEND | LOCK_EX);
            throw new Exception('Bad Signature')
        }
    }
    else
    {
        // file_put_contents('callback.txt', "* Bad Parameter *\r\n\r\n", FILE_APPEND | LOCK_EX);
        throw new Exception('Bad Parameter')
    }
?>

When the customer makes a payment. Duitku will send an HTTP POST that includes the results of paying a bill from a customer. To process the results of transactions made by customers, Merchants need to provide a page to receive the callback.

Parameters

Parameter Description Example
merchantCode Merchant code from Duitku. D0010
paymentAmount Payment amount. 150000
merchantOrderId Order ID from merchant. abcde12345
productDetail Product detail. Payment for Example Store
additionalParam Additional parameter (optional).
paymentCode Payment method. VC
resultCode Payment status. 00 - Success
01 - Failed
merchantUserId User ID from merchant. [email protected]
reference Reference from Duitku, save this to trace the transaction. D0010E65V0MLAI4M2O4S
signature Signature. Formula: MD5(merchantcode + amount + merchantOrderId + merchantKey)

Frontend Integration or View Side

General Review

The frontend integration goal is to show Duitku payment page within your site.

Include duitku.js into your page so Duitku checkout module is available.

You can start the payment process by calling checkout.process with DUITKU_REFERENCE acquired from backend integration as the parameter.

Duitku JS module location

You can add script tag between your HTML head tag.

<script src="https://app-prod.duitku.com/lib/js/duitku.js"></script>

<script src="https://app-sandbox.duitku.com/lib/js/duitku.js"></script>

Duitku JS

After you include Duitku JS script tag you can use object checkout.

process(duitkuReference, options)

checkout.process(result.reference, {
    defaultLanguage: "id", //optional to set default language
    successEvent: function(result){
    // your code here
        console.log('success');
        console.log(result);
        alert('Payment Success');
    },
    pendingEvent: function(result){
    // your code here
        console.log('pending');
        console.log(result);
        alert('Payment Pending');
    },
    errorEvent: function(result){
    // your code here
        console.log('error');
        console.log(result);
        alert('Payment Error');
    },
    closeEvent: function(result){
    // your code here
        console.log('customer closed the popup without finishing the payment');
        console.log(result);
        alert('customer closed the popup without finishing the payment');
    }
}); 

Start Duitku payment page.

Parameter:

Name Type Description
duitkuReference string Duitku reference get from backend integration.
options.defaultLanguage string (optional) Language settings.
en - english.
id - indonesian language.
options.successEvent function (optional) Payment success callback (00).
options.pendingEvent function (optional) Payment pending callback (01).
options.errorEvent function (optional) Payment error callback.
options.closeEvent function (optional) Called if customer closed the payment popup without finishing the payment (02).

JS Callback

Transaction Result

{
    "resultCode": "00",
    "merchantOrderId": "abcde12345",
    "reference": "qwerty12345"
}

The object representing transaction result passed to Duitku callback.

Name Type Description
resultCode string Result code from Duitku.
merchantOrderId string Order ID from merchant.
reference string Reference from Duitku.

Window Redirection

There is an alternative technique to load the pop UI page instead of calling duitku.js, this method call window redirection. Merchants can utilize the response value in paymentUrl from the Create Pop Token request. Merchants don’t have to load duitku.js on their page, as the user is redirected to a page that is hosted by Duitku. For language configuration you may add &lang=en query parameter on the paymentUrl as below.

https://app-sandbox.duitku.com/redirect_checkout?reference=DXXXXS875LXXXX32IJZ7&lang=en

With this redirection merchants can load the pop page in full window mode view like this:

Redirect

After the transaction and billing request is formed, from the Duitku payment page(Window Redirection), user will be redirect to the address provided in the Create Invoice(returnUrl) parameter after payment or via the return button. And at the time of the redirect, Duitku will include several related billing parameters. You'll need to create a landing page in this return URL address.

Example

GET: http://www.merchantweb.com/redirect.php?merchantOrderId=abcde12345&resultCode=00&reference=D0010E65V0MLAI4M2O4S

Parameters

Parameter Description Example
merchantOrderId Order ID from merchant. abcde12345
reference Reference from Duitku. D0010E65V0MLAI4M2O4S
resultCode Result code. 00

Payment Method

Here are some payment methods available on Duitku and you could use. You can put payment method(paymentMethod) on parameter create invoice, as a step to set direct payment to specific payment. Customers will be directed to wanted payment without necessary to pick a payment.

Payment Type Payment Code Description
Credit Card

VC

(Visa / Master Card / JCB)
Virtual Account

BC

BCA Virtual Account

M2

Mandiri Virtual Account

VA

Maybank Virtual Account

I1

BNI Virtual Account

B1

CIMB Niaga Virtual Account

BT

Permata Bank Virtual Account

A1

ATM Bersama

AG

Bank Artha Graha

NC

Bank Neo Commerce/BNC

BR

BRIVA

S1

Bank Sahabat Sampoerna
Retail

FT

Pegadaian/ALFA/Pos

A2

POS Indonesia

IR

Indomaret
E-Wallet

OV

OVO (Support Void)

SA

ShopeePay Apps (Support Void)

LF

LinkAja Apps (Fixed Fee)

LA

LinkAja Apps (Percentage Fee)

DA

DANA
QRIS

SP

ShopeePay

LQ

LinkAja

NQ

Nobu
Credit

DN

Indodana Paylater

Expiry Period

List the values ​​of the expiryPeriod parameter if Default or NULL. Transaction expiry period on minutes.

Payment Channel Default Expiry Period Duitku Expired Page
Credit Card 10 minutes
Virtual Account 1440 minutes > 1440 minutes
Retail 1440 minutes > 1440 minutes
OVO 10 minutes* 1440 minutes
Shopee Pay Apps 10 minutes 60 minutes
LinkAja Apps 10 minutes 1440 minutes
DANA 1440 minutes
Shopee Pay Account Link 30 minutes
OVO Account Link 15 minutes
QRIS Payment 10 minutes 60 minutes
Indodana Paylater 1440 minutes

Errors

HTTP Response

Error Code Error Name Description
400 Bad Request There is something wrong with the request that has been sent to the API.
401 Unauthorized Access being rejected because authorization.
404 Not Found The page or API is not recognized.
500 Internal Server Error Error in the server when trying to process the request.

API Response

Callback

Response Code Response Name Description
00 Success Transaction has been successfully paid.
02 Failed Transaction has been failed.

Redirect

Response Code Response Name Description
00 Success Transaction has been pay.
01 Process Transaction has not been pay.
02 Canceled/Failed Transaction canceled or not being paid.

Testing

Here is a list of dummy transaction credentials that can be used to make a transaction in the sandbox environment.

Credit Card

3D Secure Transaction

Card Type Credit Card Number Valid Thru CVV
VISA 4000 0000 0000 0044 03/33 123
MASTERCARD 5500 0000 0000 0004 03/33 123

Virtual Account

Demo transaction virtual account sandbox click-here.

Indodana Pay Later

Phone Number PIN
081282325566 000000

Pop API Demo

Pop API Demo click-here.

Sample Project

For a sample you can see at our Github link here.