> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.fluveo.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.fluveo.com/_mcp/server.

# Handle payment authentication (3DS)

Some payments need the cardholder to complete a Strong Customer Authentication
(SCA / 3-D Secure) step. When that happens, a confirmed PaymentIntent doesn't
fail — it returns `status: "requires_action"`, and the customer finishes the
challenge in their browser before the payment can succeed.

This guide covers how to detect that state and drive it to completion. For the
full lifecycle and every status, see the [API Reference](/api-reference).

## The states you'll branch on

After you confirm a PaymentIntent, branch on `status`:

| `status`                  | Meaning                                       | Your move                         |
| ------------------------- | --------------------------------------------- | --------------------------------- |
| `succeeded`               | Authentication not required (or already done) | Fulfil the order.                 |
| `requires_action`         | The customer must authenticate (3DS)          | Send them to complete it (below). |
| `requires_payment_method` | The card was declined or auth failed          | Ask for a new payment method.     |

## 1. Confirm and read the status

Pass a `return_url` so Fluveo knows where to send the customer back after any
off-domain authentication step.

**`curl`**

```bash title="curl"
curl https://api.devfluveo.com/v1/payment_intents/pi_1A9e8AzB2xQRH9JfQu5N/confirm \
  -u sk_test_123: \
  -d payment_method=pm_card_authenticationRequired \
  -d return_url='https://yourapp.example/checkout/return'
```

On a US account, to exercise `requires_action`, confirm in test mode with
`pm_card_authenticationRequired`, Stripe's test PaymentMethod for a card that requires
3D Secure. On a Brazilian (BRL) account the result follows other rules: see
[Brazilian (BRL) accounts](/guides/testing#brazilian-brl-accounts). Inline card details
(`payment_method_data[card]`) are hidden from public `/v1`.

## 2. Respect the current browser boundary

Fluveo does not issue publishable keys today, so there is no certified public
browser-SDK completion flow. Never place `sk_test_*` in browser code and never
log `client_secret`. Treat `requires_action` as a test-mode integration gap
until the browser authentication product and its exact `next_action` contract
are promoted.

## 3. Confirm the final status

After the customer returns, retrieve the PaymentIntent to see where it landed —
don't trust the redirect alone.

**`curl`**

```bash title="curl"
curl https://api.devfluveo.com/v1/payment_intents/pi_1A9e8AzB2xQRH9JfQu5N \
  -u sk_test_123:
```

Retrieve the PaymentIntent server-side before fulfillment. You may also register
a merchant-public WebhookEndpoint as a completion signal; verify its signature
before acting.

## Next

* [Webhooks](/webhooks) — contracted Event reads and endpoint management.
* [Errors](/errors) — handle declines and `authentication_required`.