Glossary

Sandbox

A sandbox is an isolated test environment that mirrors the production API but moves no real funds. You authenticate with test API keys instead of live ones, and every call you make — creating an invoice, submitting a payout, receiving a webhook — runs against test data that is kept entirely separate from your live account. The point is to build and exercise an integration end to end, watching how each request behaves and how the system responds, before a single real payment is ever in play.

01

What a sandbox is

A sandbox is a self-contained copy of an API's behaviour, set aside for testing. It accepts the same requests, returns the same response shapes, and walks through the same states as production, but it operates on test data that has no effect on anything real. Access is gated by a separate credential — a test API key — so a request you make in the sandbox can never reach your live account, and a live request can never touch test data. That separation is the whole value: you get a faithful rehearsal of the real system with none of the consequences.

The word borrows from a children's sandbox: a bounded space where you can build and knock things down freely because nothing outside it is affected. In software the same idea applies to side effects. In the sandbox you can submit a request that would move money in production, watch the system accept it and transition through its states, and learn exactly how your code reacts — without any money actually moving. Mistakes are cheap. A malformed payout, a request you forgot to retry, a webhook handler that throws: you find these in the sandbox, where the only cost is a fixed test.

A good sandbox is faithful in the parts that matter for integration. The same endpoints exist, the same fields are required, the same validation rejects the same bad input, and the same lifecycle states fire in the same order. What it deliberately does not reproduce is the real-world settlement underneath — there are no on-chain transactions and no real balances, because the goal is to test your code against the contract, not to test a blockchain. When your integration passes in the sandbox, you have confidence it will speak the protocol correctly in production.

02

Why it matters for crypto payments

Crypto payments are unusually unforgiving of integration bugs, which is exactly why a sandbox earns its place. An on-chain payout that goes out is settled and cannot be clawed back; there is no chargeback to reverse a mistake. A charge created for the wrong amount, a webhook acted on before its signature was verified, a payout released twice because a timeout was retried without protection — each of these can cost real funds the moment it happens against a live account. The sandbox is where you provoke all of them on purpose and fix them while they are free.

It also lets you rehearse the parts of the flow you cannot easily trigger on demand in production. You want to see how your code handles an invoice that is underpaid, overpaid, or expired before a real customer ever underpays one. You want to confirm your webhook handler verifies the signature, returns quickly, and is idempotent before real events depend on it. And you want to prove that submitting a payout, then retrying it after a dropped connection, results in exactly one transfer rather than two. The sandbox is the only place to drive these paths deliberately and repeatedly, which is what makes it the natural home for an integration's automated tests.

03

The sandbox on halfin

On halfin the sandbox is a test environment you reach with test API keys: a test key authenticates a request the same way a live key does, but it operates only on test data and never touches your live account or real funds. You can build the full integration against it — create invoices, submit single and mass payouts, and receive webhooks — and watch each one move through its real lifecycle before you switch any of it to live. Because the request and response shapes match production, the code you write in the sandbox is the code you ship; going live is a matter of swapping the key, not rewriting the integration.

The flows worth exercising first are the ones with the most states. On the invoicing side, create fiat-anchored invoices and drive them through the lifecycle so your handler is ready for the events halfin actually sends — invoice.confirming, invoice.paid, and the edge cases invoice.overpaid, invoice.underpaid, and invoice.expired — rather than only the happy path. On the payout side, submit a payout and confirm it enters pending approval, then test a retry: because the idempotency_key is a field in the request body, re-sending the same payout after a timeout is matched on that key and never pays a destination twice. Throughout, verify the HMAC signature on every webhook before acting on it, exactly as you will in production, so the verification path is proven in the sandbox and not in front of real money.

  • A sandbox is an isolated test environment that mirrors the production API but moves no real funds and keeps test data fully separate from your live account.
  • Access is gated by test API keys — a test key behaves like a live key but only ever touches test data.
  • It is where you drive the full lifecycle: create invoices, exercise underpaid / overpaid / expired paths, submit payouts, and verify HMAC-signed webhooks.
  • Going live is a credential swap, not a rewrite — the request and response shapes you build against match production.