> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kwugwo.africa/llms.txt
> Use this file to discover all available pages before exploring further.

# Testing in sandbox

> Build and test against sandbox, simulate payments, and go live.

The sandbox at `https://sandbox-api.kwugwo.africa` behaves like live,
but every PSP runs in its own **test mode**, so no real money moves.

## Set up sandbox

**1. Switch the dashboard to sandbox**

Sandbox has its own workspace, keys, checkouts and webhooks. Nothing
is shared with live.

**2. Connect a PSP with its test credentials**

Use the **test** (sandbox) API credentials from your PSP's dashboard,
not the live ones.

**3. Create a checkout**

Enable the mediums you want to test (for example bank transfer and
USSD) and route them to that PSP.

**4. Generate a sandbox secret key and register a webhook**

Use a tunnel such as `ngrok` or `cloudflared` so Kwugwo can reach
your local server.

Sandbox IDs end in `_t` (`ugw.VCvr.7K2qPmRtV9xLnQ8sD1cYwH_t`), so test
data is easy to spot in logs. See [IDs and prefixes](https://docs.kwugwo.africa/ids-and-prefixes.md#sandbox-suffix).

## Simulating a payment

Kwugwo doesn't hold or move money. Each payment is processed by your
PSP, so **how a sandbox payment completes depends on the PSP**:

* **Completed automatically.** For some PSPs, Kwugwo simulates the
  customer's payment in sandbox: the activity moves to `successful` on
  its own shortly after you create it, and the webhooks fire as they
  would in live.
* **Completed with the PSP's test tools.** For others, you complete the
  payment yourself, for example by "paying" a test virtual account or
  approving a test charge from the PSP's dashboard or test API. Use the
  `psp_external_id` on the activity to find the transaction there.

> [!TIP]
>
> Check your PSP's documentation for how to simulate payments in test
> mode, and which test bank accounts, USSD codes, OTPs and PINs it
> accepts.

If a sandbox activity stays in `requires_action`, the PSP is waiting for
that simulated customer step.

## What to test

| Scenario | How | Expect |
| - | - | - |
| Happy path | Pay the full amount. | `ugwo.successful`; ugwo `ugwo_successful`. |
| Abandoned bank transfer | Create a `bank_transfer` activity with a short `expires_at` and don't pay. | Activity `expired`; ugwo back to `requires_ugwo`. |
| Retry with another medium | After the expiry above, charge again with `ussd`. | New activity on the same ugwo. |
| Duplicate order | Create two ugwos with the same `ref`. | Second returns `409 ref_already_exists`. |
| Switch medium | Create a `bank_transfer` activity, then a `ussd` one on the same ugwo, and pay the USSD one. | Ugwo `ugwo_successful`; the transfer expires. |
| Double charge | Pay both open attempts. | Second gets `is_double_charge: true` and `ugwo.activity.double_charge_detected`. |
| Charge a paid ugwo | Create an activity on an `ugwo_successful` ugwo. | `409 already_processed`. |
| Webhook replay | Process the same delivery twice. | Your handler fulfils once. |
| Bad signature | Change one byte of the body. | Your handler returns `401`. |
| Refund | [Refund](https://docs.kwugwo.africa/refunds/create.md) a successful activity. | `refund.successful` or `refund.failed`. |
| Missed webhook | Stop your server, pay, restart. | Your reconciliation job catches it. |

Use your PSP's test tools to cover declines and short payments where it
supports them.

## Going live

> [!TIP]
>
> * Connect your PSP with **live** credentials in the **live** dashboard, and recreate your checkouts.
> * Generate a live secret key and public key; store them separately from the sandbox ones.
> * Register your production webhook URL and **set a signing secret**.
> * Change the base URL to `https://api.kwugwo.africa`.
> * Allowlist `176.97.192.227` if your webhook endpoint is behind a firewall.
> * Make sure fulfilment runs only through the [validate and fulfil](https://docs.kwugwo.africa/guides/validate-and-fulfil.md) checks.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.