Integration Steps
Integrate Durianpay Checkout with your website to start accepting online payments from your customers. Durianpay supports a slew of payment methods such as bank transfers/VA, credit and debit cards, e-wallets (OVO, Dana, Linkaja) and others. Our checkout library provides all the essential features for integrating Durianpay Checkout with the client-side of your application.
💡 Learn about the best practices to follow while integrating Durian Checkout on your website.
Preparation
Create a Durianpay account
If you haven't done it already, click here to sign up. Sign up for Durianpay account here to retrieve API keys for Sandbox environment and to test integrations end-to-end.
Generate API Keys
Retrieve Sandbox API keys that will be used in next section(s) It is okay to have only the
sandbox
key for now. If you havelive
key, you can use it too.Check if view port meta tag is added in the tag of your webpage HTML code. If not, add the following line.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Steps Overview
- Step1: Create an order/token from the server
- Step2: Initialize Checkout
- Step3: Handle callbacks payment success and failures
- Step4: Webhooks / Store fields on your servers (Optional)
- Step5: Verify signature (Optional)
Step1: Create an order
/token
from the server
Use following endpoint to create an order
For advanced usecases, you can also just call our
/token
api to generate short lived client token from your servers and use it on your client to initiate checkout. Read more
var options = {
amount: "20000",
currency: "IDR",
order_ref_id: "order2314", // optional, your order reference
customer: {
customer_ref_id: "cust_001", // optional, your customer reference
given_name: "Imam Sugiarto",
email: "imam.sugiarto@koss.info", // mandatory
mobile: "08972638003",
address: { // mandatory for BNPL
receiver_name: "Jude Casper",
receiver_phone: "8987654321",
label: "Judes Address",
address_line_1: "Cambridge layout",
address_line_2: "Apartment #786",
city: "Bangalore",
region: "Jogupalya",
country: "Indonesia",
postal_code: "560008",
landmark: "Kota Jakarta Selatan"
}
},
items: [
{
"name": "LED Television",
"qty": 1,
"price": "925001.55",
"logo": "/static/tv_image.jpg"
}
]
};
// Create Orders
dpay.orders.create(options).then(resp => {
console.log(resp);
// order_id = resp.order_id;
})
.catch(error => {
console.log(error.err + ' | ' + JSON.stringify(error.data));
});
// Sample response
{
"id": "ord_A31sd3AwAgItmmXdp", "customer_id": "cus_rX2ABaMbZJ0050",
"amount": "20000",
"currency": "IDR",
"payment_option": "full_payment",
"status": "started",
"order_ref_id": "order2314",
"address_id": 3863,
"created_at": "2021-08-04T06:06:37.849813Z",
"updated_at": "2021-08-04T06:06:37.849813Z",
"metadata": {},
"access_token": "adsyoi12sdASd123ASX@qqsda231", ...
}
Read more: Learn more about Orders API.
Step 2: Initialize Checkout
This step will help you create a checkout button on your website which will initiate Durianpay checkout flow for your users seamlessly. The Durianpay checkout modal opens in place without redirecting user to any new tab or url, hence is a much better customer experience leading to better conversions and lower drop offs. You can configure the payment methods in backend with the help of your dedicated Customer success manager easily. Also, you can customize the look and feel at the time of onboarding itself which will forever apply to all your checkout sessions across all devices and users.
You should pass
order_id
andaccess_token
you received in previous step while creating Order. These need to be passed during checking initialization.
Put the following script
tag in your <head>
or at any other appropriate place.
After the above script is loaded, you can initialize sdk as below.
var dpay = Durianpay.init({
locale: "id",
environment: "production", // Value should be 'production' for both sandbox and live mode
access_key: "<ACCESS_TOKEN>",
site_name: "testmerchant.com",
dark_mode: <true/false>
pre_selected_payment_method: "VA", // only for flexible checkout
pre_selected_payment_code: "BCA", // only for flexible checkout
back_url: "http://merchant.com/redirect", // only for flexible checkout
order_info: {
id: "<ORDER_ID>", // e.g. ord_XASDadse2312asd31
customer_info: {
id: "cus_F5OHtM2L6u4292",
email: "jose@testmerchant.com",
phone: "+6285722173217",
name: "Jose",
}
},
container_elem: "pay-btn-container",
});
// If you want to show Durianpay checkout button, use this
// function to pass the parent container and css class
dpay.getCheckoutButton("pay-btn-container", "btn filled");
// OR
// If you want to trigger checkout from your button click handler
dpay.checkout();
Field | Data attribute | Description |
---|---|---|
environment | data-environment | production (default) |
locale | data-locale | en OR id (default) |
access_key | data-access-key | Your token which you have generated on server side by calling Durianpay APIs |
dark_mode | data-dark_mode | Set to true to enable dark mode |
order_info.id | data-order-id | Order Id received on your server side by calling Durianpay APIs |
site_name | data-site-name | Your domain name |
customer_info.id | data-customer-id | Customer Id received on your server side by calling Durianpay APIs |
customer_info.name | data-customer-name | Customer Name, if present |
customer_info.email | data-customer-email | Customer Email, if present |
customer_info.mobile | data-customer-mobile | Customer Mobile, if present |
method | data-method | getCheckoutButton , Checkout (default) |
container_elem | data-container-id | Id of container which should be root of checkout button and popup |
btn_class_name | data-btn-class-name | CSS class you want to apply for checkout button, if required |
Successful creation of order
returns an id (referred to as order_id
) that should be stored against the Order defined in your system.
Step3: Handle callbacks payment success and failures
You can pass javascript handlers which will be called when payment flow is completed in Durian Checkout flow. The onSuccess
method is fired when the transaction is successful. This is where you include any action you want to perform when the transaction is successful. The onFailure
method is fired when the transaction has failed. This is where you include any action you want to perform when the transaction is unsuccessful.
var dpay = Durianpay.init({
locale: "id",
environment: "production", // Value should be 'production' for both sandbox and live mode
access_key: "c6e8ed8e650b08bef67808617c25fbfa",
site_name: "test.com",
order_info: {
id : "ord_XASDadse2312asd31"
},
customer_id: "cust_001",
container_elem: "pay-btn-container",
onSuccess: function(response) { // this happens after the payment is completed successfully
var paymentId = response.payment_id; alert('Payment complete! Payment Id: ' + paymentId); // Make an AJAX call to your server with the reference to verify the transaction
},
onFailure: function() { alert('Transaction was not completed, transaction failed!'); },});
{
payment_id: "pay_XXXXX",
order_id: "ord_YYYYY",
amount: "20000",
currency: "IDR",
}
Alternatively, if you want to redirect users after payment to a separate url. You can use redirect_url
param to achieve the same.
var dpay = Durianpay.init({
...
redirect_url: "https://merchant.com/redirect" ...
});
Step4: Webhooks / Store fields on your servers (Optional)
Whenever certain transaction actions occur on your Durianpay Checkout integration, we trigger events which your application can listen to. This is where webhooks come in. A webhook is a URL on your server where we send payloads for such events. For example, if you implement webhooks, once a payment is successful, we will immediately notify your server with a payment.completed
event. Here is a list of events we can send to your webhook URL.
You can specify your webhook URL on your dashboard (or through your dedicated Customer success manager) where we would send POST requests to whenever an event occurs.
Valid events
payment.completed
payment.failed
, payment.cancelled
, order.created
, order.completed
{
"event": "payment.completed",
"data":{
"id": "pay_dAS123ad123Asd",
"signature": "9e892f199d026d06a56669e658a56f264610431d24e8b4d07f7bd46f6d5062d2",
"order_id": "ord_XXXXXXXXX",
"amount": "10000",
"currency": IDR,
"paid_at": "2016-09-30T21:10:19.000Z",
"created_at":"2016-09-30T21:09:56.000Z",
"metadata": {
"key": "value"
},
}
Step5: Verify signature on your server side (Optional)
You will get payment_id
through webhook callback (if configured). You should ideally try to validate the payment and store the details in your server/database against the order/transaction accordingly.
First, you need to get verification signature
from Durianpay which would have been provided to you in your webhook callback.
If you didn't receive it for any reason, you can call payment status check API from your server/backend which will respond back with signature
if status
of payment is completed.
This signature is computed by us using payment_id
, amount
and your secret key
. You need to create the hash on your server/backend where you have all these elements and match with the signature
provided by us.
Sample code for signature
generation
// Function to generate the signature for verification of payment
//use appropriate key if it is a sandbox order please use dp_test key and if it is a live order then use dp_live key
func GenerateSignature(paymentID string, amount string, accessKey string) (generatedSignature string) {
//message passed includes payment_id + “|” + amount. Amount is in “15000.00” format
secretData := paymentID + "|" + amount
// Create a new HMAC by defining the hash type and the key (as byte array)
h := hmac.New(sha256.New, []byte(accessKey))
// Write Data to it
h.Write([]byte(secretData))
// Get result and encode as hexadecimal string
generatedSignature = hex.EncodeToString(h.Sum(nil))
return
}
Test Integration
Test payments
Sandbox Mode
To simulate the charge API flow in sandbox mode, merchants can use dp_test_XXXXXXXXX
key. By default we will simulate the success scenario.
If you want to simulate the failure scenario, you should use the sandbox_options
json field in the request. This contains force_fail
and delay_ms
fields.
Field | Description |
---|---|
force_fail | bool Make this field as true in the request if you want to simulate failure scenario. |
delay_ms | integer If you want to simulate a delay in making the payment as success or failed, give a value in milliseconds in this field in the request. |
Note: Currently sandbox_options
is supported for VA, E-Wallet and RetailStore.
Example checkout initialization in sandbox.
var dpay = Durianpay.init({
locale: "id",
environment: "production", // Value should be 'production' for both sandbox and live mode
access_key: "<ACCESS_TOKEN>",
site_name: "testmerchant.com",
dark_mode: <true/false>
order_info: {
id: "<ORDER_ID>", // e.g. ord_XASDadse2312asd31
customer_info: {
id: "cus_F5OHtM2L6u4292",
email: "jose@testmerchant.com",
phone: "+6285722173217",
name: "Jose",
}
},
container_elem: "pay-btn-container",
sandbox_options: {
force_fail: true,
delay_ms: 10000,
}
});
// If you want to show Durianpay checkout button, use this
// function to pass the parent container and css class
dpay.getCheckoutButton("pay-btn-container", "btn filled");
// OR
// If you want to trigger checkout from your button click handler
dpay.checkout();
Verify Payment status
Through Dashboard
- Log into the Dashboard and navigate to Payments in sidebar.
- Check if a
payment_id
has been generated. If nopayment_id
has been generated, it means that the transaction has failed (and didn't even initiate from user's end)
Through APIs
Use following endpoint to do status check on a payment (Read more about Payment Status Check API)
curl -u <YOUR_SECRET_KEY> \
-X GET https://api.durianpay.id/v1/payments/pay_B14sdfwAdmmSDF24a/status \
-H "content-type: application/json"'
{
"data": {
"status": "completed",
"is_completed": true,
"signature": "9e892f199d026d06a56669e658a56f264610431d24e8b4d07f7bd46f6d5062d2"
}
}
Accept LIVE payments
After testing the flow of funds end-to-end in sandbox
mode, you can switch to the live
mode and start accepting payments from your customers. However, make sure that you swap the test API keys with the live keys.
- Log into Dashboard and switch to
Live
mode on the sidebar menu. - Navigate to Settings → API Keys to access your API key for live mode.
- Replace the
sandbox
API key with theLive
Key in the Checkout code and start accepting real-time payments.