Skip to main content
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
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.

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.
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.
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:
{
  "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 for the full list of webhook events.