Skip to main content

Buat transaksi QRIS — Partner Transactions API

POST /api/v1/transactions/qris

Membuat QRIS dengan nominal yang sudah ditentukan (dynamic QRIS). QR string yang dihasilkan hanya bisa dibayar satu kali dan akan kedaluwarsa sesuai expiredAt.

Setelah dibuat, transaksi diteruskan ke payment provider yang dipilih berdasarkan groupId. Status pada response ini bukan status final transaksi; status akan diperbarui secara asinkron melalui webhook dari provider.

Autentikasi

Kirim header Authorization: Bearer <accessToken>, memakai accessToken yang didapat dari Partner Auth API. Butuh permission transactions:create.

Idempotency

Wajib kirim header Idempotency-Key (string non-kosong apa pun -- rekomendasi kami: UUID v4) di setiap request. Request kedua dengan key yang sama dan body yang sama persis mengembalikan response yang identik tanpa memproses ulang. Body berbeda dengan key yang sama menghasilkan 409 Conflict. Lihat panduan lengkap di Idempotency.

HeaderWajibDeskripsi
Idempotency-KeyYaUnik per percobaan transaksi (BUKAN per retry -- gunakan key yang sama untuk retry dari transaksi yang sama). Rekomendasi: UUID v4.

Request body

FieldTipeWajibDeskripsi
externalReferencestring (maks 100)YaID unik transaksi dari sisi kamu, untuk rekonsiliasi. Harus unik per partner.
amountinteger (Long)YaNominal dalam Rupiah (bilangan bulat, tidak ada sen). Minimum 100 (= Rp 100). Contoh: 15000 = Rp 15.000.
descriptionstring (maks 500)TidakKeterangan transaksi, bisa ditampilkan ke customer.
groupIdUUIDYaGroup tujuan. Provider yang dipakai ditentukan oleh Routing Configuration yang di-setup untuk group ini (gateway Primary dengan weight, Backup dengan urutan priority buat failover) -- request ini sendiri tidak punya parameter untuk memaksa provider tertentu, tapi kamu bisa atur pool provider & prioritasnya lewat Routing Configuration.
expiredAtISO-8601 UTCTidakWaktu kedaluwarsa QRIS. Kalau kosong, ditentukan provider (biasanya 30 menit).

Contoh request

Request
curl -X POST '{{BASE_URL}}/api/v1/transactions/qris' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"externalReference": "INV-2026-001234",
"amount": 150000,
"description": "Pembayaran order #INV-2026-001234",
"groupId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"expiredAt": "2026-07-07T10:30:00Z"
}'

Response sukses

201 Created

201 Created
{
"code": "00",
"message": "Success",
"data": {
"transactionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"partnerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"groupId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"externalReference": "INV-2026-001234",
"platformReference": "TXN-20260707-A1B2C3",
"transactionType": "PAYMENT",
"paymentMethod": "QRIS_DYNAMIC",
"status": "PENDING",
"amount": 150000,
"currency": "IDR",
"providerCode": "GDC",
"providerReference": null,
"qrString": "00020101021226...",
"expiredAt": "2026-07-07T10:30:00Z",
"description": "Pembayaran order #INV-2026-001234",
"createdAt": "2026-07-07T09:00:00Z",
"updatedAt": "2026-07-07T09:00:00Z"
},
"correlationId": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"requestId": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
"timestamp": "2026-08-13T09:15:30.123Z"
}

providerCode di atas hanya contoh -- provider yang benar-benar dipakai ditentukan otomatis saat runtime berdasarkan groupId kamu, bisa berbeda dari contoh ini.

Render data.qrString sebagai kode QR untuk ditampilkan ke customer. Pantau data.status lewat polling Detail transaksi sampai berstatus SUCCESS, FAILED, atau EXPIRED.

Response error

HTTP StatuscodeKapan terjadi
400VALIDATION_ERRORField wajib kosong/format salah, ATAU header Idempotency-Key tidak dikirim sama sekali.
400IDEMPOTENCY_KEY_REQUIREDHeader Idempotency-Key dikirim tapi isinya kosong/blank.
401INVALID_TOKENAuthorization header tidak ada, JWT tidak valid, atau kadaluarsa.
403ACCESS_DENIEDTidak punya permission transactions:create.
403GROUP_NOT_OWNEDgroupId tidak ditemukan atau bukan milik partner ini.
403GROUP_INACTIVEgroupId valid tapi statusnya sudah tidak aktif.
409DUPLICATE_TRANSACTIONexternalReference sudah pernah dipakai partner ini sebelumnya.
409IDEMPOTENCY_KEY_CONFLICTIdempotency-Key sudah dipakai sebelumnya dengan body request yang berbeda.
409IDEMPOTENCY_REQUEST_IN_PROGRESSRequest lain dengan Idempotency-Key yang sama masih diproses -- coba lagi sebentar.
422NO_GATEWAYTidak ada gateway pembayaran yang eligible untuk groupId ini saat ini.
422NO_CREDENTIALGateway ditemukan tapi belum ada credential yang terpasang untuk groupId ini.
500INTERNAL_ERRORGateway/provider pembayaran tidak bisa dihubungi atau timeout -- aman di-retry dengan Idempotency-Key yang sama.
Contoh -- 400 Validation Error
{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"data": {
"amount": "must not be null",
"groupId": "must not be null"
},
"correlationId": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"requestId": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
"timestamp": "2026-08-13T09:15:30.123Z"
}
Contoh -- 409 Idempotency Conflict
{
"code": "IDEMPOTENCY_KEY_CONFLICT",
"message": "Idempotency-Key 'a1b2c3d4-...' sudah pernah dipakai dengan request body yang berbeda.",
"correlationId": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"requestId": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
"timestamp": "2026-08-13T09:15:30.123Z"
}
Contoh -- 409 Duplicate Transaction
{
"code": "DUPLICATE_TRANSACTION",
"message": "External reference sudah digunakan: INV-2026-001234",
"correlationId": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"requestId": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
"timestamp": "2026-08-13T09:15:30.123Z"
}