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

# Create an invoice

> Creates a new invoice and returns a payment URL for the checkout/payment session integration.
The idempotency key must be a v4 UUID generated on the client side.
Optionally set a pass-through settlement address using `receiver_override_*` fields.
Example UUID v4 generation in JavaScript:
```javascript
import { v4 as uuidv4 } from 'uuid';
const idempotencyKey = uuidv4();
```




## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/invoices
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/v1/invoices:
    post:
      tags:
        - Invoices
      summary: Create an invoice
      description: >
        Creates a new invoice and returns a payment URL for the checkout/payment
        session integration.

        The idempotency key must be a v4 UUID generated on the client side.

        Optionally set a pass-through settlement address using
        `receiver_override_*` fields.

        Example UUID v4 generation in JavaScript:

        ```javascript

        import { v4 as uuidv4 } from 'uuid';

        const idempotencyKey = uuidv4();

        ```
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Postapiv1invoicesRequest'
      responses:
        '201':
          description: Invoice created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Postapiv1invoicesResponse201'
        '400':
          description: Validation errors with invoice request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Postapiv1invoicesResponse400'
        '401':
          description: Authentication required or invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Postapiv1invoicesResponse401'
        '409':
          description: Conflict errors (idempotency, duplicates)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Postapiv1invoicesResponse409'
        '500':
          description: Internal server errors
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Postapiv1invoicesResponse500'
      security:
        - ApiKeyAuth: []
components:
  parameters:
    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: true
      schema:
        type: string
        format: uuid
        pattern: ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$
        example: 123e4567-e89b-42d3-a456-556642440000
      description: >-
        A v4 UUID to prevent duplicate requests. Must be unique for each
        request.
  schemas:
    Postapiv1invoicesRequest:
      type: object
      required:
        - amount_usd
      properties:
        amount_usd:
          type: number
          format: float
          minimum: 0.01
          maximum: 1000000
          description: Amount in USD
          example: 99.99
        description:
          type: string
          maxLength: 255
          description: Description of the invoice
          example: Premium Plan Subscription
        customer_id:
          type: string
          maxLength: 255
          description: Optional customer identifier
        metadata:
          type: object
          description: Additional structured data (max 512 bytes)
          example:
            order_id: ORD-123
            items:
              - id: SKU-1
                qty: 2
        expires_in:
          type: number
          description: >-
            Optional expiration time in milliseconds (default 12 hours, max 30
            days)
          minimum: 1
          maximum: 2592000000
          example: 43200000
        receiver_override_enable:
          type: boolean
          description: >
            When true, the invoice will use a receiver override (pass-through)
            address for merchant settlement.

            Requires `receiver_override_address`. The settlement network is
            derived from the merchant's configured

            settlement token (or the system default).
          example: true
        receiver_override_address:
          type: string
          description: Pass-through address to receive the merchant settlement amount.
          example: '0x1111111111111111111111111111111111111111'
        invoice_title:
          type: string
          maxLength: 255
          description: >-
            Optional custom title for the invoice. Defaults to the merchant's
            company_name if not provided.
          example: Monthly Subscription - Premium Plan
        invoice_footer:
          type: string
          maxLength: 255
          description: >-
            Optional custom footer text for the invoice. Defaults to the
            merchant's company_name if not provided.
          example: Thank you for your business!
        customer_email:
          type: string
          format: email
          maxLength: 255
          description: Optional customer email address for receipts and notifications.
          example: customer@example.com
        payment_return_url:
          type: string
          format: uri
          maxLength: 2048
          pattern: ^https://
          description: >
            Optional return URL for hosted checkout to redirect after payment.
            Must be HTTPS.

            If omitted, the merchant default return URL may be used.
          example: https://merchant.example.com/checkout/complete
        payment_return_url_enabled:
          type: boolean
          description: >
            Controls whether the return URL is used. When false, no redirect is
            applied even if a URL is set.
          example: true
        questions:
          type: object
          nullable: true
          description: >-
            Optional questions to collect during checkout (max 5 questions, max
            512 bytes).
          properties:
            questions:
              type: array
              minItems: 1
              maxItems: 5
              items:
                $ref: '#/components/schemas/InvoiceQuestion'
    Postapiv1invoicesResponse201:
      type: object
      properties:
        invoice_id:
          type: string
          format: uuid
          description: Unique identifier for the invoice
          example: 123e4567-e89b-12d3-a456-426614174000
        payment_url:
          type: string
          format: uri
          description: Hosted payment page URL (valid until `expires_at`)
        expires_at:
          type: integer
          description: Expiration timestamp (epoch seconds).
          example: 1711024496
        session_token:
          type: string
          description: >-
            Payment session token (send as `x-session-token` to
            `/api/v1/payments/*`)
        signature:
          type: string
          description: >-
            Payment session signature (send as `x-signature` to
            `/api/v1/payments/*`)
        payment_session_headers:
          type: object
          description: Convenience mapping of required payment session headers
          properties:
            x-session-token:
              type: string
              description: Session token (UUID)
            x-signature:
              type: string
              description: Signature in the format `signature_hash.timestamp_ms`
    Postapiv1invoicesResponse400:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              description: INV error code for consistent error handling
              enum:
                - INV120
                - INV121
                - INV122
                - INV123
                - INV124
                - INV125
                - INV128
                - INV129
                - INV139
                - INV140
                - INV150
            message:
              type: string
              description: Human-readable error message
              example: Amount must be between $0.01 and $1,000,000
            details:
              type: object
              description: Additional error context
            timestamp:
              type: integer
              example: 1711024496
            traceId:
              type: string
              description: Unique identifier for error tracking
              example: a1b2c3d4e5f6
    Postapiv1invoicesResponse401:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INV201
                - INV202
                - INV203
            message:
              type: string
              example: Authentication required
            timestamp:
              type: integer
            traceId:
              type: string
    Postapiv1invoicesResponse409:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INV401
                - INV402
                - INV403
            message:
              type: string
              example: Idempotency key already used
            timestamp:
              type: integer
            traceId:
              type: string
    Postapiv1invoicesResponse500:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - INV501
                - INV502
                - INV503
                - INV601
                - INV602
                - INV700
                - INV701
            message:
              type: string
              example: Failed to create invoice
            timestamp:
              type: integer
            traceId:
              type: string
    InvoiceQuestion:
      type: object
      description: Invoice question definition (configured when creating an invoice).
      additionalProperties: false
      properties:
        id:
          type: string
          pattern: ^q[1-5]$
          description: Question id (q1..q5).
        question:
          type: string
          description: Prompt shown to the payor.
        type:
          type: string
          enum:
            - multiple_choice
            - email
            - number
            - text
            - address
          description: Input type.
        options:
          type: array
          items:
            type: string
          description: Required when type is multiple_choice.
        validation:
          type: object
          nullable: true
          additionalProperties: false
          properties:
            required:
              type: boolean
            pattern:
              type: string
            errorMessage:
              type: string
            min:
              type: number
            max:
              type: number
            minLength:
              type: number
            maxLength:
              type: number
      example:
        id: q1
        question: Email address
        type: email
        validation:
          required: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token for wallet authentication
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for authentication

````