Skip to content

Testing

Don't ship to production untested. The sandbox environment is a full clone of the production API with mock payment gateways, instant settlement, and replayable webhooks.

Sandbox setup

Email [email protected] and request:

  • Sandbox LINK_SIGNING_SECRET
  • Sandbox WEBHOOK_SECRET
  • Sandbox seller UUID (we'll provision a test seller)

You'll get separate credentials from production. Never use production secrets in your test environment — and never commit either to git.

Sandbox base URLs

ResourceURL
APIhttps://sandbox-api.rekberpay.com
Web apphttps://sandbox.rekberpay.com
Statushttps://status.rekberpay.com

Everything else (paths, auth model, response shapes) is identical to production.

Test users

Create test buyers in the sandbox via the regular signup flow at https://sandbox.rekberpay.com/register. Pre-provisioned test accounts:

EmailPasswordRole
[email protected]BuyerSandbox123!Buyer with KYC verified
[email protected]BuyerSandbox123!Buyer without KYC
[email protected]SellerSandbox123!Seller with KYC verified

Mock payment

In the sandbox, the QRIS gateway is wired to a mock that auto-confirms after 2 seconds. You don't need to scan anything — just click "Pay with QRIS" and the webhook fires shortly after.

For tighter test loops, hit the dev-only mock-pay endpoint:

bash
curl -X POST https://sandbox-api.rekberpay.com/api/escrows/<id>/mock-pay \
  -H "Cookie: rekberpay_session=<test-buyer-session>"

This skips the gateway entirely. State goes from pending_paymentpaid instantly and the webhook fires.

Dev-only

mock-pay is rejected in production with 404 NOT_FOUND. Don't build it into your production code paths.

Scenarios you should cover

A good test suite covers the happy path plus the most likely failure modes.

1. Happy path

  1. Sign a link with valid params
  2. POST to /api/escrows/from-link
  3. Verify response: 201, escrow_url present
  4. Trigger mock-pay
  5. Receive payment.completed webhook
  6. Verify your system marked the order as paid

2. Invalid signature

  1. Sign a link
  2. Tamper with amount after signing
  3. POST → expect 403 INVALID_SIGNATURE

This catches accidental field reordering, encoding bugs, and wrong-secret deploys before they hit production.

  1. Set expires to 5 minutes in the past
  2. POST → expect 400 LINK_EXPIRED

4. Duplicate ref

  1. Create an escrow with ref: TEST_001
  2. Create another with the same ref → expect 409 DUPLICATE_REF

The second escrow should not be created.

5. Idempotency replay

  1. Create an escrow with Idempotency-Key: <uuid-1>
  2. Repeat the request with the same key
  3. Verify both responses have the same escrow.id
  4. Verify the second response includes Idempotent-Replay: true header

6. Webhook signature verification

Send your handler a forged webhook (POST with no signature field, or with signature: "00000..."). Verify your handler returns 401 and does not process the event.

7. Webhook retry

Have your handler return 500 once. Verify RekberPay retries within ~1 second. Then return 200 — verify the second attempt succeeds and the event is processed.

In sandbox, you can replay any webhook from the dashboard at https://sandbox.rekberpay.com/dashboard/webhooks/<event-id>/replay.

8. Out-of-order webhooks

In rare cases, webhooks can arrive out of order (e.g., escrow.received before escrow.sent if your handler is slow on the first event). Verify your handler can recover from out-of-order delivery — typically by trusting the status field in the payload over your local state.

9. Concurrent escrows

Create 10 escrows in parallel for the same seller. Verify all succeed and that no race condition causes duplicate ref values.

10. Partial failures

Disconnect the network mid-request. Verify your retry logic kicks in with the same Idempotency-Key.

Replaying webhooks

Every webhook delivery is logged in the sandbox dashboard. To replay:

  1. Open https://sandbox.rekberpay.com/dashboard/webhooks
  2. Find the event
  3. Click Replay

Useful for testing changes to your handler without re-running the full payment flow.

Load testing

The sandbox API is rate-limited (1000 req/min per IP). For load testing:

  • Start small (10 RPS) and ramp up
  • Use distinct ref values per request
  • Use distinct Idempotency-Key values per attempt
  • Don't hammer the same escrow with multiple state transitions in parallel

If you need higher limits, email [email protected] — we can raise sandbox limits temporarily.

CI integration

A typical CI flow:

yaml
# .github/workflows/integration.yml
test:
  steps:
    - run: pnpm install
    - run: pnpm test:unit
    - run: pnpm test:integration
      env:
        REKBERPAY_API_BASE: https://sandbox-api.rekberpay.com
        LINK_SIGNING_SECRET: ${{ secrets.SANDBOX_LINK_SIGNING_SECRET }}
        WEBHOOK_SECRET: ${{ secrets.SANDBOX_WEBHOOK_SECRET }}
        TEST_SELLER_ID: ${{ secrets.SANDBOX_SELLER_ID }}

Store secrets in GitHub Secrets / GitLab CI variables / your CI's vault. Never commit them.

Going to production

When you're ready:

  1. Email [email protected] with evidence your integration is stable (test results, error rate, etc.)
  2. Sign the partner agreement
  3. Receive production LINK_SIGNING_SECRET and WEBHOOK_SECRET
  4. Update environment variables (no code changes needed)
  5. Configure production webhook URL in the partner dashboard
  6. Run a single live transaction with a small amount before opening the floodgates
Sandbox stays available

Even after you go live, your sandbox credentials keep working. Use it for ongoing development and CI tests.

Common testing gotchas

GotchaFix
Signature works in test, fails in prodDifferent secret. Verify your env var resolution.
Tests pass locally, fail in CINetwork egress to sandbox-api.rekberpay.com is blocked. Whitelist the domain.
Webhooks don't arrive in CICI doesn't have a public URL. Use smee.io or ngrok tunnel, or mock the webhook handler in tests.
Idempotency cache hits when you don't want themUse a fresh UUID per test run; don't hardcode keys.
Mock-pay returns 404 in prodExpected — only available in sandbox. Use real payment in prod e2e.

Next steps

Released under the proprietary RekberPay license. Built for Indonesian merchants.