Source: https://docs.neropay.app/api/?environment=sandbox

Environment: Sandbox. Code examples: cURL.

10-2026 · Sandbox API reference

# Test the payment journey.  
No real money moves.

Use isolated test credentials to create a simulated checkout, choose its outcome and inspect test webhooks and API logs. This is a payment-flow simulator, not a full replica of the live API.

**/v2/sandbox**Dedicated test base path

**Separate keys**Live keys are not accepted

**3 outcomes**Success, failure, cancellation

**No real funds**No payouts or balance changes

 

**Sandbox reference selected.** These examples use only the test environment. Changing this documentation selector does not change your merchant account, other dashboard pages or live payments. Never use real card details or customer information here.

 

## Quick start

From a test key to a verified result in four steps.

1. Open [Developer → Sandbox mode → API](<https://eu.neropay.app/merchant/developer?mode=test&tab=api>) and generate your sandbox keys.
2. Create a payment from your server using the sandbox secret and a unique ` Idempotency-Key `.
3. Open the returned ` checkout_url ` and select a simulated result. The checkout does not collect card details.
4. Read the payment back and check Developer → Webhooks / API Logs with Sandbox mode on.

Configure a separate sandbox callback endpoint. A test success must never fulfil a live order. Check ` livemode: false ` and ` environment: sandbox `.

Create a sandbox payment

```bash
curl https://eu.neropay.app/v2/sandbox/hosted-payments \
  -X POST \
  -H "Authorization: Bearer YOUR_TEST_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: sandbox-order-0001" \
  --data '{
  "identifier": "sandbox-order-0001",
  "amount": 10,
  "currency": "GBP",
  "details": "Sandbox order"
}'
```

 

## Authentication & headers

Base URL: ` https://eu.neropay.app/v2/sandbox `

Send ` Authorization: Bearer YOUR_TEST_SECRET_KEY `. Sandbox secrets start with ` np_test_sk_ ` followed by 64 hexadecimal characters. The merchant is resolved from this key; do not send an account ID.

| Header | Sandbox requirement |
| --- | --- |
| Authorization | Bearer sandbox secret. Alternatively, use ` X-NeroPay-Secret-Key `. |
| Accept | ` application/json ` |
| Content-Type | ` application/json ` for POST requests. |
| Idempotency-Key | Required for create: 8–100 letters, digits or ` . _ : - `. |
| X-NeroPay-Public-Key | Optional. If supplied, it must match the sandbox secret. |
| X-NeroPay-Account | Not supported for sandbox creation. No connected-account routing. |

Sandbox API requests do not require the live write-signature headers. Callback signatures are separate and are described below.

Keep secrets server-side, including when using JavaScript examples. Live keys cannot authenticate in sandbox; test keys cannot authenticate against the live API. Rotating sandbox keys does not rotate live keys.

List sandbox payments

```bash
curl https://eu.neropay.app/v2/sandbox/hosted-payments?page=1 \
  -H "Authorization: Bearer YOUR_TEST_SECRET_KEY" \
  -H "Accept: application/json"
```

 

## Simulated payments & payment links

Three aliases share the same isolated payment records.

POST` /v2/sandbox/hosted-payments `

Create a simulated hosted payment.

POST` /v2/sandbox/payment-links `

Create the same simulated checkout through the payment-link alias.

POST` /v2/sandbox/transactions `

Create the same simulated checkout through the transactions alias.

### Request fields

| Field | Validation |
| --- | --- |
| identifier | Required string, maximum 100 characters. |
| amount | Required number, 0.01–10,000; rounded to two decimal places. |
| currency | GBP, EUR or USD (lowercase is also accepted). |
| details | Optional string, maximum 500 characters. |
| ipn\_url | Optional public HTTPS callback URL, maximum 1,000 characters. |
| success\_url / cancel\_url | Optional public HTTPS return URLs, maximum 1,000 characters each. |

Do not send ` account_id `, ` merchant_id `, connected-account routing fields, ` on_behalf_of `, ` card_number `, ` cvc `, ` cvv ` or ` payment_method `. They are rejected; no real payment instrument is used.

### Idempotency

The same key and same validated parameters return the existing test payment. Reusing a key with different parameters returns HTTP 409. Use a new key for a new simulated order. The aliases share this key space; repeated requests do not create separate copies.

Example create response · HTTP 201

```json
{
  "success": true,
  "data": {
    "id": "test_pay_<64-hex-id>",
    "account_id": "test_account_123",
    "identifier": "sandbox-order-0001",
    "reference": "NP-TEST-0123456789ABCDEF",
    "payment_reference": "NP-TEST-0123456789ABCDEF",
    "amount": "10.00",
    "currency": "GBP",
    "details": "Sandbox order",
    "status": "open",
    "payment_status": null,
    "payment_link": "https://eu.neropay.app/developer-sandbox/checkout/test_pay_<64-hex-id>/<token>",
    "checkout_url": "https://eu.neropay.app/developer-sandbox/checkout/test_pay_<64-hex-id>/<token>",
    "sandbox": true,
    "livemode": false,
    "environment": "sandbox",
    "expires_at": "2026-10-02 12:00:00"
  }
}
```

IDs, timestamps and tokens shown here are illustrative. Use the exact URL and ID returned by your request. Checkout URLs contain a capability token; keep them private.

 

## Lookups & pagination

GET` /v2/sandbox/hosted-payments `

List your test records.

GET` /v2/sandbox/hosted-payments/{id} `

Retrieve one test payment.

The same GET collection and GET-by-ID paths are supported under ` /payment-links ` and ` /transactions `. The ID is ` test_pay_ ` followed by 64 hexadecimal characters. Only records belonging to the authenticated merchant are returned.

Lists are newest first, 20 records per page. Use ` ?page=2 ` for the next page. The response has ` data `, ` page ` and ` last_page `; it does not use the live API pagination envelope.

Retrieve a sandbox payment

```bash
curl https://eu.neropay.app/v2/sandbox/transactions/test_pay_<64-hex-id> \
  -H "Authorization: Bearer YOUR_TEST_SECRET_KEY" \
  -H "Accept: application/json"
```

Empty list response

```json
{
  "success": true,
  "data": [],
  "page": 1,
  "last_page": 1
}
```

 

## Checkout simulator

Choose one terminal outcome. Nothing is charged.

| Choice | status | payment\_status | Event |
| --- | --- | --- | --- |
| Success | paid | succeeded | transaction.succeeded |
| Failure | failed | failed | transaction.failed |
| Cancellation | cancelled | cancelled | transaction.cancelled |

A fresh payment starts with ` status: open ` and ` payment_status: null `. Completion is single-use: choosing a result again does not create another event. Create a new payment with a new idempotency key to test another outcome.

Checkout expires after 24 hours (HTTP 410). The simulator presents a return button instead of automatically redirecting to an external site. Do not treat arrival at a return URL as proof of payment; verify the API result or signed notification.

This flow does not test real card authorisation, 3DS, settlement, refunds, terminals or bank payouts. It does not require Stripe test-card numbers.

Successful result fields

```json
{
  "status": "paid",
  "payment_status": "succeeded",
  "sandbox": true,
  "livemode": false,
  "environment": "sandbox"
}
```

 

## Sandbox webhooks & retries

Configure up to three endpoints in [Developer → Sandbox mode → Webhooks](<https://eu.neropay.app/merchant/developer?mode=test&tab=webhooks>). Only enabled endpoints subscribed to the selected outcome receive the JSON event.

Supported events: ` transaction.succeeded `, ` transaction.failed `, ` transaction.cancelled `. Sandbox endpoint management is in the dashboard, not a public sandbox webhook-management API.

### Verify JSON signatures

Compute lowercase hexadecimal ` HMAC-SHA256(timestamp + "." + raw_request_body, webhook_signing_secret) ` and compare it in constant time with ` X-NeroPay-Signature `. Read the timestamp from ` X-NeroPay-Timestamp `, enforce an appropriate freshness window and deduplicate ` X-NeroPay-Event-Id `. Do not re-serialize the JSON before verifying.

Headers also include ` X-NeroPay-Environment: sandbox ` and ` X-NeroPay-Delivery `. The event contains ` id `, ` type `, ` created_at `, ` livemode: false `, ` environment: sandbox ` and payment ` data `. Checkout URLs and capability tokens are excluded from the callback.

### Delivery behaviour

The first attempt runs after the simulator response. Failed or pending deliveries can be retried from Developer: at least one minute apart, at most five total attempts, and within ten hours of creation. Sandbox deliveries do not use the live automatic redelivery queue. A delivered event is not resent by this test retry action.

Return HTTP 2xx promptly. Test callbacks have a five-second timeout and a 64 KB response limit. Public HTTPS hostnames on port 443 with publicly routable IPv4 resolution are required; localhost, private/reserved IPs, embedded credentials, URL fragments and redirects are not supported.

Example JSON webhook headers

```
Content-Type: application/json
X-NeroPay-Environment: sandbox
X-NeroPay-Event-Id: evt_test_<event-hash>
X-NeroPay-Delivery: evt_test_<event-hash>
X-NeroPay-Timestamp: <unix-seconds>
X-NeroPay-Signature: <lowercase-hmac-sha256>
```

Use the endpoint's sandbox signing secret for JSON webhooks, not your live API key. Store callback results in a separate test system.

 

## Hosted-payment IPN

Supplying ` ipn_url ` when creating a payment adds a form-encoded callback for the simulated outcome. This is separate from the dashboard's JSON webhook endpoints; do not process the same order twice if you enable both.

Validate the form field ` signature ` using uppercase hexadecimal ` HMAC-SHA256(data.amount + identifier, sandbox_API_secret) `. Use the exact amount string received, including eight decimal places, not a floating-point reconstruction.

Top-level ` status ` is ` success `, ` failed ` or ` cancelled `; success is not named ` succeeded ` in this form payload. The form includes ` environment=sandbox ` and ` livemode=false ` as strings. ` data.currency ` is an object with ` code ` and ` symbol `.

Decoded form fields · example

```
status=success
identifier=sandbox-order-0001
environment=sandbox
livemode=false
signature=<UPPERCASE_HMAC_SHA256>
data[payment_trx]=NP-TEST-0123456789ABCDEF
data[amount]=10.00000000
data[currency][code]=GBP
data[currency][symbol]=£
data[account_holder]=Test Customer
data[charge]=0
data[status]=success
data[payment_type]=hosted
data[payment_timestamp]=2026-10-01 12:00:00
```

 

## Limits, errors & unavailable operations

| Limit | Value |
| --- | --- |
| API requests | 30 per minute per merchant. |
| Request body | 16 KB maximum. |
| New test payments | 100 in the preceding 24 hours. |
| Stored test payments | 2,000 maximum. |
| Webhook endpoints | 3 per merchant. |
| Checkout validity | 24 hours. |

Developer → API → Clear expired test records removes expired test payments and test logs/deliveries older than seven days. It does not delete keys, webhook settings or live data. Test API logs retain up to 500 recent entries and exclude credentials and raw request bodies.

### Common HTTP results

**401:** invalid/mismatched test credentials. **403:** unsupported operation. **404:** payment not found for this merchant. **409:** idempotency conflict. **410:** checkout expired. **413:** request too large. **422:** invalid fields or unsafe URL. **429:** rate, payment or storage limit. **503:** sandbox storage has not been installed.

Balances, transfers, payouts, refunds, bank accounts, connected-account routing, terminals and live resource changes are unavailable. Requests outside the supported paths/methods fail closed; they do not fall back to the live API. Old generic dry-run resource and terminal endpoints are not supported by this sandbox.

Blocked operation response · HTTP 403

```json
{
  "success": false,
  "error": {
    "code": "sandbox_operation_disabled",
    "message": "Sandbox supports simulated hosted payments and payment links only. Balances, transfers, payouts, refunds, account changes and live resources are unavailable."
  }
}
```

 

## Ready plugins & going live

Prefer an existing integration? Browse [ready-to-use plugins](<https://eu.neropay.app/merchant/integrations#npReadyPlugins>). Supported plugin flows do not require custom API development, but installation, account setup and credentials may still be required. Check each plugin's own sandbox compatibility; this simulator does not automatically add sandbox support to every plugin.

When ready, switch this reference to LIVE and follow the live authentication and endpoint contract. Configure separate production credentials and callbacks. Sandbox records and outcomes are not migrated into real transactions, and this selector does not activate live payments.

NeroPay API v2 · 10-2026 Sandbox reference. Examples simulate payments only; no real money moves.
