Déployer la facturation et les paiements en ligne
Cette version fait de la facture client le document unique pour l’argent qu’un client doit, permet aux clients de payer depuis une page hébergée, et durcit la manière dont les paiements en ligne sont confirmés. Suivez les étapes dans l’ordre.
1. Lancer les migrations
Section intitulée « 1. Lancer les migrations »| Base de données | Migration | Ce qu’elle ajoute |
|---|---|---|
| Globale | 0036_payment_intents |
Un index, à l’échelle de la plateforme, de chaque tentative de paiement en ligne, pour qu’une notification de passerelle soit rattachée au bon locataire ; des tentatives de paiement suivies pour les factures d’abonnement des locataires eux-mêmes. |
| Locataire | 0117_customer_invoice_lines |
Les lignes et totaux de facture, et le lien entre une vente à crédit et sa facture. |
| Locataire | 0118_payments_hardening |
Le statut de paiement En cours d’examen et les garde-fous qui empêchent qu’un paiement soit crédité deux fois. |
Lancez la migration globale, puis celle des locataires, sur la base partagée et sur chaque base de locataire dédiée :
make migrate-global-upmake migrate-tenant-upLes changements de règlements et de frais sont livrés dans leurs propres migrations et sont traités avec règlements et frais.
2. Régler l’environnement
Section intitulée « 2. Régler l’environnement »| Variable | À régler sur | Pourquoi |
|---|---|---|
PAY_BASE_URL |
API, planificateur | Origine publique de l’application de paiement. Les liens de facture et les boutons de paiement sont construits dessus. Voir déployer SaleSprint Pay. |
PUBLIC_API_BASE_URL |
API | L’origine publique de cette API telle qu’une passerelle de paiement peut l’atteindre, sans /api/v1. Elle construit l’URL de webhook affichée sur chaque configuration de passerelle. Laissée vide, ce champ est vide. |
PAYMENTS_SECRET_KEY |
API, planificateur | Clé de 32 octets en base64 qui chiffre les identifiants de passerelle stockés. Se rabat sur la clé de connexion externe quand elle n’est pas définie — définissez-en une dédiée en production. |
DOCUMENT_LINK_SECRET |
API, planificateur | Clé dont dérivent les liens clients. La faire tourner invalide tous les liens déjà envoyés. |
3. Déployer l’application de paiement
Section intitulée « 3. Déployer l’application de paiement »Voir déployer SaleSprint Pay.
4. Enregistrer les webhooks des passerelles
Section intitulée « 4. Enregistrer les webhooks des passerelles »Chaque configuration de passerelle affiche une URL de webhook en lecture seule :
{PUBLIC_API_BASE_URL}/api/v1/webhooks/payments/{gateway}où {gateway} vaut paystack, payswitch ou hubtel.
- Une URL par passerelle sert tous les locataires. Collez-la une fois dans le tableau
de bord de ce prestataire. Les notifications sont rattachées au locataire et au paiement
par la référence du paiement lui-même, aucun identifiant de locataire n’est donc
nécessaire. L’ancienne forme
?tenant=fonctionne encore. - La même URL transporte les notifications des paiements d’abonnement des locataires.
- Une notification n’est qu’un coup de coude. SaleSprint ne règle jamais d’après le corps de la notification ; il interroge la passerelle sur ce paiement et règle d’après la réponse de la passerelle.
5. S’assurer que le planificateur tourne
Section intitulée « 5. S’assurer que le planificateur tourne »Le planificateur (cmd/scheduler) est ce qui rend les paiements fiables quand une
notification est en retard ou perdue. Il :
- revérifie chaque tentative de paiement ouverte auprès de sa passerelle — encaissements marchands comme paiements d’abonnement ;
- rejoue les notifications arrivées alors qu’un paiement était encore en attente ;
- fait expirer les demandes que personne n’a payées, après avoir confirmé auprès de la passerelle que rien n’a été payé.
Sans lui, un paiement dont la notification n’arrive jamais reste en attente jusqu’à ce que le client revienne sur la page de paiement.
Deux paramètres à portée y contribuent, tous deux sous Payments :
payments.payment_intent_expiry_minutes (combien de temps une demande de paiement reste
valide) et payments.merchant_collection_hold_hours (combien de temps l’argent encaissé
attend avant de devenir disponible).
6. Convertir les ventes à crédit existantes
Section intitulée « 6. Convertir les ventes à crédit existantes »Les ventes à crédit finalisées après la mise à niveau émettent leur facture automatiquement. Les ventes à crédit ouvertes d’avant continuent de fonctionner, mais n’ont pas de facture — donc ni rappels, ni lien de paiement, et elles ne figurent pas dans la liste des Factures clients — tant qu’elles ne sont pas converties.
La conversion est un appel d’API, fait une fois par locataire par un utilisateur de ce locataire autorisé à créer des factures clients :
POST /admin/customer-invoices/backfill-from-sales(sous le préfixe habituel /api/v1 de l’API — voir la
référence de l’API). Il répond en indiquant combien de factures il
a émises et s’il en reste :
{ "created": 200, "remaining": true }- Il traite jusqu’à 200 ventes par appel. Répétez tant que
remainingvauttrue. - Il peut être relancé sans risque : une vente qui a déjà une facture est ignorée.
- Chaque vente à crédit ouverte reçoit une facture numérotée dans la séquence normale de factures du locataire, avec une échéance tirée des conditions de paiement du client. Les paiements déjà enregistrés sur la vente sont conservés.
- Les ventes à crédit entièrement payées sont laissées telles quelles.
- Les clients ne reçoivent pas d’e-mail. Ce sont des dettes que le client connaît déjà.
- Une vente qui ne peut pas être convertie est ignorée et journalisée ; les autres continuent.
Ce que les marchands remarqueront
Section intitulée « Ce que les marchands remarqueront »À transmettre à vos locataires :
- Créer une facture avec un statut autre que Brouillon est désormais refusé.
- Un produit au stock suivi sur une facture émise dans les finances est refusé
(
stocked_product_requires_sale). - Une vente à crédit au-delà de la limite de crédit du client est refusée
(
credit_limit_exceeded), sauf si l’utilisateur détientsales.sale.credit_limit_override. Accordez-la aux superviseurs avant la mise en service, sinon les caisses seront arrêtées par des limites que personne n’appliquait auparavant. - Annuler une vente à crédit dont la facture porte des paiements est refusé
(
invoice_has_payments). - Un paiement ne peut pas être marqué terminé à la main, et un paiement dont le montant ou la devise ne correspond pas est mis En cours d’examen jusqu’à ce qu’un opérateur le résolve.
- Les locataires qui paient leur propre facture d’abonnement par carte passent par la page de redirection de la passerelle ; le paiement est vérifié par rapport à une tentative créée par le serveur.