Développeurs
L’API, en une page
Une API REST en JSON pour les paiements par carte et en espèces au Maroc. Vos clés de test arrivent avec votre compte, et la documentation donne chaque exemple en 10 langages.
I. Démarrage rapide
Un premier paiement, en trois étapes
En mode test : aucun argent réel ne circule, et la page de la carte est une simulation.
I.
Récupérez votre clé de test
Inscrivez-vous : votre clé secrète de test s’affiche une seule fois, à ce moment-là. Gardez-la dans une variable d’environnement sur votre serveur.
export APX_SECRET_KEY="apx_sk_test_…"II.
Créez une session de paiement
Un montant en centimes, la devise, les moyens de payer, et l’adresse où renvoyer votre client. La réponse contient l’adresse de la page : redirigez-y votre client.
curl https://pay-api.adpromax.com/v1/checkout/sessions \ -u "$APX_SECRET_KEY:" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: checkout-order-1042" \ -d '{ "amount": 25000, "currency": "mad", "payment_method_types": ["card"], "success_url": "https://shop.example.com/thanks", "cancel_url": "https://shop.example.com/cart", "metadata": { "order_id": "1042" } }'III.
Apprenez l’issue par un webhook
Quand le paiement réussit, nous envoyons
payment_intent.succeededà votre point de terminaison. Vérifiez la signature sur le corps brut, puis honorez la commande.Le retour sur votre page de succès n’est pas une preuve de paiement : livrez sur le webhook.
import { Buffer } from 'node:buffer' import { createServer } from 'node:http' import { verifySignature } from './verify-signature.mjs' createServer(async (request, response) => { const chunks = [] for await (const chunk of request) chunks.push(chunk) // The exact bytes: verify them before parsing. const rawBody = Buffer.concat(chunks) const header = request.headers['x-adpromaxpay-signature'] ?? '' const secret = process.env.APX_WEBHOOK_SECRET if (!verifySignature(rawBody, header, secret)) { response.writeHead(400).end() return } const event = JSON.parse(rawBody.toString('utf8')) if (event.type === 'payment_intent.succeeded') { const paymentIntent = event.data.object // Fulfil the order that holds this payment intent, once. console.log('paid', paymentIntent.id) } response.writeHead(200).end() }).listen(4242)
II. Les objets
Six objets, nommés pour ce qu’ils sont
Chacun a un identifiant qui commence par son type : une ligne de journal dit d’emblée de quoi elle parle.
pi_…
Intention de paiement
Un paiement, de sa création à son issue. Elle passe par quelques statuts, et votre code lit le statut au lieu de le deviner.
cs_…
Session de paiement
Une visite de la page de paiement hébergée pour une commande. Elle porte l’adresse de la page et l’intention de paiement qu’elle règle.
cus_…
Client
Qui paie : un e-mail, un nom, un téléphone. Facultatif, et il regroupe les paiements d’une même personne.
re_…
Remboursement
De l’argent rendu pour un paiement par carte, en totalité ou en partie.
evt_…
Événement
La trace de quelque chose qui s’est passé. Ce sont les événements que vos webhooks livrent.
we_…
Point de terminaison de webhook
Une adresse sur votre serveur, et les événements qu’elle veut recevoir.
III. Webhooks
Signés, et renvoyés
Un webhook est une requête HTTPS que nous envoyons à votre serveur quand quelque chose se passe. Chaque envoi est signé, et celui auquel votre serveur n’a pas répondu est renvoyé.
- Une signature dans un en-tête : un HMAC-SHA256 de l’heure et du corps brut
- Un envoi vieux de plus de cinq minutes est refusé : un envoi intercepté ne peut pas être rejoué
- Des nouvelles tentatives étalées sur environ trois jours
- Chaque tentative figure dans le tableau de bord, avec un bouton pour la renvoyer
- Un événement d’exemple pour vérifier votre adresse, en mode test
X-AdProMaxPay-Signature: t=1790851200,v1=d2e39688034d…9a9879e
IV. Idempotence
Renvoyez-la, sans la doubler
Le réseau peut tomber après que nous avons fait le travail et avant que vous ayez lu la réponse. Renvoyez la même requête avec la même Idempotency-Key et vous recevez la première réponse : rien ne s’exécute une seconde fois.
- Obligatoire sur chaque requête qui déplace de l’argent
- Conservée 24 heures, pour chaque organisation et chaque mode
- Une réponse rejouée le dit, dans un en-tête
V. Erreurs
Des erreurs sur lesquelles agir
Une requête qui échoue répond par un objet d’erreur. Votre code se décide sur son type et son code ; le message, lui, est pour les humains.
- Sept types, de la requête mal formée à la carte refusée
- Un code stable pour chaque cause, avec sa propre page dans la documentation
- Un identifiant de requête sur chaque réponse, pour la retrouver dans les journaux
- Des messages en anglais, en français ou en arabe, selon ce que demande votre requête
VI. Limites
Des limites que vous voyez
L’API limite le nombre de requêtes qu’une organisation envoie par minute, pour que la rafale d’une intégration ne ralentisse jamais les autres. Le mode test a ses propres limites.
- Trois en-têtes sur chaque réponse vous disent où vous en êtes
- Un refus vous dit combien de temps attendre
- Le tableau de bord affiche les limites qui s’appliquent à vous, et permet d’en demander davantage
VII. Clés
Des clés, de test et de production
Une clé dit à l’API quelle organisation vous êtes et dans quel mode vous travaillez. Les clés de test fonctionnent dès l’inscription ; les clés de production, une fois votre compte activé.
- Une clé secrète s’affiche une seule fois, à sa création
- Renouvelez une clé : l’ancienne continue de fonctionner le temps que vous choisissez
- Une clé de test ne voit que les données de test, une clé de production que celles de production
VIII. Exemples
Chaque exemple, en 10 langages
Choisissez-en un dans la documentation : toutes les pages suivent.
- curl
- Node.js
- TypeScript
- Python
- PHP
- Ruby
- Go
- Java
- C#
- Rust
IX. La documentation
Pour aller plus loin, page par page
Prenez vos clés de test, envoyez une première requête
Elles arrivent avec votre compte. Aucun argent réel ne circule en mode test.