Integrasikan pembayaran melalui satu API.
Client berkomunikasi hanya dengan Payantara. Konfigurasi pemrosesan internal tidak mengubah kontrak API client.
Quick Start
curl -X POST "https://gateway.payantara.com/api/v1/payments" \
-H "Content-Type: application/json" \
-H "X-Public-Key: pk_sandbox_xxxxxxxxx" \
-H "Authorization: Bearer sk_sandbox_xxxxxxxxx" \
-H "Idempotency-Key: ORDER-1001" \
-d '{
"order_id": "ORDER-1001",
"amount": 10000,
"payment_method": "QRIS",
"customer_name": "Budi",
"customer_email": "budi@example.com",
"customer_phone": "081234567890",
"expire_minutes": 15
}'Authentication
Kirim Public Key dan Secret API Key project pada setiap request yang membutuhkan autentikasi. Jangan menaruh secret di browser, aplikasi mobile, repository, atau log publik.
X-Public-Key: pk_live_xxxxxxxxx
Authorization: Bearer sk_live_xxxxxxxxx
Content-Type: application/jsonPublic key pk_... mengidentifikasi credential. Secret key sk_... membuktikan autentikasi server-to-server. Header X-Secret-Key dapat digunakan sebagai fallback bila server client tidak meneruskan header Authorization.
Rate Limiting
Request dibatasi berdasarkan alamat IP dan API key. Saat batas terlampaui, API mengembalikan HTTP 429. Terapkan exponential backoff dan jangan melakukan retry agresif.
Idempotency
Gunakan nilai unik dan stabil untuk setiap order. Mengulang request dengan key yang sama mencegah pembuatan pembayaran ganda.
Idempotency-Key: ORDER-1001Payments
Resource pembayaran utama memakai path /api/v1/payments. Endpoint yang tersedia saat ini adalah create, get status, dan cancel payment.
Create Payment
/api/v1/payments| Field | Type | Required | Keterangan |
|---|---|---|---|
order_id | string | Ya | ID order unik dari sistem client. |
amount | number | Ya | Nominal pembayaran dalam rupiah. |
payment_method | string | Ya | Kode channel dari endpoint payment methods. |
customer_name | string | Tidak | Nama pembayar. |
customer_email | string | Tidak | Email pembayar. |
customer_phone | string | Tidak | Nomor telepon pembayar. |
expire_minutes | integer | Tidak | Durasi kedaluwarsa pembayaran. |
return_url | URL | Tidak | URL tujuan setelah checkout. |
Get Payment Status
/api/v1/payments/{transaction_id_or_order_id}curl "https://gateway.payantara.com/api/v1/payments/ORDER-1001" \
-H "X-Public-Key: pk_live_xxxxxxxxx" \
-H "Authorization: Bearer sk_live_xxxxxxxxx"Cancel Pending Payment
/api/v1/payments/{transaction_id_or_order_id}/cancelCancel hanya berlaku untuk pembayaran yang masih dapat dibatalkan. Pembayaran yang sudah final tidak dapat dibatalkan melalui endpoint ini.
Payment Status
| Status | Arti |
|---|---|
PENDING | Menunggu pembayaran. |
PAID | Pembayaran berhasil dan final. |
EXPIRED | Pembayaran melewati batas waktu atau dibatalkan. |
FAILED | Pembayaran tidak dapat diproses. |
Payment Channels & Fees
/api/v1/payment-methodsGunakan endpoint ini sebagai sumber kebenaran untuk daftar channel, status ketersediaan, batas nominal, biaya, dan masa berlaku. Jangan hard-code ketersediaan channel.
curl "https://gateway.payantara.com/api/v1/payment-methods" \
-H "X-Public-Key: pk_live_xxxxxxxxx" \
-H "Authorization: Bearer sk_live_xxxxxxxxx"Gunakan kode channel yang dikembalikan API. Response create payment dapat memuat checkout URL atau QR string.
Tampilkan hanya bila channel dikembalikan dalam keadaan aktif untuk project Anda.
Payment Instructions
Response create payment dapat berbeda menurut channel. Render field yang tersedia, seperti:
payment_urlatau checkout URL;qr_stringuntuk QRIS;va_numberuntuk Virtual Account;instructionsuntuk langkah pembayaran;expires_atuntuk batas waktu pembayaran.
Webhooks
Payantara mengirim perubahan status ke callback URL project. Receiver harus menggunakan HTTPS, memverifikasi signature, memeriksa timestamp, dan menyimpan idempotency key.
X-Payantara-Webhook-Id: wh_xxx
X-Payantara-Idempotency-Key: idem_xxx
X-Payantara-Event: payment.paid
X-Payantara-Timestamp: 1780000000
X-Payantara-Signature: t=1780000000,v1=<hmac_sha256_hex>
X-Payantara-Signature-Version: v1
X-Payantara-Delivery-Attempt: 1Events
| Event | Keterangan |
|---|---|
payment.paid | Payment berubah menjadi PAID. |
payment.expired | Payment berubah menjadi EXPIRED. |
webhook.test | Event pengujian dari Developer Center. |
PHP Signature Verification
<?php
$secret = getenv('PAYANTARA_WEBHOOK_SECRET') ?: '';
$rawBody = file_get_contents('php://input');
$timestamp = (int)($_SERVER['HTTP_X_PAYANTARA_TIMESTAMP'] ?? 0);
$signature = $_SERVER['HTTP_X_PAYANTARA_SIGNATURE'] ?? '';
$idempotencyKey = $_SERVER['HTTP_X_PAYANTARA_IDEMPOTENCY_KEY'] ?? '';
if (!$timestamp || abs(time() - $timestamp) > 300) {
http_response_code(400);
exit('stale');
}
$expected = 't=' . $timestamp . ',v1=' .
hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);
if (!hash_equals($expected, $signature)) {
http_response_code(401);
exit('invalid signature');
}
// Simpan $idempotencyKey sebelum memproses event.
http_response_code(200);
echo json_encode(['success' => true]);Error Codes
Client hanya menerima kontrak error Payantara. Detail teknis internal tidak dikirim melalui response API, webhook, dokumentasi, atau dashboard client.
{
"success": false,
"error": {
"code": "PAYMENT_PROCESSING_FAILED",
"message": "Payment could not be processed. Please try again."
},
"request_id": "req_xxxxxxxxx"
}| HTTP | Code | Keterangan |
|---|---|---|
| 400 | INVALID_REQUEST | Request tidak dapat dibaca. |
| 401 | AUTHENTICATION_FAILED | API key tidak valid atau tidak aktif. |
| 404 | PAYMENT_NOT_FOUND | Payment tidak ditemukan untuk project tersebut. |
| 422 | VALIDATION_FAILED | Field request tidak valid. |
| 429 | RATE_LIMITED | Terlalu banyak request. |
| 503 | PAYMENT_PROCESSING_FAILED | Payment belum dapat diproses. |
| 503 | PAYMENT_CANCEL_FAILED | Payment belum dapat dibatalkan. |