# Read public checkout payment status (/docs/api-reference/public-checkout/read-public-checkout-payment-status)

No authentication. Poll this payer-safe endpoint after starting a Pay Link, event, Split Pay, or storefront order payment. It returns current database status immediately after callback or reconciliation settlement and never exposes payer contact details, provider references, or internal IDs.

OpenAPI operation (JSON):
{
  "openapi": "3.2.0",
  "paths": {
    "/api/v1/payments/collections": {
      "post": {
        "description": "Requires collections:create. Supports bank transfer, USSD, and QR without accepting raw card data. Use POST /v1/checkout/sessions for card-capable hosted checkout. Atomically records a pending transaction before provider initialization. Retry with the same key and body to replay the initial response.",
        "operationId": "initialize-a-server-side-collection",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-idempotency-key",
            "in": "header",
            "description": "1–128 letters/digits or ._:-. Same key and payload replay for 24 hours; conflicting, in-flight, or expired keys return 409. Never change a key to retry an uncertain payment.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCollectionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionCreationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, missing wallet, or missing payer email/phone required by Paga."
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          },
          "409": {
            "description": "Idempotency key already used for a different request."
          },
          "503": {
            "description": "Paga credentials or callback URL are missing for the selected environment. No funds or records are changed."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Initialize a server-side collection",
        "tags": [
          "Collections"
        ]
      }
    },
    "/api/v1/payouts/recipients/validate": {
      "post": {
        "description": "Requires payouts:create. Uses the environment on the API key and Paga Business Validate Deposit to Bank. Simulated sandbox behavior is available only when PAGA_SANDBOX_SIMULATE=true.",
        "operationId": "validate-a-payout-recipient",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-idempotency-key",
            "in": "header",
            "description": "1–128 letters/digits or ._:-. Same key and payload replay for 24 hours; conflicting, in-flight, or expired keys return 409. Never change a key to retry an uncertain payment.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateRecipientDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipientValidationResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Validate a payout recipient",
        "tags": [
          "Payouts"
        ]
      }
    },
    "/api/v1/payouts": {
      "post": {
        "description": "Requires payouts:create. Validates the recipient, atomically reserves funds, and writes a durable payout-dispatch record before BullMQ sends it to Paga. Provider calls are never retried automatically after dispatch begins.",
        "operationId": "queue-a-payout",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-idempotency-key",
            "in": "header",
            "description": "1–128 letters/digits or ._:-. Same key and payload replay for 24 hours; conflicting, in-flight, or expired keys return 409. Never change a key to retry an uncertain payment.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePayoutDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PayoutCreationResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, missing wallet, or insufficient balance."
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          },
          "409": {
            "description": "Idempotency key already used for a different request."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Queue a payout",
        "tags": [
          "Payouts"
        ]
      }
    },
    "/api/v1/virtual-accounts": {
      "get": {
        "description": "Requires virtual-accounts:read. Results are scoped to the API key environment. Provision accounts through the Business owner/admin API.",
        "operationId": "list-dedicated-collection-accounts",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VirtualAccountResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "List dedicated collection accounts",
        "tags": [
          "Virtual accounts"
        ]
      }
    },
    "/api/v1/sandbox/virtual-accounts/{id}/transfers": {
      "post": {
        "description": "Requires sandbox:simulate and a sandbox API key. Immediately creates and posts a collection ledger entry and credits available balance. This route simulates a verified bank notification; it does not accept or process real transfers.",
        "operationId": "simulate-an-incoming-transfer-to-a-sandbox-virtual-account",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Sandbox virtual-account ID returned by the list/provision endpoints.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-idempotency-key",
            "in": "header",
            "description": "1–128 letters/digits or ._:-. Same key and payload replay for 24 hours; conflicting, in-flight, or expired keys return 409. Never change a key to retry an uncertain payment.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimulateVirtualTransferDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "transactionId",
                    "reference",
                    "status",
                    "amountMinor",
                    "currency",
                    "virtualAccountId"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "transactionId": {
                      "type": "string"
                    },
                    "reference": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "SUCCESS"
                      ]
                    },
                    "amountMinor": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "provider": {
                      "type": "string"
                    },
                    "providerReference": {
                      "type": "string"
                    },
                    "virtualAccountId": {
                      "type": "string"
                    },
                    "requiresReconciliation": {
                      "type": "boolean",
                      "examples": [
                        false
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          },
          "404": {
            "description": "No active virtual account belonging to this sandbox merchant."
          },
          "409": {
            "description": "Duplicate/changed idempotency key or duplicate collection reference."
          },
          "501": {
            "description": "Live virtual account callbacks are not implemented."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "Simulate an incoming transfer to a sandbox virtual account",
        "tags": [
          "Virtual accounts"
        ]
      }
    },
    "/api/v1/bills/categories": {
      "get": {
        "description": "Uses the environment attached to the API key. VTpass is selected by default; pass FLUTTERWAVE to use the secondary provider.",
        "operationId": "list-bill-categories",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "required": false,
            "in": "query",
            "schema": {
              "default": "VTPASS",
              "type": "string",
              "enum": [
                "VTPASS",
                "FLUTTERWAVE"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillCatalogResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key/secret, signed request, timestamp, or IP whitelist."
          },
          "403": {
            "description": "API key lacks the required permission or environment is not allowed."
          }
        },
        "security": [
          {
            "api-key": []
          }
        ],
        "summary": "List bill categories",
        "tags": [
          "Bills"
        ]
      }
    },
    "/api/v1/bills/billers": {
      "get": {
        "operationId": "list-billers-services-for-a-provider-category",
        "parameters": [
          {
            "name": "x-api-secret",
            "in": "header",
            "description": "Recommended: API secret sent over HTTPS. You may send it as Authorization: Bearer instead. If supplied, x-timestamp and x-signature are not required.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-timestamp",
            "in": "header",
            "description": "Legacy signed mode: Unix time in milliseconds; maximum clock skew five minutes.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "x-signature",
            "in": "header",
            "description": "Legacy signed mode: HMAC-SHA256(secret, timestamp.METHOD.url.idempotencyKey.bodyHash).",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "required": false,
            "in": "query",
            "schema": {
              "default": "VTPASS",
              "type": "string",
              "enum": [
                "VTPASS",
                "FLUTTERWAVE"
              ]
            }
          },
          {
            "name": "category",
            "re