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

# Simulate a Commerce order transition (devnet only)

> Advances a **devnet** commerce order to a specific state for integration testing.

Typical devnet flow:
1. Create a checkout order + invoice via `POST /api/commerce/merchant/checkout/invoice` (returns `orderId`)
2. Simulate payment confirmation: `transitionTo=payment_confirmed`
3. Simulate settlement (unlocks placement): `transitionTo=payment_settled`
4. Simulate provider placement: `transitionTo=placed`
5. Simulate tracking: `transitionTo=shipped` (optionally include `tracking`)
6. Optionally simulate delivery: `transitionTo=delivery_confirmed`

Notes:
- `payment_settled` also simulates provider submission (`substatus=PROVIDER_PLACEMENT_SUBMITTED`).
- `failed` can only be simulated from `status=processing`.
- `cancelled` can only be simulated from `status=placed`.
- `refunded` requires a valid BSC refund destination (capture it at checkout or simulate payment using `walletNetwork=bsc`).




## OpenAPI

````yaml /api-reference/openapi.json post /api/commerce/devnet/orders/{orderId}/simulate
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/devnet/orders/{orderId}/simulate:
    post:
      tags:
        - Commerce - Devnet Simulator
      summary: Simulate a Commerce order transition (devnet only)
      description: >
        Advances a **devnet** commerce order to a specific state for integration
        testing.


        Typical devnet flow:

        1. Create a checkout order + invoice via `POST
        /api/commerce/merchant/checkout/invoice` (returns `orderId`)

        2. Simulate payment confirmation: `transitionTo=payment_confirmed`

        3. Simulate settlement (unlocks placement):
        `transitionTo=payment_settled`

        4. Simulate provider placement: `transitionTo=placed`

        5. Simulate tracking: `transitionTo=shipped` (optionally include
        `tracking`)

        6. Optionally simulate delivery: `transitionTo=delivery_confirmed`


        Notes:

        - `payment_settled` also simulates provider submission
        (`substatus=PROVIDER_PLACEMENT_SUBMITTED`).

        - `failed` can only be simulated from `status=processing`.

        - `cancelled` can only be simulated from `status=placed`.

        - `refunded` requires a valid BSC refund destination (capture it at
        checkout or simulate payment using `walletNetwork=bsc`).
      operationId: simulateCommerceOrderDevnet
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CommerceDevnetSimulateRequest'
            examples:
              payment_confirmed:
                summary: Mark invoice paid (settlement pending)
                value:
                  transitionTo: payment_confirmed
                  walletNetwork: bsc
                  walletAddress: '0x0000000000000000000000000000000000000001'
              payment_settled:
                summary: Mark settlement settled (unlocks placement)
                value:
                  transitionTo: payment_settled
                  walletNetwork: bsc
                  walletAddress: '0x0000000000000000000000000000000000000001'
              placed:
                summary: Simulate provider placement confirmation
                value:
                  transitionTo: placed
              shipped:
                summary: Simulate tracking obtained
                value:
                  transitionTo: shipped
                  tracking:
                    merchantOrderId: 123-1234567-1234567
                    productId: B08N5WRWNW
                    carrier: UPS
                    trackingNumber: 1Z999AA10123456784
                    obtainedAt: 1765843200
              delivery_confirmed:
                summary: Simulate delivered tracking
                value:
                  transitionTo: delivery_confirmed
                  tracking:
                    merchantOrderId: 123-1234567-1234567
                    productId: B08N5WRWNW
                    carrier: UPS
                    trackingNumber: 1Z999AA10123456784
                    obtainedAt: 1765843200
              failed:
                summary: >-
                  Simulate terminal placement failure (refund becomes pending if
                  destination exists)
                value:
                  transitionTo: failed
              cancelled:
                summary: >-
                  Simulate cancellation success (refund becomes pending if
                  destination exists)
                value:
                  transitionTo: cancelled
              refunded:
                summary: Simulate refund confirmation (sets refund status + tx hash)
                value:
                  transitionTo: refunded
      responses:
        '200':
          description: Updated order snapshot
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/PostapicommercedevnetordersorderIdsimulateResponse200
        '400':
          description: Validation error
        '403':
          description: >-
            Devnet-only enforcement, invalid transition, or invalid state for
            the transition
        '404':
          description: Order not found for this merchant/environment
        '409':
          description: Order is busy (row lock contention); retry shortly
      security:
        - commerceApiKey: []
        - merchantApiKey: []
components:
  schemas:
    CommerceDevnetSimulateRequest:
      type: object
      description: Devnet-only request for simulating a commerce order transition.
      required:
        - transitionTo
      properties:
        transitionTo:
          type: string
          enum:
            - payment_confirmed
            - payment_settled
            - placed
            - shipped
            - delivery_confirmed
            - failed
            - cancelled
            - refunded
          example: placed
        tracking:
          type: object
          nullable: true
          description: Optional tracking payload used for shipped/delivery transitions.
          properties:
            merchantOrderId:
              type: string
              example: 123-1234567-1234567
            productId:
              type: string
              nullable: true
              example: B08N5WRWNW
            carrier:
              type: string
              nullable: true
              example: UPS
            trackingNumber:
              type: string
              nullable: true
              example: 1Z999AA10123456784
            obtainedAt:
              type: integer
              nullable: true
              example: 1765843200
            retailerTrackingNumber:
              type: string
              nullable: true
              example: TBA111189418000
            retailerTrackingUrl:
              type: string
              nullable: true
              example: https://www.amazon.com/progress-tracker/...
        walletNetwork:
          type: string
          nullable: true
          description: >-
            Optional payer wallet network used for payment simulation
            transitions.
          example: bsc
        walletAddress:
          type: string
          nullable: true
          description: >-
            Optional payer wallet address used for payment simulation
            transitions (must be EVM address for bsc).
          example: '0x0000000000000000000000000000000000000001'
    PostapicommercedevnetordersorderIdsimulateResponse200:
      type: object
      properties:
        success:
          type: boolean
          example: true
        data:
          type: object
          properties:
            order:
              $ref: '#/components/schemas/CommerceMerchantOrderSnapshot'
    CommerceMerchantOrderSnapshot:
      type: object
      description: >-
        Merchant-facing commerce order snapshot (scoped by merchant +
        environment).
      properties:
        orderId:
          type: string
          format: uuid
        invoiceId:
          type: string
          format: uuid
        merchantId:
          type: integer
          example: 123
        networkEnvironment:
          type: string
          enum:
            - devnet
            - mainnet
          example: devnet
        retailer:
          type: string
          nullable: true
          example: amazon
        createdAt:
          type: integer
          nullable: true
        updatedAt:
          type: integer
          nullable: true
        customerId:
          type: string
          nullable: true
          example: cust_123456
        walletAddress:
          type: string
          nullable: true
          example: '0x0000000000000000000000000000000000000001'
        walletNetwork:
          type: string
          nullable: true
          example: bsc
        status:
          type: string
          enum:
            - pending_payment
            - processing
            - placed
            - shipped
            - cancelled
            - failed
          example: placed
        substatus:
          type: string
          nullable: true
          example: AWAITING_TRACKING
        actions:
          type: object
          properties:
            canCancel:
              type: boolean
              example: false
        timeline:
          type: array
          items:
            type: object
            properties:
              status:
                type: string
                example: placed
              timestamp:
                type: integer
                example: 1765843200
              message:
                type: string
                example: Order placed with retailer
        payment:
          type: object
          properties:
            status:
              type: string
              enum:
                - paid
                - unpaid
              example: paid
            txHash:
              type: string
              nullable: true
              example: 0xpay
            settlement:
              type: object
              properties:
                status:
                  type: string
                  nullable: true
                  example: settled
                txHash:
                  type: string
                  nullable: true
                  example: 0xsettle
                network:
                  type: string
                  nullable: true
                  example: bsc
        fulfillment:
          type: object
          properties:
            shipments:
              type: array
              items:
                $ref: '#/components/schemas/CommerceMerchantShipment'
        lineItems:
          type: array
          items:
            $ref: '#/components/schemas/CommerceMerchantOrderLineItem'
        shippingAddress:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/CommerceMerchantShippingAddress'
        cancellationStatus:
          type: string
          nullable: true
          example: none
        refundStatus:
          type: string
          nullable: true
          example: NONE
        totalAmountUsd:
          type: string
          example: '10.00'
        commerceFeeUsd:
          type: string
          example: '1.00'
        refund:
          type: object
          properties:
            status:
              type: string
              nullable: true
              example: NONE
            amountUsd:
              type: string
              nullable: true
              example: '9.00'
            feeUsd:
              type: string
              nullable: true
              example: '1.00'
            destinationWalletAddressBsc:
              type: string
              nullable: true
              example: '0x0000000000000000000000000000000000000001'
            txHash:
              type: string
              nullable: true
              example: 0xrefund
        refundQuote:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/CommerceMerchantRefundQuote'
    CommerceMerchantShipment:
      type: object
      description: Merchant-facing shipment/tracking snapshot.
      properties:
        shipmentId:
          type: string
          example: ship_123
        carrier:
          type: string
          nullable: true
          example: UPS
        trackingNumber:
          type: string
          nullable: true
          example: 1Z999AA10123456784
        carrierTrackingUrl:
          type: string
          nullable: true
          example: https://t.17track.net/en#nums=1Z999AA10123456784
        deliveryStatus:
          type: string
          nullable: true
          example: In Transit
        retailerTrackingNumber:
          type: string
          nullable: true
          example: TBA111189418000
        retailerTrackingUrl:
          type: string
          nullable: true
          example: https://www.amazon.com/progress-tracker/...
        obtainedAt:
          type: integer
          nullable: true
          example: 1765843200
    CommerceMerchantOrderLineItem:
      type: object
      description: Merchant-facing commerce order line item.
      properties:
        productId:
          type: string
          example: B08N5WRWNW
        title:
          type: string
          example: Item
        imageUrl:
          type: string
          nullable: true
          example: https://example.com/product.jpg
        quantity:
          type: integer
          example: 1
        price:
          type: string
          example: '9.00'
          description: Unit price in USD (string with 2 decimals).
        status:
          type: string
          nullable: true
          example: processing
    CommerceMerchantShippingAddress:
      type: object
      description: Validated shipping address snapshot.
      properties:
        addressId:
          type: string
          example: addr_123
        firstName:
          type: string
          example: Jane
        lastName:
          type: string
          example: Doe
        addressLine1:
          type: string
          example: 123 Main St
        addressLine2:
          type: string
          nullable: true
          example: Apt 4B
        city:
          type: string
          example: Miami
        state:
          type: string
          example: FL
        zipCode:
          type: string
          example: '33101'
        country:
          type: string
          example: US
        email:
          type: string
          example: jane@example.com
        phoneNumber:
          type: string
          nullable: true
          example: '+13055550123'
        validated:
          type: boolean
          example: true
        validatedAt:
          type: integer
          nullable: true
          example: 1765843200
    CommerceMerchantRefundQuote:
      type: object
      description: Deterministic refund quote (amounts are stable snapshots for the order).
      properties:
        originalAmountUsd:
          type: string
          example: '10.00'
        feeAmountUsd:
          type: string
          example: '1.00'
        refundAmountUsd:
          type: string
          example: '9.00'
        refundToken:
          type: object
          properties:
            network:
              type: string
              example: bsc
            symbol:
              type: string
              example: USD1
        refundDestination:
          type: object
          properties:
            network:
              type: string
              example: bsc
            address:
              type: string
              nullable: true
              example: '0x0000000000000000000000000000000000000001'
  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)

````