How to interface with Indonesia Payment API?
How to interface with Indonesia Payment API?
I. Overview of the Indonesian payments market
Indonesia, the largest digital economy in Southeast Asia, has seen explosive growth in its e-payment market in recent years. According to the latest data, Indonesia's digital payment transactions are expected to reach $400 billion by 2025. For companies wishing to enter the Indonesian market, it is crucial to understand and access the mainstream local payment methods.
Popular local Indonesian payment methods include:
- bank transfer: Real-time transfers offered by major banks such as Mandiri, BCA, BNI, etc.
- electronic wallet (e.g. for money): OVO, DANA, LinkAja, etc. dominate the scene
- Convenience Store Payment: The two major convenience store chains, Indomaret and Alfamart, have extensive coverage
- virtual account: the preferred collection method for many e-commerce platforms
II. Preliminary preparatory work
1. Entity of incorporation and compliance requirements
Before docking any Indonesian payment API, you need to make sure:
- Completed company registration in Indonesia (PT PMA or local company)
- Obtaining relevant financial licences issued by the Central Bank (OJK) (depending on the type of business)
- PCI DSS Compliance Certification (required for processing credit card transactions)
2. API documentation access
Mainstream Indonesian payment providers provide good developer documentation:
Official developer portal example:
- Xendit: developer.xendit.co
- Doku: doku.com/developer
- Midtrans: docs.midtrans.com
It is recommended that you first read the API reference documentation and technical specification documents in their entirety.
III. Detailed steps for technology docking
Step1: API Authentication Configuration
Most Indonesian payment gateways use OAuth 2.0 or Basic Auth authentication:
# Python Example - Xendit API Authentication
import requests
api_key = "your_live_secret_key"
headers = {
"Authorization": f "Basic {api_key}",
"Content-Type": "application/json"
}
response = requests.get(
"https://api.xendit.co/available_virtual_account_banks",
headers=headers)
Important Safety Tip:
✔️ Never expose API keys on the front end!
✔️ Managing Sensitive Information Using Environment Variables
✔️ Regular rotation of access vouchers
Step2: Webhook Setup Guide
Correctly handling asynchronous notifications is a core aspect:
// Java Spring Boot Sample - Midtrans Notification Handling
@PostMapping("/payment-notification")
public ResponseEntity handleNotification(
@RequestBody NotificationPayload payload, @RequestBody
@RequestHeader("X-Signature") String signature) {
// 1. Verify the validity of the signature
if(!SignatureTool.verify(payload, signature, merchantKey)){
return ResponseEntity.status(403).build();
}
// 2. Handle business logic...
}
The validation mechanisms that must be implemented include:
✅ HMAC-SHA256 signature verification
✅ IP whitelist filtering (common gateway IPs need to be pre-configured)
✅ Idempotency processing (to prevent duplicate notifications leading to multiple billings)
Step3: SDK Integration Best Practices
It is recommended to give priority to using the official SDK to improve development efficiency:
Node.js Integration with Midtrans Example.
const midtransClient = require('midtrans-client');
let snap = new midtransClient.Snap({
isProduction : false,
serverKey : 'YOUR_SERVER_KEY',
clientKey : 'YOUR_CLIENT_KEY'
});
snap.createTransaction(parameter)
.then((transaction)=>{
console.log(transaction);
})
The address for obtaining SDGs in each language is usually located at.
/docs/sdk | /developer-tools | /integration-libraries
Step4: QRIS Harmonised Standard Access
Starting in 2023, all merchants must support the QRIS interoperability standard:
Example of a call parameter.
{
"qr_type": "dynamic",
"amount":150,000.
"merchant_city": "Jakarta".
"seller_name": "YourStoreID"
}
Response Result Parsing Focus Fields.
- qr_string → Base64 encoded QR code image data
- expiration_time → UTC format expiration time stamp
- transaction_id → unique identifier for subsequent queries
Fourth, the whole process of testing and on-line
1️⃣ Sandbox Environment Test Points.
test scenario | Expected results | Tool Recommendations |
---|---|---|
Amount Boundary Value | -Minimum 0.01 IDR -Maximum 1 billion IDRs successfully processed |
Postman Newman |
Concurrent requests | <500ms response time No data competition issues |
JMeter |
2️⃣ Production Environment Checklist.
☑️ SSL certificate valid and TLS version 1.3+
☑️ Failover mechanism deployed (minimum dual AZ architecture recommended)
☑️ BI mandated daily reconciliation statement functionality verified
V. Quick checklist of common error codes
Prioritise these high-frequency errors when encountering problems.
HTTP status code | Analysis of causes | prescription |
---|---|---|
402 PAYMENT_REQUIRED | Insufficient balance/overspending of limits | Contact acquirer to adjust limits |
409 CONFLICT | Duplicate Order Number (idempotency-key duplicate) | Generate a new UUID as a request identifier |
451 UNAVAILABLE_FOR_LEGAL_REASONS BPJSTK/KYC incomplete Submission of complete tax registration certificate |
VI. Performance Optimisation Recommendations
Special considerations for high traffic scenarios.
▸ Bulk query interface instead of a single request (e.g., using the/batch_status?reference_ids=id1,id2
)
▸ Enable long connection hold (Keep-Alive timeout ≥ 60s recommended)
▸ Local caching of static data (TTL set to 24h+ for bank list rate tables etc.)
VII. Expanding learning resources
Advanced developers can delve into.
→ Bank Indonesia Payment System Regulation No21/2019 Original Regulation
→ ISO 20022 message standard in clearing systems
→ Technical implementation of the Tokenisation scheme to reduce PCI audit coverage
VIII. Indonesia Payment API Advanced Function Development
1. Phased programme of payments
Indonesian e-commerce platforms generally support instalment payments (Cicilan), technical implementation points:
"`php
// PHP Example - Akulaku Staging Interface Calls
$client = new \GuzzleHttp\Client();
$response = $client->post('https://api.akulaku.com/v2/installment', [
'headers' => [
'X-Api-Key' => env('AKULAKU_KEY'),
'Accept' => 'application/json'
],
'json' => [
'order_id' => uniqid(),
'amount' => 5000000,
'tenor_options' => [3,6,12], //optional number of instalment months
'customer_phone' => '+62812XXXXXXXXX'
]
]);
// Parsing the returned staging options
$plans = json_decode($response->getBody())->available_plans;
“`
Description of key parameters:
- tenor_options: must contain the number of periods supported by the bank (usually 3/6/12 for BCA)
- merchant_fee: need to clearly show the interest charges borne by the merchant or paid by the user
2. Deep integration of the DANA e-wallet
DANA API Special Requests Handling Process:
"`javascript
// Node.js DANA OAuth2.0 Authorisation Example
const crypto = require('crypto');
function generateDanaSignature(payload, secret) {
return crypto.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex').
}
const authPayload = {
grant_type: "client_credentials",
client_id: "YOUR_DANA_MERCHANT_ID",
timestamp: new Date().toISOString()
};
const signature = generateDanaSignature(authPayload, "YOUR_SECRET");
“`
Special attention:
- Timestamp should be accurate to the millisecond level and the time difference with the server should not exceed 5 minutes.
- redirect_url must use HTTPS and the domain name has been filed in DANA merchant backend
IX. Localised Compliance Enhancement Strategy
1. BPJS Kesehatan social security automatic deduction
Technical specifications for interfacing with government health insurance systems:
|FieldName|Type|ValidationRules|
|—|—|—|
|bpjs_number|string|13 digits + 1 check digit|
|payment_month|date_format `YYYYY-MM` cannot be later than the current month|
Example of a request message:
"`xml
“`
Important: This interface is only available to payment institutions with a PJPAB licence.
2. Value added tax (VAT) calculation in real time
Different tax rates are automatically applied based on the commodity category:
"`java
public class IndoVatCalculator {
private static final Map
"basic_needs", new BigDecimal("0"), //basic food exemptions
"premium_goods", new BigDecimal("11"), //new tax rate for 2024
"digital_services", new BigDecimal("11")
);
public Invoice calculate(Order order) {
BigDecimal rate = VAT_RATES.get(order.getGoodsType());
return new Invoice(
order.getAmount(),
order.getAmount().multiply(rate).divide(100)
);
} }
“`
Tax Rule Notes:
→Additional 10%-40% surtax will be levied on Luxury Goods.
→ Application of Reverse Taxation Mechanism (RCM) to Cross-Border Digital Services
X. Monitoring and Disaster Recovery Monitoring and disaster recovery programme design
A list of monitoring metrics recommended for deployment:
*Prometheus configuration fragment*
“`
scrape_configs.
- job_name:'indonesia_payment'
metrics_path:'/actuator/prometheus'
static_configs.
targets:['gateway-service']
rule_files.
- rules/payment_alerts.yml # predefined rules include.
#api_error_rate >5%
#settlement_delay >4h
“`
Recommended for multi-live architectures:
“`
Dual Deployment Jakarta Main Centre + Batam Disaster Recovery Centre
⇒ MySQL Group Replication Keeping Data in Sync
⇒ AWS Global Accelerator Enables Intelligent Route Switching
A failover is automatically triggered when the following conditions are detected:
✖ BCA bank channel consecutive failures exceed thresholds
✖ Telkomsel backbone latency >800ms for more than 15 minutes
XI. Developer Frequently Asked Questions FAQ
Q1:Why is the status of my demo account not updated after receiving payment?
►99% because DOKU's POST notification was not handled correctly, check that the Content-Type should be `application/x-www-form-urlencoded`.
Q2:How to get Corporate ID of BCA Bank?
►The SKDP company registration documents need to be submitted to BCA, the approval cycle is usually 7 working days
Q3:How to solve the error "USER_BLOCKED" in OVO payment?
►Indicates end-user account abnormality, directs customer to contact OVO customer service hotline 1500965
XII. Notes on Version Upgrade
2024 Major Change Alert:
◉ QRIS standard upgraded to v2.1 (old version to be discontinued in June)
◉ BI mandates UAIC unique audit identifier for all transactions
◉ GoPay to gradually migrate to LinkAja unified platform
It is recommended to subscribe to each payment provider's technical announcement mailing list to get timely updates on what is happening. By following the systematic approach of this guide, developers can efficiently complete the integration of the Indonesian payment ecosystem.