Introduction
Spirit Pay permet d’encaisser par virement instantané (Open Banking, via Bridge) à partir d’un lien ou d’un QR code. Vous pilotez tout depuis votre backend : création de lien, relances, réception des statuts par webhook.
Trois familles de parcours coexistent : envoi du lien par Spirit Pay (mode A), récupération du lien pour vos propres canaux (mode B), et encaissement en point de vente avec QR dynamique (mode C, POS).
La plateforme n’est pas limitée à quelques ERP nommés sur le site : vous choisissez comment brancher votre environnement. Les connecteurs Odoo, Abby, Axonaut ou Sage sont des entrées prêtes à l’emploi, pas un périmètre fermé. Les équipes qui veulent uniquement le moteur paiement utilisent l’API et le SDK npm comme tout service financier standard.
Liens factures
Associez chaque facture (ou document métier) à un lien et un QR alignés sur votre référence.
Paiement différé
Le payeur peut programmer une date d’exécution ; vous recevez les événements sur vos webhooks.
POS
Caisse ou tablette : montant saisi, QR affiché, confirmation temps réel par flux serveur (SSE).
Devis & app métier
Un bouton « Payer » dans votre outil (devis, CRM, logiciel sur mesure). voir le guide.
1. Votre système appelle Spirit Pay. Vous utilisez les clés secrètes sk_test_… / sk_live_… sur vos serveurs : module Odoo officiel, microservice, orchestrateur Make, caisse qui consomme l’API, ou projet Node.js avec @spiritpay/node. C’est le même contrat d’API pour toutes ces cibles : standard, ouvert, pas réservé à un éditeur.
2. Spirit Pay appelle votre outil métier. Pour des connecteurs comme Abby, Axonaut ou Sage, vous enregistrez en général leurs identifiants dans le tableau de bord Spirit Pay. Notre plateforme tire les factures et pousse le paiement sans que vous ayez à coller vos sk_… dans leur interface pour ce mode standard.
Vous pouvez combiner les approches selon vos projets (par exemple connecteur pour la facturation et API pour un outil interne). Les équipes qui veulent uniquement le moteur via npm ou HTTP n’ont pas besoin d’un ERP packagé : elles s’authentifient comme tout client API.
Odoo illustre le cas (1) : c’est Odoo qui envoie les requêtes et consomme les webhooks pour le lettrage. Les tests côté Abby ou Axonaut s’appuient surtout sur leur bac à sable et sur vos réglages dans Spirit Pay.
Démarrage rapide
Si vous appelez l’API Spirit Pay depuis votre code ou un module type Odoo, créez un compte développeur, activez l’environnement test, puis récupérez une clé secrète dans la rubrique dédiée aux clés API. Ne collez jamais une clé secrète dans une application frontale exposée aux navigateurs.
- Inscription et validation de l’espace marchand.
- Génération d’une clé
sk_test_…réservée au serveur. - Installation du paquet npm officiel (ci-dessous) ou appels HTTP directs.
- Déclaration d’une URL de webhook HTTPS accessible depuis Internet.
- Test du parcours payeur sur un lien généré en simulation.
Tester chez vous avec npm : il vous faut une clé secrète sk_test_… émise par Spirit Pay depuis votre compte (page « Clés API » après inscription). On retrouve la même idée qu’un bac à sable : vous codez et vous appelez notre API avec le préfixe test, les paiements restent en simulation. Quand le compte est prêt pour le réel, vous utilisez une clé sk_live_… sur votre backend de production. Vous ne configurez pas à la place des « clés Bridge » côté npm pour parler à Spirit Pay : votre application s’authentifie auprès de l’API Spirit Pay, et la couche bancaire réglementée est gérée dans notre infrastructure.
// 1. Installer le SDK
npm install @spiritpay/node
// 2. Initialiser
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({ apiKey: 'sk_test_...' });
// 3. Créer un lien de paiement
const payment = await spiritpay.invoices.create({
amount: 10000,
currency: 'EUR',
invoiceRef: 'FAC-2024-001',
dueDate: '2026-03-30',
invoiceAmountHT: 8333,
invoiceAmountTVA: 1667,
vatBreakdown: [{ rate: 20, base: 8333, vat: 1667 }],
payerName: 'Client SAS',
payerEmail: 'client@exemple.com',
sendEmail: true,
});
console.log(payment.paymentLink);Besoin des clés tout de suite ? Créer un compte développeur puis ouvrez la page « Clés API » une fois connecté.
Authentification
Chaque requête vers l’API doit inclure un jeton Bearer correspondant à votre clé secrète de compte. Les préfixes sk_test_ et sk_live_ distinguent simulation et production.
En-tête obligatoire
Authorization: Bearer sk_test_votre_cle_secrete
Les clés publiques (pk_test_…) servent aux intégrations côté client lorsque le produit l’autorise explicitement. Par défaut, considérez que toute opération sensible passe par votre backend.
Référence API (aperçu)
L’URL de base utilisée dans les exemples est https://api.spiritpay.fr/api. Les chemins sont relatifs à cette racine. Les corps sont en JSON UTF-8 ; les réponses suivent les codes HTTP standards.
Créer un lien de paiement facture
Méthode et chemin : POST /invoice-payments/create-payment-link
POST https://api.spiritpay.fr/api/invoice-payments/create-payment-link
Content-Type: application/json
Authorization: Bearer sk_test_...
{
"type": "invoice",
"amount": 10000,
"currency": "EUR",
"invoiceRef": "FAC-2024-001",
"dueDate": "2026-03-30",
"invoiceAmountHT": 8333,
"invoiceAmountTVA": 1667,
"vatBreakdown": [{ "rate": 20, "base": 8333, "vat": 1667 }],
"payerName": "Client SAS",
"payerEmail": "client@exemple.com",
"sendEmail": true,
"erpProvider": "odoo",
"erpInvoiceId": "12345"
}Réponse typique (succès)
HTTP 201 Created
{
"success": true,
"paymentId": "pay_abc123",
"paymentLink": "https://spiritpay.fr/pay/pay_abc123?type=invoice",
"qrCode": "data:image/png;base64,...",
"expiresAt": "2026-03-30T23:59:59Z"
}Paramètres du corps (liaison facture)
| Nom | Type | Requis | Description |
|---|---|---|---|
type | string | Oui | Valeur attendue : invoice. |
amount | integer | Oui | Montant en centimes (ex. 10000 pour 100,00 €). |
currency | string | Oui | Devise ISO 4217 (EUR, XOF, etc.). |
invoiceRef | string | Oui | Référence facture côté métier. |
dueDate | string | Non | Échéance au format YYYY-MM-DD. |
invoiceAmountHT | integer | Non | Montant HT en centimes (comptabilité). |
invoiceAmountTVA | integer | Non | Montant TVA en centimes. |
vatBreakdown | array | Non | Détail multi-taux : [{ rate, base, vat }] en centimes. |
payerName | string | Non | Nom affiché du payeur. |
payerEmail | string | Non | Adresse pour notifications et parcours payeur. |
sendEmail | boolean | Non | Si true, Spirit Pay peut envoyer l’e-mail au client (mode A). |
erpProvider | string | Non | Code ERP source (ex. odoo, sage). |
erpInvoiceId | string | Non | Identifiant facture dans votre ERP. |
metadata | object | Non | Métadonnées libres (limites appliquées côté serveur). |
D’autres routes (statuts, annulations selon produit, intégrations ERP dédiées) sont disponibles depuis votre tableau de bord une fois le compte activé. Les payloads exacts peuvent évoluer ; votre implémentation doit tolérer des champs additionnels ignorés.
Liens de paiement
Mode A. Spirit Pay envoie l’e-mail au client lorsque vous activez l’option correspondante dans la création de lien. Idéal lorsque vous ne maîtrisez pas encore le canal d’envoi ou lorsque vous voulez homogénéiser le template de message.
Mode B. Vous récupérez uniquement paymentLink et le QR, puis vous les placez dans votre PDF, votre ERP ou votre messagerie. Vous restez maître du wording et du moment d’envoi.
Dans les deux cas, conservez la référence facture et, si possible, l’identifiant ERP pour faciliter le rapprochement automatique après paiement.
Pour un devis validé ou une intégration hors e-commerce (bouton paiement seul), consultez la section .
Devis & bouton paiement (hors e-commerce)
Cette section s’adresse aux équipes qui veulent uniquement la brique d’encaissement : votre client valide un devis (ou un bon de commande) dans votre outil, puis clique sur « Payer » et arrive sur sa banque via Bridge. Pas besoin de boutique en ligne, de panier, ni du connecteur ERP du dashboard Spirit Pay.
Cas typiques : logiciel de devis sur mesure, CRM, application métier couplée à Pennylane ou autre compta, middleware entre votre stack et Spirit Pay. Vous gérez la signature / validation du devis ; Spirit Pay gère le virement Open Banking et le webhook de confirmation.
| Besoin | SDK recommandé | Expérience payeur |
|---|---|---|
| Devis signé → clic → banque immédiatement Recommandé pour un bouton paiement simple | checkout.create | Redirection directe Bridge (bridgeRedirectURL) |
| Facture / devis avec référence, échéance, QR, e-mail optionnel | invoices.create | Lien paymentLink (récap Spirit Pay) puis Bridge, ou envoi e-mail Spirit Pay si sendEmail: true |
| Portail payeur multi-factures (optionnel) | Smart Dashboard payeur | Le client consulte plusieurs factures d’un même créancier. pas requis pour un simple bouton devis |
Flux recommandé : devis → Bridge direct
- Le devis est validé dans votre application (signature manuelle, statut métier, etc.).
- Votre backend appelle
checkout.createavec le montant, la référence devis (orderRef) et le client (nom + e-mail). - Vous redirigez le navigateur vers
bridgeRedirectURL. - Le client choisit sa banque et valide le virement.
- Votre serveur reçoit
payment.executed(webhook) et marque le devis comme payé.
Exemple SDK : bouton « Payer mon devis »
// Devis validé dans VOTRE app → bouton « Payer » → Bridge direct (sans panier e-commerce)
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({
apiKey: process.env.SPIRITPAY_API_KEY,
environment: 'test' // puis 'production' après validation du compte
});
// Route serveur déclenchée au clic « Payer » (devis déjà signé côté métier)
const session = await spiritpay.checkout.create({
lineItems: [
{ name: 'Devis DEV-2026-042', quantity: 1, unitPriceHt: 2500, vatRate: 20 }
],
customer: {
name: req.body.clientName, // connu dans votre outil (CRM, devis, ERP custom)
email: req.body.clientEmail
},
orderRef: 'DEV-2026-042',
currency: 'EUR',
successUrl: 'https://portail.exemple.com/devis/DEV-2026-042/paiement-ok',
cancelUrl: 'https://portail.exemple.com/devis/DEV-2026-042/paiement-annule',
sendConfirmationEmail: false
});
res.redirect(session.bridgeRedirectURL);Variante : référence facture / devis (invoices.create)
Utilisez invoices.create si vous avez besoin d’une référence comptable stricte (invoiceRef), d’une échéance, d’un QR code, ou si Spirit Pay doit envoyer l’e-mail au client (sendEmail: true). Le payeur passe par une courte page Spirit Pay avant Bridge, utile pour l’historique et le Smart Dashboard côté payeur.
// Variante facture B2B : référence devis, échéance, rapprochement comptable
const payment = await spiritpay.invoices.create({
amount: 300000, // 3 000,00 € TTC (centimes)
currency: 'EUR',
invoiceRef: 'DEV-2026-042',
dueDate: '2026-07-15',
payerName: 'Client SAS',
payerEmail: 'client@exemple.com',
sendEmail: false, // vous gérez le bouton / l'e-mail dans votre app
erpProvider: 'odoo', // optionnel, code libre pour votre stack
erpInvoiceId: 'dev-8842'
});
// payment.paymentLink → page Spirit Pay (récap) puis Bridge
// Idéal si vous voulez aussi un QR ou un e-mail Spirit Pay plus tard
res.redirect(payment.paymentLink);Prérequis côté marchand
- Compte Spirit Pay + clé
sk_test_…puissk_live_…après inscription et validation production. - Clé secrète uniquement sur votre serveur, jamais dans le navigateur public.
- IBAN de reversement configuré (obligatoire en production pour encaisser).
- Formule Starter suffisante si vous n’utilisez que l’encaissement (sans module décaissement / Mes achats).
Confirmation du paiement
Dans le dashboard développeur, menu Webhooks : URL HTTPS (mode test puis production séparés), secret whsec_… affiché une seule fois à la création. Spirit Pay ajoute le chemin /spirit_pay/webhook à votre URL de base si besoin.
Configurez un endpoint avec corps brut (express.raw) et utilisez webhooks.verifySignature pour traiter payment.executed (paiement réussi). Voir la section ). Mettez à jour le statut du devis dans votre base à la réception de l’événement.
Retour navigateur : votre portail ou Spirit Pay
Passez successUrl et cancelUrl (HTTPS) dans checkout.create pour renvoyer le client vers votre page de confirmation ou d’annulation après le parcours Bridge. Spirit Pay ajoute paymentId, status, orderRef et sig (signature HMAC) en query string. Sans ces URLs, le client voit la page Spirit Pay /payment-success.
sendConfirmationEmail: false désactive l’e-mail de confirmation envoyé au payeur par Spirit Pay (utile si votre portail gère déjà le message). L’e-mail « paiement reçu » au marchand et le webhook restent actifs.
Redirection (successUrl / cancelUrl) = expérience utilisateur lorsque Bridge renvoie le navigateur vers Spirit Pay après le parcours banque.
Webhook (payment.executed) = vérité serveur pour marquer le devis payé dans votre base, dans tous les cas. Ne vous fiez pas uniquement au retour navigateur.
Limite Bridge : si le client ferme l’onglet ou quitte Bridge sans déclencher de retour, Spirit Pay ne peut pas rediriger vers cancelUrl. Appuyez-vous sur le webhook (ou un polling du statut paiement) pour détecter qu’un paiement n’a pas abouti.
API HTTP équivalente au checkout : POST /ecommerce/checkout-session. Voir aussi la section (même mécanisme, le nom « checkout » couvre tout paiement one-shot redirigé vers Bridge).
CRM & échéancier (vente à distance)
Intégration modulaire pour logiciels CRM, devis sur mesure ou ERP léger : l’acompte peut être encaissé en boutique (hors Spirit Pay) ; Spirit Pay gère le solde à distance par virement Open Banking (Bridge). Vous choisissez les briques : e-mails Spirit Pay ou les vôtres, webhooks, page de retour, échéancier Smart Dashboard.
Brique A : Solde 1× : POST /crm/pay-balance → lien Bridge direct (channel=crm), option successUrl / cancelUrl.
Brique B : Échéancier : POST /crm/payment-plan → N lignes de paiement + Smart Dashboard payeur (?channel=crm) : paiement immédiat ou programmation multi-dates (selon banque). Retour post-Bridge sur le dashboard, sans successUrl.
Brique C : Notifications : sendEmail / sendWelcomeEmail (Spirit Pay) ou vous distribuez paymentLink / payerDashboardUrl depuis votre CRM.
Brique D : Synchro CRM : webhooks payment.executed / payment.scheduled + polling GET /crm/orders/:ref/status.
Brique E : Paiement libre : POST /crm/open-opportunity → le client choisit le montant de chaque virement sur le Smart Dashboard (?channel=crm) jusqu’au solde complet. Paiements partiels, webhook enrichi (amount_paid_cumulative, remaining_balance). Distinct de l’échéancier (pas de mensualités fixes).
Parcours client
- Votre commercial crée l’opportunité dans le CRM (acompte boutique saisi manuellement).
- Votre backend appelle Spirit Pay (clé API
sk_*). - Le client reçoit un e-mail (Spirit Pay ou le vôtre) ou ouvre le Smart Dashboard.
- Paiement ou programmation via Bridge ; webhook → votre CRM met à jour le statut.
Solde unique, API
POST https://api.spiritpay.fr/api/crm/pay-balance
Authorization: Bearer sk_live_...
{
"crmOrderRef": "CMD-2026-8842",
"amount": 1200,
"payerName": "Mme Dupont",
"payerEmail": "client@exemple.com",
"sendEmail": true,
"depositPaid": 300,
"dueDate": "2026-07-15",
"successUrl": "https://crm.exemple.com/commande/ok",
"cancelUrl": "https://crm.exemple.com/commande/annule",
"commercialName": "Marie Martin"
}| Champ | Type | Requis | Description |
|---|---|---|---|
crmOrderRef | string | Oui | Référence commande / opportunité dans votre CRM (unique côté métier). |
amount | number | Oui | Solde restant TTC en euros. |
payerEmail | string | Oui | E-mail du client (Smart Dashboard + relances). |
payerName | string | Non | Nom affiché sur le portail bancaire. |
sendEmail | boolean | Non | Défaut true : Spirit Pay envoie l’e-mail « demande de règlement ». Si false, utilisez paymentLink dans votre CRM. |
depositPaid | number | Non | Acompte déjà encaissé hors Spirit Pay (tracé, informatif). |
dueDate | string | Non | Échéance ISO (YYYY-MM-DD) pour relances. |
successUrl | string | Non | HTTPS : retour navigateur après paiement validé (?paymentId=&status=&orderRef=&sig=). |
cancelUrl | string | Non | HTTPS : retour si abandon / échec Bridge. |
commercialName | string | Non | Nom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM. |
commercialId | string | Non | ID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité. |
commercialEmail | string | Non | E-mail optionnel du commercial (notification encaissement). |
// CRM / vente à distance : solde restant (acompte déjà encaissé en boutique)
const balance = await spiritpay.crm.payBalance({
crmOrderRef: 'CMD-2026-8842',
amount: 1200, // euros TTC restants
payerName: 'Mme Dupont',
payerEmail: 'client@exemple.com',
sendEmail: true, // false = vous envoyez le lien vous-même
depositPaid: 300,
successUrl: 'https://crm.exemple.com/ok',
cancelUrl: 'https://crm.exemple.com/annule'
});
// balance.paymentLink → Bridge direct (channel=crm)
// Webhook payment.executed = source fiable pour marquer « payé »Échéancier, API
POST https://api.spiritpay.fr/api/crm/payment-plan
Authorization: Bearer sk_live_...
{
"crmOrderRef": "CMD-2026-8842",
"amount": 1200,
"installments": 6,
"firstDueDate": "2026-07-01",
"payerName": "Mme Dupont",
"payerEmail": "client@exemple.com",
"sendWelcomeEmail": true,
"depositPaid": 300,
"commercialName": "Marie Martin"
}| Champ | Type | Requis | Description |
|---|---|---|---|
crmOrderRef | string | Oui | Référence commande CRM. |
amount | number | Oui | Solde total à étaler en mensualités. |
installments | number | Oui | Nombre d’échéances (1 à 60). |
firstDueDate | string | Non | Date 1re mensualité (défaut : aujourd’hui). |
payerEmail | string | Oui | E-mail client : une session Smart Dashboard pour tout l’échéancier. |
payerName | string | Non | Nom payeur. |
sendWelcomeEmail | boolean | Non | Défaut true : e-mail d’accueil avec lien échéancier (?channel=crm). |
depositPaid | number | Non | Acompte boutique déjà réglé. |
commercialName | string | Non | Nom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM. |
commercialId | string | Non | ID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité. |
commercialEmail | string | Non | E-mail optionnel du commercial (notification encaissement). |
Note : payment-plan n’accepte pas successUrl / cancelUrl : le retour post-Bridge reste sur le Smart Dashboard (voir section « Page de retour » ci-dessous).
// CRM : échéancier N mensualités, Smart Dashboard payeur
const plan = await spiritpay.crm.createPaymentPlan({
crmOrderRef: 'CMD-2026-8842',
amount: 1200,
installments: 10,
payerName: 'Mme Dupont',
payerEmail: 'client@exemple.com',
sendWelcomeEmail: true,
depositPaid: 300,
firstDueDate: '2026-07-01'
});
// plan.installments[] + Smart Dashboard (même e-mail = toutes les échéances)
// Relances automatiques à chaque date d'échéance (cron Spirit Pay)
// Webhook payment.executed avec plan_id + installment_indexPaiement libre (montant au choix du client)
Pour une opportunité à 1 000 € où le client peut régler 100 €, 200 €, etc. à sa guise (jusqu’au solde) : pas d’échéancier, un seul Smart Dashboard avec saisie du montant. Odoo : bouton Spirit Pay — paiement libre.
POST https://api.spiritpay.fr/api/crm/open-opportunity
Authorization: Bearer sk_live_...
{
"crmOrderRef": "CMD-2026-8842",
"totalAmount": 1000,
"payerName": "Mme Dupont",
"payerEmail": "client@exemple.com",
"sendEmail": true,
"depositPaid": 200,
"commercialId": "42",
"commercialName": "Marie Martin",
"commercialEmail": "marie@exemple.com"
}| Champ | Type | Requis | Description |
|---|---|---|---|
crmOrderRef | string | Oui | Référence opportunité CRM (ex. CM8). |
totalAmount | number | Oui | Montant total à encaisser (le client choisit chaque virement sur le dashboard). |
payerEmail | string | Oui | E-mail client : lien magique vers le Smart Dashboard (?channel=crm). |
payerName | string | Non | Nom affiché (pré-rempli sur le dashboard payeur). |
sendEmail | boolean | Non | Défaut true : e-mail Spirit Pay avec lien dashboard. |
depositPaid | number | Non | Acompte déjà encaissé hors Spirit Pay. |
commercialName | string | Non | Nom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM. |
commercialId | string | Non | ID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité. |
commercialEmail | string | Non | E-mail optionnel du commercial (notification encaissement). |
Réponse : opportunityId, payerDashboardUrl. Chaque encaissement déclenche un webhook payment.executed avec crm_payment_mode: open_amount, amount_paid_this_time, amount_paid_cumulative, remaining_balance, crm_order_status (partial ou completed).
Commerciaux — suivi des ventes (optionnel)
Pas obligatoire pour encaisser. Sur pay-balance, payment-plan et open-opportunity, les champs commercialName, commercialId et commercialEmail sont optionnels. Vous pouvez créer un paiement sans commercial : Spirit Pay fonctionne normalement.
Deux sources possibles (non exclusives) : (1) votre CRM assigne un vendeur sur l’opportunité et l’intégration envoie son nom automatiquement (ex. Odoo user_id) ; (2) votre middleware ou l’admin entreprise passe les champs à la main dans l’appel API. Rien n’est rigide côté CRM.
Identifiant principal : le nom (commercialName). Spirit Pay filtre les transactions et les sous-comptes commerciaux sur ce nom. ID CRM optionnel (commercialId) : utile si votre CRM expose un identifiant stable (ex. Odoo res.users).
Dashboard admin : onglet Transactions → filtre par nom ou URL /developers/transactions?commercialName=Marie%20Martin.
Connexion commercial (menu Commerciaux) : utile si l’entreprise crée des sous-comptes pour que chaque vendeur consulte ses ventes. 2FA par e-mail activable par l’admin (coché par défaut à la création) : code à 6 chiffres sur nouvel appareil, option « appareil de confiance » 30 jours. Le nom configuré doit correspondre au commercialName des paiements (CRM ou API).
Ce qu’un commercial ne fait pas (volontairement) : pas de clé API, pas de création de liens hors CRM, pas de webhooks ni paramètres entreprise. Les paiements partent toujours de l’opportunité ou de votre middleware CRM.
Smart Dashboard payeur (échéancier)
Réponse payerDashboardUrl : lien magique signé vers /pay/dashboard?channel=crm. Le client y voit toutes ses mensualités, peut :
- Payer immédiatement une ou plusieurs échéances (même créancier).
- Programmer à la date de chaque facture : une validation bancaire peut couvrir plusieurs dates si la banque le permet (fenêtre Bridge ~60 jours).
- Enregistrer sa banque dans « Mes banques » pour activer le paiement groupé / multi-échéances.
Relances automatiques Spirit Pay (cron) : J-3, jour J, J+1 à J+3 si toujours pending ; e-mails avec lien échéancier et date d’échéance dans le corps du message.
E-mails : Spirit Pay ou votre CRM ?
sendEmail: false (solde 1×) ou sendWelcomeEmail: false (plan) : Spirit Pay ne contacte pas le client : vous envoyez paymentLink ou payerDashboardUrl depuis votre outil (SMS, e-mail métier, portail client).
Si true (défaut), les modèles Spirit Pay partent avec la date d’échéance et le bouton vers le bon parcours.
Page de retour après paiement : solde vs échéancier
Règle produit : deux parcours distincts, complémentaires :
- Solde 1× (
pay-balance) :successUrl/cancelUrloptionnels : vous choisissez le retour vers votre portail CRM ou le fallback Spirit Pay. - Échéancier (
payment-plan) : pas desuccessUrlpar mensualité : le retour post-Bridge reste sur le Smart Dashboard (?channel=crm). - Synchro CRM : webhooks
payment.executed/payment.scheduled(source de vérité pour mettre à jour l’opportunité).
Solde 1×, retour configurable
Comme pour l’e-commerce : passez successUrl et cancelUrl (HTTPS) sur POST /crm/pay-balance. Après Bridge, le navigateur est renvoyé vers votre URL avec paymentId, status, orderRef et sig (HMAC). Sans URL : page Spirit Pay /payment-success.
Échéancier, Smart Dashboard par défaut (recommandé)
Après chaque validation bancaire (paiement immédiat ou programmation), le client revient sur son échéancier Spirit Pay : mensualités restantes, programmation partielle, file multi-créanciers, horizon 60 jours recalculé. C’est l’expérience la plus adaptée quand plusieurs échéances restent à régler.
- Pas de
successUrlsurpayment-plan: paramètre non exposé volontairement. - Distribuez
payerDashboardUrlau client (e-mail Spirit Pay, le vôtre, ou portail CRM). - Pour une page « Merci » ou un statut custom dans votre CRM : déclenchez-la sur le webhook, pas sur le retour Bridge.
- Polling de secours :
GET /crm/orders/{crmOrderRef}/status.
Pourquoi ne pas rediriger vers le CRM après chaque mensualité ? Le client sortirait de l’échéancier, perdrait le fil (échéances restantes, programmation en plusieurs validations), et vous devriez reconstruire l’état côté portail.
Webhooks CRM
Configurez l’URL et le secret dans le (événements payment.executed, payment.scheduled recommandés).
{
"event": "payment.executed",
"channel": "crm",
"payment_id": "INV_...",
"invoice_ref": "CMD-8842-E3/6",
"crm_order_ref": "CMD-8842",
"plan_id": "PLAN_...",
"installment_index": 3,
"installment_total": 6,
"amount": 200,
"currency": "EUR",
"status": "completed",
"payer": { "name": "...", "email": "..." },
"timestamp": "2026-07-01T10:00:00.000Z"
}Polling de secours : GET /crm/orders/{crmOrderRef}/status et GET /crm/plans/{planId}.
Référence Odoo CRM
Module open source fourni : spirit_pay_crm (opportunités CRM, wizard échéancier, webhook entrant). Dépend de spirit_pay_odoo. Idéal pour démo bijouterie ou base de customisation.
- Champs : acompte boutique, solde restant, statut Spirit Pay, JSON paiements.
- Boutons : payer 1×, paiement libre, créer échéancier, synchroniser statut (API Spirit Pay).
- Webhook Odoo : route
/spirit_pay/webhook, même secret que le dashboard développeur. - Commercial : champs optionnels (
commercialName,commercialId) — auto si vendeur assigné sur l’opportunité, sinon omis.
Autres CRM (EspoCRM, Salesforce, sur mesure)
Même API HTTP. Exemple Node minimal : dossier integrations/crm-demo/ du dépôt Spirit Pay. Votre middleware appelle /api/crm/* et expose un endpoint webhook vers votre base.
Hub développeur : onglet CRM & échéancier avec la checklist d’installation, briques modulaires et liens rapides (clés API, webhooks).
E-commerce (site custom)
Pour un site codé de A à Z (hors Shopify) : votre backend crée une session checkout et redirige le client directement vers Bridge. Collectez nom et e-mail sur votre propre page checkout, sans modal Spirit Pay intermédiaire.
SDK : checkout.create
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({ apiKey: 'sk_test_...' });
const session = await spiritpay.checkout.create({
lineItems: [
{ name: 'Fauteuil', quantity: 1, unitPriceHt: 100, vatRate: 20 }
],
customer: { name: 'Jean Dupont', email: 'client@exemple.com' },
orderRef: 'WEB-8842',
currency: 'EUR',
successUrl: 'https://boutique.exemple.com/commande/ok',
cancelUrl: 'https://boutique.exemple.com/commande/annule',
sendConfirmationEmail: false
});
// Redirection navigateur → Bridge (banque)
res.redirect(session.bridgeRedirectURL);API
POST https://api.spiritpay.fr/api/ecommerce/checkout-session
Authorization: Bearer sk_test_...
{
"lineItems": [
{ "name": "Fauteuil", "quantity": 1, "unitPriceHt": 100, "vatRate": 20 }
],
"customer": { "name": "Jean Dupont", "email": "client@exemple.com" },
"orderRef": "WEB-8842",
"currency": "EUR",
"successUrl": "https://boutique.exemple.com/commande/ok",
"cancelUrl": "https://boutique.exemple.com/commande/annule",
"sendConfirmationEmail": false
}Paramètres checkout.create / checkout-session
| Champ | Type | Requis | Description |
|---|---|---|---|
lineItems | array | Oui | Lignes panier : name, quantity, unitPriceHt, vatRate (montants en euros). |
customer | object | Oui | name + email du payeur (collectés sur votre site / portail). |
orderRef | string | Non | Référence commande ou devis côté métier (idempotence si réutilisée). |
currency | string | Non | Devise ISO (défaut EUR). |
successUrl | string | Non | HTTPS : retour sur votre portail après paiement validé. Sinon page Spirit Pay. |
cancelUrl | string | Non | HTTPS : retour sur votre portail si annulation / échec côté Bridge. Sinon page Spirit Pay. |
sendConfirmationEmail | boolean | Non | Si false : pas d’e-mail de confirmation au payeur (défaut true). Webhook inchangé. |
Réponse : bridgeRedirectURL, paymentId, montant. Confirmez la commande via webhook payment.executed (section ).
successUrl / cancelUrl renvoient le navigateur vers votre site quand Bridge déclenche un retour. Le webhook payment.executed reste la source fiable pour valider la commande côté serveur.
Si le client ferme l’onglet sans retour Bridge, cancelUrl n’est pas appelée — utilisez le webhook ou le polling statut.
POS (caisse)
Le flux caisse cible les grands comptes et intégrateurs retail : votre logiciel (ERP, WMS, app tablette) envoie le montant, Spirit Pay renvoie un QR dynamique (virement instantané Open Banking via Bridge vers l’IBAN marchand). Pas de parcours e-mail : le client scanne et valide sur sa banque. Idéal pour remplacer ou compléter le TPE carte en point de vente.
Installez @spiritpay/node sur votre serveur caisse ou middleware (pas dans une app cliente exposée). Méthodes : pos.create, pos.getStatus, pos.getEventSourceUrl (kiosque navigateur).
Création (API)
POST https://api.spiritpay.fr/api/pos/create-payment
Content-Type: application/json
Authorization: Bearer sk_test_...
{
"amount": 15000,
"currency": "EUR",
"terminalId": "caisse-1",
"label": "Ticket T-8842",
"erpProvider": "odoo",
"erpOrderId": "SO123",
"erpInvoiceId": "INV123"
}Réponse
HTTP 201 Created
{
"success": true,
"paymentId": "INV_...",
"paymentLink": "https://pay.bridgeapi.io/...",
"qrCode": "data:image/png;base64,...",
"expiresAt": "2026-05-26T12:05:00.000Z",
"isSimulation": false
}Exemple SDK
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({ apiKey: 'sk_live_...' });
const sale = await spiritpay.pos.create({
amount: 15000,
currency: 'EUR',
terminalId: 'lvmh-flagship-01',
label: 'Vente boutique'
});
// Tablette : <img src={sale.qrCode} alt="Payer" />
const url = spiritpay.pos.getEventSourceUrl(sale.paymentId); // kiosque sécurisé uniquementSuivi temps réel
GET https://api.spiritpay.fr/api/pos/payments/:paymentId/stream?token=sk_test_... Content-Type: text/event-stream // EventSource (navigateur kiosque) : la clé sk_* passe en query token= // Alternative serveur : Authorization: Bearer sk_* sur GET .../status Événements : ready | payment.status (status completed = payé)
Montant : pour l’EUR, envoyez le montant en centimes (ex. 15000 = 150,00 €). Le lien expire en quelques minutes (TTL configurable côté plateforme).
Prototype interactif : écran POS du dashboard développeur (après connexion et clé API).
Webhooks
Les webhooks signalent les transitions utiles pour votre ERP ou votre middleware : programmation, réussite, échec. Configurez une URL HTTPS dans le dashboard développeur (menu Webhooks), mode test et production séparés. Spirit Pay ajoute automatiquement /spirit_pay/webhook à l’URL de base si ce suffixe est absent.
Le secret whsec_… n’est affiché qu’une fois à la création. Copiez-le immédiatement. Vérifiez la signature sur le corps brut de la requête (pas après re-sérialisation JSON). Utilisez webhooks.verifySignature du SDK.
| Événement | Rôle |
|---|---|
payment.scheduled | Le client a programmé un paiement différé. |
payment.executed | Le paiement a été exécuté avec succès. |
payment.failed | Le paiement a échoué. |
La configuration détaillée, le bouton de test et les journaux d’envoi se trouvent dans la section Webhooks du dashboard après authentification. Payload : champ event (ex. payment.executed), plus payment_id, invoice_ref, amount.
Erreurs HTTP
| Code | Interprétation courante |
|---|---|
| 200 | Succès |
| 201 | Ressource créée |
| 400 | Requête invalide (champs manquants ou format incorrect) |
| 401 | Non authentifié (clé API absente ou invalide) |
| 403 | Accès refusé |
| 404 | Ressource introuvable |
| 429 | Limite de débit dépassée |
| 500 | Erreur serveur |
Les corps d’erreur incluent en général un code métier lisible par machine et un message court. Évitez d’afficher brutalement ces messages aux utilisateurs finaux sans les contextualiser.
SDK et bibliothèques
Le package @spiritpay/node (npm) est le point d’entrée pour les intégrations natives : équipes techniques de grands groupes, éditeurs de caisse, middleware ERP. Chaque marchand dispose d’un compte Spirit Pay et d’une clé sk_… stockée côté serveur.
| Méthode SDK | Usage |
|---|---|
checkout.create | Devis, app métier, e-commerce custom : redirection Bridge directe (bridgeRedirectURL) |
invoices.create | Facture B2B, lien, QR, e-mail payeur optionnel |
pos.create | Caisse / QR dynamique : montant ticket, affichage QR tablette |
pos.getStatus | Polling statut paiement caisse (completed = encaissé) |
pos.getEventSourceUrl | SSE navigateur kiosque (poste sécurisé) |
webhooks.verifySignature | Vérification signature événements serveur |
npm install @spiritpay/node
Factures (invoices.create)
// 1. Installer le SDK
npm install @spiritpay/node
// 2. Initialiser
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({ apiKey: 'sk_test_...' });
// 3. Créer un lien de paiement
const payment = await spiritpay.invoices.create({
amount: 10000,
currency: 'EUR',
invoiceRef: 'FAC-2024-001',
dueDate: '2026-03-30',
invoiceAmountHT: 8333,
invoiceAmountTVA: 1667,
vatBreakdown: [{ rate: 20, base: 8333, vat: 1667 }],
payerName: 'Client SAS',
payerEmail: 'client@exemple.com',
sendEmail: true,
});
console.log(payment.paymentLink);Devis & bouton paiement (checkout.create)
// Devis validé dans VOTRE app → bouton « Payer » → Bridge direct (sans panier e-commerce)
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({
apiKey: process.env.SPIRITPAY_API_KEY,
environment: 'test' // puis 'production' après validation du compte
});
// Route serveur déclenchée au clic « Payer » (devis déjà signé côté métier)
const session = await spiritpay.checkout.create({
lineItems: [
{ name: 'Devis DEV-2026-042', quantity: 1, unitPriceHt: 2500, vatRate: 20 }
],
customer: {
name: req.body.clientName, // connu dans votre outil (CRM, devis, ERP custom)
email: req.body.clientEmail
},
orderRef: 'DEV-2026-042',
currency: 'EUR',
successUrl: 'https://portail.exemple.com/devis/DEV-2026-042/paiement-ok',
cancelUrl: 'https://portail.exemple.com/devis/DEV-2026-042/paiement-annule',
sendConfirmationEmail: false
});
res.redirect(session.bridgeRedirectURL);Guide détaillé : section .
POS (caisse)
// Caisse / retail : QR dynamique (grand compte, tablette)
import { createClient } from '@spiritpay/node';
const spiritpay = createClient({
apiKey: process.env.SPIRITPAY_API_KEY,
environment: 'production'
});
const sale = await spiritpay.pos.create({
amount: 15000, // centimes EUR → 150,00 €
currency: 'EUR',
terminalId: 'caisse-paris-1',
label: 'Ticket T-8842'
});
// sale.qrCode → afficher sur l'écran caisse (data:image/png;base64,...)
// sale.paymentLink → même URL encodée dans le QR (Bridge)
const status = await spiritpay.pos.getStatus(sale.paymentId);
// status.status === 'completed' → encaissement confirméCe SDK ne remplace pas les connecteurs ERP du dashboard (INFast, Abby, module Odoo…) : ceux-ci se configurent dans Spirit Pay sans npm. Python et PHP : appels HTTPS directs ou contactez le support pour les préversions SDK.
FAQ développeur
Puis-je tester sans transaction réelle ?
Oui, l’environnement test simule les flux ; aucune instruction bancaire réelle n’est envoyée.
Où trouver mes clés ?
Dans votre espace connecté, menu réservé aux développeurs, entrée « Clés API ». Cette documentation publique n’affiche aucune clé.
Comment fonctionne la tarification côté API ?
La tarification marchande est indépendante du protocole d’appel : elle suit vos conditions contractuelles (offres Starter, Business ou Enterprise). Formules à l'inscription : Starter (0 € + 1 % plaf. 5 € sur les deux flux), Business Encaissement (199 € HT + 2 € / encaissement), Business Décaissement (199 € HT : forfait 100 virements / mois, au-delà du quota 1 € / virement), Business Complet (349 € HT : 2 € / encaissement, forfait 300 virements / mois, au-delà du quota 1 € / virement, Spirit Scan inclus). Référez-vous aux CGV et à la page Tarifs pour le détail.
Je veux seulement un bouton « Payer » après un devis : quelle API ?
Utilisez checkout.create (SDK) ou POST /ecommerce/checkout-session : votre serveur redirige vers bridgeRedirectURL. Voir la section .
Faut-il le Smart Dashboard payeur ?
Non pour un devis one-shot. Le Smart Dashboard est utile si vos clients doivent regrouper plusieurs factures à payer (optionnel, indépendant du npm).
Spirit Pay prélève-t-il ses commissions sur mes encaissements ?
Non. Spirit Pay ne prélève pas ses commissions sur les virements de vos clients. Chaque paiement client arrive intégralement sur votre compte bancaire : la plateforme initie le virement via Open Banking (Bridge) et ne détient pas les fonds : elle ne peut donc pas les retenir à la source.
Le 1er de chaque mois, vous recevez un récapitulatif(email et espace marchand) des commissions sur les transactions réussies du mois précédent, ainsi que de votre abonnement le cas échéant. C'est ensuite vous qui réglez Spirit Pay par virement bancaire, avec une échéance au 5 du mois suivant (prélèvement SEPA possible si activé).
Les modalités complètes figurent dans les Conditions Générales de Vente (section Tarification, facturation mensuelle) et les Mentions légales.
Stockage des données sensibles
Ne persistez pas les IBAN ou jetons bancaires hors des cadres réglementaires. Utilisez les identifiants techniques renvoyés par Spirit Pay pour corréler paiement et facture.