Orange Money — AskPayment (contrat V2)

Production
Orange Money — AskPayment
Contrat d'interface V2 — Orange Finances Mobiles Mali, mai 2023. Cette page décrit l'intégration opérée par Neka Paie derrière l'API marchand : elle s'adresse aux équipes techniques et d'exploitation, pas aux marchands.

Le paiement en deux étapes

1 · Authentification POST {AUTH}/login
loginOMY + passwordOMY → token dans l'en-tête Authorization, valable pour plusieurs paiements.
2 · Push USSD POST {PAY}/back/askPaymentPush
transactionId, msisdn, montant, motif. Réponse = accusé de réception.
3 · Confirmation client Le client valide sur son téléphone avec son code secret, depuis la notification ou le menu USSD « paiements en attente ».
4 · Notification Orange appelle notre URL en GET. Neka Paie reconfirme systématiquement le statut avant de créditer le marchand.
5 · Statut GET {PAY}/back/payment/status/ref/{ref} puis, si la cause est masquée, GET {AUTH}/payment/status/session/{id}.
Différence majeure avec l'ancienne intégration WebPay. Le contrat AskPayment n'expose aucune page de paiement hébergée et aucun webservice de décaissement. Neka Paie fournit sa propre page d'attente (/payment/pending/{ref}) et l'API /payments/cashout répond 501 tant qu'Orange n'a pas fourni le webservice correspondant.

Endpoints actifs

valeurs réellement utilisées par cette instance
TestProduction
Authentification https://197.155.141.49:9090/login https://197.155.141.49:9093/login
Push USSD https://197.155.141.49:9091/back/askPaymentPush https://197.155.141.49:9094/back/askPaymentPush
Statut par référence https://197.155.141.49:9091/back/payment/status/ref/{Ref_Partenaire} https://197.155.141.49:9094/back/payment/status/ref/{Ref_Partenaire}
Statut par session https://197.155.141.49:9090/payment/status/session/{ID_SESSION} https://197.155.141.49:9093/payment/status/session/{ID_SESSION}
Compte technique ✓ configuré ⚠️ manquant
Durée du token 1800 s 1800 s
Accès réseau. Ces endpoints ne sont joignables qu'à travers le tunnel IPsec 2.25.85.154 ⇄ 197.155.141.49 (IKEv2, AES-256/SHA-256, DH14). Flux ouverts : 9090/9091 en test, 9093/9094 en production. Les noms internes équivalents côté SI Orange sont appsi.orangemali.local:32302 (authentification) et appsi.orangemali.local:32305 (paiement) : basculez dessus par paramètre si le DNS interne est résolu depuis le serveur.

URL de notification à déclarer chez Orange

URLhttps://www.nekapaie.com/api/webhooks/orange/notification
https://www.nekapaie.com/api/webhooks/orange/ML/notification

Orange l'appelle en GET avec msisdn, sessionId, montant, transactionId et refPartenaire. Réponses possibles :

200Notification reçue dans le bon format.
00075Numéro client non renseigné.
Le contrat ne prévoit aucune signature. L'authenticité repose sur le filtrage d'IP (ORANGE_ASKPAY_NOTIFY_ALLOWED_IPS, par défaut 197.155.141.49) et, en option, un jeton partagé (?token=… ou en-tête X-Orange-Token). Une notification ne peut jamais à elle seule faire passer une transaction en succès : le statut est systématiquement reconfirmé auprès d'Orange avant tout crédit de solde.

Paramètres de configuration

.env → config/services.yaml

Aucune URL, aucun chemin et aucun identifiant n'est codé en dur dans l'application. La cascade de résolution est : défaut de paramètre → variable d'environnement → surcharge de la filiale (back-office : Filiales & Pays). Une valeur laissée vide sur une filiale fait hériter du paramètre global.

VariableRôleDéfaut
ORANGE_ASKPAY_TEST_AUTH_BASE_URLBase authentification + statut par session (test)https://197.155.141.49:9090
ORANGE_ASKPAY_TEST_PAYMENT_BASE_URLBase push + statut par référence (test)https://197.155.141.49:9091
ORANGE_ASKPAY_PROD_AUTH_BASE_URLBase authentification + statut par session (prod)https://197.155.141.49:9093
ORANGE_ASKPAY_PROD_PAYMENT_BASE_URLBase push + statut par référence (prod)https://197.155.141.49:9094
ORANGE_ASKPAY_LOGIN_PATHChemin d'authentification/login
ORANGE_ASKPAY_PUSH_PATHChemin du push USSD/back/askPaymentPush
ORANGE_ASKPAY_STATUS_REF_PATHChemin du statut par référence/back/payment/status/ref
ORANGE_ASKPAY_STATUS_SESSION_PATHChemin du statut par session/payment/status/session
ORANGE_ASKPAY_TEST_LOGIN / _PASSWORDCompte technique de recetteà fournir par OFM
ORANGE_ASKPAY_PROD_LOGIN / _PASSWORDCompte technique de productionà fournir par OFM
ORANGE_ASKPAY_TOKEN_TTLDurée de validité du token, en secondes1800
ORANGE_ASKPAY_TOKEN_PREFIXPréfixe ajouté au token s'il n'en a pas (ex. Bearer)vide
ORANGE_ASKPAY_TIMEOUTTimeout HTTP des appels Orange30
ORANGE_ASKPAY_VERIFY_TLSVérification du certificat (0 pour un certificat interne)0
ORANGE_ASKPAY_MSISDN_LOCAL_FORMATEnvoyer le numéro au format local (8 chiffres)1
ORANGE_ASKPAY_MSISDN_COUNTRY_CODEIndicatif retiré / ajouté selon le format223
ORANGE_ASKPAY_DEFAULT_MOTIFMotif du push si le marchand n'en fournit pasPaiement Neka Paie
ORANGE_ASKPAY_NOTIFY_ALLOWED_IPSIPs autorisées sur l'endpoint de notification197.155.141.49
ORANGE_ASKPAY_NOTIFY_TOKENJeton partagé exigé sur la notification (optionnel)vide
ORANGE_ASKPAY_CASHOUT_PATHChemin de décaissement — vide = API cash-out désactivéevide
Secrets. loginOMY / passwordOMY ne doivent jamais être écrits dans un fichier commité. Sur le serveur de production, le fichier qui fait foi est /var/www/html/nekapaie/.env.local — chargé avant .env.prod, raison pour laquelle aucune valeur Orange n'est fixée dans les fichiers versionnés. Alternative : surcharge sur la filiale dans le back-office.

Correspondance des statuts

state Orangetxn_statusStatut Neka PaieInterprétation
OK200SUCCESSPaiement confirmé et débité.
PENDINGPENDINGPush délivré, en attente du client.
cancelednullFAILEDLe client n'a pas validé le paiement.
canceled54321FAILEDÉchec : la cause exacte s'obtient par le statut de session.
tout500PENDINGSI Orange indisponible — cas ambigu, on ne conclut pas.
KOvariableFAILEDÉchec signalé par la session.

Table complète des codes d'échec (solde, code secret, seuils client) : codes d'erreur →

Exploitation

Relance des paiements en attente

Filet de sécurité si la notification Orange n'arrive pas. À planifier dans la crontab root du VPS ; le délai de 3 minutes laisse au client le temps de saisir son code secret :

CRON* * * * * cd /var/www/html/nekapaie && php bin/console nekapay:poll-pending --older-than=3 --env=prod
Vérifier l'état du tunnel

À lancer depuis le VPS (2.25.85.154) : le tunnel ne part pas d'un poste de développement. Tant que la SA n'est pas établie, tous les appels Orange tomberont en timeout.

BASHsudo ipsec statusall | grep -A5 orange-mali
for p in 9090 9091 9093 9094; do nc -z -w 4 197.155.141.49 $p && echo "$p ouvert" || echo "$p FERMÉ"; done
Vérifications après une mise en service
  1. Tunnel IPsec établi et flux ouverts vers 197.155.141.49.
  2. Compte technique renseigné dans /var/www/html/nekapaie/.env.local, puis php bin/console cache:clear --env=prod.
  3. Migration jouée (doctrine:migrations:migrate --env=prod), après sauvegarde de la base.
  4. Tests → Authentification Orange : token obtenu en test puis en production.
  5. Tests → Push USSD : paiement réel de bout en bout avec un numéro Orange Money.
  6. URL de notification déclarée chez Orange et rejouée depuis la console de test.
  7. Filiale activée dans Filiales & Pays.

Procédure complète, paramètres du tunnel et blocs de configuration prêts à coller : docs/orange-askpayment-deploiement.md dans le dépôt.