Sandbox & Testing Guide
Panduan untuk menguji integrasi PSP di environment staging sebelum go-live.
Staging Environment
Base URL (Lookup API) : https://api-merchant-staging.kesles.com
Base URL (Events API) : https://api-merchant-staging.kesles.com
Kredensial staging (API Key ID + secret) diberikan terpisah oleh tim Kesles saat onboarding. Jangan gunakan kredensial production di staging.
- Merchant lookup (
/api/psp/v1/merchants/*): gunakanX-API-Key-ID/X-Timestamp/X-Signature - Event forwarding (
/psp/v1/events,/psp/v1/settlements): gunakanX-PSP-Key-ID/X-PSP-Timestamp/X-PSP-Signature
Test Merchant Data
Staging menyediakan merchant dummy yang bisa digunakan untuk testing:
| NMID | Bank Code | Status | Deskripsi |
|---|---|---|---|
ID102326873TEST1 | sesuai bank kamu | active | Merchant normal |
ID102326873TEST2 | sesuai bank kamu | active | Merchant dengan banyak outlet |
ID102326873TEST3 | sesuai bank kamu | suspended | Merchant tersuspend (akan return 404) |
NMID staging berbeda dengan production. Semua NMID staging memiliki suffix TEST.
Test Cases Wajib
1. Merchant Lookup by NMID
curl -X GET \
"https://api-merchant-staging.kesles.com/api/psp/v1/merchants/by-nmid/ID102326873TEST1" \
-H "X-API-Key-ID: $STAGING_KEY_ID" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: hmac-sha256=$COMPUTED_SIG" \
-H "X-Request-ID: $(uuidgen)"
Expected: 200 dengan payload merchant lengkap.
2. Merchant Lookup by UUID
curl -X GET \
"https://api-merchant-staging.kesles.com/api/psp/v1/merchants/{merchant_uuid}" \
-H "X-API-Key-ID: $STAGING_KEY_ID" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: hmac-sha256=$COMPUTED_SIG" \
-H "X-Request-ID: $(uuidgen)"
Expected: 200 dengan payload merchant + outlets.
3. NMID Tidak Ditemukan
curl "...by-nmid/ID999999999NOTEXIST" \
-H "X-API-Key-ID: $STAGING_KEY_ID" ...
Expected: 404 merchant_not_found.
4. Forward Transaction Event (Events API)
Signed_payload untuk Events API memakai format: method\npath\ntimestamp\nbody dengan timestamp berformat RFC3339 (bukan unix seconds). Header X-PSP-Signature berisi raw hex signature tanpa prefix hmac-sha256=.
TIMESTAMP=$(date -u +%FT%TZ)
BODY='{"external_event_id":"test-evt-001","event_type":"transaction.success","nmid":"ID102326873TEST1","gross_amount":75000,"transaction_code":"TRX-TEST-001","transaction_at":"2026-05-23T14:23:45Z","status":"success"}'
# Hitung signature dengan format: method\npath\ntimestamp\nbody
STRING_TO_SIGN="POST\n/psp/v1/events\n${TIMESTAMP}\n${BODY}"
SIGNATURE=$(printf "%s" "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$STAGING_PSP_SECRET" -hex | awk '{print $2}')
curl -X POST \
"https://api-merchant-staging.kesles.com/psp/v1/events" \
-H "X-PSP-Key-ID: $STAGING_PSP_KEY_ID" \
-H "X-PSP-Timestamp: $TIMESTAMP" \
-H "X-PSP-Signature: $SIGNATURE" \
-H "X-Request-ID: $(uuidgen)" \
-H "Content-Type: application/json" \
-d "$BODY"
Expected: 200 dengan { "status": "success", "flow": "A", "event_id": "<uuid>", "merchant_id": "<uuid>" }.
5. Idempotency — Event Duplikat
Kirim event yang sama dua kali dengan external_event_id yang sama.
Expected:
- Panggilan pertama:
{ "status": "success", "flow": "A", "event_id": "<uuid>", "merchant_id": "<uuid>" } - Panggilan kedua:
200dengan{ "status": "duplicate_skipped" }
6. Timestamp Expired (Replay Attack Prevention)
Kirim request dengan X-Timestamp (atau X-PSP-Timestamp) yang sudah lebih dari 5 menit lalu.
Expected: 401 timestamp_expired.
7. Signature Invalid
Kirim request dengan header signature yang salah.
Expected: 401 invalid_signature.
8. Data Isolation (Wajib Diverifikasi)
Coba lookup NMID yang tidak diterbitkan oleh bank kamu.
Expected: 404 merchant_not_found (bukan 403 — server tidak mengkonfirmasi apakah merchant ada atau tidak untuk bank lain).
9. Rate Limit
Kirim request by-nmid lebih dari 1.000 kali dalam 1 menit.
Expected: 429 rate_limit_exceeded dengan header Retry-After.
10. Delta Sync dengan Cursor Pagination
# Halaman pertama
curl "...merchants?limit=100&updated_since=2026-01-01T00:00:00Z" ...
# Ambil next_cursor dari response, lalu halaman berikutnya
curl "...merchants?cursor=eyJpZCI6ImJmYTMifQ==" ...
Expected: merchant terpaginasi dengan benar, has_more: false di halaman terakhir.
11. Webhook Signature Verification
Tim Kesles akan mengirim test webhook ke endpoint kamu di staging. Verifikasi bahwa:
X-Kesles-Signatureberhasil diverifikasi- Event
merchant.activateddiproses dengan benar - Duplicate webhook (
X-Kesles-Event-IDsama) diabaikan
12. Forward Settlement
curl -X POST \
"https://api-merchant-staging.kesles.com/psp/v1/settlements" \
-H "X-PSP-Key-ID: $STAGING_PSP_KEY_ID" \
-H "X-PSP-Timestamp: $TIMESTAMP" \
-H "X-PSP-Signature: $SIGNATURE" \
-H "Content-Type: application/json" \
-d '{
"external_event_id": "sett-test-001",
"nmid": "ID102326873TEST1",
"gross_amount": 1500000,
"settlement_date": "2026-05-23",
"completed_at": "2026-05-24T08:00:00Z"
}'
Expected: 200 dengan { "status": "success", "event_id": "<uuid>", "settlement_id": "<uuid>" }.
UAT Sign-off Checklist
Sebelum go-live, semua test case di atas harus lulus:
- Merchant lookup by NMID — 200 OK
- Merchant lookup by UUID — 200 OK
- 404 untuk NMID tidak ada
- Transaction event diteruskan — respons Flow A
- Event duplikat idempoten —
status: duplicate_skipped - 401 untuk timestamp expired
- 401 untuk signature invalid
- Data isolation verified
- Rate limit handling implemented
- Cursor pagination works
- Webhook signature verification implemented
- Settlement diteruskan berhasil
- Exponential backoff implemented
- Sign-off dari technical PIC Kesles
Kontak Tim Teknis Kesles
Untuk pertanyaan selama testing atau UAT, hubungi:
- Email: support@kesles.com
- Sertakan: bank code, API Key ID, request ID, dan error yang diterima