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
| Item | Value |
|---|---|
| Base URL | https://staging-api.withcapera.com/b2b |
| API key prefix | sk_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
- Create a customer with a unique
reference - Generate a static virtual account for that customer
- Simulate a deposit by transferring from a test bank account to the virtual account number
- Confirm your webhook endpoint receives
customer.deposit.success - Call
GET /v1/depositsto verify the deposit appears in history
Dynamic virtual accounts
- Generate a dynamic virtual account for a specific
amount - Simulate a deposit of exactly that amount
- Confirm your webhook receives
deposit.success - Call
GET /v1/deposits/validate/{reference}and checkvalid: true
MoMo collection
- List operators for the test country
- Call
POST /v1/momo/collectionwith a test phone number and amount - If the operator requires OTP, submit a test OTP via
POST /v1/momo/collection/verify-otp - Poll
GET /v1/momo/collection/{reference}for the final status
Testing payouts (outflow)
NGN bank transfers
- Call
GET /v1/banksand pick any bank from the list - Call
GET /v1/bank/resolvewith a test account number to verify it resolves - Call
POST /v1/transfers/initiate— the transfer will be queued - Poll
GET /v1/transfers/{reference}and confirm it reachesSUCCESS - Confirm your webhook receives
transfer.success
Testing failure scenarios
| Scenario | How to trigger |
|---|---|
| Duplicate reference | Submit two transfers with the same reference |
| Invalid bank | Use a bankSlug that does not exist |
| Zero amount | Set amount to 0 |
MoMo transfer
- List operators for the test country
- Resolve a test phone number
- Call
POST /v1/momo/transfer - 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.ioRegister 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
tandv1from theX-Webhook-Signatureheader - Concatenate
{t}.{raw_request_body} - Compute
HMAC-SHA256using the webhook secret - Compare with
v1using 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.successwebhook is received and processed - Dynamic virtual account is generated for a specific amount
- Deposit arrives and
deposit.successwebhook is received and processed -
GET /v1/deposits/validate/{reference}returnsvalid: trueafter a successful deposit
Transfers (outflow)
- Bank list is fetched and cached
- Account resolve is called before every transfer initiation
- Transfer initiates and reaches
SUCCESSstatus -
transfer.successwebhook is received and processed -
transfer.failedwebhook is received and handled (retry or notify) - Duplicate
referencedoes not create a second transfer
Webhooks
- Signature verification passes for valid payloads
- Signature verification rejects tampered payloads
- Endpoint responds
200within 30 seconds - Failed deliveries appear in
GET /v1/webhooks/events - Manual retry via
POST /v1/webhooks/events/{eventId}/retryworks
Error handling
-
400errors surface theerror.messageto your logs -
5xxerrors trigger exponential backoff retry -
409conflicts are handled without creating duplicates
Go live
Once your checklist is complete:
- Generate a
sk_live_key in the dashboard - Update
CAPERA_API_KEYandCAPERA_BASE_URLto production values - Register a new webhook subscription with
"environment": "production" - Run one small real transaction end-to-end
- Monitor
GET /v1/webhooks/eventsfor the first few hours to confirm delivery
Contact [email protected] if you need help during go-live.
Updated 4 months ago