Documentation développeur

Intégrez Spirit Pay sans passer par le tableau de bord : API REST, SDK Node.js, webhooks et flux caisse (POS). Cette page est publique. Les clés secrètes se génèrent après inscription, depuis votre espace développeur.

Base API : https://api.spiritpay.fr/api

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.

Deux façons courantes de brancher votre ERP ou votre stack

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.

  1. Inscription et validation de l’espace marchand.
  2. Génération d’une clé sk_test_… réservée au serveur.
  3. Installation du paquet npm officiel (ci-dessous) ou appels HTTP directs.
  4. Déclaration d’une URL de webhook HTTPS accessible depuis Internet.
  5. 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.

Intégration IA avec le serveur MCP

Spirit Pay expose un serveur MCP public pour permettre aux assistants et agents compatibles MCP d'utiliser certaines fonctions Spirit Pay avec l'autorisation du marchand. L'intégration ne remplace pas l'API REST : elle fournit une interface adaptée aux agents qui savent découvrir et appeler des outils MCP.

URL du serveur MCP

https://mcp.spiritpay.fr/mcp

Authentification : OAuth 2.0. Aucun secret sk_test_… ousk_live_… ne doit être transmis à un agent IA.

Ce qu'un agent peut faire

  • identifier l'environnement connecté (Sandbox ou Production) ;
  • rechercher des clients et consulter les paiements ou impayés ;
  • préparer des demandes de paiement, leur envoi par e-mail et les relances ;
  • obtenir des synthèses, prévisions et analyses d'encaissement ;
  • préparer des paiements fournisseurs selon le parcours sécurisé Spirit Pay.

Les actions sensibles passent par une préparation puis une confirmation explicite. Le choix Sandbox/Production est associé au jeton OAuth et les données restent isolées par marchand et par environnement. Les actions disponibles dépendent des permissions accordées au compte Spirit Pay connecté.

Connexion depuis un autre client ou assistant compatible MCP

La publication dans le répertoire ChatGPT facilite la connexion depuis ChatGPT, mais ne rend pas Spirit Pay disponible automatiquement dans tous les clients. Un autre client peut l'utiliser s'il prend en charge les serveurs MCP distants et OAuth : son administrateur doit alors ajouter l'URL ci-dessus, autoriser les outils nécessaires et faire connecter chaque utilisateur.

Cela permet d'intégrer Spirit Pay dans un assistant interne d'entreprise, un agent de support, un CRM ou un orchestrateur de tâches, sans exposer de clé secrète dans le navigateur. Commencez toujours en Sandbox et appliquez le principe du moindre privilège.

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)

NomTypeRequisDescription
typestringOuiValeur attendue : invoice.
amountintegerOuiMontant en centimes (ex. 10000 pour 100,00 €).
currencystringOuiDevise ISO 4217 (EUR, XOF, etc.).
invoiceRefstringOuiRéférence facture côté métier.
dueDatestringNonÉchéance au format YYYY-MM-DD.
invoiceAmountHTintegerNonMontant HT en centimes (comptabilité).
invoiceAmountTVAintegerNonMontant TVA en centimes.
vatBreakdownarrayNonDétail multi-taux : [{ rate, base, vat }] en centimes.
payerNamestringNonNom affiché du payeur.
payerEmailstringNonAdresse pour notifications et parcours payeur.
sendEmailbooleanNonSi true, Spirit Pay peut envoyer l’e-mail au client (mode A).
erpProviderstringNonCode ERP source (ex. odoo, sage).
erpInvoiceIdstringNonIdentifiant facture dans votre ERP.
metadataobjectNonMé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.

Quelle méthode choisir ?
BesoinSDK recommandéExpérience payeur
Devis signé → clic → banque immédiatement
Recommandé pour un bouton paiement simple
checkout.createRedirection directe Bridge (bridgeRedirectURL)
Facture / devis avec référence, échéance, QR, e-mail optionnelinvoices.createLien paymentLink (récap Spirit Pay) puis Bridge, ou envoi e-mail Spirit Pay si sendEmail: true
Portail payeur multi-factures (optionnel)Smart Dashboard payeurLe client consulte plusieurs factures d’un même créancier. pas requis pour un simple bouton devis

Flux recommandé : devis → Bridge direct

  1. Le devis est validé dans votre application (signature manuelle, statut métier, etc.).
  2. Votre backend appelle checkout.create avec le montant, la référence devis (orderRef) et le client (nom + e-mail).
  3. Vous redirigez le navigateur vers bridgeRedirectURL.
  4. Le client choisit sa banque et valide le virement.
  5. 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_… puis sk_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 vs webhook, ne pas confondre

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.

Architecture modulaire

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

  1. Votre commercial crée l’opportunité dans le CRM (acompte boutique saisi manuellement).
  2. Votre backend appelle Spirit Pay (clé API sk_*).
  3. Le client reçoit un e-mail (Spirit Pay ou le vôtre) ou ouvre le Smart Dashboard.
  4. 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"
}
ChampTypeRequisDescription
crmOrderRefstringOuiRéférence commande / opportunité dans votre CRM (unique côté métier).
amountnumberOuiSolde restant TTC en euros.
payerEmailstringOuiE-mail du client (Smart Dashboard + relances).
payerNamestringNonNom affiché sur le portail bancaire.
sendEmailbooleanNonDéfaut true : Spirit Pay envoie l’e-mail « demande de règlement ». Si false, utilisez paymentLink dans votre CRM.
depositPaidnumberNonAcompte déjà encaissé hors Spirit Pay (tracé, informatif).
dueDatestringNonÉchéance ISO (YYYY-MM-DD) pour relances.
successUrlstringNonHTTPS : retour navigateur après paiement validé (?paymentId=&status=&orderRef=&sig=).
cancelUrlstringNonHTTPS : retour si abandon / échec Bridge.
commercialNamestringNonNom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM.
commercialIdstringNonID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité.
commercialEmailstringNonE-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"
}
ChampTypeRequisDescription
crmOrderRefstringOuiRéférence commande CRM.
amountnumberOuiSolde total à étaler en mensualités.
installmentsnumberOuiNombre d’échéances (1 à 60).
firstDueDatestringNonDate 1re mensualité (défaut : aujourd’hui).
payerEmailstringOuiE-mail client : une session Smart Dashboard pour tout l’échéancier.
payerNamestringNonNom payeur.
sendWelcomeEmailbooleanNonDéfaut true : e-mail d’accueil avec lien échéancier (?channel=crm).
depositPaidnumberNonAcompte boutique déjà réglé.
commercialNamestringNonNom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM.
commercialIdstringNonID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité.
commercialEmailstringNonE-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_index

Paiement 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"
}
ChampTypeRequisDescription
crmOrderRefstringOuiRéférence opportunité CRM (ex. CM8).
totalAmountnumberOuiMontant total à encaisser (le client choisit chaque virement sur le dashboard).
payerEmailstringOuiE-mail client : lien magique vers le Smart Dashboard (?channel=crm).
payerNamestringNonNom affiché (pré-rempli sur le dashboard payeur).
sendEmailbooleanNonDéfaut true : e-mail Spirit Pay avec lien dashboard.
depositPaidnumberNonAcompte déjà encaissé hors Spirit Pay.
commercialNamestringNonNom du commercial — identifiant principal pour filtrage et sous-compte. Optionnel sur tous les modes CRM.
commercialIdstringNonID CRM optionnel (ex. res.users Odoo). Envoyé automatiquement si un vendeur est assigné sur l’opportunité.
commercialEmailstringNonE-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 / cancelUrl optionnels : vous choisissez le retour vers votre portail CRM ou le fallback Spirit Pay.
  • Échéancier (payment-plan) : pas de successUrl par 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 successUrl sur payment-plan : paramètre non exposé volontairement.
  • Distribuez payerDashboardUrl au 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).

ERP, agios & regroupement des demandes de règlement

Si votre client installe lui-même Spirit Pay en complément de son ERP, il peut piloter deux briques depuis le portail développeur sans écrire de code côté partenaire : les agios et la fréquence d’envoi des e-mails facture.

Point important

Ces réglages ne passent pas par les clés API sk_*. Ils se pilotent avec un JWT de session du portail développeur sur /api/developers/*.

En pratique : votre middleware ERP peut rester léger. Le marchand active ces options lui-même, puis votre outil se contente de créer les factures, liens ou échéanciers Spirit Pay comme d’habitude.

Cas d’usage

  • Agios : afficher une politique de retard cohérente côté payeur, e-mails et Smart Dashboard.
  • Regroupement hebdomadaire ou mensuel : éviter d’envoyer une demande de règlement par facture lorsque le même client reçoit plusieurs échéances.
  • Smart Dashboard : garder la liberté de brancher vos propres alertes, tableaux de bord ou relances métier autour de Spirit Pay.

API portail développeur — agios

Le marchand définit sa politique d’agios une seule fois. Spirit Pay la réutilise ensuite dans le dashboard payeur, les e-mails et les écrans de confirmation.

GET https://api.spiritpay.fr/api/developers/agios-settings
Authorization: Bearer <jwt_portail_developpeur>
PUT https://api.spiritpay.fr/api/developers/agios-settings
Content-Type: application/json
Authorization: Bearer <jwt_portail_developpeur>

{
  "agiosEnabled": true,
  "agiosGraceDays": 2,
  "agiosAnnualRatePct": 10,
  "agiosFixedRecoveryEur": 40
}
ChampTypeRequisDescription
agiosEnabledbooleanNonActive les agios pour ce marchand.
agiosGraceDaysnumberNonDélai de grâce en jours calendaires (0 à 90).
agiosAnnualRatePctnumberNonTaux annuel appliqué aux retards. Minimum suggéré : valeur légale en vigueur.
agiosFixedRecoveryEurnumberNonForfait de recouvrement en euros. Minimum suggéré : valeur légale en vigueur.

Réponse type : agiosEnabled, agiosGraceDays, agiosAnnualRatePct, agiosFixedRecoveryEur et agiosLegalDefaults.

API portail développeur — regroupement d’e-mails ERP

Quand la fréquence n’est plus instant, Spirit Pay met les factures en file, puis envoie un digest regroupé par payeur. Cela évite de spammer un client qui reçoit plusieurs factures sur une même période.

GET https://api.spiritpay.fr/api/developers/erp-email-batch-settings
Authorization: Bearer <jwt_portail_developpeur>
PUT https://api.spiritpay.fr/api/developers/erp-email-batch-settings
Content-Type: application/json
Authorization: Bearer <jwt_portail_developpeur>

{
  "emailBatchFrequency": "weekly",
  "intervalDays": 4,
  "weekday": 5,
  "dayOfMonth": 1,
  "timezone": "Europe/Paris"
}
ChampTypeRequisDescription
emailBatchFrequencystringNonFréquence : instant, every_x_days, weekly ou monthly.
intervalDaysnumberNonNombre de jours entre deux regroupements si frequency = every_x_days (1 à 30).
weekdaynumberNonJour ISO 1=lundi … 7=dimanche si frequency = weekly.
dayOfMonthnumber|stringNonJour du mois 1..28, ou last_business_day si frequency = monthly.
timezonestringNonTimezone IANA du marchand. Par défaut : Europe/Paris.

Cron d’envoi : les lots dus sont expédiés chaque jour à 06:00 Europe/Paris.

Retour à l’instantané : si le marchand repasse de weekly, monthly ou every_x_days vers instant, Spirit Pay déclenche immédiatement l’envoi des factures encore en file.

Prérequis : l’automatisation e-mail de l’intégration ERP concernée doit déjà être activée.

Ce qu’un intégrateur doit retenir

  1. Votre outil continue à appeler les endpoints Spirit Pay classiques avec sk_* pour créer les paiements, liens ou échéanciers.
  2. Le marchand conserve la main sur les règles métier sensibles, comme les agios ou la cadence des e-mails, via son portail Spirit Pay.
  3. Vous pouvez brancher vos propres dashboards, alertes ou relances autour de ces briques sans perdre le parcours payeur natif Spirit Pay.

Paiements fournisseurs : régler vos factures en un clic

Si votre ERP ou votre logiciel interne permet de sélectionner des factures fournisseurs, Spirit Pay les règle par virement Open Banking : le payeur valide dans son application bancaire, puis votre outil reçoit l’état de chaque facture et enregistre le paiement.

Trois situations

Vous sélectionnezCe qui se passeBanque
Plusieurs factures d’un seul fournisseurUn seul virement du total, dont le libellé reprend les numéros de facture. Une seule validation.Toutes les banques
Factures de plusieurs fournisseursPaiement groupé (« bulk ») : une seule validation bancaire pour tous, un virement par fournisseur.Banques compatibles uniquement (liste ci-dessous)
Plusieurs fournisseurs, banque non compatibleUn fournisseur à la fois : chaque virement est validé séparément.Les autres banques
Ne pas confondre

Regrouper les factures d’un même fournisseur en un virement fonctionne avec n’importe quelle banque. Seul le paiement de plusieurs fournisseurs d’un coup dépend de la banque du payeur.

Vérifier la compatibilité d’une banque avant d’intégrer

Cette liste est publique : aucune clé API n’est nécessaire pour la consulter. Elle est mise à jour quotidiennement et reste indicative ; le tableau de bord Spirit Pay indique aussi, pour la banque du compte payeur, si le paiement groupé est disponible.

GET https://api.spiritpay.fr/api/v1/partners/bulk-banks
# aucune clé API requise
{
  "success": true,
  "country": "FR",
  "count": 42,
  "banks": [{ "name": "…" }, { "name": "…" }],
  "note": "Liste indicative, mise à jour quotidiennement. …"
}

Intégration par l’API partenaire

Avec votre clé partenaire, votre outil envoie les factures sélectionnées en une seule requête : elles sont validées ensemble (tout ou rien), puis le payeur est redirigé vers sa banque. Une clé de test sp_test_partner_… reste en sandbox : aucun euro ne bouge.

POST https://api.spiritpay.fr/api/v1/partners/purchase-invoices/pay
Authorization: Bearer sp_test_partner_…   # clé partenaire (sp_live_partner_… en production)
Content-Type: application/json

{
  "returnUrl": "https://erp.example.com/spiritpay/return",
  "invoices": [
    {
      "externalInvoiceId": "FF-2026-0412",
      "supplierName": "Imprimerie Dupont",
      "supplierIban": "FR76…",
      "supplierBic": "BNPAFRPP",
      "amountTTC": 1200.00,
      "currency": "EUR",
      "invoiceRef": "FA-9981"
    }
  ]
}
{
  "success": true,
  "bridgeRedirectURL": "https://…",   // redirigez le navigateur du payeur ici
  "batchRef": "PAY_…",
  "totalEUR": 1200,
  "invoiceCount": 1
}

# Au retour sur returnUrl (?ref=<batchRef>), vérifiez le résultat côté serveur :
GET https://api.spiritpay.fr/api/v1/partners/purchase-invoices/batches/<batchRef>
→ { "outcome": "paid", "invoices": [{ "externalInvoiceId": "FF-2026-0412", "status": "paid", … }] }
Banque non compatible avec le paiement groupé

Via l’API, Spirit Pay ne bascule pas automatiquement vers un paiement fournisseur par fournisseur. Si le compte payeur est dans une banque absente de la liste, votre outil doit envoyer une requête par fournisseur (les factures d’un même fournisseur restent regroupées en un virement).

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

ChampTypeRequisDescription
lineItemsarrayOuiLignes panier : name, quantity, unitPriceHt, vatRate (montants en euros).
customerobjectOuiname + email du payeur (collectés sur votre site / portail).
orderRefstringNonRéférence commande ou devis côté métier (idempotence si réutilisée).
currencystringNonDevise ISO (défaut EUR).
successUrlstringNonHTTPS : retour sur votre portail après paiement validé. Sinon page Spirit Pay.
cancelUrlstringNonHTTPS : retour sur votre portail si annulation / échec côté Bridge. Sinon page Spirit Pay.
sendConfirmationEmailbooleanNonSi 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 ).

Redirection portail vs webhook

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.

SDK recommandé pour la caisse

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é uniquement

Suivi 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énementRôle
payment.scheduledLe client a programmé un paiement différé.
payment.executedLe paiement a été exécuté avec succès.
payment.failedLe 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

CodeInterprétation courante
200Succès
201Ressource créée
400Requête invalide (champs manquants ou format incorrect)
401Non authentifié (clé API absente ou invalide)
403Accès refusé
404Ressource introuvable
429Limite de débit dépassée
500Erreur 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 SDKUsage
checkout.createDevis, app métier, e-commerce custom : redirection Bridge directe (bridgeRedirectURL)
invoices.createFacture B2B, lien, QR, e-mail payeur optionnel
pos.createCaisse / QR dynamique : montant ticket, affichage QR tablette
pos.getStatusPolling statut paiement caisse (completed = encaissé)
pos.getEventSourceUrlSSE navigateur kiosque (poste sécurisé)
webhooks.verifySignatureVérification signature événements serveur
createPartnerClientAPI partenaire (ERP, coopératives) : invoices.create, purchases.pay, purchases.getBatch, bulkBanks — clé sp_…_partner_…
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);

API partenaire (createPartnerClient)

Pour les éditeurs d’ERP et les coopératives : un client distinct, authentifié par clé partenaire (pas sk_…), à utiliser côté serveur. Une clé de test reste en sandbox. Disponible à partir de la version 0.4.0. Détail du paiement fournisseur : .

import { createPartnerClient } from '@spiritpay/node';

const spiritpay = createPartnerClient({ partnerKey: process.env.SPIRITPAY_PARTNER_KEY }); // sp_test_partner_… / sp_live_partner_…

// Encaisser une facture (l'enseigne apparaît comme sous-marchand)
const link = await spiritpay.invoices.create({
  externalInvoiceId: '497582', payerEmail: 'client@exemple.com', amount: 840,
  invoiceRef: 'FC763-2610', issuerExternalId: '12', issuerName: 'Auprès Fauteuil Remplacer.'
});

// Payer des factures fournisseur, puis vérifier le lot au retour de la banque
const pay = await spiritpay.purchases.pay({ returnUrl: 'https://erp.exemple.com/retour', invoices: [/* … */] });
const batch = await spiritpay.purchases.getBatch(pay.batchRef); // enregistrer seulement status === 'paid'

// Banques compatibles avec le paiement groupé (liste publique)
const { banks } = await spiritpay.bulkBanks();

SDK Python (spiritpay)

Même couverture que le SDK Node, pour les serveurs Python (enDI, Odoo, Dolibarr, Django, Flask…) : Client pour une entreprise (clé sk_… : checkout, factures, caisse, CRM) et PartnerClient pour les ERP et coopératives (clé partenaire). Aucune dépendance, Python 3.8 ou plus. Paquet : pypi.org/project/spiritpay.

pip install spiritpay

import os
from spiritpay import Client, PartnerClient

# Entreprise avec son serveur : clé sk_…
spiritpay = Client(api_key=os.environ["SPIRITPAY_API_KEY"], environment="test")
session = spiritpay.checkout.create(
    line_items=[{"name": "Devis DEV-2026-042", "quantity": 1, "unit_price_ht": 2500, "vat_rate": 20}],
    customer={"name": "Client SAS", "email": "client@exemple.com"},
    order_ref="DEV-2026-042",
)
# rediriger le client vers session["bridgeRedirectURL"]

# Éditeur d'ERP / coopérative : clé partenaire sp_…_partner_…
partner = PartnerClient(partner_key=os.environ["SPIRITPAY_PARTNER_KEY"])
batch = partner.purchases.get_batch("PAY_…")  # enregistrer seulement status == "paid"

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.

Marque blanche (multi-tenant)

Cette section s'adresse aux éditeurs de logiciels, ERP, CRM, plateformes, groupes et coopératives qui souhaitent intégrer nativement le paiement par virement dans leur propre produit. Le partenaire conserve son interface, ses e-mails, ses références métier et la relation avec ses utilisateurs ; Spirit Pay fournit la création du paiement, le parcours bancaire Bridge et les notifications serveur.

Toute création de paiement se fait depuis le backend du partenaire. La clé partenaire ne doit jamais être placée dans une page web, une application mobile distribuée ou un modèle d'e-mail.

Responsabilités de chaque système
Votre logicielSpirit Pay
Crée et valide la factureCrée un paiement rattaché à votre identifiant de facture
Place le bouton dans l'e-mail ou le portailRetourne une URL signée prête à utiliser
Conserve les clés uniquement côté serveurOuvre Bridge et applique la configuration du bénéficiaire
Traite le webhook de manière idempotenteNotifie la réussite ou l'échec du paiement
Enregistre l'encaissement et solde la factureExpose le statut pour vérification et reprise

Choisir le bon parcours payeur

Le choix ne dépend pas de la taille du partenaire mais de l'usage du payeur. Une facture unique appelle généralement un parcours direct ; un ensemble de factures ou un échéancier appelle un espace payeur.

D'où viennent ces URL ?

Vous ne créez aucune URL vous-même. Votre backend appelle POST /api/v1/partners/invoices avec la facture. La réponse JSON contient notamment paymentUrl et paymentUrlDirect.

const response = await createSpiritPayInvoice(invoice);
const paymentLink = response.paymentUrlDirect;

// Placez paymentLink dans le href du bouton de votre e-mail ou portail.

Pour une facture classique émise depuis un ERP, récupérez donc response.paymentUrlDirectet placez cette valeur dans le bouton « Payer par virement ». Le détail de l'appel et de sa réponse figure à l'étape 4 ci-dessous.

BesoinChamp renvoyé par Spirit PayExpérience client
Facture unique, bouton natif ERPpaymentUrlDirectEntrée Spirit Pay signée puis ouverture immédiate de Bridge et de la liste des banques.
Facture avec récapitulatifpaymentUrlPage de paiement à la marque du partenaire, puis Bridge.
Plusieurs factures ou échéancierpayerDashboardUrl via l'API CRM/échéancierSmart Dashboard : sélection, historique et paiement de plusieurs éléments.
Caisse ou QR dynamiqueAPI POSScan du QR puis paiement Bridge, sans e-mail.
À retenir

Pour un bouton « Payer par virement » dans l'e-mail d'une facture émise par votre ERP : appelez l'API depuis votre serveur, lisez paymentUrlDirect dans la réponse, puis utilisez cette URL comme destination du bouton. Le Smart Dashboard est optionnel et réservé aux parcours multi-factures, aux échéanciers ou à un véritable espace payeur.

Architecture recommandée

  1. Votre serveur détecte une facture validée et non soldée.
  2. Il appelle POST /api/v1/partners/invoices avec un identifiant externe stable.
  3. Spirit Pay renvoie le même paiement si cet identifiant a déjà été traité : un nouvel e-mail ne crée pas de doublon.
  4. Votre logiciel insère l'URL retournée dans son bouton HTML, son PDF, son SMS ou son portail.
  5. Le client choisit sa banque et confirme le virement dans Bridge.
  6. Spirit Pay envoie invoice.paid à votre webhook signé.
  7. Votre serveur enregistre l'encaissement une seule fois, puis solde la facture dans votre système.

1. Obtenir les accès et séparer les environnements

Utilisez sp_test_partner_… pour le bac à sable etsp_live_partner_… après activation de la production. Les clés, secrets webhook, URL de webhook et journaux sont séparés entre test et production.

X-Partner-Key: sp_test_partner_VOTRE_CLE
Content-Type: application/json
  • Stockez la clé dans un gestionnaire de secrets ou une variable d'environnement serveur.
  • Ne journalisez jamais la clé complète ni le secret webhook.
  • Prévoyez une rotation sans interruption : mise à jour du secret, déploiement, puis révocation de l'ancien accès.

2. Choisir le modèle de reversement

ModèleBénéficiaire BridgeCas typique
Compte centraliséCompte de reversement configuré pour le partenaireCAE, coopérative, groupe ou réseau encaissant pour ses adhérents.
Compte par marchandIBAN propre au marchand finalERP SaaS dont chaque entreprise cliente encaisse sur son propre compte.

Dans la version partenaire v1 actuellement exposée, POST /api/v1/partners/invoices utilise le compte de reversement central configuré pour le partenaire. C'est le modèle adapté aux coopératives comme une CAE. L'identifiant d'un adhérent sert au rapprochement métier ; il ne change pas automatiquement le bénéficiaire bancaire. Un reversement individuel par marchand doit être activé et validé comme modèle d'intégration distinct avant la production.

Cas d'usage : ERP de coopérative / CAE

L'ERP conserve une seule clé partenaire sur son backend. Lorsqu'un membre ou un adhérent envoie une facture, l'ERP transmet l'identifiant technique de cette facture et récupère paymentUrlDirect. Le bénéficiaire Bridge reste la coopérative configurée ; la facture et l'adhérent sont retrouvés grâce aux identifiants métier. Il n'est pas nécessaire de remettre une clé API à chaque adhérent. Après invoice.paid, l'ERP crée l'encaissement et solde la facture concernée. Ce modèle convient à toute solution de gestion de CAE ou de coopérative, indépendamment de l'éditeur.

3. Activer ou synchroniser les utilisateurs finaux

Le parcours hébergé est recommandé lorsqu'un utilisateur final doit fournir son identité et ses coordonnées bancaires. Votre serveur crée une URL d'activation temporaire, puis redirige l'utilisateur vers Spirit Pay.

POST /api/v1/partners/onboarding
X-Partner-Key: sp_test_partner_VOTRE_CLE
Content-Type: application/json

{
  "externalMerchantId": "erp_member_48291",
  "siret": "12345678900012",
  "raisonSociale": "Atelier Démonstration",
  "prenom": "Marie",
  "nom": "Martin",
  "email": "marie@exemple.fr",
  "telephone": "+33612345678",
  "returnUrl": "https://erp.exemple.fr/integrations/spirit-pay"
}

Conservez externalMerchantId : c'est votre identifiant stable, jamais une adresse e-mail. L'URL d'activation expire après 24 heures. Un nouvel appel avec le même identifiant reprend le dossier existant. Le retour navigateur améliore l'expérience utilisateur ; le webhook merchant.activatedreste la source de vérité.

Dans un modèle de reversement centralisé, ce parcours n'est requis que si chaque utilisateur doit disposer de son propre espace Spirit Pay ou faire l'objet d'une activation individuelle. Pour une intégration entièrement pilotée par l'ERP avec un bénéficiaire unique, la clé partenaire centrale peut suffire.

4. Créer le paiement d'une facture

POST /api/v1/partners/invoices
X-Partner-Key: sp_test_partner_VOTRE_CLE
Content-Type: application/json

{
  "externalInvoiceId": "erp:invoice:98452",
  "invoiceRef": "FAC-2026-0456",
  "payerName": "Marie Martin",
  "payerEmail": "client@entreprise.fr",
  "amount": 1250.00,
  "currency": "EUR",
  "dueDate": "2026-10-15"
}
Unité du montant

Sur cette API partenaire, amount est exprimé en euros décimaux :1250.00 signifie 1 250,00 €. Ne réutilisez pas sans conversion un montant en centimes provenant de l'API marchande ou du SDK standard.

ChampObligatoireRôle
externalInvoiceIdFortement recommandéIdentifiant technique stable et unique dans votre base ; utilisé pour l'idempotence et le webhook.
invoiceRefRecommandéNuméro lisible par le client et la comptabilité.
payerEmailOuiAdresse du payeur, normalisée en minuscules.
payerNameNonNom affiché dans le parcours et les outils de suivi.
amountOuiMontant TTC positif en euros décimaux.
currencyNonDevise, EUR par défaut.
dueDateNonDate ISO de l'échéance.
immediateOnlyNonSi vrai, paymentUrl ouvre lui aussi le parcours Bridge direct. paymentUrlDirect reste toujours fourni.
HTTP 201 Created
{
  "success": true,
  "paymentId": "INV_a1b2c3d4",
  "paymentUrl": "https://spiritpay.fr/pay/invoice/INV_a1b2c3d4?partner=erp&sig=...",
  "paymentUrlDirect": "https://spiritpay.fr/pay/invoice/INV_a1b2c3d4?partner=erp&sig=...&immediateOnly=1"
}

Ne reconstruisez, ne raccourcissez et ne modifiez jamais ces URL. Elles sont signées. Stockez au minimumpaymentId, externalInvoiceId et l'URL distribuée. Une répétition avec le même externalInvoiceId renvoie le paiement encore actif avecidempotent: true.

Exemple backend Node.js minimal

const response = await fetch('https://api.spiritpay.fr/api/v1/partners/invoices', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Partner-Key': process.env.SPIRITPAY_PARTNER_KEY
  },
  body: JSON.stringify({
    externalInvoiceId: invoice.id,
    invoiceRef: invoice.number,
    payerName: invoice.customer.name,
    payerEmail: invoice.customer.email,
    amount: invoice.totalTtc,
    currency: 'EUR',
    dueDate: invoice.dueDate
  })
});

if (!response.ok) {
  throw new Error('Création du paiement Spirit Pay impossible');
}

const { paymentId, paymentUrlDirect } = await response.json();
await savePaymentMapping(invoice.id, paymentId, paymentUrlDirect);

5. Ajouter un bouton natif dans un e-mail ou un portail

Spirit Pay ne demande pas d'iframe. Dans un e-mail HTML, le bouton est un lien classique donthref contient exactement l'URL retournée par l'API. Pour une facture simple, utilisez paymentUrlDirect.

<a href="{{ paymentUrlDirect }}"
   style="display:inline-block;padding:12px 20px;border-radius:8px;
          background:#4f46e5;color:#ffffff;text-decoration:none;
          font-family:Arial,sans-serif;font-weight:700;">
  Payer par virement
</a>
  • Échappez l'URL selon le moteur de template, sans transformer durablement ses paramètres.
  • Dans du HTML, &amp; peut apparaître dans la source ; le navigateur doit néanmoins ouvrir l'URL complète.
  • N'utilisez jamais une URL Bridge brute enregistrée après redirection : elle peut expirer. Distribuez l'URL signée Spirit Pay.
  • Le client final n'a pas besoin de créer un compte Spirit Pay pour payer une facture unique.

6. Smart Dashboard pour plusieurs factures

Le Smart Dashboard est un produit distinct du bouton direct. Il convient lorsqu'un même payeur doit voir plusieurs factures, sélectionner celles qu'il règle, suivre un échéancier ou retrouver son historique. L'URLpayerDashboardUrl est un lien magique signé lié au payeur ; elle ne doit pas être déduite à partir de son adresse e-mail.

La route partenaire v1 de création de facture renvoie aujourd'hui paymentUrl etpaymentUrlDirect. Pour activer un Smart Dashboard multi-factures dans une intégration marque blanche, utilisez les endpoints CRM/échéancier documentés ou faites activer ce parcours dans votre contrat partenaire.

7. Recevoir et vérifier les webhooks

Après confirmation bancaire, Spirit Pay appelle l'URL correspondant à l'environnement du paiement. Répondez rapidement en HTTP 2xx, puis effectuez le traitement métier en arrière-plan.

X-SpiritPay-Event: invoice.paid
X-SpiritPay-Timestamp: 1789982400
X-SpiritPay-Signature: sha256=<signature>

{
  "id": "evt_9fcb...",
  "event": "invoice.paid",
  "timestamp": 1789982400,
  "data": {
    "paymentId": "INV_a1b2c3d4",
    "partnerExternalInvoiceId": "erp:invoice:98452",
    "amount": 1250.00,
    "currency": "EUR",
    "payerEmail": "client@entreprise.fr",
    "paidAt": "2026-09-28T10:05:32.000Z",
    "transactionReference": "request_bridge_..."
  }
}

Vérifiez la signature sur le corps HTTP brut, avant de parser le JSON. Pour les secretswhsec_…, Spirit Pay utilise le SHA-256 du secret comme clé HMAC, puis calcule le HMAC-SHA256 du corps brut.

import crypto from 'node:crypto';

function verifySpiritPayWebhook(rawBody, signatureHeader, webhookSecret) {
  const key = /^[a-f0-9]{64}$/i.test(webhookSecret)
    ? webhookSecret.toLowerCase()
    : crypto.createHash('sha256').update(webhookSecret).digest('hex');

  const expected = 'sha256=' + crypto
    .createHmac('sha256', key)
    .update(rawBody)
    .digest('hex');

  const received = Buffer.from(signatureHeader || '');
  const reference = Buffer.from(expected);
  return received.length === reference.length
    && crypto.timingSafeEqual(received, reference);
}
  • Refusez une signature absente ou invalide.
  • Refusez un horodatage trop ancien afin de limiter les rejeux.
  • Utilisez id comme clé d'idempotence de l'événement.
  • Utilisez partnerExternalInvoiceId pour retrouver la facture ; ne rapprochez pas uniquement par montant.
  • Ne soldez jamais une facture sur la seule redirection du navigateur : seul le webhook confirmé ou une lecture serveur du statut fait foi.

8. Vérifier le statut et reprendre après incident

GET /api/v1/partners/invoices/INV_a1b2c3d4
X-Partner-Key: sp_test_partner_VOTRE_CLE

{
  "success": true,
  "payment": {
    "paymentId": "INV_a1b2c3d4",
    "status": "pending | processing | completed | abandoned | failed",
    "invoiceAmount": 1250.00,
    "invoiceCurrency": "EUR",
    "partnerExternalInvoiceId": "erp:invoice:98452"
  }
}

Cette lecture sert au support, au rattrapage d'un webhook ou à une réconciliation planifiée. Elle ne doit pas provoquer la création répétée de nouveaux paiements.

9. Erreurs, retries et règles d'idempotence

RéponseAction recommandée
400Corriger le payload ; ne pas retenter à l'identique automatiquement.
401Vérifier l'environnement et la clé partenaire.
409Configuration bénéficiaire ou compte incompatible ; intervention requise.
429Retenter avec délai exponentiel et jitter.
5xxRetenter avec le même externalInvoiceId.

Côté webhook, Spirit Pay retente les erreurs réseau et les réponses 5xx. Une réponse 4xx est considérée comme un rejet fonctionnel et n'est pas retentée automatiquement. Les journaux sont disponibles dans l'onglet Partenariat.

10. Configuration visuelle et obligations

Le nom affiché, le logo, les couleurs, le domaine autorisé et les paramètres d'e-mail sont configurables. La mention réglementaire de Bridge reste affichée lorsqu'elle est requise. Une marque blanche ne signifie pas que le partenaire peut masquer les informations légales du prestataire de paiement.

Checklist avant mise en production

  • Clé live stockée uniquement côté serveur et distincte de la clé test.
  • Compte de reversement et nom du bénéficiaire validés.
  • Identifiants externes stables et uniques.
  • Bouton testé dans les principaux clients e-mail et sur mobile.
  • Webhook live signé, idempotent et observable.
  • Scénarios testés : réussite, abandon, échec, double clic, nouvel envoi d'e-mail et indisponibilité temporaire.
  • Réconciliation de secours par lecture du statut.
  • Procédure documentée pour la rotation des clés et secrets.

Obtenir un accès partenaire

Depuis l'onglet Partenariat, générez la clé de test, configurez le webhook test et consultez les journaux. Le passage en production nécessite le dossier entreprise, la vérification d'identité du dirigeant, la validation du modèle de reversement et la configuration du bénéficiaire.

Pour une architecture de coopérative, un domaine dédié, un Smart Dashboard multi-factures ou un reversement individuel par marchand, contactez contact@spiritpay.fr avant la mise en production.

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) ou Business (199 € HT / mois + 2 € / encaissement réussi, 100 virements fournisseurs Open Banking réussis inclus / mois, puis 2 € / virement fournisseur réussi). 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.