---
title: "Retrieve payment status"
method: GET
path: "/payments/{payment_id}/status"
tags: ["Payments"]
---

# Retrieve payment status

`GET /payments/{payment_id}/status`

Retrieves how far a payment has got and what the buyer must do next, if anything. A payment is collected in the background, so poll this rather than reading the create response. Accepts either a secret key or the payment's own `client_secret`, so the surface collecting the payment can poll it directly.

## Path parameters

- `payment_id` string, required

## Response `200`

Payment status retrieved

- PaymentStatus
  - `id` string, required — The payment this status describes, prefixed `pay_`.
  - `last_payment_error` PaymentLastPaymentError, required
    - `code` string, nullable, required — A machine-readable classification of the failure.
    - `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' | 'null', nullable, required — The reason the payment was declined.
    - `message` string, nullable, required — A human-readable explanation of the failure.
  - `next_action` union, required — What the buyer must do to finish. `type` picks the shape and each type carries only its own `data`, so switching on `type` gives you exactly that step's payload.
    - PaymentNextActionRedirect
      - `data` PaymentNextActionRedirectData, required
        - `frame_max_width` integer, nullable, required — The widest the provider's page lays out usefully, in CSS pixels — cap a frame or dialog presenting it at this width. `null` when the page fills whatever width it is given.
        - `url` string, required — The provider's page for this payment, as an absolute URL — take the buyer there.
      - `render` string[], required
      - `type` 'redirect', required — Always `redirect`: send the buyer to `data.url`. The provider hands them back to `return_url` when they are done.
    - PaymentNextActionDisplayInstructions
      - `data` union, required — What to show the buyer so they can pay. `kind` picks the shape and the details sit under the key named for it, so switching on `kind` gives you exactly that kind's payload. Every detail field is optional — the rails behind these methods publish them unevenly — but a kind that arrives with `document_url` can always fall back to sending the buyer to that hosted copy of the instructions.
        - PaymentVoucherInstructions
          - `kind` 'voucher', required — Always `voucher`: a code the buyer pays in person, at a convenience store or bank counter.
          - `voucher` PaymentVoucher, required
            - `amount` Money
              - …
            - `barcode` string — The barcode's contents, when the voucher carries one — render it in the symbology named by `barcode_format`.
            - `barcode_format` string — The symbology `barcode` is encoded in, such as `CODE_128`.
            - `company_name` string — Who the payment is made out to.
            - `document_url` string — A hosted page with the complete, printable instructions. If you would rather not render the details yourself, send the buyer here.
            - `expires_at` string — When the voucher stops being payable, as an ISO 8601 timestamp.
            - `provider_logo` string — URL of that network's logo.
            - `provider_name` string — The network the buyer pays at, such as OXXO.
            - `reference` string — The voucher's number — what the buyer reads out or types at the counter to pay.
        - PaymentQrInstructions
          - `kind` 'qr', required — Always `qr`: a code the buyer scans with their banking app.
          - `qr` PaymentQr, required
            - `amount` Money
              - …
            - `document_url` string — A hosted page with the complete, printable instructions. If you would rather not render the details yourself, send the buyer here.
            - `expires_at` string — When the code stops being payable, as an ISO 8601 timestamp.
            - `key` string — An account key the buyer can pay to directly (Colombia's Bre-B llave), for apps that take a key instead of a scan.
            - `qr_code` string — The QR code's contents, ready to render as a scannable image — `qr_format` says how it is encoded.
            - `qr_format` string — How `qr_code` is encoded.
        - PaymentBankTransferInstructions
          - `bank_transfer` PaymentBankTransfer, required
            - `account_number` string — The account to send to, in the local scheme's format — `account_number_label` says what to call it.
            - `account_number_label` string — What to call `account_number` when showing it, in the local scheme's own terms — `CLABE` in Mexico, for example.
            - `amount` Money
              - …
            - `bank_account_type` string — The kind of account receiving the transfer, such as a checking account, in the local system's own vocabulary.
            - `bank_branch` string — The receiving branch, where the local system routes by branch.
            - `bank_code` string — The receiving bank's code in the local clearing system.
            - `bank_name` string — The receiving bank's name.
            - `beneficiary_document` string — The account holder's tax or identity document number, where the local system needs it to send.
            - `beneficiary_document_type` string — What kind of document `beneficiary_document` is, in the local system's own vocabulary.
            - `beneficiary_name` string — Who the account belongs to — the name the buyer's bank may ask them to confirm.
            - `document_url` string — A hosted page with the complete, printable instructions. If you would rather not render the details yourself, send the buyer here.
            - `expires_at` string — When these details stop being payable, as an ISO 8601 timestamp.
            - `instructions` string — The rail's own step-by-step payment text, when it supplies one.
            - `reference` string — The reference the buyer must attach to the transfer so it can be matched to this payment.
            - `secondary_account_number` string — A second account number, where the rail publishes the same destination in more than one format.
            - `secondary_account_number_label` string — What to call `secondary_account_number` when showing it.
          - `kind` 'bank_transfer', required — Always `bank_transfer`: account details the buyer sends money to from their own bank.
      - `render` string[], required
      - `type` 'display_instructions', required — Always `display_instructions`: show the buyer `data` — what to pay, where, and by when. The payment completes once they pay and the rail confirms it, so keep polling `status`.
    - PaymentNextActionAwaitConfirmation
      - `data` PaymentNextActionAwaitConfirmationData, required
        - `expires_at` string, required — When the confirmation window closes, as an ISO 8601 timestamp. A payment still unconfirmed by then will not succeed — watch `status` for the failed attempt.
      - `render` string[], required
      - `type` 'await_confirmation', required — Always `await_confirmation`: nothing to show — the buyer has done their part and the rail settles out of band. Poll `status` until it moves.
  - `object` string, required — Always `payment_status`.
  - `processing_details` PaymentProcessingDetails, required
    - `expected_by` string, nullable, required — When the payment is expected to settle, as an ISO 8601 timestamp.
  - `return_url` string, nullable, required — Where to send the buyer once the payment reaches a resting state, or `null` to leave them where they are. Editable until they return — see the return_url operation.
  - `status` 'requires_confirmation' | 'requires_action' | 'confirming' | 'processing' | 'succeeded' | 'canceled', required — How far the payment has got. `requires_confirmation` — nothing attempted yet, or the last attempt failed and can be retried. `requires_action` — the buyer has a step outstanding; see `next_action`. `confirming` — the buyer has done their part and the processor is deciding. `processing` — the money is moving; see `processing_details`. `succeeded` — collected. `canceled` — voided or written off.

## Other responses

- `401` — Unauthorized
- `403` — Forbidden
- `404` — Resource not found

---

[API](https://skmtc.net/whop/apis/whop-api.md) · [All operations](https://skmtc.net/whop/apis/whop-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/whop/whop-api/revisions/4a1a4a5d2c72/schema)
