curl https://api.kwugwo.africa/v1/ugwo/ugw.VCvr.qnbBJaElzSTHOcaTzxbuDlIs/activities \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "charge",
"data": {
"medium": "bank_transfer",
"expires_at": "2026-05-15T10:30:00+00:00"
}
}'
const res = await fetch(
`https://api.kwugwo.africa/v1/ugwo/${ugwoUid}/activities`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "charge",
data: { medium: "bank_transfer" },
}),
}
);
const activity = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo/{$ugwoUid}/activities");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KWUGWO_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'charge',
'data' => ['medium' => 'bank_transfer'],
]),
]);
$activity = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
activity = requests.post(
f"https://api.kwugwo.africa/v1/ugwo/{ugwo_uid}/activities",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"type": "charge",
"data": {"medium": "bank_transfer"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"type": "charge",
"data": map[string]any{"medium": "bank_transfer"},
})
url := fmt.Sprintf("https://api.kwugwo.africa/v1/ugwo/%s/activities", ugwoUid)
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("KWUGWO_SECRET_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}
{
"uid": "act.VCvr.qnbBJaElzSTHOcaTzxbuDlIs",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "5kfxw34ugz",
"next_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": "requires_action",
"created_at": "2026-05-14T19:55:50+00:00",
"error": null,
"updated_at": "2026-05-14T19:55:51+00:00"
}
{
"uid": "act.VCvr.w9qTsfJMQkBIaITiGRDucv1u",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "s09v485jla6ckt1",
"next_action": {
"type": "user_action",
"instruction": "Please dial *737*33*4*92811# on your mobile phone to complete the transaction",
"headers": {
"ussd": "*737*33*4*92811#"
}
},
"status": "requires_action",
"created_at": "2026-05-15T16:10:18+00:00",
"error": null,
"updated_at": "2026-05-15T16:10:18+00:00"
}
{
"title": "Validation Failed",
"status": 422,
"violations": [
{ "propertyPath": "provider", "title": "This value should not be blank." }
]
}
Payments (Ugwo)
Charge an ugwo
Run a charge activity against a payment request.
POST
/
v1
/
ugwo
/
{ugwoUid}
/
activities
curl https://api.kwugwo.africa/v1/ugwo/ugw.VCvr.qnbBJaElzSTHOcaTzxbuDlIs/activities \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "charge",
"data": {
"medium": "bank_transfer",
"expires_at": "2026-05-15T10:30:00+00:00"
}
}'
const res = await fetch(
`https://api.kwugwo.africa/v1/ugwo/${ugwoUid}/activities`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "charge",
data: { medium: "bank_transfer" },
}),
}
);
const activity = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo/{$ugwoUid}/activities");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KWUGWO_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'charge',
'data' => ['medium' => 'bank_transfer'],
]),
]);
$activity = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
activity = requests.post(
f"https://api.kwugwo.africa/v1/ugwo/{ugwo_uid}/activities",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"type": "charge",
"data": {"medium": "bank_transfer"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"type": "charge",
"data": map[string]any{"medium": "bank_transfer"},
})
url := fmt.Sprintf("https://api.kwugwo.africa/v1/ugwo/%s/activities", ugwoUid)
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("KWUGWO_SECRET_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}
{
"uid": "act.VCvr.qnbBJaElzSTHOcaTzxbuDlIs",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "5kfxw34ugz",
"next_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": "requires_action",
"created_at": "2026-05-14T19:55:50+00:00",
"error": null,
"updated_at": "2026-05-14T19:55:51+00:00"
}
{
"uid": "act.VCvr.w9qTsfJMQkBIaITiGRDucv1u",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "s09v485jla6ckt1",
"next_action": {
"type": "user_action",
"instruction": "Please dial *737*33*4*92811# on your mobile phone to complete the transaction",
"headers": {
"ussd": "*737*33*4*92811#"
}
},
"status": "requires_action",
"created_at": "2026-05-15T16:10:18+00:00",
"error": null,
"updated_at": "2026-05-15T16:10:18+00:00"
}
{
"title": "Validation Failed",
"status": 422,
"violations": [
{ "propertyPath": "provider", "title": "This value should not be blank." }
]
}
Creates an activity on the ugwo. The activity describes one attempt
to act on the payment; today the only supported type is
Available for Nigeria (NGN).Available for Nigeria (NGN).Expected shape:
For
charge,
which sends the ugwo to a PSP through the medium you specify.
Activities are independent: a single ugwo can host many of them. If
a mobile_money charge fails, you can immediately create a
bank_transfer activity on the same ugwo without recreating it.
The ugwo must have a resolved checkout before you can create an
activity against it. If the ugwo’s
checkout is null (no
checkout was supplied at creation and the workspace couldn’t route
one), this endpoint returns 422.Path parameters
string
required
The ugwo to charge,
ugw.XXXX.YYYY....Body parameters
string
required
The activity type. Currently only
charge is supported.object
required
Type-specific payload.
data.medium selects the payment medium,
and the rest of the keys inside data are the parameters for that
medium (see Medium parameters below).Medium parameters
data.medium is one of bank_transfer, ussd, or mobile_money.
The other keys inside data depend on which one you picked.
- bank_transfer
- ussd
- mobile_money
{
"type": "charge",
"data": {
"medium": "bank_transfer",
"expires_at": "2026-05-15T10:30:00+00:00"
}
}
string
ISO-8601 (
DATE_ATOM) timestamp for when the virtual account
should stop accepting transfers. Optional; defaults to 15
minutes from now. Must be in the future and no more than
15 minutes ahead; timestamps in the past or further out
than 15 minutes return 422.{
"type": "charge",
"data": {
"medium": "ussd",
"provider": "gtb"
}
}
string
required
Bank code. Pass the text code from the supported banks
table, e.g.
gtb. Unknown
codes return 422.Coming soon with Ghana (GHS) support. See Concepts.
{
"type": "charge",
"data": {
"medium": "mobile_money",
"provider": "mtn",
"phone": "+233201234567"
}
}
Response
string
Activity ID (
act.…).string
Always
charge for this endpoint.string
Initial activity status.
requires_action when the customer has
more to do (bank transfer, USSD), processing when handed off to
the PSP without further customer input, or failed on a
synchronous error.object | null
Snapshot of the checkout this activity was routed through. Includes
uid, the currency as [code, label], and the configured
mediums.object | null
Tokenised medium (e.g. a stored card or wallet) the activity used;
null for one-off mediums like bank_transfer.string
The PSP that handled the charge, e.g.
paystack_ng.string | null
The reference the PSP issued for this attempt. Useful when
cross-referencing in your PSP dashboard.
object | null
What the customer needs to do next, if anything. See
next_action shape.object | null
Populated when the activity failed synchronously.
string
ISO-8601 timestamp.
string
ISO-8601 timestamp.
next_action shape
For bank_transfer, next_action.type is user_action and the
headers block carries everything the customer needs to complete
the transfer (account number, bank name, expiry, amount).
{
"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"
}
}
curl https://api.kwugwo.africa/v1/ugwo/ugw.VCvr.qnbBJaElzSTHOcaTzxbuDlIs/activities \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "charge",
"data": {
"medium": "bank_transfer",
"expires_at": "2026-05-15T10:30:00+00:00"
}
}'
const res = await fetch(
`https://api.kwugwo.africa/v1/ugwo/${ugwoUid}/activities`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "charge",
data: { medium: "bank_transfer" },
}),
}
);
const activity = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo/{$ugwoUid}/activities");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('KWUGWO_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'charge',
'data' => ['medium' => 'bank_transfer'],
]),
]);
$activity = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
activity = requests.post(
f"https://api.kwugwo.africa/v1/ugwo/{ugwo_uid}/activities",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"type": "charge",
"data": {"medium": "bank_transfer"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"type": "charge",
"data": map[string]any{"medium": "bank_transfer"},
})
url := fmt.Sprintf("https://api.kwugwo.africa/v1/ugwo/%s/activities", ugwoUid)
req, _ := http.NewRequest("POST", url, bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("KWUGWO_SECRET_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}
{
"uid": "act.VCvr.qnbBJaElzSTHOcaTzxbuDlIs",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "5kfxw34ugz",
"next_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": "requires_action",
"created_at": "2026-05-14T19:55:50+00:00",
"error": null,
"updated_at": "2026-05-14T19:55:51+00:00"
}
{
"uid": "act.VCvr.w9qTsfJMQkBIaITiGRDucv1u",
"activity_type": "charge",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": ["NGN", "Nigerian Naira (NGN)"],
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"ugwo_medium": null,
"psp": "paystack_ng",
"psp_external_id": "s09v485jla6ckt1",
"next_action": {
"type": "user_action",
"instruction": "Please dial *737*33*4*92811# on your mobile phone to complete the transaction",
"headers": {
"ussd": "*737*33*4*92811#"
}
},
"status": "requires_action",
"created_at": "2026-05-15T16:10:18+00:00",
"error": null,
"updated_at": "2026-05-15T16:10:18+00:00"
}
{
"title": "Validation Failed",
"status": 422,
"violations": [
{ "propertyPath": "provider", "title": "This value should not be blank." }
]
}

