# Sandbox and test data

This page covers what you do inside the sandbox once you have access: seed test borrowers, loans, and payments through the same public API you use in production, and exercise the payment failure path so your integration handles declines before you go live. For the sandbox host, the environment model, and how sandbox differs from production at the environment level, see [Portals and environments](/getting-started/portals-and-environments); this page does not restate them.

## Getting sandbox access

Peach provisions your sandbox for you and provides it during onboarding. You cannot reset the sandbox yourself, and there is no public API endpoint to create, seed, or reset one — you reach it at the sandbox host with the credentials issued to you, and you populate it yourself through the API described below. For the sandbox base URL, see [Portals and environments](/getting-started/portals-and-environments); for the API key you authenticate with, see [Credentials and access](/getting-started/credentials-and-access).

## Seeding test data

You do not load test data through a special fixtures mechanism. You create it with the same public endpoints your production integration calls, pointed at the sandbox host. The minimal sequence to get a payable loan is: create a borrower, create a loan against a `loanTypeId`, activate the loan to disburse it, then create a payment transaction against it.

| Step | Method and path | What it creates |
|  --- | --- | --- |
| 1. Create a borrower | `POST /people` | The person the loan belongs to. Returns a `personId`. |
| 2. Create a loan | `POST /people/{personId}/loans` | A loan from one of your configured loan types. Returns a `loanId`. |
| 3. Activate the loan | `POST /people/{personId}/loans/{loanId}/activate` | Disburses principal and starts the loan. |
| 4. Create a payment | `POST /people/{personId}/loans/{loanId}/transactions` | A transaction (for example, a One Time Payment) against the loan. |


The request and response contracts for these endpoints are identical to production — the sandbox is the same API at a different host. This table is an index to sequence the calls; for the field-level contract of each endpoint, use the public API Reference. The endpoints are the ones you already use to onboard a real borrower, so seeding test data and building your production flow exercise the same code path.

## Test payment instruments and values

To move money against a sandbox loan you attach a payment instrument — a card or bank account — to the borrower, then reference it on the transaction. Which specific card numbers, bank routing/account numbers, and amounts are officially supported as client-facing sandbox test values is not settled by the API specification. Peach's internal end-to-end test suite carries fixture cards and accounts, but a value existing in an internal fixture is not the same as a supported, published test value — treat the officially client-facing set as unconfirmed until Peach provides it, rather than reusing internal fixtures.

## Exercising the decline and failure path

Your integration must handle a payment that does not succeed, so the sandbox lets you drive a card payment to a declined outcome. Two mechanisms are settled by the code.

**Card transactions route to the CyberSource sandbox.** Card payments process through CyberSource. In every environment except production, the processor runs against CyberSource's test host, `apitest.cybersource.com`; it switches to the live host, `api.cybersource.com`, only when the environment is production. A card charge you make in sandbox therefore reaches CyberSource's test environment, not the live card network.

**A declined card surfaces as a failed transaction.** When the processor returns a decline, the transaction lands in `Failed` status with the failure reason `CardDeclined`. The CyberSource processor maps decline response codes — general decline, payment refused, stolen or lost card, and related reasons — onto that single `CardDeclined` reason. Your integration reads the transaction status and failure reason to detect the decline.

The public API also exposes an administrative failure endpoint. `POST /people/{personId}/loans/{loanId}/transactions/fail` marks applicable transactions as `failed` and replays the loan from the earliest effective date of those transactions. Use it to force existing transactions into a failed state without depending on a processor decline.

The exact test card number or amount that forces a decline in the sandbox is a specific test value, not a code-settled contract — see [Test payment instruments and values](#test-payment-instruments-and-values) above and its VERIFY note.

## Sandbox versus production caveats

- **Test data is sandbox-only.** Borrowers, loans, and payments you create in the sandbox exist only there. Sandbox credentials do not authenticate against production and the reverse holds — see [Portals and environments](/getting-started/portals-and-environments).
- **Card processing is stubbed to a test host.** As above, sandbox card transactions reach CyberSource's test environment, so no funds move on the live card network. Do not expect production settlement behavior from a sandbox charge.
- **Other environment differences are not code-settled.** How long sandbox data is retained, whether rate limits differ, and which other external integrations are mocked rather than live are operational properties the specification does not fix. See [Portals and environments](/getting-started/portals-and-environments) for the environment-level comparison.


## See also

- [Portals and environments](/getting-started/portals-and-environments) — The sandbox and production hosts and how the environments differ.
- [Credentials and access](/getting-started/credentials-and-access) — The API key you authenticate seeding calls with.
- [Core concepts](/getting-started/core-concepts) — The borrowers, loans, and loan types you create as test data.