> ## Documentation Index
> Fetch the complete documentation index at: https://docs.momentco.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Method Verification

> Verify a customer's payment method without taking payment

Payment method verification allows merchants to confirm that a payment method is valid and save it for future use without charging the customer. It is initiated by creating a session with `amount: 0`.

Payment method verification currently applies to card payments only. The Moment checkout will present only card payment methods on `amount: 0` sessions.

Two session types are supported depending on the intended future payment flow:

* **`one_time`**: verifies and saves the payment method for future customer-initiated payments such as repeat purchases
* **`first_in_series`**: verifies the payment method and creates a mandate for future merchant-initiated payments such as subscriptions and recurring charges

This is commonly used for:

* **Card on file setup** where the customer saves a payment method for future purchases without being charged immediately
* **Free trials** where the first charge happens after the trial period ends
* **Subscription sign-ups** with a deferred first billing cycle

<Note>
  `capture_method` is not relevant for payment method verification. Any value supplied via `payment_method_options.card.capture_method` on an `amount: 0` session is ignored because the zero amount already signals verification intent. No capture or void step follows a successful verification.
</Note>

## Card on File

Use `one_time` with `amount: 0` to verify and save a payment method for future customer-initiated purchases. `amount: 0` on a `one_time` session implicitly saves the payment method, so `checkout_options.save_payment_method` does not need to be supplied. If supplied, only `always` is accepted; other values are rejected.

```json theme={"system"}
POST /collect/payment_sessions

{
  "amount": 0,
  "currency": "ZAR",
  "type": "one_time",
  "options": {
    "checkout_options": {
      "return_url": "https://merchant.example/return"
    }
  }
}
```

No mandate is created. The payment method is saved and available for future customer-present payments.

```
1. Customer creates an account on an e-commerce platform
2. Create one_time session with amount: 0
3. Payment method is verified and saved
4. Webhook: payment.succeeded (authorised_amount: 0)
5. Customer makes a purchase later → new one_time session using the saved payment method
```

## Recurring Setup

Use `first_in_series` with `amount: 0` to verify the payment method and create a mandate in a single step. No initial payment is taken. `mandate_options.amount` is required in this case because the session-level `amount: 0` cannot serve as the consent ceiling for future `next_in_series` payments. For full details on configuring the mandate created at this step, see [Mandates](/documentation/collect/payment-sessions/mandates/overview).

```json theme={"system"}
POST /collect/payment_sessions

{
  "amount": 0,
  "currency": "ZAR",
  "type": "first_in_series",
  "options": {
    "customer": {
      "name": "Jane",
      "email": "jane@example.com"
    },
    "checkout_options": { "return_url": "https://merchant.example/return" },
    "mandate_options": {
      "type": "scheduled",
      "amount": 2500,
      "recurrence": {
        "type": "monthly",
        "interval_count": 1
      }
    }
  }
}
```

On completion, the mandate is created and available for future `next_in_series` payments. No capture or void is needed.

```
1. Customer signs up for a 14-day free trial
2. Create first_in_series session with amount: 0
3. Payment method is verified, mandate created
4. Webhook: payment.succeeded (authorised_amount: 0)
5. After trial ends → create next_in_series session to charge the first billing cycle
```

## Session Outcome

On successful verification, the Payment Session transitions to `status: completed` with `payment_outcome: payment_method_verified`. This is a terminal outcome that signals no payment was taken but the payment method was verified and vaulted. The deprecated `payment_status` field continues to be populated with `paid` for backwards compatibility.

## Payment Object on Success

On successful verification, the payment object reflects zero amounts. The `intent` field is set to `payment_method_verification` to make the nature of the payment explicit:

```json theme={"system"}
{
  "id": "pay_Vn8kLmQ2rTwX4y",
  "status": "succeeded",
  "intent": "payment_method_verification",
  "amount": 0,
  "currency": "ZAR",
  "authorised_amount": 0,
  "paid_amount": 0,
  "voided_amount": 0,
  "country": "ZA",
  "payment_method_details": {
    "type": "card",
    "card": {
      "type": "CREDIT",
      "scheme": "VISA",
      "bin": "411111",
      "last4": "1234"
    }
  }
}
```

No capture or void is required after verification.

## Webhooks

* **`payment.succeeded`**: fired when verification succeeds. `intent` is `payment_method_verification` and `authorised_amount` is `0`.

See the [Payments API Overview](/api-reference/collect/payments/overview) for the full list of webhook events.
