> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anyspend.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkout Sessions

Server-side checkout session management for programmatic payment flows

Checkout sessions represent an individual payment attempt. You can create sessions server-side to generate unique checkout URLs for each customer, pre-fill payment details, and track conversions with your own reference IDs.

Checkout sessions expire after 30 minutes by default. Use the `expires_in` parameter to customize the expiration window (minimum 5 minutes, maximum 24 hours).

## The Checkout Session object

**id**

Unique identifier for the checkout session (e.g., `cs_abc123`).

**url**

The checkout URL to redirect the customer to.

**status**

Current status of the session. One of: `open`, `processing`, `completed`, `expired`, `failed`.

**payment_link_id**

Associated payment link ID, if the session was created from a payment link.

**product_id**

Associated product ID.

**token_address**

Contract address of the token to receive.

**chain_id**

Chain ID where you want to receive payment.

**recipient_address**

Wallet address that receives the payment.

**amount**

Payment amount in the token's smallest unit.

**amount_usd**

USD equivalent at the time of session creation.

**success_url**

URL the customer is redirected to after successful payment. Supports template variables.

**cancel_url**

URL the customer is redirected to if they cancel.

**client_reference_id**

Your internal reference ID for this session.

**metadata**

Arbitrary key-value pairs passed through to webhooks and the transaction.

**customer_email**

Email address of the customer. Encrypted at rest, included in webhook payloads.

**customer_name**

Name of the customer. Encrypted at rest, included in webhook payloads.

**payer_address**

Wallet address of the payer (populated after connection).

**tx_hash**

On-chain transaction hash (populated after submission).

**customer_id**

Associated customer ID (populated after payment).

**form_data**

Custom form data submitted by the customer.

**shipping_address**

Shipping address provided by the customer.

**utm_source**

UTM source parameter for attribution.

**utm_medium**

UTM medium parameter for attribution.

**utm_campaign**

UTM campaign parameter for attribution.

**expires_at**

ISO 8601 expiration timestamp.

**created_at**

ISO 8601 creation timestamp.

**completed_at**

ISO 8601 completion timestamp.

### Session statuses

| Status | Description |
|--------|-------------|
| `open` | Session is active and waiting for the customer to pay. |
| `processing` | Customer has initiated payment; transaction is being processed on-chain. |
| `completed` | Payment confirmed and received by the recipient. |
| `expired` | Session expired before the customer completed payment. |
| `failed` | Payment failed due to on-chain error or timeout. |

### URL template variables

The `success_url` and `cancel_url` fields support template variables that are replaced with actual values when the customer is redirected:

| Variable | Description | Example |
|----------|-------------|---------|
| `{SESSION_ID}` | The checkout session ID | `cs_abc123` |

Use template variables to look up session details on your server after redirect:
  `https://example.com/success?session_id={SESSION_ID}`

---

## List checkout sessions

Retrieve a paginated list of checkout sessions.

Filter by session status: `open`, `processing`, `completed`, `expired`, `failed`.

Filter by payment link ID.

Page number for pagination.

Number of results per page (max 100).

```bash cURL
curl -X GET "https://platform-api.anyspend.com/api/v1/checkout-sessions?status=completed&page=1&limit=20" \
  -H "Authorization: Bearer asp_xxx"
```

```typescript SDK
import { AnySpendPlatformClient } from "@b3dotfun/sdk/anyspend/platform";

const platform = new AnySpendPlatformClient(process.env.ANYSPEND_API_KEY!);

const { data, pagination } = await platform.checkoutSessions.list({
  status: "completed",
  page: 1,
  limit: 20,
});
```

**Response**

```json
    {
      "data": [
        {
          "id": "cs_abc123",
          "url": "https://anyspend.com/pay/s/cs_abc123",
          "status": "completed",
          "payment_link_id": "pl_abc123",
          "product_id": null,
          "token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
          "chain_id": 1,
          "recipient_address": "0x1234567890abcdef1234567890abcdef12345678",
          "amount": "50000000",
          "amount_usd": "50.00",
          "success_url": "https://example.com/success?session_id=cs_abc123",
          "cancel_url": "https://example.com/cancel",
          "client_reference_id": "order_12345",
          "metadata": {
            "order_id": "12345"
          },
          "payer_address": "0xaabb1234ccdd5678eeff9900aabb1234ccdd5678",
          "tx_hash": "0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e",
          "customer_id": "cust_abc123",
          "form_data": null,
          "shipping_address": null,
          "utm_source": "twitter",
          "utm_medium": "social",
          "utm_campaign": "launch_feb_2026",
          "expires_at": "2026-02-25T08:45:00Z",
          "created_at": "2026-02-25T08:15:00Z",
          "completed_at": "2026-02-25T08:16:30Z"
        }
      ],
      "pagination": {
        "page": 1,
        "limit": 20,
        "total": 340,
        "total_pages": 17,
        "has_more": true
      }
    }
    ```

---

## Create a checkout session

Create a server-side checkout session with a unique payment URL. Use this for programmatic integrations where you control the checkout flow from your backend.

Create the session from an existing payment link. This inherits the link's configuration. Either `payment_link_id` or the manual fields (`token_address`, `chain_id`, `recipient_address`, `amount`) are required.

Contract address of the token to receive. Required if `payment_link_id` is not provided.

Chain ID where you want to receive payment. Required if `payment_link_id` is not provided.

Wallet address that receives the payment. Required if `payment_link_id` is not provided.

Payment amount in the token's smallest unit. Required if `payment_link_id` is not provided.

Associate the session with a product.

URL to redirect the customer to after successful payment. Supports `{SESSION_ID}` template variable.

URL to redirect the customer to if they cancel.

Your internal reference ID (e.g., order ID). Maximum 200 characters.

Arbitrary key-value pairs passed through to webhooks and the resulting transaction. Up to 50 keys, 500 character values.

Customer email address. Encrypted at rest and included in webhook payloads for order fulfillment.

Customer name. Encrypted at rest and included in webhook payloads for order fulfillment.

Session expiration time in seconds. Minimum 300 (5 minutes), maximum 86400 (24 hours). Default: 1800 (30 minutes).

UTM source for attribution tracking.

UTM medium for attribution tracking.

UTM campaign for attribution tracking.

```bash cURL
# Create from a payment link
curl -X POST "https://platform-api.anyspend.com/api/v1/checkout-sessions" \
  -H "Authorization: Bearer asp_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_link_id": "pl_abc123",
    "success_url": "https://example.com/success?session_id={SESSION_ID}",
    "cancel_url": "https://example.com/cancel",
    "client_reference_id": "order_12345",
    "metadata": {
      "order_id": "12345"
    },
    "customer_email": "alice@example.com",
    "customer_name": "Alice Smith",
    "expires_in": 3600
  }'

# Create with manual configuration
curl -X POST "https://platform-api.anyspend.com/api/v1/checkout-sessions" \
  -H "Authorization: Bearer asp_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "chain_id": 1,
    "recipient_address": "0x1234567890abcdef1234567890abcdef12345678",
    "amount": "25000000",
    "success_url": "https://example.com/success?session_id={SESSION_ID}",
    "cancel_url": "https://example.com/cancel",
    "client_reference_id": "inv_67890",
    "utm_source": "email",
    "utm_medium": "newsletter",
    "utm_campaign": "february_promo"
  }'
```

```typescript SDK
// Create from a payment link
const session = await platform.checkoutSessions.create({
  paymentLinkId: "pl_abc123",
  successUrl: "https://example.com/success?session_id={SESSION_ID}",
  cancelUrl: "https://example.com/cancel",
  clientReferenceId: "order_12345",
  metadata: {
    order_id: "12345",
    user_email: "alice@example.com",
  },
  expiresIn: 3600,
});

// Redirect the customer
console.log(session.url);
// => "https://anyspend.com/pay/s/cs_newSession123"

// Create with manual configuration
const manualSession = await platform.checkoutSessions.create({
  tokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  chainId: 1,
  recipientAddress: "0x1234567890abcdef1234567890abcdef12345678",
  amount: "25000000",
  successUrl: "https://example.com/success?session_id={SESSION_ID}",
  cancelUrl: "https://example.com/cancel",
  clientReferenceId: "inv_67890",
});
```

**Response**

```json
    {
      "id": "cs_newSession123",
      "url": "https://anyspend.com/pay/s/cs_newSession123",
      "status": "open",
      "payment_link_id": "pl_abc123",
      "product_id": null,
      "token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "chain_id": 1,
      "recipient_address": "0x1234567890abcdef1234567890abcdef12345678",
      "amount": "50000000",
      "amount_usd": "50.00",
      "success_url": "https://example.com/success?session_id={SESSION_ID}",
      "cancel_url": "https://example.com/cancel",
      "client_reference_id": "order_12345",
      "metadata": {
        "order_id": "12345",
        "user_email": "alice@example.com"
      },
      "payer_address": null,
      "tx_hash": null,
      "customer_id": null,
      "form_data": null,
      "shipping_address": null,
      "utm_source": null,
      "utm_medium": null,
      "utm_campaign": null,
      "expires_at": "2026-02-27T11:30:00Z",
      "created_at": "2026-02-27T10:30:00Z",
      "completed_at": null
    }
    ```

---

## Retrieve a checkout session

The checkout session ID (e.g., `cs_abc123`).

Use this endpoint in your `success_url` handler to verify payment status and retrieve transaction details after the customer is redirected back to your site.

```bash cURL
curl -X GET "https://platform-api.anyspend.com/api/v1/checkout-sessions/cs_abc123" \
  -H "Authorization: Bearer asp_xxx"
```

```typescript SDK
const session = await platform.checkoutSessions.get("cs_abc123");

if (session.status === "completed") {
  // Payment was successful
  console.log("Transaction hash:", session.tx_hash);
  console.log("Payer:", session.payer_address);
}
```

**Response**

Returns the full [Checkout Session object](#the-checkout-session-object).

---

## Expire a checkout session

Manually expire an open checkout session. This is useful when the underlying order is cancelled or the payment is no longer needed.

The checkout session ID.

Only sessions with `status: "open"` can be expired. Attempting to expire a session in any other status will return a `400 Bad Request` error.

```bash cURL
curl -X POST "https://platform-api.anyspend.com/api/v1/checkout-sessions/cs_abc123/expire" \
  -H "Authorization: Bearer asp_xxx"
```

```typescript SDK
const expired = await platform.checkoutSessions.expire("cs_abc123");
console.log(expired.status); // => "expired"
```

**Response**

```json
    {
      "id": "cs_abc123",
      "url": "https://anyspend.com/pay/s/cs_abc123",
      "status": "expired",
      "payment_link_id": "pl_abc123",
      "product_id": null,
      "token_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
      "chain_id": 1,
      "recipient_address": "0x1234567890abcdef1234567890abcdef12345678",
      "amount": "50000000",
      "amount_usd": "50.00",
      "success_url": "https://example.com/success?session_id=cs_abc123",
      "cancel_url": "https://example.com/cancel",
      "client_reference_id": "order_12345",
      "metadata": {
        "order_id": "12345",
        "user_email": "alice@example.com"
      },
      "payer_address": null,
      "tx_hash": null,
      "customer_id": null,
      "form_data": null,
      "shipping_address": null,
      "utm_source": null,
      "utm_medium": null,
      "utm_campaign": null,
      "expires_at": "2026-02-27T10:35:00Z",
      "created_at": "2026-02-27T10:30:00Z",
      "completed_at": null
    }
    ```

---

## Common patterns

### Server-side checkout flow

A typical server-side integration creates a checkout session on your backend and redirects the customer to the session URL:

```typescript
// 1. Your server creates a session
app.post("/create-checkout", async (req, res) => {
  const session = await platform.checkoutSessions.create({
    paymentLinkId: "pl_abc123",
    successUrl: "https://yoursite.com/success?session_id={SESSION_ID}",
    cancelUrl: "https://yoursite.com/cart",
    clientReferenceId: req.body.orderId,
    metadata: {
      user_id: req.user.id,
    },
    expiresIn: 1800, // 30 minutes
  });

  // 2. Redirect customer to pay
  res.redirect(303, session.url);
});

// 3. Handle the redirect after payment
app.get("/success", async (req, res) => {
  const session = await platform.checkoutSessions.get(
    req.query.session_id
  );

  if (session.status === "completed") {
    // Fulfill the order
    await fulfillOrder(session.client_reference_id, {
      txHash: session.tx_hash,
      payer: session.payer_address,
    });
  }

  res.render("success", { session });
});
```

Always verify the session status server-side after redirect. Do not rely solely on the redirect to confirm payment -- use webhooks for reliable payment confirmation.

### Polling for session completion

If you prefer polling over webhooks, you can check the session status periodically:

```typescript
async function waitForPayment(sessionId: string, timeoutMs = 300000) {
  const startTime = Date.now();

  while (Date.now() - startTime < timeoutMs) {
    const session = await platform.checkoutSessions.get(sessionId);

    if (session.status === "completed") {
      return session;
    }

    if (session.status === "expired" || session.status === "failed") {
      throw new Error(`Session ${session.status}: ${sessionId}`);
    }

    // Wait 3 seconds before polling again
    await new Promise((resolve) => setTimeout(resolve, 3000));
  }

  throw new Error(`Timeout waiting for payment: ${sessionId}`);
}
```

For production use, we strongly recommend using [webhooks](/anyspend/api/webhooks-api) instead of polling. Webhooks provide real-time notifications and do not require keeping a connection open.