Environments: Sandbox vs. Production
Understand the difference between test and live environments, network mapping, and how to go live.
Environments: Sandbox vs. Production
Bag has two environments. They share the same API, the same dashboard, and the same SDK — the only difference is which API key you use.
| Sandbox | Production | |
|---|---|---|
| API key prefix | bag_test_sk_* | bag_live_sk_* |
| Real money | No | Yes |
| KYB required | No | Yes |
| Networks | base_sepolia, eth_sepolia, solana_devnet | base, ethereum, polygon, solana |
| Tokens | Testnet USDC | Real USDC |
| Settlements | Not available | Available after KYB |
Enforcement
The API enforces strict separation between sandbox and production:
- Test keys (
bag_test_sk_*) can only create resources on testnet networks. Attempting to use a mainnet network with a test key returns a400error. - Live keys (
bag_live_sk_*) can only create resources on mainnet networks. Attempting to use a testnet network with a live key returns a400error. - All resources (payment links, transactions, checkout sessions) are tagged with a
modefield (testorlive). - API responses include a
livemodeboolean so you can programmatically distinguish test from live data. - Webhook payloads include a top-level
livemodeboolean field.
Network mapping
Each production network has a testnet counterpart:
| Production | Testnet | Chain type |
|---|---|---|
base | base_sepolia | EVM |
ethereum | eth_sepolia | EVM |
polygon | — (no testnet) | EVM |
solana | solana_devnet | Solana |
When you're ready to go live, swap the network value in your payment link creation calls. Everything else stays the same.
Getting testnet USDC
To test payments, you need testnet USDC in a wallet. Here's where to get it:
| Network | Faucet |
|---|---|
| Base Sepolia | Circle USDC Faucet |
| Ethereum Sepolia | Circle USDC Faucet |
| Solana Devnet | Solana Faucet + devnet USDC mint |
You'll also need native tokens for gas (ETH on Sepolia, SOL on Devnet). Use the respective chain faucets.
Switching to production
When you're ready to accept real payments:
- Complete KYB verification — Submit your business details in the dashboard.
- Generate a live API key — Available in Developer Settings after KYB approval.
- Update your network values — Change
base_sepoliatobase(or whichever production network you want). - Update your API key — Swap
bag_test_sk_*forbag_live_sk_*in your environment variables. - Test with a small real payment — Verify the full flow before going wide.
Your webhook endpoints, payment link structure, and SDK code stay exactly the same. Only the key and network change.
Dashboard behavior
The Bag dashboard includes a Test mode toggle in the sidebar. When enabled:
- An orange "TEST MODE" banner appears across the top of the dashboard.
- All data views (payment links, transactions, settlements) are filtered to show only sandbox data.
- Stats and balances reflect test transactions only.
Toggle it off to return to your live production data. Both modes use the same dashboard URL — no separate accounts needed.
Webhook behavior
All webhook payloads include a livemode field at the top level and inside data:
{
"event": "payment.completed",
"livemode": false,
"data": {
"sessionId": "...",
"txHash": "0x...",
"amount": "1.00",
"network": "base_sepolia",
"livemode": false
},
"timestamp": "2026-03-01T12:05:00.000Z"
}Use the livemode field to route test events separately from production events in your webhook handler.
Checkout page
When a customer visits a checkout link created with a test key, the checkout page displays:
- A prominent "TEST MODE" banner at the top of the page
- A TEST badge next to the checkout header
- A testnet notice explaining that no real funds will be transferred