Process 3DS Payments (Redirect)
This guide walks through authenticating a card payment with 3D Secure using the redirect transport: Credova creates the 3DS session server-side, and any challenge is presented by navigating the cardholder to a hosted page. When the challenge finishes, the cardholder is returned to a callback route you host. For a conceptual overview and the comparison with the iframe transport, see 3D Secure.
The redirect transport requires no JavaScript SDK on your checkout page, which makes it a good fit for native mobile webviews and server-rendered checkouts.
Getting Started
To get started, you will need a Credova Account.
Get your Secret Key
Your backend will need your Secret Key. Go to your Developers section, click Reveal for your Secret Key, and copy the value.
confirm and complete calls below.Prerequisites
This guide assumes you have:
- A collected card. Follow Collect Cards to obtain a
card_…payment method. - 3DS enabled on your account. 3DS is off by default — contact Credova to enable it.
- Two callback routes you control — a success URL and a failure URL — that Basis Theory will return the cardholder to after the challenge.
https://merchant.example.com/3ds/success/pi_2YKewBonG4tgk12MheY3PiHDy.Step 1 — Confirm the Payment Intent
From your backend, call Confirm Payment Intent with the three_d_secure block set to the redirect transport and your callback URLs. The session is created server-side, so no session_id is supplied here.
curl 'https://api.publicsquare.com/payment-intents/pi_2YKewBonG4tgk12MheY3PiHDy/confirm' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"three_d_secure": {
"transport": "redirect",
"success_url": "https://merchant.example.com/3ds/success/pi_2YKewBonG4tgk12MheY3PiHDy",
"failure_url": "https://merchant.example.com/3ds/failure/pi_2YKewBonG4tgk12MheY3PiHDy"
}
}'
The response is a PaymentIntent. There are two outcomes:
Frictionless — authentication succeeded with no challenge. The intent is succeeded and you are done.
{
"id": "pi_2YKewBonG4tgk12MheY3PiHDy",
"status": "succeeded",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
...
}
Challenge required — the intent is requires_action and next_action.three_d_secure carries a redirect_url.
{
"id": "pi_2YKewBonG4tgk12MheY3PiHDy",
"status": "requires_action",
"next_action": {
"type": "three_d_secure",
"three_d_secure": {
"session_id": "<SESSION_ID>",
"transport": "redirect",
"redirect_url": "https://app.basistheory.com/3ds/..."
}
},
...
}
Step 2 — Redirect the cardholder
When the intent is requires_action, navigate the browser to next_action.three_d_secure.redirect_url. The hosted page handles the challenge and then returns the cardholder to your success_url or failure_url.
window.location.href = nextAction.redirect_url;
Step 3 — Handle the callback and complete
When the cardholder lands on your callback route, read the session id (from your stored state or the path) and call Complete Payment Intent 3DS Challenge from your backend. Credova retrieves the authentication result and submits the payment to the processor.
curl 'https://api.publicsquare.com/payment-intents/pi_2YKewBonG4tgk12MheY3PiHDy/three_d_secure/complete' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"three_d_secure": {
"session_id": "<SESSION_ID>"
}
}'
session_id from the confirm response, retrieve it from the intent's next_action.three_d_secure.session_id via Get Payment Intent by ID before calling complete.The response is the final PaymentIntent, succeeded when authentication and authorization both pass, or failed with a last_payment_error otherwise.
{
"id": "pi_2YKewBonG4tgk12MheY3PiHDy",
"status": "succeeded",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
...
}
Testing
Use the test cards in 3D Secure → Testing to exercise frictionless, challenge, and failure scenarios in the test environment.
Conclusion
You have authenticated a card payment with 3DS via redirect. Next:
- Process 3DS Payments (Iframe) — the in-page challenge alternative
- Authorize and Capture Payments
- Issue a Refund