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

# How Kwugwo works

> The payment flow end to end: who calls what, when, and which state each object is in.

## The payment flow

```mermaid theme={"system"}
sequenceDiagram
    autonumber
    participant C as Customer (browser)
    participant S as Your server
    participant K as Kwugwo API
    participant P as Your PSP

    C->>S: Checkout (order #4719)
    S->>K: POST /v1/ugwo { amount, currency, ref }
    K-->>S: ugwo (status: requires_ugwo)
    S-->>C: ugwo.uid

    alt Embedded checkout
        C->>K: KwugwoCheckout.open({ ugwoUid })
    else Direct API
        S->>K: POST /v1/ugwo/{uid}/activities { medium }
        K->>P: Create charge
        K-->>S: activity (requires_action + next_action)
        S-->>C: Show next_action (account no., USSD code, URL)
    end

    C->>P: Pays (transfer / dial / approve)
    P-->>K: Charge confirmed
    K->>S: Webhook ugwo.successful (signed)
    S->>K: GET /v1/ugwo/{uid}
    K-->>S: ugwo (status: ugwo_successful)
    S->>S: Validate amount / ref, fulfil order
```

What to take from it:

* **Your secret key never leaves your server.** The browser only ever
  holds the ugwo `uid` and, for the embed, your public key.
* **The browser is not the source of truth.** A customer can close the
  tab after paying, or tamper with a callback. Fulfil from the webhook
  plus a server-side `GET`. See [Validate and fulfil](https://docs.kwugwo.africa/guides/validate-and-fulfil.md).
* **Payment is asynchronous.** Bank transfers and USSD complete when
  the customer acts, which may be minutes later.

## The objects

```mermaid theme={"system"}
flowchart LR
    O[Onye<br/>customer] -. optional .-> U[Ugwo<br/>payment]
    CH[Checkout<br/>routing config] --> U
    U --> A1[Activity<br/>attempt 1: failed]
    U --> A2[Activity<br/>attempt 2: successful]
    A2 --> NA[Next action<br/>what the customer must do]
    A2 --> R[Refund]
```

| Object | What it is | You create it with |
| - | - | - |
| [Ugwo](https://docs.kwugwo.africa/ugwo/object.md) | The amount you want to collect for one order. | `POST /v1/ugwo` |
| [Activity](https://docs.kwugwo.africa/ugwo/activity-object.md) | One attempt to collect the ugwo through one medium. Retry with a new activity if one fails. | `POST /v1/ugwo/{uid}/activities`, or the embed |
| [Next action](https://docs.kwugwo.africa/ugwo/next-action-object.md) | What the customer must do to complete an activity. | Kwugwo, automatically |
| [Refund](https://docs.kwugwo.africa/refunds/object.md) | Money returned from a successful activity. | `POST /v1/refunds` |
| [Onye](https://docs.kwugwo.africa/customers/object.md) | A customer record. Optional. | `POST /v1/onye`, or implicitly via `onye_email` |
| [Checkout](https://docs.kwugwo.africa/checkouts/object.md) | Which mediums to offer and how to route them to PSPs. | Dashboard |

## Lifecycles

### Ugwo

```mermaid theme={"system"}
stateDiagram-v2
    [*] --> requires_ugwo: created
    requires_ugwo --> processing: attempt waiting on customer
    processing --> requires_ugwo: attempt failed / expired / reversed
    processing --> ugwo_successful: activity successful
    requires_ugwo --> cancelled: DELETE /v1/ugwo/{uid}
    ugwo_successful --> partially_refunded: refund
    ugwo_successful --> refunded: full refund
    partially_refunded --> refunded: remaining refunded
    cancelled --> [*]
```

* **Several attempts can be open at once.** A customer who starts a
  bank transfer can switch to USSD; just create another activity. The
  first one to succeed pays the ugwo. If a later one also succeeds, it
  is flagged as a [double charge](https://docs.kwugwo.africa/webhook-events.md#double-charge-detected)
  and the ugwo is not changed. Once the ugwo is paid or cancelled, new
  activities are rejected with `409`.
* **A failed attempt doesn't close the ugwo.** It returns to
  `requires_ugwo` and you can try again, with any medium.
* **Underpayment keeps it open.** If a PSP reports collecting less than
  the ugwo's `amount`, the ugwo goes back to `requires_ugwo` and
  `total_amount_paid` records what was received so far.

### Activity

```mermaid theme={"system"}
stateDiagram-v2
    [*] --> processing: created, being sent to the PSP
    processing --> requires_action: customer must act
    requires_action --> processing
    requires_action --> successful
    requires_action --> expired
    requires_action --> failed
    processing --> successful
    processing --> failed
    successful --> reversed
    successful --> partially_refunded
    successful --> refunded
    partially_refunded --> refunded
```

Full status tables live on each object page: [Ugwo](https://docs.kwugwo.africa/ugwo/object.md#status),
[Activity](https://docs.kwugwo.africa/ugwo/activity-object.md#status), [Next action](https://docs.kwugwo.africa/ugwo/next-action-object.md#status),
[Refund](https://docs.kwugwo.africa/refunds/object.md#status).

## Where to go next

> **[Quickstart](https://docs.kwugwo.africa/quickstart/accept-first-payment.md)**
>
> Run the flow above with cURL in sandbox.

> **[Validate and fulfil](https://docs.kwugwo.africa/guides/validate-and-fulfil.md)**
>
> The checks to run before you ship an order.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.