Testing
Test Credentials
There is no separate public sandbox environment. All credentials work against the production infrastructure.
For integration testing:
- Request test credentials from your account manager or platform administrator
- Use small amounts (e.g., IDR 1,000 =
amount_minor: 100000) - Test QRIS payments using any QRIS-compatible payment app (GoPay, OVO, etc.) by scanning the generated QR code
If your account is set up for local development, test credentials are available in the seeded data:
| Credential | Value |
|---|---|
legacy_client_id | TEST_CLIENT_001 |
legacy_client_secret | TEST_SECRET_001 |
| RSA private key | pga-api/tools/keys/legacy_test_private.pem |
| RSA public key | pga-api/tools/keys/legacy_test_public.pem |
| V1 API key | From GET /v1/merchants after seeding |
Testing Order Creation
V1 API
# Create a QRIS order for IDR 1,000
curl -X POST http://localhost:8080/v1/orders \
-H "X-API-Key: YOUR_TEST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"merchant_order_id": "TEST-001",
"amount_minor": 100000,
"payment_method": "QRIS",
"notify_url": "http://localhost:9999/callback"
}'
Legacy API
# Compute signature
SIG=$(echo -n "TEST_CLIENT_001|TEST-001|1000|TEST_SECRET_001" | sha512sum | awk '{print $1}')
# Create order
curl -X POST http://localhost:8080/api/order/create \
-H "Content-Type: application/json" \
-d "{
\"clientId\": \"TEST_CLIENT_001\",
\"orderId\": \"TEST-001\",
\"totalAmount\": 1000,
\"paymentType\": \"QRIS\",
\"signature\": \"$SIG\",
\"notifyUrl\": \"http://localhost:9999/callback\"
}"
Testing Webhooks Locally
Use a webhook testing service to inspect incoming payloads:
- ngrok —
ngrok http 9999to expose a local port - webhook.site — no-install, browser-based
Set the public URL as notify_url in your test orders.
Testing Disbursements (Legacy RSA)
Generate the test X-SIGNATURE using the test private key:
PHP — generate X-SIGNATURE for testing
<?php
$privateKeyPem = file_get_contents('pga-api/tools/keys/legacy_test_private.pem');
$privateKey = openssl_pkey_get_private($privateKeyPem);
$body = json_encode(['clientId' => 'TEST_CLIENT_001']);
$bodyHash = hash('sha256', $body);
$stringToSign = 'TEST_CLIENT_001|TEST_SECRET_001|' . $bodyHash;
openssl_sign($stringToSign, $rawSig, $privateKey, OPENSSL_ALGO_SHA256);
echo base64_encode($rawSig);
Checking Results
After creating a test order:
- Scan the returned QR code with a real payment app
- Confirm the webhook fires at your
notify_urlwithstatus: "PAID" - Query the order to verify status:
GET /v1/orders/:ref_code - Check the admin dashboard to see the order listed with
source_apibadge
Simulating Edge Cases
| Scenario | How to test |
|---|---|
| Duplicate order | Submit same merchant_order_id twice — expect DUPLICATE_ORDER (V1) or same order back (Legacy) |
| Signature mismatch | Change any character in the signature — expect Invalid Signature |
| Insufficient balance | Request disbursement larger than wallet balance — expect INSUFFICIENT_BALANCE |
| Expired order | Set expire_minutes: 1 and wait — order transitions to EXPIRED within 30 seconds of TTL |