---
title: "Create Setup Intent"
method: POST
path: "/setup_intents"
tags: ["Setup Intents"]
---

# Create Setup Intent

`POST /setup_intents`

Saves a buyer's payment method for later without charging it. Pass a `confirmation_token` for a method the buyer just supplied through the payment elements in setup mode, or a `payment_method_id` already on file to re-verify it. The response is the setup intent as created, not its outcome: while it is `requires_action` the buyer still has a step, so hand `client_secret` to the elements' `handleNextAction` or poll Retrieve setup status. A buyer's own token holding `member:payment_methods:use` may create a setup intent for itself from a confirmation token.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `account_id` string, required — The account to save the payment method for, prefixed `biz_`.
  - `confirmation_token` string, nullable — A confirmation token describing a payment method the buyer just supplied, collected by the payment elements in setup mode. Provide this or `payment_method_id`, not both. The buyer is resolved from the token's billing email, or from `email`, and may still have a step to complete — poll Retrieve setup status for what to do next.
  - `currency` string, nullable — The currency the saved payment method will be used with, as a lowercase ISO 4217 code. Controls which currency-specific payment methods are available. Defaults to `usd`.
  - `email` string, nullable — Overrides the buyer email carried on the confirmation token, resolving or creating the user the method belongs to. Ignored unless `confirmation_token` is provided, and when the token was created by a signed-in buyer or the caller is the buyer.
  - `metadata` object, nullable — Custom metadata to attach to the setup intent. Returned on the setup intent and its webhooks.
  - `payment_method_id` string, nullable — An existing payment method to re-verify and save, prefixed `payt_`. Provide this or `confirmation_token`, not both. Not available to a buyer credential.
  - `purpose` 'ads_billing', nullable — What the saved payment method will pay for. Set to `ads_billing` when saving a card to pay for Whop Ads on `account_id`: the card is verified by Whop Ads, the merchant that charges it, which helps minimize security declines on ad payments, and it requires `ad_campaign:create` on `account_id`. Omit it for any other payment method.
  - `return_url` string, nullable — Where the buyer continues after completing an off-site step. An absolute https URL without credentials, at most 2,048 characters.

## Response `201`

setup intent created from a confirmation token

- SetupIntent
  - `account_id` string, nullable, required — The account the payment method is saved for, prefixed `biz_`.
  - `checkout_configuration_id` string, nullable, required — The checkout configuration this setup was created through, prefixed `ch_`. Null for a setup created through this API rather than a hosted checkout.
  - `client_secret` string, nullable, required — The credential a buyer's surface presents to poll this setup and set its return URL — hand it to the elements' `handleNextAction`. Only on setups created through this API, and always null in list responses — retrieve the setup intent for it.
  - `created_at` string, required — When the setup intent was created, as an ISO 8601 timestamp.
  - `id` string, required — Setup intent ID, prefixed `sint_`.
  - `last_setup_error` SetupLastSetupError, required
    - `code` string, nullable, required — A machine-readable classification of the failure, e.g. `enrollment_declined`. Absent when the buyer simply abandoned the setup.
    - `message` string, nullable, required — A human-readable explanation of the failure.
  - `member_id` string, nullable, required — The buyer's member record on the account, prefixed `mber_`. Null without the member:basic:read permission, unless the caller is the buyer.
  - `metadata` object, nullable, required — Your own key-value data attached when the setup intent was created.
  - `payment_instrument` PaymentInstrument, required
    - `card` PaymentInstrumentCard, required
      - `brand` string, nullable, required — The network identifier (`visa`, `amex`, …), matching `card.networks` entries and saved card payment methods. Null when the vault did not record the network.
      - `exp_month` number, nullable, required — The card's expiry month, 1 to 12. Null when the vault did not record it.
      - `exp_year` number, nullable, required — The card's four-digit expiry year. Null when the vault did not record it.
      - `issuer_identification_number` string, nullable, required — The issuer identification number, also called the BIN: the card's leading six or eight digits, which identify the issuing bank. Null when the processor did not report it.
      - `last4` string, nullable, required — The card's last four digits, when captured.
    - `display_name` string, required — Buyer-facing instrument name — "Visa •••• 4242" when the card surfaced, else the method's own name ("Klarna").
    - `icons` PaymentMethodIcons, required
      - `card` PaymentMethodIconVariants, required
        - `dark` PaymentMethodIconFiles, required
          - `png_1x` string, required — Raster fallback at the shape's native size.
          - `png_2x` string, required — Raster fallback at double density.
          - `png_4x` string, required — Raster fallback at quadruple density.
          - `svg` string, required — The vector file. Prefer this everywhere SVG renders.
        - `light` PaymentMethodIconFiles, required
          - `png_1x` string, required — Raster fallback at the shape's native size.
          - `png_2x` string, required — Raster fallback at double density.
          - `png_4x` string, required — Raster fallback at quadruple density.
          - `svg` string, required — The vector file. Prefer this everywhere SVG renders.
      - `square` PaymentMethodIconVariants, required
        - `dark` PaymentMethodIconFiles, required
          - `png_1x` string, required — Raster fallback at the shape's native size.
          - `png_2x` string, required — Raster fallback at double density.
          - `png_4x` string, required — Raster fallback at quadruple density.
          - `svg` string, required — The vector file. Prefer this everywhere SVG renders.
        - `light` PaymentMethodIconFiles, required
          - `png_1x` string, required — Raster fallback at the shape's native size.
          - `png_2x` string, required — Raster fallback at double density.
          - `png_4x` string, required — Raster fallback at quadruple density.
          - `svg` string, required — The vector file. Prefer this everywhere SVG renders.
    - `installment_count` number, nullable, required — Installment methods only: how many payments the charge splits into. Data, not copy — compose and translate the label client-side.
    - `payment_method_type` string, required — The payment method type identifier, e.g. `card`, `klarna`, `apple_pay`.
  - `payment_method_id` string, nullable, required — The saved payment method, prefixed `payt_`, ready to charge with Create Payment. Null until the setup has `succeeded`.
  - `payment_method_type` 'acss_debit' | 'addi' | 'affirm' | 'afterpay_clearpay' | 'alipay' | 'alipayhk' | 'alma' | 'amazon_pay' | 'apple' | 'apple_pay' | 'au_bank_transfer' | 'au_becs_debit' | 'bacs_debit' | 'bancolombia' | 'bancontact' | 'bank_wire' | 'billie' | 'blik' | 'boleto' | 'bre_b' | 'ca_bank_transfer' | 'capchase_pay' | 'card' | 'card_installments_three' | 'card_installments_six' | 'card_installments_twelve' | 'cashapp' | 'claritypay' | 'coinbase' | 'crypto' | 'custom' | 'customer_balance' | 'demo_pay' | 'efecty' | 'eps' | 'eu_bank_transfer' | 'fpx' | 'flex_pay' | 'gb_bank_transfer' | 'gcash' | 'giropay' | 'google_pay' | 'gopay' | 'grabpay' | 'id_bank_transfer' | 'ideal' | 'interac' | 'kakao_pay' | 'klarna' | 'klarna_pay_now' | 'konbini' | 'kr_card' | 'kr_market' | 'kriya' | 'kueski' | 'link' | 'mb_way' | 'm_pesa' | 'mercado_pago' | 'mercado_pago_ar' | 'mercado_pago_mx' | 'mobilepay' | 'modo' | 'mondu' | 'multibanco' | 'naver_pay' | 'nequi' | 'netbanking' | 'ng_bank' | 'ng_bank_transfer' | 'ng_card' | 'ng_market' | 'ng_ussd' | 'ng_wallet' | 'nupay' | 'nz_bank_account' | 'oney' | 'oney_3x' | 'oney_4x' | 'opay' | 'oxxo' | 'p24' | 'pago_efectivo' | 'pse' | 'pay_by_bank' | 'payco' | 'paynow' | 'paypal' | 'paypay' | 'payto' | 'pix' | 'platform_balance' | 'promptpay' | 'qris' | 'rapipago' | 'rechnung' | 'revolut_pay' | 'samsung_pay' | 'satispay' | 'scalapay' | 'sencillito' | 'sepa_debit' | 'sequra' | 'servipag' | 'sezzle' | 'shop_pay' | 'shopeepay' | 'sofort' | 'south_korea_market' | 'spei' | 'splitit' | 'sunbit' | 'swish' | 'tabby' | 'tamara' | 'touch_n_go' | 'twint' | 'upi' | 'us_bank_account' | 'us_bank_transfer' | 'venmo' | 'verve' | 'vipps' | 'webpay' | 'wechat_pay' | 'yape' | 'zip' | 'coinflow' | 'unknown', required — The different types of payment methods that can be used.
  - `return_url` string, nullable, required — Where the buyer lands after completing an off-site step, or `null` to leave them where they are.
  - `status` 'processing' | 'succeeded' | 'canceled' | 'requires_action', required — How far the setup has got. **A 201 or 200 means we answered, not that the method was saved — always branch on this.** `requires_action` — the buyer has a step outstanding; hand `client_secret` to the elements or poll Retrieve setup status. `processing` — the processor is deciding. `succeeded` — the method is saved, and only this one means saved. `canceled` — abandoned or refused; see `last_setup_error`.
  - `three_ds_verified` boolean, required — True when the buyer completed 3D Secure while saving this payment method.
  - `updated_at` string, required — When the setup intent was last updated, as an ISO 8601 timestamp.
  - `user` UserSummary, required
    - `id` string, required — User ID, prefixed `user_`.
    - `name` string, nullable, required — Display name.
    - `profile_picture` UserProfilePicture, required
      - `url` string, required — Avatar image URL. Always present — a generated placeholder when the user set no picture.
    - `username` string, required — Public username.

## Other responses

- `400` — confirmation token combined with a stored payment method
- `401` — Unauthorized
- `403` — Forbidden
- `404` — Resource not found
- `409` — Conflict

## Changes

> 74 revisions in range; 1 not diffed.

- **2026-09-26** `73dd0533cd81` — 1 info
  - added the new optional request property `purpose`
- **2026-09-25** `86b97292852d` — 1 warning
  - added the new `alipayhk` enum value to the `payment_method_type/oneOf[#/components/schemas/PaymentMethodTypes]/` response property for the response status `201`
- **2026-09-24** `7fcefabddb0a` — 1 warning
  - added the new `tabby` enum value to the `payment_method_type/oneOf[#/components/schemas/PaymentMethodTypes]/` response property for the response status `201`
- **2026-09-23** `140d015b9966` — 3 breaking, 4 warning, 17 info
  - added the new required request property `account_id`
  - removed `subschema #1: CreateSetupIntentInputWithConfirmationToken, subschema #2: CreateSetupIntentInputWithPaymentMethodId` from the request body `oneOf` list
  - removed the success response with the status `200`
  - removed the optional property `error/param` from the response with the `400` status
  - …20 more
- **2026-09-15** `c19acf2e2548` — 1 warning, 1 info
  - added the new `touch_n_go` enum value to the `payment_method/payment_method_type` response property for the response status `200`
  - removed the `bizum` enum value from the `payment_method/payment_method_type` response property for the response status `200`

[Full history](https://skmtc.dev/whop/apis/whop-api/changes/setup_intents/post.md)

---

[API](https://skmtc.dev/whop/apis/whop-api.md) · [All operations](https://skmtc.dev/whop/apis/whop-api/llms.txt) · [OpenAPI document](https://skmtc.dev/whop/apis/whop-api/revisions/78e1ed7366cd?raw)
