# Custom Payment Page

> Build a merchant-rendered payment page from Stafiel payment session data.

Canonical: https://stafiel.org/documentation/developer-integration/custom-payment-page
Version: v1.0.0

## Endpoint

GET https://api.stafiel.com/api/v1/c/pay/{paymentToken}/data

## Request Payment Data

- Create a [checkout session](/documentation/developer-integration/checkout-api)
from your backend and store the returned checkoutSessionUrl.

- Read the final path segment of checkoutSessionUrl as the payment token.
For example, the token in
https://pay.stafiel.com/pay/ps_live_example is ps_live_example.

- Replace {paymentToken} in the endpoint and request the payment data from
your backend.
curl "https://api.stafiel.com/api/v1/c/pay/ps_live_example/data"

- Return only the fields your frontend needs for rendering.

Only extract a token from the checkoutSessionUrl returned for a checkout
session created by your backend. For Hosted Checkout or
[Widget integrations](/documentation/developer-integration/widget-integration),
pass the complete URL exactly as returned.

## Success Response

{
  "success": true,
  "data": {
    "orderId": "ord_your_order_id",
    "amountUsd": "20.00",
    "totalPaidAmountUsd": "0",
    "tokenSymbol": "USDC",
    "tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "tokenDecimals": 6,
    "orderAddress": "0x372B9150e1b0436f4c295D3D48e197b0aaDFBB5D",
    "paymentRequest": {
      "plainAddress": "0x372B9150e1b0436f4c295D3D48e197b0aaDFBB5D",
      "requestUri": "ethereum:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913@8453/transfer?address=0x372B9150e1b0436f4c295D3D48e197b0aaDFBB5D&uint256=20000000",
      "requestKind": "erc_681",
      "reference": null,
      "chainSupport": "available",
      "unavailableReason": null,
      "solanaAddressContext": null
    },
    "paymentAddressState": "ready",
    "chainId": 8453,
    "chainSlug": "base",
    "chainNetwork": "mainnet",
    "chainCompatibility": "evm",
    "chainName": "base",
    "chainDisplayName": "base",
    "chainExplorerUrl": "https://basescan.org",
    "orderAddressExplorerUrl": "https://basescan.org/address/0x372B9150e1b0436f4c295D3D48e197b0aaDFBB5D",
    "merchantPublicName": "Example Merchant",
    "metadata": {
      "productName": "Membership Plus",
      "quantity": "1",
      "unitLabel": "month"
    },
    "expiresAt": "2026-08-19T12:30:00.000Z",
    "status": "awaiting_payment",
    "createdAt": "2026-08-19T12:00:00.000Z"
  }
}

## Response Fields

Field
Type
Description

orderId
string
Stafiel order ID for the checkout session.

amountUsd
string
Expected payment amount.

totalPaidAmountUsd
string
Total payment amount currently recorded for the order.

tokenSymbol
string
Token the customer must send.

tokenAddress
string
Token contract or mint address. Do not use it as the payment recipient.

tokenDecimals
number
Token decimals used for amount representation.

orderAddress
string
Payment recipient address. Prefer paymentRequest.plainAddress when rendering payment controls.

paymentRequest
object
Stafiel-generated plain address and optional wallet payment request. See [paymentRequest Object](#paymentrequest-object).

paymentAddressState
string
ready means the payment address is available. provisioning means it is being prepared, while failed means it is unavailable.

chainId
number
Numeric chain ID.

chainSlug, chainName, chainDisplayName
string
Public chain identifiers and display value.

chainNetwork
string
Network associated with the checkout session.

chainCompatibility
string
Chain family, such as evm, solana, or tron.

chainExplorerUrl
string or omitted
Chain explorer base URL when available.

orderAddressExplorerUrl
string or omitted
Explorer URL for the payment recipient when available.

merchantPublicName
string or omitted
Merchant name for customer-facing display.

metadata
object or null
Sanitized checkout metadata.

expiresAt
string
ISO 8601 timestamp when the payment session expires.

status
string
Current order status.

createdAt
string
ISO 8601 checkout creation timestamp.

### paymentRequest Object

Field
Type
Description

plainAddress
string
Payment recipient for address-only display, copy, and QR code.

requestUri
string or null
Complete wallet payment request URI for the original checkout amount. Use it exactly as returned. It does not represent a remaining balance after an underpayment.

requestKind
erc_681, solana_pay, or null
Payment request format when available.

reference
string or null
Solana payment reference when present.

chainSupport
available or unavailable
Whether requestUri can be offered.

unavailableReason
string or null
Machine-readable reason that a payment request is unavailable.

solanaAddressContext
object or null
Solana-specific address-role information. Use plainAddress as the displayed recipient.

chainSupport: unavailable means only that a wallet payment request URI is not
available. The checkout can still accept an address-only payment when the
session is otherwise payable.

## Status and Fulfillment

Use the Payment Data API only to render the customer payment page. For
fulfillment, verify the order from your backend using signed
[webhooks](/documentation/developer-integration/webhooks-and-events) or the
authenticated [Orders API](/documentation/developer-integration/orders-api).

For status meanings and merchant handling considerations, see
[Order Lifecycle and Payment Status](/documentation/accept-payments/order-lifecycle-and-payment-status).

## Error Responses

HTTP Status
Error
Meaning

404
unavailable
The payment token is invalid, expired, inactive, or otherwise unavailable. The response does not reveal the specific reason.

429
RATE_LIMIT_EXCEEDED
Too many requests. Retry after the indicated time.

## Security Notes

- Render metadata values as text, not HTML.

- The checkoutSessionUrl contains the payment token used to access the payment
session data. Avoid sending it to logs, analytics, error reporting, or
third-party scripts.
