Skip to main content
Pay with transfer gives each payment its own one-time virtual bank account. The customer opens their banking app, sends exactly the amount shown to that account, and Vestrapay matches the inbound credit to the payment. There are no card details involved and no redirect to a bank, which makes transfer a good fallback when a card fails or an issuer is unavailable. The email address on initialise is required for this channel. If you did not send one, the request fails with payment.customer_email_required.

How it works

  1. You initialise the payment as usual.
  2. From checkout, you request a virtual account for that payment.
  3. You show the bank name, account number, account name and a countdown.
  4. The customer transfers the exact amount from their bank.
  5. Vestrapay detects the credit, completes the payment and posts payment.completed to your webhook.
  6. You verify and fulfil.
Hosted checkout performs steps 2 and 3 for you. The rest of this page is for custom pay screens.

Request an account

After initialise, request the account from checkout using the access code, not the secret key. There is no request body.
The account details are in the data object:
Display the bank name, account number, account name and a countdown driven by expiresInSeconds. Repeating the request while the account is still valid returns the same account, so it is safe to call again after a page refresh.
The customer must send the exact total shown on the pay screen, from their own bank account, before the countdown ends. Make the amount and the account number easy to copy, and say plainly that the amount must match.

Confirm the transfer

The customer pays at their bank, so your system learns about it asynchronously.
  1. Subscribe to payment.completed and payment.failed on your webhook.
  2. If your pay screen shows live progress, listen to the checkout events checkout.awaiting_transfer and then checkout.completed on GET /v1/payment/checkout/events.
  3. Verify the reference before you fulfil.
Do not mark the order paid because the customer says they have transferred, or because their bank app shows a success screen. Only a verified success counts.

When things go wrong

Test mode

In the sandbox, you do not need to move money. Call the simulate endpoint with the access code and choose the outcome:
The allowed scenarios are success, failed and abandoned. The endpoint is rejected on live with HTTP 403. When the GTBank sandbox is the active transfer processor, success creates a sandbox virtual account and funds it, so the payment completes through the same webhook path as production. That makes the simulation a faithful test of your webhook handler. See Test payments.