Skip to main content
CBPay runs on two environments: test (sandbox, simulated money) and live (production, real money). They are fully isolated — separate URLs, separate API keys, separate data — and expose exactly the same API, so an integration built against test works in live by swapping the base URL and the key.
Keys never cross environments: a pk_test_ key is rejected by live and a live pk_ key is rejected by test. There is no flag to flip — the environment is defined by where you point your requests.

How the test environment behaves

The test environment is fully self-contained: every corridor (payouts, payins, transfers, crypto, banking, cards, identity verification) is served by an internal simulator, so it never depends on any third party being up. Operations resolve deterministically:
  • Any operation you create is accepted and reaches completed after a few seconds (default ~10s), firing the same webhooks as live.
  • Specific magic values force every other outcome, so you can test your failure handling without guessing.

Magic values

Crypto deposits in test are credited from the dashboard (or by your platform administrator) — there is no real chain to send from. Withdrawals, balances, holds and webhooks behave exactly like live.

Sample PIX QRs (Brazil QR payout)

The test scan validates the BR Code exactly like production, so you need real PIX payloads. Use these (or generate your own with any static PIX QR generator):
Fixed amount 75.00 BRL (happy path)
Open amount (you choose the amount on confirm)
Fixed amount 80.99 BRL (the confirm fails — magic value .99)

What differs from live

  • No real money, cards, emails or SMS ever leave the test environment.
  • Accounts are born verified: every new test account starts with kyc_status: approved, so you can exercise every product immediately — no onboarding gate. In live, accounts are born unverified and must complete KYC/KYB before money can leave.
  • Accounts are born populated: every new test account starts with ~6 months of realistic demo history across all products (payouts, payins, transfers, crypto, swaps, cards, banking, contacts…), with balances, a reconciled statement and analytics ready to explore — you can build dashboards and reports before creating a single operation yourself.
  • Bank catalogs are fictitious (Simulated National Bank, …).
  • FX rates are real (same source as live) so amounts look realistic.
  • Test data is fully independent from live: nothing is copied from production. Treat the test dataset as disposable.

Test mode from the dashboard

The dashboard’s test/live switch moves your session between environments with one click — no separate registration and no second login. If your account does not exist in test yet, it is created automatically the first time you switch — born verified and populated with demo history, like every test account. API keys are managed per environment: create your pk_test_ keys while in test mode.

Testing webhooks in local development

Callback URLs must be public HTTPS: localhost, private IPs and .local domains are rejected when creating the subscription. To develop on your machine use an HTTPS tunnel:
Then create the subscription with that public URL (note the test base URL):
Failed deliveries retry up to 5 times with incremental backoff, so if your tunnel drops for a few minutes you will not lose the event. Always verify the HMAC signature — full recipe in webhooks.

Exercising every flow in test

Go-live checklist

Before pointing your integration at the live environment:
  • Swap the base URL to https://api.qbank.cl/platform and the key to your live pk_... (issued in live mode).
  • API keys live in a secrets manager (never in the frontend or the repo).
  • Every money operation sends an idempotency_key derived from YOUR internal id (not a random UUID per attempt).
  • On timeout or 5xx you do not retry with a new key: repeat with the same key or query the state with the GET.
  • You verify the HMAC signature of every webhook and answer 2xx fast (process async).
  • You handle non-final states (pending, processing) without assuming success — in live, settlement takes longer than the 10 simulated seconds.
  • You re-created your webhook subscriptions in live (test subscriptions do not carry over).
  • You query GET /v1/services to show only enabled products — see services.
  • You reconcile daily with GET /v1/movements or the statement.
  • You have a channel with the CBPay team for unassigned deposits or incidents.
In live every operation is real and irreversible once completed. A completed payout is already in the beneficiary’s account; the only reversal path is outside the API (contact the CBPay team).
No. Fees are charged against simulated balances, so you can exercise the full pricing logic without spending real money.
No. Each environment only accepts its own keys (pk_test_ in test, pk_ in live). A key from the other environment returns 401.
Every response carries the CBPay-Environment header (test or live), and GET /healthz returns livemode.
It is generated at account creation: ~6 months of deterministic, accounting-consistent demo operations across every product. It is not real data and it is not copied from production — the environments share nothing. Treat test data as disposable.
Yes — the exact same events, signed with your test subscription’s secret. Point them at your development tunnel.
Last modified on July 17, 2026