Payments

Create Payment

Charges a buyer for one or more plans. Pass a payment method already on file (member_id and payment_method_id), or a confirmation_token describing a method the buyer just supplied. Collection runs in the background: the response is the payment as created, not its outcome — poll Retrieve status for how far it has got and, for a confirmation-token payment, what the buyer must still do. Pass line_items for one or more plans with quantities, plan_id for an existing plan, or plan to find or create one inline. These inputs are mutually exclusive.

post/payments

Headers

Idempotency-Keystring
Example:d9105228-4a08-46b1-8b91-42fed586d383

A unique key that makes this request safe to retry. See Idempotent requests.

Request body

account_idstring required

The account to charge for, prefixed biz_.

auto_capture_after_minutesinteger nullable

Minutes after authorization at which Whop captures the hold automatically unless it has been voided. Requires capture: false. Between 5 and 5760 (4 days).

captureboolean nullable

Whether to capture a card payment immediately. Defaults to true. Pass false to place an authorization hold that must be captured in full within five days via the capture endpoint, or automatically after auto_capture_after_minutes.

confirmation_tokenstring nullable

A confirmation token describing a payment method the buyer just supplied. Provide this instead of member_id and payment_method_id; the buyer is resolved from the token's billing email, or from email. The buyer may still have a step to complete — poll the payment's status for what to do next.

emailstring nullable

Overrides the buyer email carried on the confirmation token, resolving or creating the user the payment belongs to. Ignored unless confirmation_token is provided, and when the token was created by a signed-in buyer.

member_idstring nullable

The member to charge, prefixed mber_. Required with payment_method_id unless confirmation_token is provided.

metadataobject nullable

Custom metadata to attach to the payment.

payment_method_idstring nullable

The stored payment method to charge, prefixed payt_. It must belong to the member. Required unless confirmation_token is provided.

plan_idstring

The plan to charge for, prefixed plan_. It must belong to the account. Mutually exclusive with plan and line_items.

promo_code_idstring nullable

An active promo code to apply, prefixed promo_. It must belong to the account and be valid for the plan.

return_urlstring nullable

Where the buyer continues after completing an off-site step. An absolute https URL without credentials, at most 2,048 characters. Ignored unless confirmation_token is provided.

statement_descriptorstring nullable

Overrides the text on the buyer's card statement for this payment only. Takes precedence over the product's and account's custom descriptors, and changes neither. Must start with WHOP* unless the business processes as the merchant of record. For businesses processing as the merchant of record, omit the WHOP* prefix; the descriptor appears as provided. Must be 5-22 characters, contain at least one letter, and use only Latin letters, numbers, spaces, underscores, hyphens, or asterisks.

Example request

{
  "account_id": "biz_xxxxxxxxxxxxxx",
  "auto_capture_after_minutes": 60,
  "confirmation_token": "ctok_xxxxxxxxxxxxxx",
  "email": "dana@shinetime.example",
  "line_items": [
    {
      "plan_id": "plan_xxxxxxxxxxxxxx",
      "quantity": 1
    }
  ],
  "member_id": "mber_xxxxxxxxxxxxxx",
  "metadata": {
    "order_ref": "SHINE-4417"
  },
  "payment_method_id": "payt_xxxxxxxxxxxxxx",
  "plan": {
    "application_fee_amount": 2,
    "currency": "usd",
    "initial_price": 20,
    "plan_type": "one_time",
    "product": {
      "collect_shipping_address": true,
      "custom_statement_descriptor": "WHOP*INLINE",
      "description": "Updated description",
      "external_identifier": "versioned-product",
      "global_affiliate_status": "enabled",
      "headline": "Product headline",
      "redirect_purchase_url": "https://example.com/thanks",
      "title": "Inline product",
      "visibility": "visible"
    },
    "product_id": "prod_xxxxxxxxxxxxxx",
    "visibility": "visible"
  },
  "plan_id": "plan_xxxxxxxxxxxxxx",
  "promo_code_id": "promo_xxxxxxxxxxxxxx",
  "return_url": "https://shinetime.example/checkout/done",
  "shipping_address": {
    "city": "Austin",
    "country": "US",
    "line1": "1114 Bouldin Ave",
    "line2": "Unit B",
    "name": "Dana Whitfield",
    "postal_code": "78704",
    "state": "TX"
  },
  "statement_descriptor": "WHOP*SHINETIME"
}

Response

payment created from a stored payment method

account_idstring nullable required

The account that received the payment, prefixed biz_.

auto_refundedboolean required

True when Whop refunded the payment automatically, for example on a dispute alert.

billing_reason'subscription_create' | 'subscription_cycle' | 'subscription_update' | 'one_time' | 'manual' | 'subscription' required

The reason why a specific payment was billed

checkout_configuration_idstring nullable required

The checkout configuration the buyer paid through, prefixed ch_, or null.

client_secretstring nullable required

The credential a buyer's surface presents to poll this payment and set its return URL. Only on payments created from a confirmation token, and always null in list responses — retrieve the payment for it.

created_atstring required

When the payment was created, as an ISO 8601 timestamp.

currency'usd' | 'sgd' | 'inr' | 'aud' | 'brl' | 'cad' | 'dkk' | 'eur' | 'nok' | 'gbp' | 'sek' | 'chf' | 'hkd' | 'huf' | 'jpy' | 'mxn' | 'myr' | 'pln' | 'czk' | 'nzd' | 'aed' | 'eth' | 'ape' | 'cop' | 'ron' | 'thb' | 'bgn' | 'idr' | 'dop' | 'php' | 'try' | 'krw' | 'twd' | 'vnd' | 'pkr' | 'clp' | 'uyu' | 'ars' | 'zar' | 'dzd' | 'tnd' | 'mad' | 'kes' | 'kwd' | 'jod' | 'all' | 'xcd' | 'amd' | 'bsd' | 'bhd' | 'bob' | 'bam' | 'khr' | 'crc' | 'xof' | 'egp' | 'etb' | 'gmd' | 'ghs' | 'gtq' | 'gyd' | 'ils' | 'jmd' | 'mop' | 'mga' | 'mur' | 'mdl' | 'mnt' | 'nad' | 'ngn' | 'mkd' | 'omr' | 'pyg' | 'pen' | 'qar' | 'rwf' | 'sar' | 'rsd' | 'lkr' | 'tzs' | 'ttd' | 'uzs' | 'rub' | 'btc' | 'cny' | 'usdt' | 'kzt' | 'awg' | 'whop_usd' | 'xau' required

The available currencies on the platform

customer_emailstring nullable required

The buyer's email address. Null without member:email:read on the account or when the buyer has no assigned email.

customer_phonestring nullable required

The phone number the buyer gave at checkout, when one was collected.

decline_code'insufficient_funds' | 'lost_card' | 'stolen_card' | 'expired_card' | 'suspected_fraud' | 'invalid_card_number' | 'invalid_cvc' | 'invalid_cvc_or_expiration' | 'incorrect_pin' | 'authentication_required' | 'card_not_supported' | 'currency_not_supported' | 'duplicate_transaction' | 'generic_decline' | 'invalid_account' | 'invalid_amount' | 'processing_error' | 'restricted_card' | 'card_velocity_exceeded' | 'contact_issuer' | 'bank_declined' | 'regulatory_blocked' | 'transaction_not_permitted' | 'transaction_stopped' | 'card_type_not_supported' | 'issuer_not_found' | 'closed_account' | 'issuer_unavailable' | 'invalid_zip' | 'invalid_expiry_month' | 'invalid_expiry_year' | 'invalid_expiry' | 'invalid_transaction' | 'cannot_authorize' | 'pin_required' | 'pin_try_exceeded' | 'provider_declined' | 'high_risk' | 'test_mode_decline' | 'merchant_blacklist' | 'reenter_transaction' | 'invalid_pin' | 'pin_required_as' | 'withdrawal_count_limit_exceeded' | 'invalid_country' | 'issuer_error' | 'invalid_card_holder_name' | 'no_accounts' | 'transaction_cancelled' | 'three_d_secure_success' | 'three_d_secure_canceled' | 'three_d_secure_invalid_card_number' | 'three_d_secure_generic_error' | 'three_d_secure_timeout' | 'three_d_secure_failed' | 'three_d_secure_card_not_enrolled' | 'three_d_secure_fraud' | 'three_d_secure_too_many_attempts' | 'three_d_secure_rejected_by_bank' | 'three_d_secure_reported_lost_or_stolen' | 'blocked_by_cardholder' | 'test_mode_test_card' | 'try_again_later' | 'transaction_not_allowed' | 'bank_insufficient_funds' | 'bank_account_not_found' | 'bank_account_closed' | 'bank_account_frozen' | 'bank_invalid_routing_number' | 'bank_non_transaction_account' | 'bank_authorization_revoked' | 'bank_payment_stopped' | 'bank_not_authorized' | 'bank_account_holder_deceased' | 'bank_duplicate' | 'bank_amount_error' | 'bank_regulatory_blocked' | 'bank_details_invalid' | 'bank_processing_error' | 'bank_generic_decline' | 'sepa_invalid_iban' | 'sepa_no_mandate' | 'sepa_mandate_data_invalid' | 'sepa_disputed' | 'sepa_refused_by_customer' | 'sepa_generic_decline' required

The reason a payment was declined.

dispute_alerted_atstring nullable required

When an issuer warned that this payment will be disputed, or null.

failure_messagestring nullable required

Why the most recent attempt failed, in plain words, or null.

financing_installments_countnumber nullable required

For installment methods, how many payments the charge splits into.

idstring required

Payment ID, prefixed pay_.

last_payment_attempt_atstring nullable required

When the most recent charge attempt ran, or null.

member_idstring nullable required

The buyer's member record on the account, prefixed mber_. Null without the member:basic:read permission.

membership_idstring nullable required

The membership this payment is billed against, prefixed mem_. Null for one-off purchases or without the member:basic:read permission.

metadataobject nullable required

Your own key-value data attached when the payment was created.

needs_trackingboolean nullable required

True when funds are held until the order ships and no tracking number has been added yet. Null without the shipment:basic:read permission.

next_payment_attempt_atstring nullable required

When the next automatic retry is scheduled, or null.

paid_atstring nullable required

When the money was collected, or null while it has not been.

payment_method_idstring nullable required

The stored payment method that was charged, prefixed payt_. Null when the method was not saved.

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.

payments_failednumber required

How many charge attempts have failed on this payment.

plan_idstring nullable required

The plan that was charged, prefixed plan_.

product_idstring nullable required

The product the plan belongs to, prefixed prod_. Null for a plan with no product.

promo_code_idstring nullable required

The promo code applied at checkout, prefixed promo_, or null.

recovery_urlstring nullable required

Whop-hosted URL where the buyer can sign in and complete 3D Secure for an off-session charge the bank challenged — a subscription renewal or a saved-card payment. Null when recovery is unavailable, you lack member:basic:read, or in list responses. Retrieve the payment for it.

refundableboolean required

True when the payment is paid, not yet fully refunded, and its processor supports refunds.

refunded_atstring nullable required

When the payment was refunded, or null.

retryableboolean required

True when the payment is open and Whop can attempt the charge again — see POST /payments/{id}/retry.

risk_scorenumber nullable required

Whop's published risk index from 0 (lowest) to 100 (highest), including enforced decision floors. This is not a fraud probability. Null when no score is available.

risk_signalsobject nullable required

Deprecated. Risk score explanations are no longer provided; always null. DEPRECATED: Risk score explanations are no longer provided. Always null.

settlement_time_atstring nullable required

When the portion not listed in holds posts to the account's available balance, at midnight UTC. The financial_activity.funds_available webhook's posted_at carries the same value when the settlement that clears it posts. Null until the payment is paid, and always null in list responses — retrieve the payment for it.

shipment_idstring nullable required

The shipment fulfilling this payment, prefixed ship_. Null when nothing ships or without the shipment:basic:read permission.

status'draft' | 'open' | 'authorized' | 'paid' | 'pending' | 'uncollectible' | 'unresolved' | 'void' required

The status of a receipt

substatus'succeeded' | 'requires_capture' | 'pending' | 'failed' | 'blocked' | 'past_due' | 'canceled' | 'price_too_low' | 'uncollectible' | 'refunded' | 'auto_refunded' | 'partially_refunded' | 'dispute_warning' | 'dispute_needs_response' | 'dispute_warning_needs_response' | 'resolution_needs_response' | 'dispute_under_review' | 'dispute_warning_under_review' | 'resolution_under_review' | 'dispute_won' | 'dispute_warning_closed' | 'resolution_won' | 'dispute_lost' | 'dispute_closed' | 'resolution_lost' | 'drafted' | 'incomplete' | 'unresolved' | 'open_dispute' | 'open_resolution' required

The friendly status of a payment. This is a derived status that provides a human-readable summary of the payment state, combining the underlying status and substatus fields.

tax_behavior'exclusive' | 'inclusive' | 'unspecified' | 'unable_to_collect' required

The type of tax inclusivity applied to the receipt, for determining whether the tax is included in the final price, or paid on top.

three_ds_verifiedboolean required

True when the buyer completed 3D Secure for this payment.

updated_atstring required

When the payment last changed, as an ISO 8601 timestamp.

voidableboolean required

True when the payment can be voided or canceled. The request is rejected if the payment is no longer eligible — see POST /payments/{id}/void.

Example response

{
  "account_id": "biz_xxxxxxxxxxxxxx",
  "amount_after_fees": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "billing_address": {
    "city": "Austin",
    "country": "US",
    "line1": "1114 Bouldin Ave",
    "line2": "Unit B",
    "name": "Dana Whitfield",
    "postal_code": "78704",
    "state": "TX"
  },
  "billing_reason": "subscription_create",
  "client_secret": "pay_xxxxxxxxxxxxxx_secret_vdefault_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "created_at": "2026-01-01T12:00:00.000Z",
  "currency": "usd",
  "customer_email": "marcus@shinetime.example",
  "customer_phone": "+xxxxxxxxxxx",
  "decline_code": "insufficient_funds",
  "holds": [
    {
      "amount": {
        "amount": "-2.50",
        "currency": "usd",
        "decimals": 2,
        "display_decimals": 2
      },
      "type": "reserve"
    }
  ],
  "id": "pay_xxxxxxxxxxxxxx",
  "line_items": [
    {
      "id": "li_xxxxxxxxxxxxxx",
      "label": "Ceramic Coating Package",
      "plan_id": "plan_xxxxxxxxxxxxxx",
      "plan_title": "Ceramic Coating — Full Vehicle",
      "product_id": "prod_xxxxxxxxxxxxxx",
      "product_title": "Ceramic Coating Package",
      "quantity": 1,
      "subtotal": {
        "amount": "-2.50",
        "currency": "usd",
        "decimals": 2,
        "display_decimals": 2
      }
    }
  ],
  "member_id": "mber_xxxxxxxxxxxxxx",
  "membership_id": "mem_xxxxxxxxxxxxxx",
  "metadata": {
    "order_ref": "SHINE-4417"
  },
  "paid_at": "2026-01-01T12:00:00.000Z",
  "payment_instrument": {
    "card": {
      "brand": "visa",
      "exp_month": 10,
      "exp_year": 2031,
      "issuer_identification_number": "41111111",
      "last4": "4242"
    },
    "display_name": "Visa •••• 4242",
    "icons": {
      "card": {
        "dark": {
          "png_1x": "https://content.whop.com/payment_methods/visa/icons/card_dark_30.png",
          "png_2x": "https://content.whop.com/payment_methods/visa/icons/card_dark_60.png",
          "png_4x": "https://content.whop.com/payment_methods/visa/icons/card_dark_120.png",
          "svg": "https://content.whop.com/payment_methods/visa/icons/card_dark.svg"
        },
        "light": {
          "png_1x": "https://content.whop.com/payment_methods/visa/icons/card_dark_30.png",
          "png_2x": "https://content.whop.com/payment_methods/visa/icons/card_dark_60.png",
          "png_4x": "https://content.whop.com/payment_methods/visa/icons/card_dark_120.png",
          "svg": "https://content.whop.com/payment_methods/visa/icons/card_dark.svg"
        }
      },
      "square": {
        "dark": {
          "png_1x": "https://content.whop.com/payment_methods/visa/icons/card_dark_30.png",
          "png_2x": "https://content.whop.com/payment_methods/visa/icons/card_dark_60.png",
          "png_4x": "https://content.whop.com/payment_methods/visa/icons/card_dark_120.png",
          "svg": "https://content.whop.com/payment_methods/visa/icons/card_dark.svg"
        },
        "light": {
          "png_1x": "https://content.whop.com/payment_methods/visa/icons/card_dark_30.png",
          "png_2x": "https://content.whop.com/payment_methods/visa/icons/card_dark_60.png",
          "png_4x": "https://content.whop.com/payment_methods/visa/icons/card_dark_120.png",
          "svg": "https://content.whop.com/payment_methods/visa/icons/card_dark.svg"
        }
      }
    },
    "payment_method_type": "card"
  },
  "payment_method_id": "payt_xxxxxxxxxxxxxx",
  "payment_method_type": "acss_debit",
  "payment_rule_matches": [
    {
      "action": "allow"
    }
  ],
  "plan_id": "plan_xxxxxxxxxxxxxx",
  "presentment_total": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "product_id": "prod_xxxxxxxxxxxxxx",
  "refunded_amount": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "retryable": true,
  "shipping_address": {
    "city": "Austin",
    "country": "US",
    "line1": "1114 Bouldin Ave",
    "line2": "Unit B",
    "name": "Dana Whitfield",
    "postal_code": "78704",
    "state": "TX"
  },
  "status": "draft",
  "substatus": "succeeded",
  "subtotal": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "tax_amount": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "tax_behavior": "exclusive",
  "tax_refunded_amount": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "total": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "updated_at": "2026-01-01T12:00:00.000Z",
  "usd_total": {
    "amount": "-2.50",
    "currency": "usd",
    "decimals": 2,
    "display_decimals": 2
  },
  "user": {
    "id": "user_xxxxxxxxxxxxxx",
    "name": "Dana Whitfield",
    "profile_picture": {
      "url": "https://ui-avatars.com/api/"
    },
    "username": "danawhitfield"
  },
  "verification_checks": {
    "address_line1": "PASS",
    "authorization_code": "A1B2C3",
    "card_holder_name": "PASS",
    "card_security_code": "PASS",
    "zip_code": "PASS"
  }
}

Changes