Payments

Create Payment with Card Details

Charges a buyer for a plan from card details the caller holds itself, for integrators whose own systems are PCI compliant. Card details are accepted only on the vault host, where the card is tokenized before it reaches Whop; the official SDKs route this operation there, and raw card details sent to the regular host are refused. (Whop's own clients, which tokenize with the Basis Theory SDK, send the resulting token intent id to the regular host.) 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 what the buyer must still do, such as 3D Secure.

post/payments/direct

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

member_idstring nullable

The member to charge, prefixed mber_. When omitted the buyer is resolved from billing_details.email.

metadataobject nullable

Custom metadata to attach to the payment.

off_sessionboolean nullable

Whether the charge is merchant-initiated, with the buyer not present. Defaults to false. When true, payment_method.card.network_transaction_id is required: a merchant-initiated charge on a card Whop has not charged before carries the id of the card's prior customer-initiated transaction. No 3D Secure step is offered: an issuer that requires the buyer to authenticate declines the charge, and the payment fails with that reason so the card can be charged again with the buyer present. A declined card is not saved.

plan_idstring

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

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 such as 3D Secure. An absolute https URL without credentials, at most 2,048 characters.

setup_future_usage'off_session' | 'on_session' nullable

Attests that the buyer was told the card will be saved for later charges. off_session for merchant-initiated charges, on_session for buyer-present ones.

statement_descriptorstring nullable

Overrides the text on the buyer's card statement for this payment only. Must start with WHOP*, 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,
  "billing_details": {
    "address": {
      "city": "San Francisco",
      "country": "US",
      "line1": "1 Market St",
      "line2": "Suite 400",
      "postal_code": "94105",
      "state": "CA"
    },
    "email": "dana@shinetime.example",
    "name": "Dana Shine",
    "phone": "+14155550123"
  },
  "member_id": "mber_xxxxxxxxxxxxxx",
  "metadata": {
    "order_ref": "SHINE-4417"
  },
  "off_session": true,
  "payment_method": {
    "card": {
      "details": {
        "cvc": "123",
        "exp_month": 12,
        "exp_year": 2031,
        "number": "4242424242424242"
      },
      "network_transaction_id": "016153570198200"
    },
    "type": "card"
  },
  "plan": {
    "currency": "usd",
    "plan_type": "renewal",
    "product": {
      "global_affiliate_status": "enabled",
      "visibility": "visible"
    },
    "visibility": "visible"
  },
  "plan_id": "plan_xxxxxxxxxxxxxx",
  "promo_code_id": "promo_xxxxxxxxxxxxxx",
  "return_url": "https://shinetime.example/checkout/done",
  "setup_future_usage": "off_session",
  "statement_descriptor": "WHOP*SHINETIME"
}

Response

payment created from card details

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

Changed in 3 of the 74 revisions of this API.21

    • ●

      added the new alipayhk enum value to the //// response property for the response status

      response-property-enum-value-added

    • ●

      added the new tabby enum value to the //// response property for the response status

      response-property-enum-value-added

    This revision also has 1 change that name no endpoint, such as unreferenced schemas being removed. See the revision's changelog

    • ○

      endpoint added

      endpoint-added

Of the 74 revisions, 1 has no diff computed.