curl --request POST \
--url https://sandbox.users.niobi.co/api/v3/payment-link-api/create \
--header 'Content-Type: application/json' \
--data '
{
"client_id": "K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr",
"salt": "justrandomstring",
"sender": "John.co",
"timestamp": 1709363033,
"signature": "2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807",
"params": {
"business_name": "my business",
"item_name": "item name",
"callback_url": "https://webhook.site/unique-id",
"redirection_url": "https://webhook.site/unique-id",
"currency": "KES",
"amount": 5000,
"logo": "This is brand logo. Use the base64 format to upload a file of maximum 2MB size.",
"country_id": 1,
"currency_country_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}
'import requests
url = "https://sandbox.users.niobi.co/api/v3/payment-link-api/create"
payload = {
"client_id": "K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr",
"salt": "justrandomstring",
"sender": "John.co",
"timestamp": 1709363033,
"signature": "2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807",
"params": {
"business_name": "my business",
"item_name": "item name",
"callback_url": "https://webhook.site/unique-id",
"redirection_url": "https://webhook.site/unique-id",
"currency": "KES",
"amount": 5000,
"logo": "This is brand logo. Use the base64 format to upload a file of maximum 2MB size.",
"country_id": 1,
"currency_country_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
client_id: 'K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr',
salt: 'justrandomstring',
sender: 'John.co',
timestamp: 1709363033,
signature: '2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807',
params: {
business_name: 'my business',
item_name: 'item name',
callback_url: 'https://webhook.site/unique-id',
redirection_url: 'https://webhook.site/unique-id',
currency: 'KES',
amount: 5000,
logo: 'This is brand logo. Use the base64 format to upload a file of maximum 2MB size.',
country_id: 1,
currency_country_id: 1,
first_name: 'John',
last_name: 'Doe',
email: 'johndoe@example.com',
phone: '254161166649'
}
})
};
fetch('https://sandbox.users.niobi.co/api/v3/payment-link-api/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.users.niobi.co/api/v3/payment-link-api/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'client_id' => 'K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr',
'salt' => 'justrandomstring',
'sender' => 'John.co',
'timestamp' => 1709363033,
'signature' => '2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807',
'params' => [
'business_name' => 'my business',
'item_name' => 'item name',
'callback_url' => 'https://webhook.site/unique-id',
'redirection_url' => 'https://webhook.site/unique-id',
'currency' => 'KES',
'amount' => 5000,
'logo' => 'This is brand logo. Use the base64 format to upload a file of maximum 2MB size.',
'country_id' => 1,
'currency_country_id' => 1,
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'johndoe@example.com',
'phone' => '254161166649'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.users.niobi.co/api/v3/payment-link-api/create"
payload := strings.NewReader("{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.users.niobi.co/api/v3/payment-link-api/create")
.header("Content-Type", "application/json")
.body("{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.users.niobi.co/api/v3/payment-link-api/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Payment link created successfully.",
"data": {
"payment_link_id": 142,
"link": "https://payments.niobi.co/pay/550e8400-e29b-41d4-a716-446655440000?environment=dev",
"amount": 5000,
"logo": "https://s3.amazonaws.com/.../logo.png",
"business_name": "Acme Store",
"currency_country_id": 1,
"country_id": 1,
"currency": "KES",
"item_name": "Software Subscription",
"callback_url": "https://example.com/callback",
"redirection_url": "https://example.com/checkout/success",
"description": "Monthly subscription fee",
"long_description": "Covers the Pro plan for one calendar month, billed in advance.",
"status": "active",
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}{
"success": false,
"message": "Payment link was not created."
}{
"success": false,
"message": "Entity integration record not found."
}Create Payment Link
Creates a payment link, and allows you to pass customer details, such as name, email, or phone number, so that the generated payment link is prefilled with this information. When shared with a customer, the link opens Niobi’s hosted checkout page, where they confirm their details and complete payment without you building any UI.
curl --request POST \
--url https://sandbox.users.niobi.co/api/v3/payment-link-api/create \
--header 'Content-Type: application/json' \
--data '
{
"client_id": "K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr",
"salt": "justrandomstring",
"sender": "John.co",
"timestamp": 1709363033,
"signature": "2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807",
"params": {
"business_name": "my business",
"item_name": "item name",
"callback_url": "https://webhook.site/unique-id",
"redirection_url": "https://webhook.site/unique-id",
"currency": "KES",
"amount": 5000,
"logo": "This is brand logo. Use the base64 format to upload a file of maximum 2MB size.",
"country_id": 1,
"currency_country_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}
'import requests
url = "https://sandbox.users.niobi.co/api/v3/payment-link-api/create"
payload = {
"client_id": "K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr",
"salt": "justrandomstring",
"sender": "John.co",
"timestamp": 1709363033,
"signature": "2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807",
"params": {
"business_name": "my business",
"item_name": "item name",
"callback_url": "https://webhook.site/unique-id",
"redirection_url": "https://webhook.site/unique-id",
"currency": "KES",
"amount": 5000,
"logo": "This is brand logo. Use the base64 format to upload a file of maximum 2MB size.",
"country_id": 1,
"currency_country_id": 1,
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
client_id: 'K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr',
salt: 'justrandomstring',
sender: 'John.co',
timestamp: 1709363033,
signature: '2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807',
params: {
business_name: 'my business',
item_name: 'item name',
callback_url: 'https://webhook.site/unique-id',
redirection_url: 'https://webhook.site/unique-id',
currency: 'KES',
amount: 5000,
logo: 'This is brand logo. Use the base64 format to upload a file of maximum 2MB size.',
country_id: 1,
currency_country_id: 1,
first_name: 'John',
last_name: 'Doe',
email: 'johndoe@example.com',
phone: '254161166649'
}
})
};
fetch('https://sandbox.users.niobi.co/api/v3/payment-link-api/create', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://sandbox.users.niobi.co/api/v3/payment-link-api/create",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'client_id' => 'K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr',
'salt' => 'justrandomstring',
'sender' => 'John.co',
'timestamp' => 1709363033,
'signature' => '2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807',
'params' => [
'business_name' => 'my business',
'item_name' => 'item name',
'callback_url' => 'https://webhook.site/unique-id',
'redirection_url' => 'https://webhook.site/unique-id',
'currency' => 'KES',
'amount' => 5000,
'logo' => 'This is brand logo. Use the base64 format to upload a file of maximum 2MB size.',
'country_id' => 1,
'currency_country_id' => 1,
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'johndoe@example.com',
'phone' => '254161166649'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.users.niobi.co/api/v3/payment-link-api/create"
payload := strings.NewReader("{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://sandbox.users.niobi.co/api/v3/payment-link-api/create")
.header("Content-Type", "application/json")
.body("{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox.users.niobi.co/api/v3/payment-link-api/create")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"client_id\": \"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr\",\n \"salt\": \"justrandomstring\",\n \"sender\": \"John.co\",\n \"timestamp\": 1709363033,\n \"signature\": \"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807\",\n \"params\": {\n \"business_name\": \"my business\",\n \"item_name\": \"item name\",\n \"callback_url\": \"https://webhook.site/unique-id\",\n \"redirection_url\": \"https://webhook.site/unique-id\",\n \"currency\": \"KES\",\n \"amount\": 5000,\n \"logo\": \"This is brand logo. Use the base64 format to upload a file of maximum 2MB size.\",\n \"country_id\": 1,\n \"currency_country_id\": 1,\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"johndoe@example.com\",\n \"phone\": \"254161166649\"\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Payment link created successfully.",
"data": {
"payment_link_id": 142,
"link": "https://payments.niobi.co/pay/550e8400-e29b-41d4-a716-446655440000?environment=dev",
"amount": 5000,
"logo": "https://s3.amazonaws.com/.../logo.png",
"business_name": "Acme Store",
"currency_country_id": 1,
"country_id": 1,
"currency": "KES",
"item_name": "Software Subscription",
"callback_url": "https://example.com/callback",
"redirection_url": "https://example.com/checkout/success",
"description": "Monthly subscription fee",
"long_description": "Covers the Pro plan for one calendar month, billed in advance.",
"status": "active",
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@example.com",
"phone": "254161166649"
}
}{
"success": false,
"message": "Payment link was not created."
}{
"success": false,
"message": "Entity integration record not found."
}signature whenever you are creating a new payment link request.first_name, last_name, email, and phone at creation time. When these are included, the customer’s hosted checkout page loads with their details already filled in, so they only need to pick a payment method and confirm.Currency Country ID (Optional)
currency_country_id identifies the country of the payer (customer), based on the selected currency. It is used to support multi-country currency scenarios and ensures payments are routed correctly depending on the payer’s location.
For backward compatibility, this field is optional; if omitted the system will infer the country from currency and country_id where possible.List of Supported Countries
This endpoint covers every corridor available through the payment link API.| ID | Country | Code | Currency | Payment Method type | Status |
|---|---|---|---|---|---|
| 1 | Kenya | 254 | KES | till number, pay bill, pesalink, send money | Active |
| 2 | Benin | 229 | XOF | mtn | Active |
| 3 | Cote D’Ivoire | 225 | XOF | mtn, Orange | Active |
| 4 | Cameroon | 237 | XAF | mtn, Orange | Active |
| 5 | DRC | 243 | CDF | Airtel, Orange, Vodacom | Active |
| 7 | Malawi | 265 | MWK | Airtel, TNM | Coming Soon (Q3 2026) |
| 8 | Rwanda | 250 | RWF | MTN MOMO, Airtel, eKash | Active |
| 9 | Senegal | 221 | XOF | Orange, Free | Active |
| 10 | Tanzania | 255 | TZS | Airtel, Halotel, Tigo | Active |
| 11 | Uganda | 256 | UGX | mtn, Airtel | Active |
| 12 | Zambia | 260 | ZMW | Zamtel, mtn | Active |
| 13 | Sierra Leone | 232 | SLE | Orange | Active |
| 15 | South Africa | 27 | ZAR | bank_eft, capitec | Active |
| 16 | Ghana | 233 | GHS | mtn, At(AirtelTigo), Vodafone | Active |
| 17 | Nigeria | 234 | NGN | bank | Active |
| 18 | Burkina Faso | 226 | XOF | Orange, Moov | Active |
| 19 | Canada | 1 | CAD | SWIFT | Not Supported via Payment Links |
| 20 | China | 86 | CNY | CNAP Payout, CNAP Payin, AliPay, WeChat Pay | Coming Soon (Q4 2026) |
| 21 | Egypt | 20 | EGP | Vodafone Cash, Orange Cash, Etisalat Cash | Coming Soon (Q1 2027) |
| 22 | Ethiopia | 251 | ETB | Tele-Birr, M-Birr | Coming Soon (Q1 2027) |
| 23 | Europe | EU | EUR | SEPA | Not Supported via Payment Links |
| 24 | Mali | 223 | XOF | Orange, Moov | Active |
| 25 | Mozambique | 258 | MZN | Vodacom MPESA, Movitel, Tmcel, SIMO | Coming Soon (Q1 2027) |
| 26 | Pakistan | 92 | PKR | SWIFT, Raast, JazzCash, Easypaisa | Coming Soon (Q4 2026) |
| 27 | Stablecoins | CRYPTO | USDT/USDC | ERC20, TRC20, Polygon, Solana | Active |
| 28 | Togo | 228 | XOF | Moov, T Money | Active |
| 29 | UAE | 971 | AED | SWIFT | Not Supported via Payment Links |
| 30 | United Kingdom | 44 | GBP | SWIFT, FPS | Coming Soon (Q4 2026) |
| 31 | United States | 1 | USD | SWIFT, ACH, Fedwire | Coming Soon (Q4 2026) |
Body
Payload for creating a payment link for API
The Client id is your public key which is generated when you are creating a new API integration from our app.
"K1PoY1WYricSpXh6Wm24twnk6ecPJOWrHGsqiKJr"
Salt is used for security purposes. This is a random string and can be unique value for each request or always the same.
"justrandomstring"
The Sender is the title of the API Integration which was created through our app. you can just copy this title and use it whenever making a new signature
"John.co"
this is the current timestamp when the request is being made
1709363033
"2193d01d50d4bd5da234ac0e0add5d4ccb40907a1b1ab27a12d2c1d88a5d5807"
Show child attributes
Show child attributes

