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

# The Activity object

> One attempt to collect an ugwo through one payment medium.

An **activity** is a single attempt to collect an [ugwo](https://docs.kwugwo.africa/ugwo/object.md).
Today every activity has `activity_type: "charge"`. An ugwo can have
many activities (an abandoned bank transfer, then a successful USSD
charge), and several can be open at the same time. The first to
succeed pays the ugwo; any later success is a [double
charge](#double-charges).

Refunds attach to the activity that collected the money, so store the
successful activity's `uid` alongside the ugwo's.

## Attributes

**uid** `string`

Unique identifier, `act.XXXX.YYYYYYYYYYYYYYYYYYYYYYYY`.

**activity\_type** `enum`

Always `charge`.

**checkout** `object`

The [checkout](https://docs.kwugwo.africa/checkouts/object.md) the attempt was routed through:
`{ uid, currency, mediums: [{ medium }] }`.

**ugwo\_medium** `object | null`

The payment instrument used for this attempt, once known.

**properties**

**medium** `string`

`bank_transfer`, `ussd`, `pay_with_bank` or `mobile_money`.

**provider** `string | null`

Bank or wallet name as the PSP reports it, e.g. `PalmPay`. This is a display name, not a [bank code](https://docs.kwugwo.africa/concepts.md#bank-codes-nigeria).

**account\_name** `string | null`

Account holder name, when the PSP reports it.

**account\_id** `string | null`

Account number or wallet identifier.

**expires\_at** `string | null`

ISO-8601 expiry of the instrument, if any.

**country** `string | null`

ISO-3166-1 alpha-2 country code.

**last4** `string | null`

The account number, masked, e.g. `00XXXX0000`, when available.

**psp\_external\_id** `string | null`

The PSP's identifier for the instrument.

**psp** `string`

The PSP that handled the attempt, e.g. `paystack_ng`.

**psp\_external\_id** `string | null`

The PSP's reference for this charge. Use it to find the transaction in
your PSP dashboard.

**status** `enum`

One of `requires_action`, `processing`, `successful`, `failed`,
`expired`, `reversed`, `partially_refunded`, `refunded`. See
[Status](#status).

**created\_at** `string`

ISO-8601 timestamp.

**error** `object | null`

Why the attempt failed. `null` unless `status` is `failed`.

**properties**

**type** `enum`

`psp_error` (the PSP rejected the charge), `issuer_error` (the
customer's bank declined it) or `system_error` (Kwugwo could not
complete the request with the PSP).

**message** `string`

Human-readable detail, often the PSP's own wording. Log it; don't
branch on it.

**updated\_at** `string`

ISO-8601 timestamp.

**amount** `integer | null`

The amount requested from the PSP, in the smallest currency unit.

**nzube\_subscription\_charge** `integer`

The Kwugwo usage charge for this attempt, in the smallest currency
unit, debited from your Kwugwo subscription balance (not from the
customer's payment).

**refunded\_amount** `integer`

How much of this activity is committed to [refunds](https://docs.kwugwo.africa/refunds/overview.md).
Rises when a refund is created and falls back if the refund fails.

**charged\_amount** `integer`

The amount the PSP says it is charging for this attempt, in the
smallest currency unit. Usually equal to `amount` and often set as
soon as the attempt is created, so **it is not proof of payment**:
check `status`. Can differ from `amount`, e.g. when a customer
transfers the wrong sum to a virtual account.

**next\_action** `object | null`

What the customer must do to complete this attempt, as a [Next action
object](https://docs.kwugwo.africa/ugwo/next-action-object.md). Present when `status` is
`requires_action`; kept afterwards with its own `status` of
`fulfilled` or `expired`.

**is\_double\_charge** `boolean`

`true` when this attempt succeeded after the ugwo had already been
paid by another activity. The ugwo is not affected; refund this
activity to return the extra money. See
[`ugwo.activity.double_charge_detected`](https://docs.kwugwo.africa/webhook-events#double-charge-detected).

### Webhook-only attributes

Activities delivered in [webhooks](https://docs.kwugwo.africa/webhook-events.md) carry two extra
fields so you can find the parent payment:

**ugwo\_uid** `string`

The parent ugwo's ID, `ugw.…`.

**ugwo** `string`

The same parent ugwo ID, `ugw.…`.

```json The Activity object theme={"system"}
{
  "uid": "act.VCvr.qnbBJaElzSTHOcaTzxbuDlIs",
  "activity_type": "charge",
  "checkout": {
    "uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
    "currency": "NGN",
    "mediums": [
      { "medium": "bank_transfer" },
      { "medium": "ussd" }
    ]
  },
  "ugwo_medium": null,
  "psp": "paystack_ng",
  "psp_external_id": "5kfxw34ugz",
  "status": "requires_action",
  "created_at": "2026-05-14T19:55:50+00:00",
  "error": null,
  "updated_at": "2026-05-14T19:55:51+00:00",
  "amount": 500000,
  "nzube_subscription_charge": 2500,
  "refunded_amount": 0,
  "charged_amount": 500000,
  "next_action": {
    "uid": "uac.VCvr.Rk4mZpQ7wLsD2vT8xNbHyCeU",
    "action": {
      "type": "user_action",
      "instruction": "Transfer to bank",
      "headers": {
        "bank_name": "Test Bank",
        "expires_at": "2026-05-14T20:10:50+00:00",
        "account_name": "PAYSTACK CHECKOUT",
        "account_number": "1260881821"
      }
    },
    "status": "pending",
    "last_error": null,
    "expires_at": "2026-05-14T20:10:50+00:00",
    "created_at": "2026-05-14T19:55:51+00:00",
    "updated_at": "2026-05-14T19:55:51+00:00"
  },
  "is_double_charge": false
}
```

## Status

| Status | Meaning | Terminal |
| - | - | - |
| `requires_action` | Waiting on the customer: transfer to an account, dial a code, approve a debit, or enter an OTP/PIN. See `next_action`. | No |
| `processing` | The initial status: the attempt is being sent to the PSP. Also used once the PSP has it and nothing is left for the customer to do. | No |
| `successful` | The customer paid. | No (can be refunded or reversed) |
| `failed` | The PSP or the bank rejected it. `error` says why. | Yes |
| `expired` | The customer didn't complete the action in time. | Yes |
| `reversed` | The PSP pulled back a payment it had confirmed. | Yes |
| `partially_refunded` | Part of the collected money has been [refunded](https://docs.kwugwo.africa/refunds/overview.md). | No |
| `refunded` | All of it has been refunded. | Yes |

When an activity ends as `failed`, `expired` or `reversed`, its ugwo
returns to `requires_ugwo` and you can start a new attempt.

## Double charges

If two open attempts on the same ugwo both succeed (say the customer
pays the bank transfer **and** dials the USSD code), the first one pays
the ugwo and the later one gets `is_double_charge: true`. The ugwo is
not changed by it, and Kwugwo sends
[`ugwo.activity.double_charge_detected`](https://docs.kwugwo.africa/webhook-events#double-charge-detected).
[Refund](https://docs.kwugwo.africa/refunds/create.md) the double-charged activity.


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