Skip to main content
This guide takes you from nothing to a verified sandbox payment. You will initialise a transaction from your server, redirect the customer to hosted checkout, and confirm the outcome before fulfilling the order. The same code runs on live later with a different key and host.

Before you begin

You need a sandbox merchant account and a test secret key.
  1. Sign in or register at merchant.sandbox.vestrapay.app.
  2. Open Settings → Developers and copy the test secret key. It starts with sk_test_.
  3. Store it as an environment variable on your server. Never put a secret key in browser code, a mobile app or a public repository.

Sandbox and live use different hosts

The integration is identical in both environments. Only the key and the base URL change. A sandbox key sent to the live host, or the other way round, is rejected. Keep the base URL in configuration alongside the key so the two always change together.

Initialise, redirect and verify

1

Initialise the payment from your server

Send the amount and the customer’s details. The email is optional for hosted card checkout but required for pay with transfer, so send it whenever you have it.
2

Read the response

Initialise returns HTTP 201 and the session is in the data object:
Save data.reference on the order immediately. It is the only identifier you need later, for webhooks and for verification.
3

Redirect the customer

Send the browser to data.checkoutUrl. Hosted checkout lists the channels enabled for your account and handles card entry, 3-D Secure and the transfer countdown.
4

Handle the return and the webhook

When checkout finishes, the customer’s browser is sent to your callback URL with query parameters appended:
At the same time, Vestrapay posts a signed webhook to the endpoint you registered. Either signal can arrive first, and either can be repeated. Neither is proof of payment on its own. Both mean “go and check”.
5

Verify from your server

Look the payment up by reference with your secret key.
A successful lookup returns HTTP 200:

Anatomy of the initialise response

Accept payments covers every request field, including metadata and distribution.

Fulfilment rules

These rules keep you safe whichever signal arrives first. They matter more than any other part of the integration.
  1. Never fulfil from the browser return alone. Query parameters on the callback URL can be edited by anyone. Always call verify from your server.
  2. Fulfil only on success with the right amount. Check that data.status is success and that data.amount equals the amount you expected for that order. A mismatch should be held for review, not fulfilled.
  3. Fulfil once. Webhooks are retried and customers reload pages. Look the order up by reference, return early if it is already paid, and mark it paid inside a transaction or with a unique constraint. Verify a payment shows the pattern.
  4. Keep the reference on the order. It is how you reconcile, answer support requests and match webhooks to orders.
  5. Treat any other status as not paid. Pending and processing mean wait. Failed and abandoned are terminal. Let the customer start a new payment rather than reusing the old reference.

Next steps

Register a webhook

Receive payment outcomes without polling, and verify the signature.

Test payments

Mock cards and transfer simulation for the sandbox.

Split a collection

Send parts of each payment to different bank accounts.

Go live

KYB, live keys and the production checklist.