Create a local-rails collection (S2S)
curl --request POST \
--url http://localhost:3001/api/v1/business/collections \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"amount": 2,
"currency": "ngn",
"country": "NG",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"networkId": "<string>"
},
"metadata": {},
"successUrl": "<string>",
"expiresInSeconds": 600,
"idempotencyKey": "<string>"
}
'import requests
url = "http://localhost:3001/api/v1/business/collections"
payload = {
"amount": 2,
"currency": "ngn",
"country": "NG",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"networkId": "<string>"
},
"metadata": {},
"successUrl": "<string>",
"expiresInSeconds": 600,
"idempotencyKey": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 2,
currency: 'ngn',
country: 'NG',
customer: {
name: '<string>',
email: 'jsmith@example.com',
phone: '<string>',
networkId: '<string>'
},
metadata: {},
successUrl: '<string>',
expiresInSeconds: 600,
idempotencyKey: '<string>'
})
};
fetch('http://localhost:3001/api/v1/business/collections', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3001",
CURLOPT_URL => "http://localhost:3001/api/v1/business/collections",
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([
'amount' => 2,
'currency' => 'ngn',
'country' => 'NG',
'customer' => [
'name' => '<string>',
'email' => 'jsmith@example.com',
'phone' => '<string>',
'networkId' => '<string>'
],
'metadata' => [
],
'successUrl' => '<string>',
'expiresInSeconds' => 600,
'idempotencyKey' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$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 := "http://localhost:3001/api/v1/business/collections"
payload := strings.NewReader("{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
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("http://localhost:3001/api/v1/business/collections")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3001/api/v1/business/collections")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "<string>",
"object": "collection",
"status": "pending",
"amount": 123,
"currency": "<string>",
"country": "<string>",
"expiresAt": "<string>",
"channel": {
"rail": "bank",
"provider": "<string>",
"channelId": "<string>",
"networkId": "<string>"
},
"instructions": {
"kind": "bank_transfer",
"bankName": "<string>",
"accountNumber": "<string>",
"accountName": "<string>",
"reference": {},
"phone": "<string>",
"prompt": "<string>",
"url": "<string>",
"provider": "<string>"
},
"businessPaymentId": "<string>",
"source": "api",
"createdAt": "<string>",
"metadata": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}Local Rails
Create a local-rails collection (S2S)
Starts a local bank transfer or mobile money collection and returns the instructions the customer follows to pay. The currency must be enabled on your account and the corridor priced, or the request is refused as unsupported; a momo channel additionally requires customer.phone. Send an idempotencyKey to make retries safe — a repeat returns the collection already created rather than a second one. The window defaults to 60 minutes for mobile money and 30 minutes for bank and EFT, overridable with expiresInSeconds.
POST
/
api
/
v1
/
business
/
collections
Create a local-rails collection (S2S)
curl --request POST \
--url http://localhost:3001/api/v1/business/collections \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '
{
"amount": 2,
"currency": "ngn",
"country": "NG",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"networkId": "<string>"
},
"metadata": {},
"successUrl": "<string>",
"expiresInSeconds": 600,
"idempotencyKey": "<string>"
}
'import requests
url = "http://localhost:3001/api/v1/business/collections"
payload = {
"amount": 2,
"currency": "ngn",
"country": "NG",
"customer": {
"name": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"networkId": "<string>"
},
"metadata": {},
"successUrl": "<string>",
"expiresInSeconds": 600,
"idempotencyKey": "<string>"
}
headers = {
"x-api-key": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 2,
currency: 'ngn',
country: 'NG',
customer: {
name: '<string>',
email: 'jsmith@example.com',
phone: '<string>',
networkId: '<string>'
},
metadata: {},
successUrl: '<string>',
expiresInSeconds: 600,
idempotencyKey: '<string>'
})
};
fetch('http://localhost:3001/api/v1/business/collections', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3001",
CURLOPT_URL => "http://localhost:3001/api/v1/business/collections",
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([
'amount' => 2,
'currency' => 'ngn',
'country' => 'NG',
'customer' => [
'name' => '<string>',
'email' => 'jsmith@example.com',
'phone' => '<string>',
'networkId' => '<string>'
],
'metadata' => [
],
'successUrl' => '<string>',
'expiresInSeconds' => 600,
'idempotencyKey' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <x-api-key>"
],
]);
$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 := "http://localhost:3001/api/v1/business/collections"
payload := strings.NewReader("{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<x-api-key>")
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("http://localhost:3001/api/v1/business/collections")
.header("x-api-key", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3001/api/v1/business/collections")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 2,\n \"currency\": \"ngn\",\n \"country\": \"NG\",\n \"customer\": {\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"networkId\": \"<string>\"\n },\n \"metadata\": {},\n \"successUrl\": \"<string>\",\n \"expiresInSeconds\": 600,\n \"idempotencyKey\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": "<string>",
"object": "collection",
"status": "pending",
"amount": 123,
"currency": "<string>",
"country": "<string>",
"expiresAt": "<string>",
"channel": {
"rail": "bank",
"provider": "<string>",
"channelId": "<string>",
"networkId": "<string>"
},
"instructions": {
"kind": "bank_transfer",
"bankName": "<string>",
"accountNumber": "<string>",
"accountName": "<string>",
"reference": {},
"phone": "<string>",
"prompt": "<string>",
"url": "<string>",
"provider": "<string>"
},
"businessPaymentId": "<string>",
"source": "api",
"createdAt": "<string>",
"metadata": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "email must be an email",
"statusCode": 400,
"errors": {}
}
}Headers
Body
application/json
Amount in major units (matches hosted checkout)
Required range:
x >= 1Pattern:
/^[a-z]{3}$/Example:
"ngn"
Required string length:
2Example:
"NG"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Used for hosted-page rails such as ZA EFT
Required range:
60 <= x <= 3600Required string length:
1 - 128