Skip to main content
When a user pays online, the merchant can ask for 3D Secure (3DS) verification. Gnosis Pay sends your backend a challenge, you show it to the user in your app, and you submit their decision before the challenge expires.
3DS is webhook-driven. Don’t poll for a list of challenges. Wait for the webhook events in the steps that follow. See Configure webhooks.

Steps

1

Receive the challenge

Listen for these webhook events:Notify the user right away, for example with a push notification, because the challenge expires.
2

Show the challenge to the user

Display these details from the event, so the user can recognize the payment:
  • Amount and currency
  • Merchant
  • Expiry time
If you need the latest state, for example when the user opens the challenge some time after the notification, call GET /3ds/challenges/{challenge_id} with the cardholder_id.
3

Submit the decision

Send the cardholder_id and the user’s decision, approve or decline, to POST /3ds/challenges/{challenge_id}/decision.You must submit before the challenge’s expires_at.
4

Wait for the final state

A 202 response means the decision is being processed, not that it’s complete. Wait for the final state before you tell the user the payment was approved or declined.

Build a safe decision screen

Never approve a challenge after its expiry time, as shown by the API’s expires_at.
  • Prevent duplicate submissions. Disable the approve and decline buttons as soon as the user taps one, and send at most one decision per challenge from your backend.
  • Reject stale challenges. Before showing or submitting, check expires_at against the current time. If the challenge has expired, show it as expired and remove the buttons.
  • Show the latest state. If the user returns to a challenge later, read it again with GET /3ds/challenges/{challenge_id} instead of trusting what’s on screen.
  • Check ownership. Before reading a challenge or submitting a decision, check that the cardholder_id belongs to the user making the request.