Sandbox (Test) Keys
Self-provisioned sk_test_ / pk_test_ credentials: rehearse your whole integration - API calls, hosted checkout, confirmations, webhooks - with zero real funds before you go live.
What sandbox keys are#
Sandbox keys are a separate credential type for testing, kept deliberately apart from your live keys:
sk_test_...- your sandbox secret key. Server-side, used exactly like your live API key (theX-Api-Keyheader onpay.u.cash/api.phpand the agents/v1API).pk_test_...- your sandbox publishable key, the twin of the Cloud token: safe for hosted test-checkout URLs, rejected by every server API.
Every record created under a sandbox key is tagged as a test record: no funds move, no fees are metered, nothing appears in live reporting, balances, or payouts. The reverse also holds: your live keys cannot create test artifacts, and sandbox keys are refused on live-only operations (refunds, payouts, balance reads, settings writes) with a clear 403 uxc_sandbox_key_rejected.
Creating keys#
In the console open Account → Sandbox (Test) Keys. Name each key (for example "Staging server"), then create a secret and/or publishable key. The raw key is shown exactly once at creation - it is stored hashed and cannot be recovered later. Rotate or revoke any key from the same card; a revoked key stops authenticating immediately.
Keys can also be managed from CI through the agents API: GET /v1/sandbox-keys to list, POST /v1/sandbox-keys {kind:"secret", label:"ci"} to create (raw returned once), POST ?key_id=N&rotate=key to rotate, DELETE ?key_id=N to revoke.
The full rehearsal flow#
- Create a test payment. With your
sk_test_key:POST /v1/resources {amount: 19.99, currency: "USD", test: true}(needs no wallet), orfunction=create-transactionon the merchant API. Everything the key creates is a test record. - Open the hosted test page. The resource's
checkout_urlrenders the real checkout with a TEST MODE banner and a Simulate payment button. - Simulate the payment. Each click (or
POST /v1/simulate-payment {challengeId}) advances the simulated confirmations; at the threshold the payment settles for $0 and your webhook fires withtest: truein the body. - Verify your handler. Check the HMAC signature exactly as for a live delivery (
t=,v1=over the raw body, see Webhooks), then confirm your dedup and fulfillment logic. Test deliveries are tagged in the webhook log and excluded from live views.
By default a simulated payment settles on the first call. Add test_confirmations (0-12, default 1) at resource creation to rehearse multi-confirmation settles step by step: with test_confirmations: 3 the payment stays pending at 1/3 and 2/3 and settles on the third advance - exactly the shape your integration sees while a real transaction waits on-chain confirmations.
Where test data lives#
Test payments live in their own console view: Sales → Sandbox. The main Payments list, the dashboard totals, analytics, CSV exports, and earnings all exclude test records, so your live reporting is never polluted. The Sandbox view also has a Simulate payment action on every pending row, so you can drive the flow without opening the hosted page.
Sandbox keys vs. testnet mode#
They answer different questions and compose freely:
- Sandbox keys simulate the payment itself - no chain activity at all, instant, unlimited, perfect for integration tests and CI.
- Testnet mode exercises the real detection stack against Bitcoin testnet / Ethereum Sepolia using testnet coins - closer to production mechanics, and account-wide while enabled.
Use sandbox keys for day-to-day development and webhook verification; use testnet mode when you specifically want to exercise real detection and confirmation behavior.
Rules and limits#
- Sandbox keys are throttled: 10 key creations per hour, 30 simulate calls per minute.
- Live-only operations (refunds, payouts, balance reads, settings writes,
get-cloud-token, cron) always return403for a sandbox key - the split is enforced server-side, not by convention. - A sandbox key never provisions or mutates account-level configuration; it can only create test records.
- When you are ready to go live, nothing to clean up: simply switch your integration to your live API key and Cloud token. Test records stay in the Sandbox view, quarantined from live reporting.