DocsTesting
  1. Docs
  2. Guides
  3. Start

Testing

Test mode runs the whole flow, from order to webhook to refund, without moving money. Use it for every scenario your code has to handle.

De documentatie voor ontwikkelaars is beschikbaar in het Engels.

Test mode

  • Use a key that starts with vp_sk_test_. Everything created with it is a test object (livemode: false) and stays separate from live data.
  • Test mode works before your business is verified and offers every payment method, whatever is switched on for live mode.
  • The same validation applies as in live mode: amount limits per method, currencies, references unique per mode, idempotency.
  • Webhook endpoints are per mode. Add a test-mode endpoint to receive test events; see webhooks for testing through a tunnel.
  • Nothing is ever sent on a chain, to Cash App or to a card provider.

Simulate a payment

Open the pay_link of a test order and choose a method. The checkout shows a Test controls box:

ButtonMethodsResult
Simulate paymentcrypto, Cash App, cardThe order becomes paid; you receive order.paid.
Simulate half paymentcryptoHalf the amount arrives. The order becomes underpaid with amount_paid at half; you receive order.underpaid.
Simulate expiryany, while nothing is paidThe order ends as if its time ran out; you receive order.expired, the same event the expiry job sends in live mode.

A crypto test payment shows a fake transaction hash starting with test_. After the simulation the payer is offered the way back to your success_url, so you can test your return page too.

Simulate the other outcomes

ScenarioHowEvent
Payer never paysClick Simulate expiry, or create the order with "expires_in": 900 (the minimum, 15 minutes) and leave it.order.expired
You cancel the orderPOST /api/v1/orders/:id/void while it is unpaid.order.voided
Payer cancelsClick the cancel link on the checkout.None. The payer lands on cancel_url with velpay_status=canceled; the order stays open until it expires.
RefundPOST /api/v1/orders/:id/refunds on a paid test order, with any well-formed address as destination.refund.created, then refund.sent right away (no review in test mode)
Method not availableAn amount below the method's minimum, e.g. "methods": ["card"] with "amount": 500 USD.None; the API answers 400 amount_too_small (see errors)
Retried requestSend the same POST /orders twice with one Idempotency-Key.One order; the second answer has Idempotent-Replay: 1

Checklist before going live

  1. A paid order is fulfilled exactly once, even when the same event is delivered twice.
  2. Your code rejects a webhook with a wrong signature (change one byte of the body) and one older than five minutes.
  3. An underpaid order is not fulfilled automatically.
  4. An expired or voided order releases stock or reservations.
  5. Your return page doesn't mark anything paid by itself; it shows "payment being confirmed" until the webhook arrives.
  6. An API error (for example a key typo) shows the customer a clear message and gets logged with the Request-Id.
  7. You have added the live webhook endpoint and swapped in the live key. See going live.