# Test mode

> Build and verify your integration without moving money.

Source: https://docs.borga.is/test-mode

Every merchant gets test mode the moment it is created. Test keys (`sk_test_…`, `pk_test_…`) behave exactly like live keys, except that card payments run against the processor's staging environment and no money moves. Test and live data are completely separate: the same customer, product or subscription does not exist in both modes.

## Test cards

Use these cards on the checkout page with any future expiry and CVC `737`.

| Card | Number | 3-D Secure |
| --- | --- | --- |
| Visa | `4111 1111 4555 1142` | no |
| Visa | `4917 6100 0000 0000` | yes |
| Mastercard | `2222 4000 7000 0005` | no |
| Mastercard | `5454 5454 5454 5454` | yes |
| Maestro | `6771 7980 2100 0008` | yes |

Cards marked "yes" trigger a 3-D Secure challenge so you can test that flow. The staging environment approves any other well-formed card number too, so use the listed ones to be sure of the outcome.

## Apple Pay and Google Pay

Wallets show on the hosted page when the browser and device support them. Apple Pay needs a sandbox tester account and test cards from Apple's [sandbox testing guide](https://developer.apple.com/apple-pay/sandbox-testing/). Google Pay accepts a real card in a test wallet without charging it, or the cards from Google's [test card suite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite).

## Bank invoices

Bank invoices (krafa) go through your accounting provider, so testing them requires PayDay connected in test mode under **Settings → Accounting system** and bank invoices enabled under **Settings → Bank invoice**. The claim is created in PayDay's test environment and will not reach a real bank. Payment is detected by a poller that runs every 15 minutes, so the resulting `payment.succeeded` webhook is delayed in test mode just as it is in live mode. See [Bank invoices](/payments/bank-invoices).

## Redirect URLs on localhost

In test mode, `return_url` and `cancel_url` may use plain `http://` when the host is exactly `localhost` or `127.0.0.1`, and those hosts skip the allowed-domain check. Any other host must be HTTPS and listed under **Settings → Account → Allowed redirect domains**, in both modes.

## Webhooks on localhost

Webhook endpoints must be public HTTPS URLs; `localhost` and private addresses are rejected when you save the endpoint. To receive events during development, expose your local server with a tunnel such as `cloudflared tunnel` or `ngrok http 3000` and register the tunnel URL. The **Webhooks** page in the dashboard shows every delivery attempt with its response, and lets you retry one.

## What you cannot test

- **Refund settlement timing.** Refunds succeed instantly in staging; live refunds can take a few seconds to confirm and days to reach the card.
- **Real invoices.** With no accounting provider connected, Borga still records an `Invoice` object for each payment but nothing is booked anywhere.
- **Fees.** No fees are recorded in test mode.

## Moving to live

Live keys are gated on merchant verification. The checklist under **Settings → Live environment** walks you through it; see [Go live](/go-live).
