Skip to content

Payment Flow

The Lydia Gate integration is a two-step model:

  1. Server side (you): Create a payment request with POST /v1/payments (amount, terminal, returnUrl). The card is not part of this request. The response returns a paymentRef (a single-use payment reference) and a handoffUrl.
  2. Browser side (the buyer): Redirect the buyer’s browser/WebView, carrying the card and the paymentRef, to the handoffUrl (Lydia Gate 3DS Relay, on the pay.* origin). The 3D Secure relay, the POST to the bank’s 3D page, and the callback all run on that surface; once complete, the buyer returns to your returnUrl.

Hash generation, the bank’s 3D relay, callback handling, and capture happen on Lydia Gate’s side. You obtain the definitive result on the server side via GET /v1/payments and webhook.

  1. Create a payment request: send amount, terminalId, and returnUrl with POST /v1/payments (no card). The response returns paymentCode, status: initiated, paymentRef, and handoffUrl. See Create Payment.
  2. Hand off to Lydia Gate 3DS Relay: redirect the buyer’s browser/WebView, carrying the card you collected plus the paymentRef, to the handoffUrl via a form POST. Detail: Card Handoff.
  3. 3D Secure: Lydia Gate 3DS Relay starts the bank’s 3D relay; the buyer’s browser POSTs to the bank’s 3D Secure page and the buyer completes authentication. These steps run automatically on Lydia Gate 3DS Relay; you do not build a form.
  4. Callback + capture: the bank reports the 3D result to Lydia Gate; Lydia Gate processes the callback and performs the capture.
  5. Return: Lydia Gate 3DS Relay redirects the buyer’s browser/WebView to your returnUrl via 303. The result carried over returnUrl is not authoritative.
  6. Confirm the result: learn the definitive status via GET /v1/payments and webhook. Your decision (order confirmation, etc.) must always rely on this authoritative result.
server: POST /v1/payments (CARDLESS) ──► { paymentRef, handoffUrl, status: initiated }
browser/WebView: card + paymentRef ──POST──► [Lydia Gate 3DS Relay (pay.*)]
│ (Lydia Gate 3DS Relay POSTs to the bank's 3D)
[bank 3D Secure]
bank callback ──► [Lydia Gate: callback + capture]
303 (from Lydia Gate 3DS Relay) ──► returnUrl (result NOT authoritative)
server: webhook + GET /v1/payments ──────────────► definitive status

The flow is the same on both channels; the only difference is how you create the browser context:

  • Web: the buyer’s native browser form-POSTs to the handoffUrl; on return the browser navigates to returnUrl via 303.
  • Mobile: the merchant app collects the card on its own native screen, opens a WebView, and POSTs the card plus the paymentRef to the handoffUrl. 3D completes inside the WebView; in the end the WebView lands on returnUrl.

Single attempt: one payment = one card attempt

Section titled “Single attempt: one payment = one card attempt”

Treat a paymentRef as single-use: technically a limited number of card attempts is allowed on the same payment (see the card attempt limit below), but build your integration on “retry = new payment”. If the buyer abandons or fails 3D, that payment becomes failed/expired and the paymentRef cannot be reused. To retry, create a new payment request (POST /v1/payments): the “retry = new payment” approach. Detail: Card Handoff.