> 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.

# Testing

Use your `sk_test_` key and one of Stripe's documented test PaymentMethods in
`payment_method`. Test mode moves no real money.

## Pay with a test PaymentMethod

Name the test PaymentMethod on create (with `confirm=true`) or on confirm:

**`curl`**

```bash title="curl"
curl https://api.devfluveo.com/v1/payment_intents \
  -u sk_test_123: \
  -d amount=4242 \
  -d currency=usd \
  -d confirm=true \
  -d payment_method=pm_card_visa
```

Fluveo resolves the PaymentMethods listed on Stripe's testing page to the same test cards.
On a US account each one gives Stripe's documented outcome. A Brazilian (BRL) account
follows other rules: see [Brazilian (BRL) accounts](#brazilian-brl-accounts). That covers:

* Card brands and countries, such as `pm_card_visa`, `pm_card_mastercard`, `pm_card_amex`
  and `pm_card_br`.
* Declines, such as `pm_card_chargeDeclined` (or `pm_card_visa_chargeDeclined`),
  `pm_card_chargeDeclinedInsufficientFunds`, `pm_card_visa_chargeDeclinedLostCard`,
  `pm_card_chargeDeclinedExpiredCard`, `pm_card_chargeDeclinedIncorrectCvc`,
  `pm_card_chargeDeclinedProcessingError` and
  `pm_card_visa_chargeDeclinedVelocityLimitExceeded`. Each one answers Stripe's 402
  `card_error` with Stripe's `code`, `decline_code` and `message`.
* Fraud checks, such as `pm_card_radarBlock` and `pm_card_cvcCheckFail`.
* Disputes, refunds and funds that skip the pending balance, such as
  `pm_card_createDispute`, `pm_card_refundFail` and `pm_card_bypassPending`.
* 3D Secure, such as `pm_card_authenticationRequired` and
  `pm_card_threeDSecure2Required`.

Stripe's page also lists `pm_card_createEthocaAlert` and
`pm_card_createMastercardComplianceDispute`, which Stripe test mode itself does not resolve.
Fluveo refuses them as below.

## Where test PaymentMethods are refused

Only PaymentIntent create and confirm and SetupIntent confirm resolve them, and only
in test mode. A live request naming one answers `resource_missing`. Any other
`pm_card` id, and a `pm_card` id on any other request that names a PaymentMethod
(a SetupIntent create or update, a
PaymentMethod path, a Customer's `invoice_settings[default_payment_method]`, a
Subscription or Invoice `default_payment_method`), answers HTTP 400 with
`param` set to the field you sent, before Fluveo reads a customer or a saved card
or calls a payment provider:

```json
{
  "error": {
    "type": "invalid_request_error",
    "message": "This Stripe test PaymentMethod is not supported here. In test mode, name a documented test PaymentMethod such as 'pm_card_visa' in payment_method on PaymentIntent create (with confirm=true) or confirm, or on SetupIntent confirm (see docs: Testing).",
    "code": "resource_missing",
    "param": "payment_method"
  }
}
```

A saved card's own `pm_` id (one that Fluveo returned to you) keeps working.

On a Brazilian account in test mode, the dispute test PaymentMethods are refused too, with
their own answer (see the next section).

## Brazilian (BRL) accounts

On a Brazilian account in test mode, Fluveo sends the test card to the acquirer's test
environment, not to Stripe. That environment decides the result from the **last digit of
the card number**, not from Stripe's rules:

| Last digit of the card number | Result                                                                  |
| ----------------------------- | ----------------------------------------------------------------------- |
| 0, 1, 4                       | Paid                                                                    |
| 2                             | Declined                                                                |
| 3                             | Refused: expired card                                                   |
| 5                             | Refused: blocked card                                                   |
| 6                             | Times out: the payment stays `processing` until an operator resolves it |
| 7                             | Refused: canceled card                                                  |
| 8                             | Refused: card problems                                                  |
| 9                             | Random result                                                           |

So a test PaymentMethod named after an outcome gives the result of its card's last digit
instead. For example, `pm_card_visa` and `pm_card_br` end in 2 and are declined.

* **To get a paid payment**, use `pm_card_mastercard` (it ends in 4) with a customer that
  has a Brazilian tax ID (`br_cpf`), which card payments on a Brazilian account need:

  **`curl`**

  ```bash title="curl"
  curl https://api.devfluveo.com/v1/payment_intents \
    -u sk_test_123: \
    -d amount=1995 \
    -d currency=brl \
    -d confirm=true \
    -d customer=cus_123 \
    -d payment_method=pm_card_mastercard
  ```

* **Do not use** test PaymentMethods whose card ends in 6, such as `pm_card_visa_debit`,
  `pm_card_refundFail` and `pm_card_pendingRefund`: the payment times out and stays
  `processing`.

* **Disputes:** test mode cannot simulate a dispute on a Brazilian account. Disputes there
  come only from the acquirer, after a real chargeback. The dispute test PaymentMethods
  (`pm_card_createDispute`, `pm_card_createDisputeProductNotReceived`,
  `pm_card_createDisputeInquiry`, `pm_card_createIssuerFraudRecord`,
  `pm_card_createMultipleDisputes`, `pm_card_createCe3EligibleDispute`,
  `pm_card_createComplianceDispute`, `pm_card_createAutoRepresentmentEligibleDispute`,
  `pm_card_createRapidDisputeResolutionDispute` and `pm_card_createCe3BlockDispute`)
  are refused at once on PaymentIntent create (with or without `confirm=true`) and
  confirm and on SetupIntent confirm, before the acquirer is called. The answer is
  HTTP 400 and no payment is made:

  ```json
  {
    "error": {
      "type": "invalid_request_error",
      "message": "This test PaymentMethod simulates a dispute, which test mode cannot do on a Brazilian (BRL) account: disputes there come only from real chargebacks. Use a test PaymentMethod that does not simulate a dispute, or a US test account (see docs: Testing).",
      "code": "payment_method_not_available",
      "param": "payment_method"
    }
  }
  ```

  To test disputes, use a US test account, where `pm_card_createDispute` opens one.

Inline card details (`payment_method_data[card]`) are hidden from public `/v1`
(see [Payments](/resources/payments#hidden-from-the-public-api)).

## Next

* [Quickstart](/quickstart) — your first payment end to end.
* [Errors](/errors) — the error envelope and common codes.