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

# Check a payment's status with the operator

> Ask the mobile-money operator what happened to a collection, by the `reference`
returned when you created it. Unlike `GET /transactions/{id}`, which reads Kori's
stored record, this queries the operator and settles the transaction if it has
completed — so it is the authoritative answer while a payment is still open.

No authentication: the reference is the credential, which is what lets a hosted
checkout page poll it from the customer's browser.

**Prefer the `payment_received` webhook.** Poll this only while a customer is
waiting on the result, and stop once `state` is no longer `pending` — a payment
that is never confirmed stays `pending` and is expired by Kori after 24 hours.




## OpenAPI

````yaml /openapi.yaml get /merchant/api/payment/status/{reference}
openapi: 3.1.0
info:
  title: Kori Merchant API
  version: 1.0.0
  description: >
    The Kori Merchant API lets your application collect and disburse
    mobile-money

    payments across Mali (Orange Money, Wave, Moov) and manage payouts,

    beneficiaries, bulk payments, payment links, your team, webhooks and
    settings.


    All amounts are in **XOF** (West African CFA franc), the currency the Mali

    mobile-money operators settle in. XOF has no minor unit, so an amount of
    5000 is

    5 000 francs, not cents. `currency` defaults to `XOF`.


    Minimums differ by direction: **100 XOF** to collect a payment, **1000 XOF**
    to send

    one (payouts, bulk pay and `/deposit`).


    Every endpoint documented here is reachable with a **merchant API key**. You

    exchange your API key + secret for a short-lived **Bearer token** scoped to
    a set

    of permissions, then call the rest of the API with that token. The scopes
    you can

    grant are exactly the ones shown in the **API Keys** screen of your Kori
    dashboard.


    ## Authentication flow

    1. `POST /merchant/api/auth` with `X-API-Key` and `X-API-Secret` headers.
    Optionally
       request a subset of `scopes` and an expiry (`expires_in_hours`, 1–720).
    2. Use the returned `data.token` as `Authorization: Bearer <token>` on every
    other call.

    3. Each endpoint requires a specific scope; a token missing that scope gets
    `403`.


    ## Response envelope

    All responses share the shape `{ "success": boolean, "message"?: string,

    "request_id"?: string, "data"?: object }`. Errors set `success: false` and a

    human-readable `message`.


    ## Asynchronous payments

    `POST /merchant/api/pay` returns `202` with `status: "pending"` — the
    customer has

    only been *prompted*. Wait for the `payment_received` webhook (or poll the

    transaction) before treating a collection as paid. Never rely on the HTTP
    response

    alone to mark an order complete.
  contact:
    name: Kori Support
    url: https://kori.ml
servers:
  - url: https://api.kori.ml
    description: Production
  - url: https://dev.kori.ml
    description: Sandbox / development
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: Exchange your API key + secret for a scoped Bearer token.
  - name: Payments
    description: >-
      Collect from customers (`pay`), disburse (`deposit`), check balance and
      transactions.
  - name: Payouts
    description: Withdraw your balance to mobile money or bank accounts.
  - name: Beneficiaries
    description: Saved payout recipients.
  - name: Payment Links
    description: Shareable hosted payment pages.
  - name: Bulk Pay
    description: Batch disbursements to many recipients.
  - name: Team
    description: Manage dashboard team members and roles.
  - name: Webhooks
    description: Register endpoints to receive event notifications.
  - name: Settings
    description: Merchant account preferences.
paths:
  /merchant/api/payment/status/{reference}:
    get:
      tags:
        - Payments
      summary: Check a payment's status with the operator
      description: >
        Ask the mobile-money operator what happened to a collection, by the
        `reference`

        returned when you created it. Unlike `GET /transactions/{id}`, which
        reads Kori's

        stored record, this queries the operator and settles the transaction if
        it has

        completed — so it is the authoritative answer while a payment is still
        open.


        No authentication: the reference is the credential, which is what lets a
        hosted

        checkout page poll it from the customer's browser.


        **Prefer the `payment_received` webhook.** Poll this only while a
        customer is

        waiting on the result, and stop once `state` is no longer `pending` — a
        payment

        that is never confirmed stays `pending` and is expired by Kori after 24
        hours.
      parameters:
        - name: reference
          in: path
          required: true
          schema:
            type: string
          description: >-
            The `reference` from the pay response, e.g.
            `PL_2_1790206361991_03437213`.
      responses:
        '200':
          description: >
            The current state. `pending` means the operator has not confirmed
            yet — it is

            not a failure, and the payment may still complete.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: SUCCESS
                  state:
                    type: string
                    enum:
                      - success
                      - failed
                      - pending
                    description: >-
                      success = paid and settled; failed = refused; pending =
                      not yet confirmed.
                  status:
                    type: boolean
                    description: Convenience flag, true only when `state` is `success`.
                example:
                  message: SUCCESS
                  state: success
                  status: true
        '500':
          description: The operator could not be reached. Retry; do not treat as a failure.
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Scoped Bearer token from `POST /merchant/api/auth`.

````