Why the Sandbox Matters

  • Mirrors production ledger semantics.
  • Produces identical webhook payloads and retry behaviour.
  • Lets you rehearse go-live runbooks without touching live funds.

Setting Up

  1. Source sandbox credentials (PAYCA_CLIENT_ID, PAYCA_CLIENT_SECRET).
  2. Register webhook endpoints that point to an externally reachable URL (use an HTTPS tunnel such as ngrok if testing locally).
  3. Prefund mirror accounts via the sandbox wire instructions provided during onboarding.
  4. Ensure your logging/metrics stack captures webhook deliveries and API responses for later analysis.

Core Helper Endpoints

Endpoint Description
POST /sandbox/transactions Simulate authorizations, settlements, adjustments, cancels, refunds, declines.
POST /sandbox/cards/fund (Optional) Top up card shadow accounts directly in test scenarios.
POST /v1/webhooks/resend Replay failed deliveries after you restart your receiver.
GET /v1/users/stats Confirm balances changed as expected after scripted scenarios.

Transaction Recipes

Authorization → Settlement → Refund

# Authorization
curl -X POST "$PAYCA_BASE_URL/sandbox/transactions" \
  -H "Content-Type: application/json" \
  -H "x-client-id: $PAYCA_CLIENT_ID" \
  -H "x-client-secret: $PAYCA_CLIENT_SECRET" \
  -d '{
    "cardId": "<card-id>",
    "currency": "USD",
    "type": "authorization",
    "amount": "60.00"
  }'

# Settlement
curl -X POST "$PAYCA_BASE_URL/sandbox/transactions" \
  -H "Content-Type: application/json" \
  -d '{
    "cardId": "<card-id>",
    "currency": "USD",
    "type": "settle",
    "amount": "60.00",
    "linkedId": "<linked-id-from-auth>"
  }'

# Refund
curl -X POST "$PAYCA_BASE_URL/sandbox/transactions" \
  -H "Content-Type: application/json" \
  -d '{
    "cardId": "<card-id>",
    "currency": "USD",
    "type": "refund",
    "amount": "60.00",
    "linkedId": "<linked-id-from-auth>"
  }'

Expect three card_transaction webhooks (authorization, cleared, refunded) and matching account_transaction entries including fee events.

Partial Release

{
  "cardId": "<card-id>",
  "currency": "USD",
  "type": "adjustment",
  "amount": "10.00",
  "linkedId": "<linked-id-from-auth>"
}

Use adjustments to simulate tipping or partial cancellations.

Hard Decline

{
  "cardId": "<card-id>",
  "currency": "USD",
  "type": "decline",
  "amount": "20.00"
}

Decline webhooks help exercise customer notification flows and ensure fees are recognised even when spends fail.

Webhook Chaos Testing

  1. Temporarily return 500 from your webhook endpoint.
  2. Trigger a sandbox transaction.
  3. Verify PayCA retries with exponential backoff.
  4. Restore 204 No Content and ensure outstanding events drain.

Data Reset Strategy

  • Sandbox data persists. Use meta tags on users and cards (e.g., "meta": {"testRun": "2025-06-02"}) to find and clean up stale test artefacts.
  • Contact support to purge large datasets if required.

What’s Different From Production?

Area Sandbox Behaviour
Settlement timing Immediate (no batch delay).
Provider fees Optional but configurable to mirror prod.
Limits Higher rate limits for testing; still respect 50 rps burst.
Card numbers Non-PCI PANs mapped to test BINs.

Exit Criteria Before Go-Live

  • ✅ Every webhook path tested (authorization, settle, refund, decline, adjustments).
  • ✅ Revenue sweeps rehearsed end-to-end.
  • ✅ Webhook replay tested with /v1/webhooks/resend.
  • ✅ Monitoring & alerting configured for key webhook failure cases.

Move on to the Go-Live Runbook to prepare for production cutover.