Initiate a Direct Payment Request
curl --request POST \
--url https://sandbox.fapshi.com/direct-pay \
--header 'Content-Type: application/json' \
--header 'apikey: <api-key>' \
--header 'apiuser: <api-key>' \
--data '
{
"amount": 101,
"phone": "<string>",
"name": "<string>",
"email": "jsmith@example.com",
"userId": "<string>",
"externalId": "<string>",
"message": "<string>"
}
'const options = {
method: 'POST',
headers: {apiuser: '<api-key>', apikey: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 101,
phone: '<string>',
name: '<string>',
email: 'jsmith@example.com',
userId: '<string>',
externalId: '<string>',
message: '<string>'
})
};
fetch('https://sandbox.fapshi.com/direct-pay', 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.fapshi.com/direct-pay",
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' => 101,
'phone' => '<string>',
'name' => '<string>',
'email' => 'jsmith@example.com',
'userId' => '<string>',
'externalId' => '<string>',
'message' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"apikey: <api-key>",
"apiuser: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://sandbox.fapshi.com/direct-pay"
payload = {
"amount": 101,
"phone": "<string>",
"name": "<string>",
"email": "jsmith@example.com",
"userId": "<string>",
"externalId": "<string>",
"message": "<string>"
}
headers = {
"apiuser": "<api-key>",
"apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://sandbox.fapshi.com/direct-pay")
.header("apiuser", "<api-key>")
.header("apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 101,\n \"phone\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"userId\": \"<string>\",\n \"externalId\": \"<string>\",\n \"message\": \"<string>\"\n}")
.asString();package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.fapshi.com/direct-pay"
payload := strings.NewReader("{\n \"amount\": 101,\n \"phone\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"userId\": \"<string>\",\n \"externalId\": \"<string>\",\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("apiuser", "<api-key>")
req.Header.Add("apikey", "<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))
}{
"message": "<string>",
"transId": "<string>",
"dateInitiated": "2023-12-25"
}{
"message": "<string>"
}Endpoints
Initiate a Direct Payment Request
Send a payment request directly to a user’s mobile device.
POST
/
direct-pay
Initiate a Direct Payment Request
curl --request POST \
--url https://sandbox.fapshi.com/direct-pay \
--header 'Content-Type: application/json' \
--header 'apikey: <api-key>' \
--header 'apiuser: <api-key>' \
--data '
{
"amount": 101,
"phone": "<string>",
"name": "<string>",
"email": "jsmith@example.com",
"userId": "<string>",
"externalId": "<string>",
"message": "<string>"
}
'const options = {
method: 'POST',
headers: {apiuser: '<api-key>', apikey: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 101,
phone: '<string>',
name: '<string>',
email: 'jsmith@example.com',
userId: '<string>',
externalId: '<string>',
message: '<string>'
})
};
fetch('https://sandbox.fapshi.com/direct-pay', 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.fapshi.com/direct-pay",
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' => 101,
'phone' => '<string>',
'name' => '<string>',
'email' => 'jsmith@example.com',
'userId' => '<string>',
'externalId' => '<string>',
'message' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"apikey: <api-key>",
"apiuser: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}import requests
url = "https://sandbox.fapshi.com/direct-pay"
payload = {
"amount": 101,
"phone": "<string>",
"name": "<string>",
"email": "jsmith@example.com",
"userId": "<string>",
"externalId": "<string>",
"message": "<string>"
}
headers = {
"apiuser": "<api-key>",
"apikey": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)HttpResponse<String> response = Unirest.post("https://sandbox.fapshi.com/direct-pay")
.header("apiuser", "<api-key>")
.header("apikey", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 101,\n \"phone\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"userId\": \"<string>\",\n \"externalId\": \"<string>\",\n \"message\": \"<string>\"\n}")
.asString();package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://sandbox.fapshi.com/direct-pay"
payload := strings.NewReader("{\n \"amount\": 101,\n \"phone\": \"<string>\",\n \"name\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"userId\": \"<string>\",\n \"externalId\": \"<string>\",\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("apiuser", "<api-key>")
req.Header.Add("apikey", "<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))
}{
"message": "<string>",
"transId": "<string>",
"dateInitiated": "2023-12-25"
}{
"message": "<string>"
}Direct pay is disabled by default on live environment; Follow the steps in the
Activate Direct pay on your Live Fapshi API guide
to enable direct pay in live mode.
Endpoint
POST /direct-pay
Send a payment request directly to a user’s mobile device. You are responsible for building your own checkout and verifying payment status.
Direct payment transactions cannot and do not expire. Consequently, their final state is either SUCCESSFUL or FAILED.
Handle this endpoint with care; misuse can result in account suspension.
Direct Pay is not available to payment aggregators (platforms that provide checkout to multiple merchants). Activation in live mode is reviewed per use case.
No idempotency. Fapshi does not support idempotency keys and does not enforce uniqueness of
externalId. Sending the same request twice creates two transactions and sends two payment prompts to the customer. If a request times out or its response is lost, do not resend it blindly; first look it up with GET /transaction/{userId}. See Transaction Handling.Parameters
| Name | Required | Type | Description |
|---|---|---|---|
| amount | Yes | integer | Amount to be paid (minimum 100 XAF). |
| phone | Yes | string | Phone number to request payment from (e.g., 67XXXXXXX). |
| medium | No | string | "mobile money" or "orange money". Omit to auto-detect. |
| name | No | string | Payer’s name. |
| No | string | Payer’s email to receive receipt. | |
| userId | No | string | Your system’s user ID (1–100 chars; a–z, A–Z, 0–9, -, _). Strongly recommended: it lets you look up the transaction if the response is lost. |
| externalId | No | string | Transaction/order ID for reconciliation (1–100 chars; a–z, A–Z, 0–9, -, _). Not required to be unique: Fapshi does not reject or deduplicate repeated values. |
| message | No | string | Reason for payment. |
Response
-
200 OKwith JSON body containing:message: success messagetransId: transaction ID to track payment statusdateInitiated: date when the payment was initiated
- Errors return 4XX with failure message.
A
200 response means the payment prompt was sent, not that the customer has paid. Track the final status with webhooks or GET /payment-status/{transId}. If the status is FAILED, the reason (insufficient funds, declined, ignored prompt, etc.) is not provided; see Failed Transactions.Body
application/json
Amount to be paid (minimum 100 XAF).
Required range:
x >= 100Phone number where payment request is sent.
Payment medium (optional).
Available options:
mobile money, orange money Name of the payer (optional).
Email of the payer for receipts (optional).
Internal user ID (optional).
Pattern:
^[a-zA-Z0-9\-_]{1,100}$Transaction/order ID for reconciliation (optional). Not required to be unique: Fapshi does not deduplicate requests, so a repeated request creates a new transaction.
Pattern:
^[a-zA-Z0-9\-_]{1,100}$Reason for payment (optional).