Relais
oca-africa.com

Intégration

Tes sites suivent déjà eBilling. Relais reprend le même contrat (factures, USSD, OAuth, callbacks HMAC). Derrière, les paiements partent sur ton portefeuille SingPay — un seul webhook, plusieurs sites.

Migrer depuis eBilling

Le code de tes sites ne change pas. Deux URLs à pointer vers https://oca-africa.com, et les credentials du site (pas ceux de SingPay).

Chez eBillingChez Relais
stg.billing-easy.com/api/v1|v2/…oca-africa.com — mêmes chemins /api/v1 et /api/v2
Cognito POST /oauth/tokenPOST /oauth/token (alias /oauth2/token)
client_id / client_secret du portailCeux du site dans Relais → Sites
notification_url de ta boutiqueInchangée — Relais signe HMAC v2
Wallet / USSD opérateurSingPay (Airtel 74, Moov 62)

Auth

POST https://oca-africa.com/oauth/token
Content-Type: application/json
{ "grant_type": "client_credentials",
  "client_id": "relais_boutique",
  "client_secret": "secret_boutique_demo" }

# Cognito-compat : POST https://oca-africa.com/oauth2/token
# form-urlencoded + Basic client_id:client_secret aussi acceptés

Authorization: Bearer <token>
# ou Basic client_id:client_secret (legacy eBilling)

Facture puis USSD

POST https://oca-africa.com/api/v1/merchant/e_bills
{ "amount": 5000,
  "payer_msisdn": "074000000",
  "short_description": "FAC-42",
  "external_reference": "FAC-2026-0042" }

PUT  https://oca-africa.com/api/v1/merchant/e_bills/{bill_id}/send
POST https://oca-africa.com/api/v2/merchant/e_bills/{bill_id}/ussd_push
{ "payment_system_name": "AIRTEL_MONEY",
  "payer_msisdn": "074000000" }

GET  https://oca-africa.com/api/v2/merchant/ussd_push/{id}
GET  https://oca-africa.com/api/v1/merchant/e_bills?external_reference=FAC-2026-0042

États eBill

created → ready → paid | expired | cancelled → processed

Callback vers ton site

Comme eBilling v2 : corps application/x-www-form-urlencoded (billingid, merchantid, customerid, transactionid, reference, paymentsystem, amount, state, createdat) et en-têtes HMAC-SHA256 X-Signature, X-Key-Id, X-Signature-Timestamp. Tes handlers PHP $_POST['billingid'] restent valides.

Webhook SingPay → Relais

Un seul callbackURL, celui du portefeuille. Relais l’enregistre via PUT /portefeuille/api/{wallet} (bouton Rail). SingPay POST ensuite tout résultat sur https://oca-africa.com/hook : Success, PIN erroné, solde, timeout, erreur. Relais vérifie le statut, clôture l’USSD, puis notifie ton site (type=payment si payé, type=ussd si échec).

# Chez SingPay Workspace, callbackURL du wallet =
https://oca-africa.com/hook

# Relais accepte aussi
POST https://oca-africa.com/api/hook
POST https://oca-africa.com/webhooks/singpay

# Corps typique
{
  "transaction": {
    "id": "sp_…",
    "status": "Terminate",
    "result": "Success | PasswordError | BalanceError | TimeOutError | Error",
    "reference": "EB_…"
  }
}

# Relais → ton site (succès)
type=payment&state=paid&result=Success&billingid=EB_…

# Relais → ton site (échec PIN, timeout, solde)
type=ussd&state=failed&result=PasswordError&billingid=EB_…

Correspondance rail

eBillingRelais / SingPay
POST /e_billsFacture interne (pas chez SingPay)
POST …/ussd_push AirtelPOST /v1/74/paiement
POST …/ussd_push MoovPOST /v1/62/paiement
external_referenceChez toi — bill_id part à SingPay
notification_url du siteRelais signe et route
callbackURL SingPayPOST /hook (un seul, jamais un site)