# Sandbox: test everything yourself

> Simulated transfers, every payment status, webhook pings, and the end-to-end test plan.

Sandbox keys start with `tph_test_`. Nothing moves real money, so run every test without asking.

## Simulate the buyer's transfer

- MCP: `simulate_transfer { payment_id, amount? }`
- CLI: `npx talo-hub sandbox pay <payment_id> [--amount <ARS>]`
- API: `POST /api/v1/sandbox/transfers { "payment_id": "…", "amount": 15000 }`

Transfers to a payment can be simulated as many times as you want; each adds to `paid`.

| Transfer | Status | Events |
|---|---|---|
| exact amount (default) | SUCCESS | payment.updated, payment.paid |
| less | UNDERPAID | payment.updated |
| more | OVERPAID | payment.updated, payment.paid |
| nothing until it expires | EXPIRED | payment.expired (when Talo reports it). Payments expire after the account's cancellation period (PATCH /api/v1/account `cancellation_period_minutes`, 5 minimum, scope full); there is no command to expire one on demand. |

Talo credits it in a few seconds; poll get_payment or list_events.

To see the whole flow before writing code, use the [demo shop](https://talopartnerhub.vercel.app/demo): it is a merchant of the hub like any other. Its order page shows the exact `sandbox pay` command for each payment.

## End-to-end test plan

1. Create a payment with an external_id from your system.
2. Simulate an UNDERPAID transfer (amount - 1), check your code does not fulfil the order.
3. Simulate the rest, check it becomes SUCCESS and your webhook handler fulfils it once.
4. Repeat the same webhook (or the same event id) and check nothing is fulfilled twice.
5. Refund it (needs scope full) and check the refund shows in get_payment.
6. Register your webhook and send a ping: `POST /api/v1/webhook-endpoints/{id}/test` (MCP test_webhook, CLI `webhooks test <id>`). It must answer 2xx after verifying the signature. This needs a public https URL that answers without a redirect or a login: a production domain, a tunnel, or a preview opened on purpose (Vercel protects previews and generated *.vercel.app URLs by default; see [talo-stack-nextjs-vercel](https://talopartnerhub.vercel.app/skills/talo-stack-nextjs-vercel/SKILL.md)). Forwarded local events are unsigned and don't count for readiness.
7. `check_go_live` / `GET /api/v1/readiness` should report ready.

## Local webhooks

`npx talo-hub events listen --forward-to http://localhost:3000/api/webhooks/talo` relays events to localhost. Those relayed events are **not signed** and carry `talo-hub-forwarded: 1`: accept them only in development. With `--json` it prints one event per line; the last few existing events come first with `"replayed": true`.

---
Human page: https://talopartnerhub.vercel.app/docs/sandbox · All pages: https://talopartnerhub.vercel.app/docs/index.md
