{
  "openapi": "3.1.0",
  "info": {
    "title": "GoBTC Pay POS API",
    "version": "v1.2",
    "x-logo": {
      "url": "https://upload.wikimedia.org/wikipedia/commons/6/62/GoMining_Logo_%28Black%29.png"
    },
    "description": "# GoBTC Pay — POS API\n\nThis API lets a developer integrate a **point-of-sale terminal** that\naccepts Bitcoin payments: create a payment, show the customer a QR code, and\ntrack it until it settles on-chain.\n\n## Getting started\n\n1. In the **merchant dashboard**, create a POS terminal and obtain its API\n   key. (Manage terminals and rotate keys from the dashboard at any time.)\n2. Use that key to **sign every request** to this API — see\n   [Authentication](#authentication).\n\n## Accepting a payment\n\nWhatever integration you choose, you always start by calling **Create\npayment**, then show the returned `qrString` to the customer. From there you\nlearn the outcome in one of two ways:\n\n- **Polling** — periodically call **Get payment** with the `paymentId` and\n  wait for the `status` to change (e.g. to `cleared`).\n- **Webhook** — register a webhook URL and receive a `payment.status.updated`\n  callback (see [Webhooks](#webhooks)) whenever the status changes. Its `data`\n  field has the **same structure as the Get payment response**, so you can\n  reuse the same parser.\n\n## Payment lifecycle\n\nA payment goes from creation to on-chain settlement. The terminal either\npolls **Get payment** or waits for the webhook until it reaches a terminal\nstatus.\n\n```mermaid\nsequenceDiagram\n  participant T as POS terminal\n  participant G as Gateway\n  participant C as Customer wallet\n  participant B as Bitcoin network\n  T->>G: Create payment (amount, currency, ts, signature)\n  G-->>T: paymentId, qrString, amountSats, expiresAt\n  T->>C: display QR\n  C->>G: pay (sign & settle payment)\n  G->>B: broadcast transaction\n  alt polling\n    loop until cleared or expired\n      T->>G: Get payment (paymentId, ts, signature)\n      G-->>T: status\n    end\n  else webhook\n    B-->>G: on-chain confirmation\n    G-->>T: payment.status.updated (status)\n  end\n```\n\n## Payment statuses\n\n```mermaid\nstateDiagram-v2\n  direction LR\n  [*] --> initiated\n  initiated --> paid: customer paid\n  initiated --> expired: TTL elapsed\n  initiated --> canceled: canceled\n  paid --> cleared: confirmed on-chain\n  cleared --> [*]\n  expired --> [*]\n  canceled --> [*]\n  classDef success fill:#1b5e20,color:#ffffff,stroke:#1b5e20\n  classDef terminal fill:#5f6368,color:#ffffff,stroke:#5f6368\n  class cleared success\n  class expired,canceled terminal\n```\n\n- **initiated** — payment created, awaiting the customer.\n- **paid** — customer payment seen, awaiting on-chain confirmation.\n- **cleared** — confirmed on-chain (final, success).\n- **expired / canceled** — final, unsuccessful.\n\n## Authentication\n\nRequests are authenticated **per POS terminal**. Each terminal is issued an\n`apiKey` (a shared secret) when it is created. The secret is **never\ntransmitted** — it only signs requests, which gives integrity and\nreplay-attack protection.\n\nA signed request carries two extra fields inside `params`:\n\n- `ts` — Unix timestamp in **milliseconds** when the request was created.\n- `signature` — hex-encoded HMAC of the request payload.\n\n**Computing the signature (client side):**\n\n1. Take the request `params` object and remove the `signature` field.\n2. Sort the remaining entries by key (ascending) and serialize with\n   `JSON.stringify` — this is the canonical message.\n3. `signature = HMAC-SHA256(key = terminal apiKey, message = canonical JSON)`,\n   hex-encoded.\n\n**Validation (server side):**\n\n1. The server resolves the terminal, recomputes the HMAC and rejects the\n   request unless it equals `signature`.\n2. `ts` must be at most 60s in the future and no older than 5 minutes.\n\n## Webhooks\n\nInstead of polling **Get payment**, register a webhook endpoint in the\n**merchant dashboard** and GoBTC Pay will notify you when a payment's status\nchanges. The `payment.status.updated` event is delivered as an HTTP `POST`\nwrapped in a thin envelope — `{ eventId, type, createdAt, data }` — where\n`data` matches the **Get payment** response.\n\nEach delivery is signed. Verify the `X-GoBTCPay-Signature: t=<unix>,v1=<hmac>`\nheader, where `v1 = HMAC-SHA256(signingSecret, \"{t}.{rawBody}\")` and the\n`signingSecret` is shown once when you create the endpoint. Delivery is\nat-least-once, so de-duplicate on `eventId`. Respond with any `2xx` to\nacknowledge; non-2xx responses are retried.\n\n---\n\nThis is the **POS terminal** surface of the GoBTC Pay API. Backwards compatibility is preserved across published versions.\n\nFound an error in the docs? Email [support@gomining.com](mailto:support@gomining.com)."
  },
  "components": {
    "securitySchemes": {
      "apiAuth": {
        "type": "custom",
        "in": "body",
        "name": "signature",
        "description": "Per-request HMAC-SHA256 signature (hex), keyed by the POS terminal apiKey, computed over the canonical key-sorted JSON of params and sent in params alongside ts. See the Authentication section for the algorithm."
      }
    }
  },
  "servers": [
    {
      "url": "https://api.gobtcpay.com/public/api/v1.2"
    }
  ],
  "paths": {
    "/pos/transaction/create-payment": {
      "post": {
        "security": [
          {
            "apiAuth": []
          }
        ],
        "summary": "Create payment",
        "description": "Creates a payment request for a POS terminal. Specify the `amount` and `currency`; the response includes the satoshi amount, the BTC price snapshot, an `expiresAt` deadline, and a `qrString` to present to the payer. `signature` and `ts` may be supplied for request signing.",
        "tags": [
          "Payments"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "posTerminalId": {
                    "type": "string",
                    "description": "POS terminal that accepts the payment (from **Create POS terminal**).",
                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  },
                  "amount": {
                    "type": "number",
                    "description": "Amount to charge, in the selected fiat `currency`.",
                    "example": 10
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description shown to the payer.",
                    "example": "Order #1024"
                  },
                  "currency": {
                    "type": "string",
                    "description": "Fiat currency code (ISO 4217), e.g. `USD`.",
                    "example": "USD"
                  },
                  "metadata": {
                    "description": "Internal system metadata attached to the payment (reserved; not set by clients).",
                    "example": {}
                  },
                  "ttlSeconds": {
                    "type": "number",
                    "description": "Optional lifetime of the payment in seconds; after this it expires.",
                    "example": 900
                  },
                  "externalId": {
                    "type": "string",
                    "description": "Merchant's own correlation id (e.g. order / invoice id). Unique per merchant, so reusing it makes create-payment idempotent. Echoed back in payment responses and webhook deliveries.",
                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  },
                  "signature": {
                    "type": "string",
                    "description": "Optional HMAC-SHA256 signature of the request (hex), authenticating the POS terminal with its `apiKey`.",
                    "example": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
                  },
                  "ts": {
                    "type": "number",
                    "description": "Request timestamp in milliseconds, used together with `signature` for replay protection.",
                    "example": 1718012345000
                  }
                },
                "required": [
                  "posTerminalId",
                  "currency",
                  "signature",
                  "ts"
                ],
                "additionalProperties": false,
                "$schema": "http://json-schema.org/draft-07/schema#"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "$case": {
                          "type": "string",
                          "const": "success",
                          "example": "success"
                        },
                        "success": {
                          "type": "object",
                          "properties": {
                            "paymentId": {
                              "type": "string",
                              "description": "Unique id of the created payment.",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "initiated",
                                "detected",
                                "paid",
                                "failed",
                                "expired",
                                "canceled",
                                "cleared"
                              ],
                              "description": "Payment status. One of `initiated`, `detected`, `paid`, `failed`, `expired`, `canceled`, `cleared`.",
                              "example": "initiated"
                            },
                            "merchantId": {
                              "type": "string",
                              "description": "Identifier of the merchant (UUID).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "merchantName": {
                              "type": "string",
                              "description": "Merchant's internal name.",
                              "example": "Satoshi Coffee"
                            },
                            "storeId": {
                              "type": "string",
                              "description": "Identifier of the store the payment belongs to (UUID).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "posTerminalLabel": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Label of the POS terminal (may be null).",
                              "example": "Front desk"
                            },
                            "posTerminalLocation": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Location of the POS terminal (may be null).",
                              "example": "Lisbon, PT"
                            },
                            "merchantDisplayName": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Merchant's public display name (may be null).",
                              "example": "Satoshi Coffee"
                            },
                            "posTerminalId": {
                              "type": "string",
                              "description": "POS terminal that accepts the payment (from **Create POS terminal**).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "externalId": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Merchant's own correlation id (e.g. order / invoice id). Unique per merchant, so reusing it makes create-payment idempotent. Echoed back in payment responses and webhook deliveries."
                            },
                            "amountSats": {
                              "type": "string",
                              "pattern": "^(?:0|[1-9][0-9]*)$",
                              "description": "Amount to pay in satoshis (converted from `amount` at `btcPriceInCurrency`).",
                              "example": "string"
                            },
                            "currency": {
                              "type": "string",
                              "description": "Fiat currency code (ISO 4217), e.g. `USD`.",
                              "example": "USD"
                            },
                            "currencySymbol": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "example": "$"
                                },
                                {
                                  "not": {},
                                  "example": {}
                                }
                              ],
                              "description": "Display symbol of the currency, e.g. `$`."
                            },
                            "amount": {
                              "type": "number",
                              "description": "Amount to charge, in the selected fiat `currency`.",
                              "example": 10
                            },
                            "expiresAt": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "description": "UnixTime (seconds since epoch)",
                                  "example": 1718012345
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Expiry time as a Unix timestamp (seconds)."
                            },
                            "btcPriceInUsd": {
                              "type": "number",
                              "description": "BTC/USD price captured when the payment was created.",
                              "example": 65000
                            },
                            "btcPriceInCurrency": {
                              "type": "number",
                              "description": "BTC price in the payment's `currency`, captured when the payment was created.",
                              "example": 65000
                            },
                            "checkoutUrl": {
                              "type": "string",
                              "example": "string"
                            },
                            "version": {
                              "type": "integer",
                              "minimum": 0,
                              "example": 0
                            },
                            "btcAddress": {
                              "type": "string",
                              "description": "Bitcoin address bound to this payment; the payer sends funds here. Can be used to look the payment up later.",
                              "example": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
                            },
                            "qrString": {
                              "type": "string",
                              "description": "Payment encoded as a BIP-21 URI, ready to render as a QR code.",
                              "example": "bitcoin:bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq?amount=0.0005"
                            }
                          },
                          "required": [
                            "paymentId",
                            "status",
                            "merchantId",
                            "merchantName",
                            "storeId",
                            "posTerminalLabel",
                            "posTerminalLocation",
                            "merchantDisplayName",
                            "posTerminalId",
                            "externalId",
                            "amountSats",
                            "currency",
                            "amount",
                            "expiresAt",
                            "btcPriceInUsd",
                            "btcPriceInCurrency",
                            "checkoutUrl",
                            "version",
                            "btcAddress",
                            "qrString"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "required": [
                        "$case",
                        "success"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "result"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "statusCode": {
                          "type": "number",
                          "description": "Numeric error status code.",
                          "example": 0
                        },
                        "description": {
                          "type": "string",
                          "description": "Optional description shown to the payer.",
                          "example": "Order #1024"
                        },
                        "statusMessage": {
                          "type": "string",
                          "description": "Short machine-readable error message.",
                          "example": "pending"
                        }
                      },
                      "required": [
                        "statusCode",
                        "description",
                        "statusMessage"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "cURL",
            "source": "curl -X POST \"$BASE_URL/pos/transaction/create-payment\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"posTerminalId\": \"pos_…\",\n  \"amount\": 10,\n  \"currency\": \"USD\",\n  \"metadata\": {}\n}'"
          }
        ]
      }
    },
    "/pos/transaction/get-payment": {
      "post": {
        "security": [
          {
            "apiAuth": []
          }
        ],
        "summary": "Get payment",
        "description": "Returns the current state of a payment by `paymentId`, including its `status`, amounts, merchant / POS details, and `qrString`. Poll this to track a payment until it is paid or expired.",
        "tags": [
          "Payments"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paymentId": {
                    "type": "string",
                    "description": "Transaction (payment) identifier — the `paymentId` returned by **Create payment**.",
                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  },
                  "signature": {
                    "type": "string",
                    "description": "Signature in hex format sha 256",
                    "example": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
                  },
                  "ts": {
                    "type": "number",
                    "description": "Timestamp in milliseconds",
                    "example": 1718012345000
                  }
                },
                "required": [
                  "paymentId",
                  "signature",
                  "ts"
                ],
                "additionalProperties": false,
                "$schema": "http://json-schema.org/draft-07/schema#"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "$case": {
                          "type": "string",
                          "const": "success",
                          "example": "success"
                        },
                        "success": {
                          "type": "object",
                          "properties": {
                            "paymentId": {
                              "type": "string",
                              "description": "Transaction (payment) identifier — the `paymentId` returned by **Create payment**.",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "initiated",
                                "detected",
                                "paid",
                                "failed",
                                "expired",
                                "canceled",
                                "cleared"
                              ],
                              "description": "Payment status. One of `initiated`, `detected`, `paid`, `failed`, `expired`, `canceled`, `cleared`.",
                              "example": "initiated"
                            },
                            "merchantId": {
                              "type": "string",
                              "description": "Identifier of the merchant (UUID).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "currency": {
                              "type": "string",
                              "description": "Fiat currency code (ISO 4217), e.g. `USD`.",
                              "example": "USD"
                            },
                            "merchantName": {
                              "type": "string",
                              "description": "Merchant's internal name.",
                              "example": "Satoshi Coffee"
                            },
                            "storeId": {
                              "type": "string",
                              "description": "Identifier of the store the payment belongs to (UUID).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "posTerminalLabel": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Label of the POS terminal (may be null).",
                              "example": "Front desk"
                            },
                            "posTerminalLocation": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Location of the POS terminal (may be null).",
                              "example": "Lisbon, PT"
                            },
                            "merchantDisplayName": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Merchant's public display name (may be null).",
                              "example": "Satoshi Coffee"
                            },
                            "posTerminalId": {
                              "type": "string",
                              "description": "Identifier of the POS terminal (UUID).",
                              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                            },
                            "externalId": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Merchant's own correlation id (e.g. order / invoice id), echoed back from create-payment. Null when none was supplied."
                            },
                            "description": {
                              "type": "string",
                              "description": "Description shown to the payer (optional).",
                              "example": "Order #1024"
                            },
                            "amountSats": {
                              "type": "string",
                              "pattern": "^(?:0|[1-9][0-9]*)$",
                              "description": "Amount to pay, in satoshis.",
                              "example": "string"
                            },
                            "btcPriceInUsd": {
                              "type": "number",
                              "description": "BTC/USD price captured when the payment was created.",
                              "example": 65000
                            },
                            "btcPriceInCurrency": {
                              "type": "number",
                              "description": "BTC price in the payment's `currency`, captured when the payment was created.",
                              "example": 65000
                            },
                            "currencySymbol": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "example": "$"
                                },
                                {
                                  "not": {},
                                  "example": {}
                                }
                              ],
                              "description": "Display symbol of the currency, e.g. `$`."
                            },
                            "amount": {
                              "type": "number",
                              "description": "Amount in the payment's fiat `currency`.",
                              "example": 10
                            },
                            "metadata": {
                              "description": "Internal system metadata attached to the payment (reserved; not set by clients).",
                              "example": {}
                            },
                            "expiresAt": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "description": "UnixTime (seconds since epoch)",
                                  "example": 1718012345
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Expiry time as a Unix timestamp (seconds)."
                            },
                            "qrString": {
                              "type": "string",
                              "description": "Payment encoded as a BIP-21 URI, ready to render as a QR code.",
                              "example": "bitcoin:bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq?amount=0.0005"
                            },
                            "version": {
                              "type": "integer",
                              "minimum": 0,
                              "example": 0
                            },
                            "transactions": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "txid": {
                                    "type": "string",
                                    "description": "On-chain Bitcoin transaction id (hex) of this receipt. Look it up in any block explorer to show the payer their transaction.",
                                    "example": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
                                  },
                                  "amountSats": {
                                    "type": "string",
                                    "pattern": "^(?:0|[1-9][0-9]*)$",
                                    "description": "What this transaction paid into **this payment's** address, in satoshis — not the transaction's total, which may pay other outputs as well.",
                                    "example": "string"
                                  },
                                  "blockHeight": {
                                    "anyOf": [
                                      {
                                        "type": "number",
                                        "example": 845000
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ],
                                    "description": "Height of the block that included the transaction; `null` while it is still in the mempool."
                                  },
                                  "blockTime": {
                                    "anyOf": [
                                      {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "UnixTime (seconds since epoch)",
                                        "example": 1718012345
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ],
                                    "description": "Timestamp of that block, Unix seconds; `null` while the transaction is still in the mempool. Historical payments confirmed before this field existed report `null` permanently."
                                  },
                                  "confirmations": {
                                    "anyOf": [
                                      {
                                        "type": "integer",
                                        "minimum": 0,
                                        "example": 0
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ],
                                    "description": "Confirmations as of **now**, not as of the moment the payment was paid, so the value keeps growing. `0` — seen but not in a block yet. `null` — the current chain tip is not known to us right now, so the count cannot be stated; do not render it as zero, the transaction may well be deeply confirmed. The remaining fields are unaffected."
                                  },
                                  "feeSats": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "pattern": "^(?:0|[1-9][0-9]*)$",
                                        "example": "string"
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ],
                                    "description": "Network fee the payer paid for this transaction, in satoshis; `null` when it is not known to us."
                                  }
                                },
                                "required": [
                                  "txid",
                                  "amountSats",
                                  "blockHeight",
                                  "blockTime",
                                  "confirmations",
                                  "feeSats"
                                ],
                                "additionalProperties": false
                              },
                              "default": [],
                              "description": "On-chain transactions observed paying this payment, freshest first. Empty until something is seen — and empty is a normal state for a payment in `initiated`. More than one element means the payer sent more than one transaction (an overpayment or a top-up); sum `amountSats` across the list to get what actually arrived. Identical for both payment routes: an in-app payment reports its single transaction here just like one paid from an external wallet."
                            },
                            "paidAt": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "description": "UnixTime (seconds since epoch)",
                                  "example": 1718012345
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "default": null,
                              "description": "When the payment was paid, Unix timestamp (seconds); `null` until then. This is the payment's settlement time — for when a single transaction was mined see `transactions[].blockTime`."
                            }
                          },
                          "required": [
                            "paymentId",
                            "status",
                            "merchantId",
                            "currency",
                            "merchantName",
                            "storeId",
                            "posTerminalLabel",
                            "posTerminalLocation",
                            "merchantDisplayName",
                            "posTerminalId",
                            "externalId",
                            "amountSats",
                            "btcPriceInUsd",
                            "btcPriceInCurrency",
                            "amount",
                            "expiresAt",
                            "qrString",
                            "version"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "required": [
                        "$case",
                        "success"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "result"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "statusCode": {
                          "type": "number",
                          "description": "Numeric error status code.",
                          "example": 0
                        },
                        "description": {
                          "type": "string",
                          "description": "Description shown to the payer (optional).",
                          "example": "Order #1024"
                        },
                        "statusMessage": {
                          "type": "string",
                          "description": "Short machine-readable error message.",
                          "example": "pending"
                        }
                      },
                      "required": [
                        "statusCode",
                        "description",
                        "statusMessage"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "bash",
            "label": "cURL",
            "source": "curl -X POST \"$BASE_URL/pos/transaction/get-payment\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n  \"paymentId\": \"pay_…\"\n}'"
          }
        ]
      }
    },
    "/pos/transaction/list": {
      "post": {
        "security": [
          {
            "apiAuth": []
          }
        ],
        "summary": "List payments",
        "description": "Returns a paginated list of payment transactions with optional `dateRange` and `status` filters. Each item carries merchant / POS context, fiat and BTC amounts, and on-chain settlement data when available. `totalCount` reflects the filtered total.",
        "tags": [
          "Payments"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pagination": {
                    "type": "object",
                    "properties": {
                      "limit": {
                        "type": "number",
                        "minimum": 1,
                        "maximum": 100,
                        "default": 20,
                        "description": "Maximum number of items to return (1–100, default 20).",
                        "example": 20
                      },
                      "skip": {
                        "type": "number",
                        "minimum": 0,
                        "default": 0,
                        "description": "Number of items to skip — offset for pagination (default 0).",
                        "example": 0
                      }
                    },
                    "additionalProperties": false
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "dateRange": {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Filter from this creation time, Unix timestamp (seconds).",
                            "example": 0
                          },
                          "end": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Filter up to this creation time, Unix timestamp (seconds).",
                            "example": 0
                          }
                        },
                        "required": [
                          "start",
                          "end"
                        ],
                        "additionalProperties": false
                      },
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "enum": [
                            "initiated",
                            "detected",
                            "paid",
                            "failed",
                            "expired",
                            "canceled",
                            "cleared"
                          ],
                          "example": "initiated"
                        },
                        "description": "Filter by payment transaction status. Values: `success`, `failed`, `pending`, `cleared`."
                      }
                    },
                    "additionalProperties": false
                  },
                  "posTerminalId": {
                    "type": "string",
                    "description": "Identifier of the POS terminal (UUID).",
                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  },
                  "signature": {
                    "type": "string",
                    "description": "Signature in hex format sha 256",
                    "example": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
                  },
                  "ts": {
                    "type": "number",
                    "description": "Timestamp in milliseconds",
                    "example": 1718012345000
                  }
                },
                "required": [
                  "posTerminalId",
                  "signature",
                  "ts"
                ],
                "additionalProperties": false,
                "$schema": "http://json-schema.org/draft-07/schema#"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "$case": {
                          "type": "string",
                          "const": "success",
                          "example": "success"
                        },
                        "success": {
                          "type": "object",
                          "properties": {
                            "items": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "paymentId": {
                                    "type": "string",
                                    "description": "Identifier of the payment (UUID).",
                                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                  },
                                  "status": {
                                    "type": "string",
                                    "enum": [
                                      "initiated",
                                      "detected",
                                      "paid",
                                      "failed",
                                      "expired",
                                      "canceled",
                                      "cleared"
                                    ],
                                    "description": "Filter by payment transaction status. Values: `success`, `failed`, `pending`, `cleared`.",
                                    "example": "initiated"
                                  },
                                  "amount": {
                                    "type": "number",
                                    "description": "Amount in the payment's fiat `currency`.",
                                    "example": 10
                                  },
                                  "amountSats": {
                                    "type": "string",
                                    "pattern": "^(?:0|[1-9][0-9]*)$",
                                    "description": "Amount in satoshis.",
                                    "example": "string"
                                  },
                                  "currency": {
                                    "type": "string",
                                    "description": "Fiat currency code (ISO 4217), e.g. `USD`.",
                                    "example": "USD"
                                  },
                                  "currencySymbol": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "example": "$"
                                      },
                                      {
                                        "not": {},
                                        "example": {}
                                      }
                                    ],
                                    "description": "Display symbol of the currency, e.g. `$`."
                                  },
                                  "description": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Description shown to the payer (may be null).",
                                    "example": "Order #1024"
                                  },
                                  "metadata": {
                                    "description": "Internal system metadata attached to the payment (reserved; not set by clients).",
                                    "example": {}
                                  },
                                  "network": {
                                    "type": "string",
                                    "enum": [
                                      "mainnet",
                                      "testnet"
                                    ],
                                    "example": "mainnet"
                                  },
                                  "btcPriceInUsd": {
                                    "type": "number",
                                    "description": "BTC/USD price captured when the payment was created.",
                                    "example": 65000
                                  },
                                  "btcPriceInCurrency": {
                                    "type": "number",
                                    "description": "BTC price in the payment's `currency`, captured when the payment was created.",
                                    "example": 65000
                                  },
                                  "externalId": {
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ]
                                  },
                                  "createdAt": {
                                    "type": "integer",
                                    "minimum": 0,
                                    "description": "Creation time as a Unix timestamp (seconds).",
                                    "example": 1718012345
                                  },
                                  "expiresAt": {
                                    "anyOf": [
                                      {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "UnixTime (seconds since epoch)",
                                        "example": 1718012345
                                      },
                                      {
                                        "type": "null",
                                        "example": null
                                      }
                                    ],
                                    "description": "Expiry time as a Unix timestamp (seconds)."
                                  },
                                  "btcAddress": {
                                    "type": "string",
                                    "example": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq"
                                  },
                                  "merchantId": {
                                    "type": "string",
                                    "description": "Identifier of the merchant (UUID).",
                                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                  },
                                  "merchantName": {
                                    "type": "string",
                                    "description": "Merchant's internal name.",
                                    "example": "Satoshi Coffee"
                                  },
                                  "merchantDisplayName": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Merchant's public display name (may be null).",
                                    "example": "Satoshi Coffee"
                                  },
                                  "posTerminalId": {
                                    "type": "string",
                                    "description": "Identifier of the POS terminal (UUID).",
                                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                                  },
                                  "posTerminalLabel": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Label of the POS terminal (may be null).",
                                    "example": "Front desk"
                                  },
                                  "posTerminalLocation": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Location of the POS terminal (may be null).",
                                    "example": "Lisbon, PT"
                                  }
                                },
                                "required": [
                                  "paymentId",
                                  "status",
                                  "amount",
                                  "amountSats",
                                  "currency",
                                  "description",
                                  "network",
                                  "btcPriceInUsd",
                                  "btcPriceInCurrency",
                                  "externalId",
                                  "createdAt",
                                  "expiresAt",
                                  "btcAddress",
                                  "merchantId",
                                  "merchantName",
                                  "merchantDisplayName",
                                  "posTerminalId",
                                  "posTerminalLabel",
                                  "posTerminalLocation"
                                ],
                                "additionalProperties": false
                              }
                            },
                            "totalCount": {
                              "type": "number",
                              "description": "Total number of records matching the filters.",
                              "example": 0
                            }
                          },
                          "required": [
                            "items",
                            "totalCount"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "required": [
                        "$case",
                        "success"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "id",
                    "result"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          },
          "500": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "statusCode": {
                          "type": "number",
                          "description": "Numeric error status code.",
                          "example": 0
                        },
                        "description": {
                          "type": "string",
                          "description": "Description shown to the payer (may be null).",
                          "example": "Order #1024"
                        },
                        "statusMessage": {
                          "type": "string",
                          "description": "Short machine-readable error message.",
                          "example": "pending"
                        }
                      },
                      "required": [
                        "statusCode",
                        "description",
                        "statusMessage"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": false,
                  "$schema": "http://json-schema.org/draft-07/schema#"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "payment.status.updated": {
      "post": {
        "tags": [
          "Payments"
        ],
        "summary": "Payment status update",
        "operationId": "paymentStatusWebhook",
        "description": "Sent to your configured webhook URL whenever a payment's `status` changes (`paid`, `cleared`, `expired`, …). The event is wrapped in a thin envelope (`eventId`, `type`, `createdAt`, `data`) where **`data` has the same structure as the Get payment response**, so you can reuse the same parser. Use this as an alternative to polling **Get payment**.\n\nEach delivery is signed: verify the `X-GoBTCPay-Signature: t=<unix>,v1=<hmac>` header, where `v1 = HMAC-SHA256(signingSecret, \"{t}.{rawBody}\")`. Delivery is at-least-once — de-duplicate on `eventId`. Respond with any `2xx` to acknowledge receipt; non-2xx responses are retried.",
        "requestBody": {
          "required": true,
          "description": "The signed event delivery. `data` carries the payment exactly as returned by **Get payment**.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eventId": {
                    "type": "string",
                    "description": "Unique id of this webhook event. Use it to de-duplicate deliveries (delivery is at-least-once).",
                    "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "payment.status.updated"
                    ],
                    "description": "Event type. Always `payment.status.updated`.",
                    "example": "payment.status.updated"
                  },
                  "createdAt": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "When this event was emitted, as a Unix timestamp (seconds).",
                    "example": 1718012345
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "paymentId": {
                        "type": "string",
                        "description": "Transaction (payment) identifier — the `paymentId` returned by **Create payment**.",
                        "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "initiated",
                          "detected",
                          "paid",
                          "failed",
                          "expired",
                          "canceled",
                          "cleared"
                        ],
                        "description": "Payment status. One of `initiated`, `detected`, `paid`, `failed`, `expired`, `canceled`, `cleared`.",
                        "example": "initiated"
                      },
                      "merchantId": {
                        "type": "string",
                        "description": "Identifier of the merchant (UUID).",
                        "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      },
                      "currency": {
                        "type": "string",
                        "description": "Fiat currency code (ISO 4217), e.g. `USD`.",
                        "example": "USD"
                      },
                      "merchantName": {
                        "type": "string",
                        "description": "Merchant's internal name.",
                        "example": "Satoshi Coffee"
                      },
                      "storeId": {
                        "type": "string",
                        "description": "Identifier of the store the payment belongs to (UUID).",
                        "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      },
                      "posTerminalLabel": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Label of the POS terminal (may be null).",
                        "example": "Front desk"
                      },
                      "posTerminalLocation": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Location of the POS terminal (may be null).",
                        "example": "Lisbon, PT"
                      },
                      "merchantDisplayName": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Merchant's public display name (may be null).",
                        "example": "Satoshi Coffee"
                      },
                      "posTerminalId": {
                        "type": "string",
                        "description": "Identifier of the POS terminal (UUID).",
                        "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                      },
                      "externalId": {
                        "anyOf": [
                          {
                            "type": "string",
                            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                          },
                          {
                            "type": "null",
                            "example": null
                          }
                        ],
                        "description": "Merchant's own correlation id (e.g. order / invoice id), echoed back from create-payment. Null when none was supplied."
                      },
                      "description": {
                        "type": "string",
                        "description": "Description shown to the payer (optional).",
                        "example": "Order #1024"
                      },
                      "amountSats": {
                        "type": "string",
                        "pattern": "^(?:0|[1-9][0-9]*)$",
                        "description": "Amount to pay, in satoshis.",
                        "example": "string"
                      },
                      "btcPriceInUsd": {
                        "type": "number",
                        "description": "BTC/USD price captured when the payment was created.",
                        "example": 65000
                      },
                      "btcPriceInCurrency": {
                        "type": "number",
                        "description": "BTC price in the payment's `currency`, captured when the payment was created.",
                        "example": 65000
                      },
                      "currencySymbol": {
                        "anyOf": [
                          {
                            "type": "string",
                            "example": "$"
                          },
                          {
                            "not": {},
                            "example": {}
                          }
                        ],
                        "description": "Display symbol of the currency, e.g. `$`."
                      },
                      "amount": {
                        "type": "number",
                        "description": "Amount in the payment's fiat `currency`.",
                        "example": 10
                      },
                      "metadata": {
                        "description": "Internal system metadata attached to the payment (reserved; not set by clients).",
                        "example": {}
                      },
                      "expiresAt": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": 0,
                            "description": "UnixTime (seconds since epoch)",
                            "example": 1718012345
                          },
                          {
                            "type": "null",
                            "example": null
                          }
                        ],
                        "description": "Expiry time as a Unix timestamp (seconds)."
                      },
                      "qrString": {
                        "type": "string",
                        "description": "Payment encoded as a BIP-21 URI, ready to render as a QR code.",
                        "example": "bitcoin:bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq?amount=0.0005"
                      },
                      "version": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                      },
                      "transactions": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "txid": {
                              "type": "string",
                              "description": "On-chain Bitcoin transaction id (hex) of this receipt. Look it up in any block explorer to show the payer their transaction.",
                              "example": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
                            },
                            "amountSats": {
                              "type": "string",
                              "pattern": "^(?:0|[1-9][0-9]*)$",
                              "description": "What this transaction paid into **this payment's** address, in satoshis — not the transaction's total, which may pay other outputs as well.",
                              "example": "string"
                            },
                            "blockHeight": {
                              "anyOf": [
                                {
                                  "type": "number",
                                  "example": 845000
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Height of the block that included the transaction; `null` while it is still in the mempool."
                            },
                            "blockTime": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "description": "UnixTime (seconds since epoch)",
                                  "example": 1718012345
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Timestamp of that block, Unix seconds; `null` while the transaction is still in the mempool. Historical payments confirmed before this field existed report `null` permanently."
                            },
                            "confirmations": {
                              "anyOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "example": 0
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Confirmations as of **now**, not as of the moment the payment was paid, so the value keeps growing. `0` — seen but not in a block yet. `null` — the current chain tip is not known to us right now, so the count cannot be stated; do not render it as zero, the transaction may well be deeply confirmed. The remaining fields are unaffected."
                            },
                            "feeSats": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "pattern": "^(?:0|[1-9][0-9]*)$",
                                  "example": "string"
                                },
                                {
                                  "type": "null",
                                  "example": null
                                }
                              ],
                              "description": "Network fee the payer paid for this transaction, in satoshis; `null` when it is not known to us."
                            }
                          },
                          "required": [
                            "txid",
                            "amountSats",
                            "blockHeight",
                            "blockTime",
                            "confirmations",
                            "feeSats"
                          ],
                          "additionalProperties": false
                        },
                        "default": [],
                        "description": "On-chain transactions observed paying this payment, freshest first. Empty until something is seen — and empty is a normal state for a payment in `initiated`. More than one element means the payer sent more than one transaction (an overpayment or a top-up); sum `amountSats` across the list to get what actually arrived. Identical for both payment routes: an in-app payment reports its single transaction here just like one paid from an external wallet."
                      },
                      "paidAt": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": 0,
                            "description": "UnixTime (seconds since epoch)",
                            "example": 1718012345
                          },
                          {
                            "type": "null",
                            "example": null
                          }
                        ],
                        "default": null,
                        "description": "When the payment was paid, Unix timestamp (seconds); `null` until then. This is the payment's settlement time — for when a single transaction was mined see `transactions[].blockTime`."
                      }
                    },
                    "required": [
                      "paymentId",
                      "status",
                      "merchantId",
                      "currency",
                      "merchantName",
                      "storeId",
                      "posTerminalLabel",
                      "posTerminalLocation",
                      "merchantDisplayName",
                      "posTerminalId",
                      "externalId",
                      "amountSats",
                      "btcPriceInUsd",
                      "btcPriceInCurrency",
                      "amount",
                      "expiresAt",
                      "qrString",
                      "version"
                    ],
                    "additionalProperties": false,
                    "description": "The payment — identical in structure to the Get payment response."
                  }
                },
                "required": [
                  "eventId",
                  "type",
                  "createdAt",
                  "data"
                ],
                "additionalProperties": false,
                "$schema": "http://json-schema.org/draft-07/schema#"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledged. Return any 2xx status to confirm receipt."
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Payments",
      "description": "Create and inspect payments, list payment history, and build / submit the signed transaction that settles a payment."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Payments & Merchants",
      "tags": [
        "Payments"
      ]
    }
  ]
}
