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

# Step 1 - Create checkout estimate (Enhanced)

> Creates a checkout estimate with three operational modes:

**Mode 1 - Direct Items**: Provide items directly (original behavior)
- Use when: Guest checkout, quick buy buttons, one-time purchases
- Required: `items` array

**Mode 2 - Cart-Based**: Pull items from saved cart
- Use when: Standard checkout from shopping cart
- Required: `useCart: true`
- Cart fetched using customer identification

**Mode 3 - Cart with Overrides**: Pull from cart with modifications
- Use when: Last-minute adjustments, promotions
- Required: `useCart: true` and `itemOverrides`

Cart behavior (modes 2 & 3):
- Pepay **does not** remove items from the cart automatically.
- `validItems[]` are eligible to be checked out.
- `invalidItems[]` are ineligible right now (e.g., no eligible offers). They stay in the cart unless you remove them.
- `invalidItems[]` intentionally contains the minimal identifiers + reason; match it back to your cart display by `productId` (+ `retailer` when relevant).

Customer identification is required: `customer_id` OR (`wallet_address` + `wallet_network`).




## OpenAPI

````yaml /api-reference/openapi.json post /api/commerce/merchant/checkout/estimate
openapi: 3.0.0
info:
  title: Pepay API (SDK-scoped)
  version: 1.0.0
  description: API documentation for Pepay API
servers:
  - url: https://api-beta.pepay.io
    description: Beta server
  - url: http://localhost:3000
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Events
    description: Events API (history + debugging) for canonical notification envelopes.
  - name: Metrics
    description: Internal Prometheus metrics (restricted).
  - name: WebSockets
    description: WebSocket streams (upgrade endpoints) and message schemas.
  - name: Commerce - Devnet Simulator
    description: >
      Deterministic devnet-only endpoints for simulating Commerce V2 order state
      transitions.


      Use this when integrating as a merchant on devnet to test your backend/UI
      against realistic order lifecycle changes

      (payment confirmation, settlement gating, placement, tracking,
      cancellation, refunds) without placing real retailer

      orders or sending real on-chain refunds.


      How it works:

      - Requires a devnet `X-Commerce-Api-Key` (merchant-scoped).

      - Only operates on orders created in `networkEnvironment=devnet`.

      - Updates the order using the same reducer/persistence paths used in
      mainnet (provider snapshots are simulated).

      - After each simulation, Pepay emits the normal `commerce.order.updated`
      merchant webhook event.
  - name: Merchant Checkout
    description: >
      Merchant-scoped **three-step** checkout flow:

      1) `POST /api/commerce/merchant/checkout/estimate` — validate items
      against current eligible offers and return `validItems[]` +
      `invalidItems[]`.

      2) `POST /api/commerce/merchant/checkout/address` — attach and validate a
      shipping address for the estimate.

      3) `POST /api/commerce/merchant/checkout/invoice` — create the final
      invoice + commerce order.


      Cart behavior (when `useCart: true`):

      - The estimate call **reads** the saved cart but does **not** remove or
      modify cart items.

      - Items with no eligible offers are returned in `invalidItems[]`.

      - To remove items from the saved cart, call the Merchant Cart APIs (`PUT
      /api/commerce/merchant/carts/items/:itemId` with `quantity: 0`, or `DELETE
      /api/commerce/merchant/carts/items/:itemId`).

      - To exclude items for *this checkout attempt* without mutating the cart,
      use `itemOverrides[]` with `quantity: 0`.
  - name: Payment Sessions
    description: >
      Payor-facing APIs used by the hosted payment page and other embedded
      checkout clients.


      Canonical base path:

      - All documented endpoints are under `/api/v1/payments/*`.


      Authentication:

      - These endpoints do **not** accept merchant API keys or bearer JWTs.

      - Send `x-session-token` and `x-signature` headers on every request (both
      are returned when creating an invoice).


      Typical flow:

      1) Create an invoice (`POST /api/v1/invoices`) → receive `payment_url`,
      `session_token`, `signature`.

      2) Render/open the `payment_url` for the payor.

      3) Fetch invoice context (`GET /api/v1/payments/session-details`).

      4) List supported tokens (`GET /api/v1/payments/available-tokens`).

      5) Allocate a payment address (`POST /api/v1/payments/payment-addresses`)
      → use `ws_connection` for `/ws/payment`.

      6) Track progress via polling (`GET /api/v1/payments/payment-status`)
      and/or websocket (`/ws/payment`).


      Security notes:

      - Treat `session_token` and `signature` as sensitive values (anyone with
      them can read the invoice/payment status).

      - Do not store them in long-lived browser storage; prefer in-memory usage
      on the payment page.
  - name: Quotes
    description: Token settlement quotes and rate calculations
  - name: Webhooks
    description: >
      Webhook endpoint management and delivery history for canonical
      notifications.


      Delivery model:

      - At-least-once delivery; receivers must dedupe by `event.id` (also sent
      as `X-Pepay-Event-ID`).

      - Payloads are canonical `PepayEvent` objects and match websocket
      `event_v1` frames for the same event type.


      Security:

      - Endpoints must be HTTPS.

      - Deliveries are signed using `HMAC_SHA256("${timestamp_ms}.${raw_body}")`
      and sent in `X-Pepay-Signature`.
paths:
  /api/commerce/merchant/checkout/estimate:
    post:
      tags:
        - Merchant Checkout
      summary: Step 1 - Create checkout estimate (Enhanced)
      description: >
        Creates a checkout estimate with three operational modes:


        **Mode 1 - Direct Items**: Provide items directly (original behavior)

        - Use when: Guest checkout, quick buy buttons, one-time purchases

        - Required: `items` array


        **Mode 2 - Cart-Based**: Pull items from saved cart

        - Use when: Standard checkout from shopping cart

        - Required: `useCart: true`

        - Cart fetched using customer identification


        **Mode 3 - Cart with Overrides**: Pull from cart with modifications

        - Use when: Last-minute adjustments, promotions

        - Required: `useCart: true` and `itemOverrides`


        Cart behavior (modes 2 & 3):

        - Pepay **does not** remove items from the cart automatically.

        - `validItems[]` are eligible to be checked out.

        - `invalidItems[]` are ineligible right now (e.g., no eligible offers).
        They stay in the cart unless you remove them.

        - `invalidItems[]` intentionally contains the minimal identifiers +
        reason; match it back to your cart display by `productId` (+ `retailer`
        when relevant).


        Customer identification is required: `customer_id` OR (`wallet_address`
        + `wallet_network`).
      operationId: createMerchantEstimate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CommerceMerchantCheckoutEstimateRequest'
            examples:
              mode1Direct:
                summary: Mode 1 - Direct Items
                value:
                  customer_id: cust_123456
                  items:
                    - productId: B08N5WRWNW
                      quantity: 2
                      price: 29.99
                      title: Test Product
              mode2Cart:
                summary: Mode 2 - Cart-Based
                value:
                  customer_id: cust_123456
                  useCart: true
              mode3Override:
                summary: Mode 3 - Cart with Overrides
                value:
                  customer_id: cust_123456
                  useCart: true
                  itemOverrides:
                    - product_id: B08N5WRWNW
                      quantity: 5
      responses:
        '200':
          description: Estimate created successfully
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/PostapicommercemerchantcheckoutestimateResponse200
              examples:
                estimate_with_invalid_items:
                  summary: >-
                    Estimate with valid + invalid cart items (cart is not
                    mutated)
                  value:
                    success: true
                    data:
                      estimateId: 550e8400-e29b-41d4-a716-446655440000
                      merchantId: 123
                      networkEnvironment: devnet
                      customerId: cust_123456
                      walletAddress: null
                      walletNetwork: null
                      validItems:
                        - productId: B08N5WRWNW
                          retailer: amazon
                          title: Item
                          quantity: 1
                          price: 9.99
                          totalPrice: 9.99
                          metadata:
                            image: https://example.com/product.jpg
                      invalidItems:
                        - productId: B000000000
                          retailer: amazon
                          error: >-
                            No eligible offers (must be New, Prime/marketplace
                            fulfilled, delivery within 6 days)
                      pricing:
                        subtotal: 9.99
                        shipping: 1
                        tax: 0
                        fees:
                          fixed: 0
                          percentage: 0
                          total: 3
                        total: 13.99
                      feeBreakdown:
                        shippingBase: 1
                        commerceFee: 3
                        totalFees: 4
                      expiresAt: 1765844100
                      createdAt: 1765843200
      security:
        - commerceApiKey: []
        - merchantApiKey: []
components:
  schemas:
    CommerceMerchantCheckoutEstimateRequest:
      description: >-
        Step 1 request. Supports direct items (Mode 1) or cart-based estimation
        (Modes 2–3). When `useCart: true`, Pepay reads the saved cart but does
        not mutate it.
      allOf:
        - $ref: '#/components/schemas/CommerceCustomerIdentifier'
        - type: object
          properties:
            useCart:
              type: boolean
              nullable: true
              description: >-
                When true, items are loaded from the saved cart for the provided
                customer identifier.
            items:
              type: array
              nullable: true
              description: 'Mode 1 only (direct items). Forbidden when `useCart: true`.'
              items:
                $ref: '#/components/schemas/CommerceMerchantCheckoutEstimateItemInput'
            itemOverrides:
              type: array
              nullable: true
              description: >-
                Mode 3 only. Requires `useCart: true`. Use `quantity: 0` to
                exclude items for this estimate without mutating the cart.
              items:
                $ref: '#/components/schemas/CommerceMerchantCheckoutItemOverride'
            addressId:
              type: string
              format: uuid
              nullable: true
              description: Reserved for future shipping estimates; currently ignored.
            shipping_zip:
              type: string
              nullable: true
              description: Reserved for future shipping estimates; currently ignored.
    PostapicommercemerchantcheckoutestimateResponse200:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          $ref: '#/components/schemas/CommerceMerchantCheckoutEstimate'
    CommerceCustomerIdentifier:
      description: Customer identification for merchant-scoped commerce APIs.
      oneOf:
        - type: object
          required:
            - customer_id
          properties:
            customer_id:
              type: string
              example: cust_123456
        - type: object
          required:
            - wallet_address
            - wallet_network
          properties:
            wallet_address:
              type: string
              example: '0x0000000000000000000000000000000000000001'
            wallet_network:
              type: string
              enum:
                - ethereum
                - base
                - solana
                - avalanche
                - ton
                - bsc
                - arbitrum
                - optimism
                - cardano
                - sui
              example: bsc
    CommerceMerchantCheckoutEstimateItemInput:
      type: object
      description: >-
        Input item for Mode 1 (direct items). Only `productId`, `quantity`, and
        optional `retailer` are used to re-validate pricing from current
        eligible offers.
      required:
        - productId
        - quantity
      properties:
        productId:
          type: string
          example: B08N5WRWNW
        retailer:
          type: string
          nullable: true
          example: amazon
        quantity:
          type: integer
          minimum: 1
          maximum: 99
          example: 1
        title:
          type: string
          nullable: true
          description: >-
            Optional; ignored for pricing (display-only / backward
            compatibility).
        price:
          type: number
          nullable: true
          description: >-
            Optional; ignored for pricing (Pepay always re-prices from current
            eligible offers).
    CommerceMerchantCheckoutItemOverride:
      type: object
      description: >-
        Cart-only override (Mode 3). Overrides are applied only to the estimate
        input; they do not modify the saved cart.
      required:
        - product_id
      properties:
        product_id:
          type: string
          example: B08N5WRWNW
        quantity:
          type: integer
          nullable: true
          minimum: 0
          maximum: 99
          description: Set to 0 to exclude an item from this estimate/checkout attempt.
          example: 0
    CommerceMerchantCheckoutEstimate:
      type: object
      description: >-
        Step 1 estimate result (15 minute TTL). Use `estimateId` for subsequent
        Step 2 + Step 3 calls.
      properties:
        estimateId:
          type: string
          format: uuid
        merchantId:
          type: integer
          example: 123
        networkEnvironment:
          type: string
          enum:
            - devnet
            - mainnet
          example: devnet
        customerId:
          type: string
          nullable: true
          example: cust_123456
        walletAddress:
          type: string
          nullable: true
        walletNetwork:
          type: string
          nullable: true
        validItems:
          type: array
          items:
            $ref: '#/components/schemas/CommerceMerchantCheckoutEstimateValidItem'
        invalidItems:
          type: array
          items:
            $ref: '#/components/schemas/CommerceMerchantCheckoutEstimateInvalidItem'
        pricing:
          $ref: '#/components/schemas/CommerceMerchantCheckoutPricing'
        feeBreakdown:
          $ref: '#/components/schemas/CommerceMerchantCheckoutFeeBreakdown'
        expiresAt:
          type: integer
        createdAt:
          type: integer
    CommerceMerchantCheckoutEstimateValidItem:
      type: object
      description: Eligible item returned from Step 1 estimate.
      properties:
        productId:
          type: string
          example: B08N5WRWNW
        retailer:
          type: string
          example: amazon
        title:
          type: string
          example: Item
        quantity:
          type: integer
          example: 1
        price:
          type: number
          description: Unit price in USD, derived from current eligible offers.
          example: 9.99
        totalPrice:
          type: number
          example: 9.99
        metadata:
          type: object
          description: Provider-derived item metadata (best-effort; shape may evolve).
          additionalProperties: true
          example:
            image: https://example.com/product.jpg
    CommerceMerchantCheckoutEstimateInvalidItem:
      type: object
      description: >-
        Ineligible item returned from Step 1 estimate. For cart-based flows,
        match back to your cart view by `productId` (+ `retailer` when
        relevant).
      properties:
        productId:
          type: string
          example: B000000000
        retailer:
          type: string
          nullable: true
          example: amazon
        quantity:
          type: integer
          nullable: true
          example: 1
        error:
          type: string
          example: No eligible offers
    CommerceMerchantCheckoutPricing:
      type: object
      description: Step 1 pricing breakdown (USD).
      properties:
        subtotal:
          type: number
          example: 9.99
        shipping:
          type: number
          example: 1
        tax:
          type: number
          example: 0
        fees:
          type: object
          properties:
            fixed:
              type: number
              example: 0
            percentage:
              type: number
              example: 0
            total:
              type: number
              example: 3
        total:
          type: number
          example: 13.99
    CommerceMerchantCheckoutFeeBreakdown:
      type: object
      description: Step 1 fee breakdown (USD).
      properties:
        shippingBase:
          type: number
          example: 1
        commerceFee:
          type: number
          example: 3
        totalFees:
          type: number
          example: 4
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for wallet authentication
    commerceApiKey:
      type: apiKey
      in: header
      name: x-commerce-api-key
      description: >-
        Legacy alias for commerce-scoped API keys. Prefer `x-api-key` with
        scope=commerce.
    merchantApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for server-to-server operations (scope=merchant or commerce)

````