Paiement direct
Votre serveur déclenche le paiement avec le numéro du client et le montant, sans passer par la page d'Integral Pay. Le client confirme sur son téléphone.
Envoyez un en-tête Idempotency-Key unique par paiement. En cas de coupure réseau, vous pourrez renvoyer exactement la même requête sans débiter deux fois votre client. Voir Idempotence.
POST /api/v1/direct-payments/
| Champ | Type | Obligatoire | Règle |
|---|---|---|---|
provider | texte | oui | orange_bf, moov_bf ou sank_money_bf, parmi les moyens actifs de votre projet |
phone | texte | oui | 70123456, 22670123456 ou +22670123456 |
dial_code | texte | non | Indicatif sans « + » ; défaut 226 |
amount | entier | oui | De 100 à 2 000 000 XOF, ou le plafond de votre projet |
otp | texte | Orange et Sank | Code de confirmation du client, chiffres uniquement |
reference | texte | non | Votre référence (numéro de commande), 100 caractères au maximum |
description | texte | non | 255 caractères au maximum |
metadata | objet | non | Données libres, renvoyées telles quelles |
Déroulement selon l'opérateur
| Opérateur | Ce que fait le client | Réponse habituelle |
|---|---|---|
| Orange Money | Génère un code OTP depuis son menu Orange Money et le saisit sur votre site | 201 réussi |
| Moov Money | Reçoit une demande de confirmation sur son téléphone, rien à saisir | 202 en attente : attendez le webhook |
| Sank Money | Reçoit un code par SMS (étape préalable ci-dessous) et le saisit sur votre site | 201 réussi |
Sank Money, étape préalable. Appelez POST /api/v1/direct-payments/sank-otp/ avec phone, amount et éventuellement dial_code : le client reçoit son code par SMS. Transmettez-le ensuite dans otp. Les envois de SMS sont limités par numéro.
Exemple
- Python
- Node.js
- PHP
- cURL
# Même clé pour tous les renvois d'une même tentative ; nouvelle tentative = nouveau numéro
idempotency_key = f"commande-{order.id}-essai-{order.payment_attempts}"
resp = session.post(
f"{API_BASE}/direct-payments/",
headers={"Idempotency-Key": idempotency_key},
json={
"provider": "orange_bf",
"phone": "70123456",
"amount": 5000,
"otp": otp_saisi_par_le_client,
"reference": f"CMD-{order.id}",
},
timeout=60,
)
payment = resp.json()
if resp.status_code == 201:
... # réussi
elif resp.status_code == 202:
... # en attente : le webhook confirmera
elif resp.status_code == 402:
... # refusé : afficher payment["message"]
const response = await fetch(`${API_BASE}/direct-payments/`, {
method: 'POST',
headers: {
'X-Api-Key': process.env.INTEGRALPAY_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': `commande-${order.id}-essai-${order.paymentAttempts}`,
},
body: JSON.stringify({
provider: 'orange_bf',
phone: '70123456',
amount: 5000,
otp: otpSaisiParLeClient,
reference: `CMD-${order.id}`,
}),
});
const payment = await response.json(); // 201 réussi · 202 en attente · 402 refusé
$response = $client->post('direct-payments/', [
'headers' => ['Idempotency-Key' => 'commande-' . $order->id . '-essai-' . $order->paymentAttempts],
'json' => [
'provider' => 'orange_bf',
'phone' => '70123456',
'amount' => 5000,
'otp' => $otpSaisiParLeClient,
'reference' => 'CMD-' . $order->id,
],
'http_errors' => false,
]);
$payment = json_decode($response->getBody(), true); // 201 réussi · 202 en attente · 402 refusé
curl -X POST https://integralpay.tech/api/v1/direct-payments/ \
-H "X-Api-Key: $INTEGRALPAY_API_KEY" \
-H "Idempotency-Key: commande-1234-essai-1" \
-H "Content-Type: application/json" \
-d '{"provider": "orange_bf", "phone": "70123456", "amount": 5000, "otp": "123456", "reference": "CMD-1234"}'
Générez la clé une fois par tentative de paiement et enregistrez-la avant l'appel. Si l'appel échoue sans réponse (délai dépassé), renvoyez la requête avec la même clé : vous obtenez le paiement déjà créé, sans second débit.
Réponse
| HTTP | status | Signification |
|---|---|---|
201 | SUCCEEDED | Paiement confirmé |
202 | PENDING | En attente de la confirmation du client |
402 | CANCELED | Refusé par l'opérateur ; message donne la raison |
{
"id": "3f2a9c1e-5b7d-4e8a-9c21-7d4e5f6a8b90",
"status": "SUCCEEDED",
"amount": "5000.00",
"currency": "XOF",
"phone": "22670123456",
"provider": "orange_bf",
"provider_reference": "OM2611061015300001",
"reference": "CMD-1234",
"fee_amount": "150.00",
"message": "Paiement confirmé.",
"test": false,
"created_at": "2026-11-06T10:15:30+00:00"
}
fee_amount est la commission prélevée ; votre solde est crédité du montant net. Le statut se consulte ensuite avec GET /api/v1/direct-payments/{id}/, qui interroge l'opérateur si le paiement est encore en attente.