Testing

Use the staging environment to build and verify your integration before going live. Staging behaves identically to production — same endpoints, same response shapes, same webhook events — but no real money is moved.


Staging credentials

ItemValue
Base URLhttps://staging-api.withcapera.com/b2b
API key prefixsk_test_

Generate a test key from Settings → API Keys in the Capera dashboard.

export CAPERA_API_KEY="sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export CAPERA_BASE_URL="https://staging-api.withcapera.com/b2b"

Testing payments (inflow)

Static virtual accounts

  1. Create a customer with a unique reference
  2. Generate a static virtual account for that customer
  3. Simulate a deposit by transferring from a test bank account to the virtual account number
  4. Confirm your webhook endpoint receives customer.deposit.success
  5. Call GET /v1/deposits to verify the deposit appears in history

Dynamic virtual accounts

  1. Generate a dynamic virtual account for a specific amount
  2. Simulate a deposit of exactly that amount
  3. Confirm your webhook receives deposit.success
  4. Call GET /v1/deposits/validate/{reference} and check valid: true

MoMo collection

  1. List operators for the test country
  2. Call POST /v1/momo/collection with a test phone number and amount
  3. If the operator requires OTP, submit a test OTP via POST /v1/momo/collection/verify-otp
  4. Poll GET /v1/momo/collection/{reference} for the final status

Testing payouts (outflow)

NGN bank transfers

  1. Call GET /v1/banks and pick any bank from the list
  2. Call GET /v1/bank/resolve with a test account number to verify it resolves
  3. Call POST /v1/transfers/initiate — the transfer will be queued
  4. Poll GET /v1/transfers/{reference} and confirm it reaches SUCCESS
  5. Confirm your webhook receives transfer.success

Testing failure scenarios

ScenarioHow to trigger
Duplicate referenceSubmit two transfers with the same reference
Invalid bankUse a bankSlug that does not exist
Zero amountSet amount to 0

MoMo transfer

  1. List operators for the test country
  2. Resolve a test phone number
  3. Call POST /v1/momo/transfer
  4. Poll GET /v1/momo/transfer/{reference} for status

Testing webhooks

Set up a test endpoint

Use webhook.site or ngrok to expose a local or temporary HTTPS endpoint.

# Expose a local server on port 3000
ngrok http 3000
# → https://abc123.ngrok.io

Register a sandbox webhook subscription

curl -X POST https://staging-api.withcapera.com/b2b/v1/webhooks \
  -H "Authorization: Bearer $CAPERA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://abc123.ngrok.io/webhooks",
    "events": [
      "transfer.success",
      "transfer.failed",
      "deposit.success",
      "customer.deposit.success"
    ],
    "environment": "sandbox"
  }'

Save the secret from the response — you need it to verify signatures.

Verify your signature handler

Send a test payload through your handler with a known signature and confirm it passes verification. Then tamper with the payload and confirm it is rejected.

A correct verification handler should:

  • Parse t and v1 from the X-Webhook-Signature header
  • Concatenate {t}.{raw_request_body}
  • Compute HMAC-SHA256 using the webhook secret
  • Compare with v1 using constant-time equality
  • Reject if the timestamp is more than 5 minutes old (replay attack prevention)

Test retry behaviour

Return a 500 from your endpoint and confirm Capera retries the delivery. Check the event log via GET /v1/webhooks/events to see retry attempts and response codes.

curl https://staging-api.withcapera.com/b2b/v1/webhooks/events?status=failed \
  -H "Authorization: Bearer $CAPERA_API_KEY"

Manually retry a failed event:

curl -X POST https://staging-api.withcapera.com/b2b/v1/webhooks/events/{eventId}/retry \
  -H "Authorization: Bearer $CAPERA_API_KEY"

Integration checklist

Work through this before switching to production:

Authentication

  • API key is stored in an environment variable, not hard-coded
  • Requests to authenticated endpoints without a key return 401
  • Invalid key returns 401

Payments (inflow)

  • Static virtual account is generated and linked to a customer
  • Deposit arrives and customer.deposit.success webhook is received and processed
  • Dynamic virtual account is generated for a specific amount
  • Deposit arrives and deposit.success webhook is received and processed
  • GET /v1/deposits/validate/{reference} returns valid: true after a successful deposit

Transfers (outflow)

  • Bank list is fetched and cached
  • Account resolve is called before every transfer initiation
  • Transfer initiates and reaches SUCCESS status
  • transfer.success webhook is received and processed
  • transfer.failed webhook is received and handled (retry or notify)
  • Duplicate reference does not create a second transfer

Webhooks

  • Signature verification passes for valid payloads
  • Signature verification rejects tampered payloads
  • Endpoint responds 200 within 30 seconds
  • Failed deliveries appear in GET /v1/webhooks/events
  • Manual retry via POST /v1/webhooks/events/{eventId}/retry works

Error handling

  • 400 errors surface the error.message to your logs
  • 5xx errors trigger exponential backoff retry
  • 409 conflicts are handled without creating duplicates

Go live

Once your checklist is complete:

  1. Generate a sk_live_ key in the dashboard
  2. Update CAPERA_API_KEY and CAPERA_BASE_URL to production values
  3. Register a new webhook subscription with "environment": "production"
  4. Run one small real transaction end-to-end
  5. Monitor GET /v1/webhooks/events for the first few hours to confirm delivery

Contact [email protected] if you need help during go-live.


Did this page help you?