curl https://api.kwugwo.africa/v1/ugwo \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": { "order_id": "4719", "channel": "web" }
}'
const res = await fetch("https://api.kwugwo.africa/v1/ugwo", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 500000,
currency: "NGN",
ref: "order_4719",
description: "Order #4719",
onye: "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
meta: { order_id: "4719", channel: "web" },
}),
});
const ugwo = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo");
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([
'amount' => 500000,
'currency' => 'NGN',
'ref' => 'order_4719',
'description' => 'Order #4719',
'onye' => 'ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE',
'meta' => ['order_id' => '4719', 'channel' => 'web'],
]),
]);
$ugwo = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
ugwo = requests.post(
"https://api.kwugwo.africa/v1/ugwo",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": {"order_id": "4719", "channel": "web"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": map[string]string{"order_id": "4719", "channel": "web"},
})
req, _ := http.NewRequest("POST", "https://api.kwugwo.africa/v1/ugwo", 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": "ugw.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"ref": "order_4719",
"onye_nzube": {
"uid": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Okeke",
"nzube_ref": "user_8821",
"billing_address": null,
"created_at": "2026-05-10T08:00:00+00:00",
"updated_at": "2026-05-10T08:00:00+00:00",
"meta": {},
"total_successful_activities": 2,
"total_failed_activities": 0,
"latest_ugwo_activity": "act.VCvr.X9yLp2KmRtV7nQ8sD4cYwHfE"
},
"amount": 500000,
"currency": "NGN",
"status": "requires_ugwo",
"description": "Order #4719",
"created_at": "2026-05-15T09:14:22+00:00",
"updated_at": "2026-05-15T09:14:22+00:00",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": "NGN",
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"total_amount_paid": 0,
"fee": 0,
"meta": { "order_id": "4719", "channel": "web" }
}
{
"message": "nzube.ugwo.error.amount_too_low",
"code": "not_allowed",
"params": []
}
{
"message": "nzube.ugwo.error.ref_already_exists",
"code": "already_exists",
"params": []
}
{
"type": "validation.error",
"title": "An error occurred",
"status": 422,
"detail": "This value should be of type int.",
"message": "Validation failed",
"errors": [
{ "field": "amount", "message": "This value should be of type int." }
]
}
Payments (Ugwo)
Create an ugwo
Create a payment for an order.
POST
/
v1
/
ugwo
curl https://api.kwugwo.africa/v1/ugwo \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": { "order_id": "4719", "channel": "web" }
}'
const res = await fetch("https://api.kwugwo.africa/v1/ugwo", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 500000,
currency: "NGN",
ref: "order_4719",
description: "Order #4719",
onye: "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
meta: { order_id: "4719", channel: "web" },
}),
});
const ugwo = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo");
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([
'amount' => 500000,
'currency' => 'NGN',
'ref' => 'order_4719',
'description' => 'Order #4719',
'onye' => 'ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE',
'meta' => ['order_id' => '4719', 'channel' => 'web'],
]),
]);
$ugwo = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
ugwo = requests.post(
"https://api.kwugwo.africa/v1/ugwo",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": {"order_id": "4719", "channel": "web"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": map[string]string{"order_id": "4719", "channel": "web"},
})
req, _ := http.NewRequest("POST", "https://api.kwugwo.africa/v1/ugwo", 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": "ugw.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"ref": "order_4719",
"onye_nzube": {
"uid": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Okeke",
"nzube_ref": "user_8821",
"billing_address": null,
"created_at": "2026-05-10T08:00:00+00:00",
"updated_at": "2026-05-10T08:00:00+00:00",
"meta": {},
"total_successful_activities": 2,
"total_failed_activities": 0,
"latest_ugwo_activity": "act.VCvr.X9yLp2KmRtV7nQ8sD4cYwHfE"
},
"amount": 500000,
"currency": "NGN",
"status": "requires_ugwo",
"description": "Order #4719",
"created_at": "2026-05-15T09:14:22+00:00",
"updated_at": "2026-05-15T09:14:22+00:00",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": "NGN",
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"total_amount_paid": 0,
"fee": 0,
"meta": { "order_id": "4719", "channel": "web" }
}
{
"message": "nzube.ugwo.error.amount_too_low",
"code": "not_allowed",
"params": []
}
{
"message": "nzube.ugwo.error.ref_already_exists",
"code": "already_exists",
"params": []
}
{
"type": "validation.error",
"title": "An error occurred",
"status": 422,
"detail": "This value should be of type int.",
"message": "Validation failed",
"errors": [
{ "field": "amount", "message": "This value should be of type int." }
]
}
Creates an ugwo, a request to collect
amount from a
customer. It starts as requires_ugwo. Then either hand its uid to
the embedded checkout, or charge it
from your own UI.
Always send
ref (your order ID). It is unique per workspace, so a
retried request with the same ref returns 409 instead of creating
a duplicate payment. See Retries and idempotency.Body parameters
integer
required
Amount to collect, in the smallest currency unit (kobo for
NGN). Must be within the currency’s limits:
for NGN, 20000 (₦200.00) to 5000000000 (₦50,000,000.00).string
required
ISO-4217 code, e.g.
NGN. Must be supported
and enabled on at least one PSP in your workspace.string
Your reference, up to 150 characters, typically the order ID.
Unique per workspace and case-sensitive. Echoed on the ugwo and in
every webhook.
string
Up to 150 characters, shown to the customer on the hosted checkout.
No line breaks.
string
The payer’s email, used when you don’t pass
onye. Kwugwo attaches
the customer with this email, creating one if needed. Ignored when
onye is set.If you send neither onye nor onye_email, the workspace’s
default payment email (dashboard settings) is used; without one,
the request fails with 422.string
ID of a checkout,
chk.…. Pins this payment to
that checkout’s mediums and routing instead of letting your workspace
routing rules choose.object
Up to 50
{ "key": "value" } pairs for your own use. Keys are
strings; values are strings of up to 255 characters, or null.
Returned on the ugwo; never shown to the customer.Response
The new Ugwo object withstatus: "requires_ugwo".
lastest_ugwo_activity is not included in this response.
Errors
| Status | message | Cause |
|---|---|---|
405 | nzube.ugwo.error.amount_too_low / amount_too_high | amount is outside the currency’s limits. |
405 | nzube.ugwo.error.currency_not_allowed | None of your PSPs accept this currency. |
409 | nzube.ugwo.error.ref_already_exists | An ugwo with this ref already exists. Fetch it instead of creating another. |
422 | (errors) | A field failed validation: unknown onye or checkout, bad email, malformed meta, no customer and no default payment email. |
curl https://api.kwugwo.africa/v1/ugwo \
-H "Authorization: Bearer $KWUGWO_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": { "order_id": "4719", "channel": "web" }
}'
const res = await fetch("https://api.kwugwo.africa/v1/ugwo", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KWUGWO_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 500000,
currency: "NGN",
ref: "order_4719",
description: "Order #4719",
onye: "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
meta: { order_id: "4719", channel: "web" },
}),
});
const ugwo = await res.json();
<?php
$ch = curl_init("https://api.kwugwo.africa/v1/ugwo");
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([
'amount' => 500000,
'currency' => 'NGN',
'ref' => 'order_4719',
'description' => 'Order #4719',
'onye' => 'ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE',
'meta' => ['order_id' => '4719', 'channel' => 'web'],
]),
]);
$ugwo = json_decode(curl_exec($ch), true);
curl_close($ch);
import os, requests
ugwo = requests.post(
"https://api.kwugwo.africa/v1/ugwo",
headers={"Authorization": f"Bearer {os.environ['KWUGWO_SECRET_KEY']}"},
json={
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": {"order_id": "4719", "channel": "web"},
},
).json()
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"amount": 500000,
"currency": "NGN",
"ref": "order_4719",
"description": "Order #4719",
"onye": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"meta": map[string]string{"order_id": "4719", "channel": "web"},
})
req, _ := http.NewRequest("POST", "https://api.kwugwo.africa/v1/ugwo", 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": "ugw.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"ref": "order_4719",
"onye_nzube": {
"uid": "ony.VCvr.7K2qPmRtV9xLnQ8sD1cYwHfE",
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Okeke",
"nzube_ref": "user_8821",
"billing_address": null,
"created_at": "2026-05-10T08:00:00+00:00",
"updated_at": "2026-05-10T08:00:00+00:00",
"meta": {},
"total_successful_activities": 2,
"total_failed_activities": 0,
"latest_ugwo_activity": "act.VCvr.X9yLp2KmRtV7nQ8sD4cYwHfE"
},
"amount": 500000,
"currency": "NGN",
"status": "requires_ugwo",
"description": "Order #4719",
"created_at": "2026-05-15T09:14:22+00:00",
"updated_at": "2026-05-15T09:14:22+00:00",
"checkout": {
"uid": "chk.VCvr.vBtGwathtd99FpQGIGwIAATX",
"currency": "NGN",
"mediums": [
{ "medium": "bank_transfer" },
{ "medium": "ussd" }
]
},
"total_amount_paid": 0,
"fee": 0,
"meta": { "order_id": "4719", "channel": "web" }
}
{
"message": "nzube.ugwo.error.amount_too_low",
"code": "not_allowed",
"params": []
}
{
"message": "nzube.ugwo.error.ref_already_exists",
"code": "already_exists",
"params": []
}
{
"type": "validation.error",
"title": "An error occurred",
"status": 422,
"detail": "This value should be of type int.",
"message": "Validation failed",
"errors": [
{ "field": "amount", "message": "This value should be of type int." }
]
}