Colas Mérand
16/06/2025
paiement récurrent
Viva Wallet
Smart Checkout
5 minutes
Intégration de paiements récurrents avec Viva Wallet : Guide complet pour les développeurs
Dans un monde où les modèles économiques par abonnement sont devenus incontournables, la mise en place d'un système de paiement récurrent fiable et sécurisé représente un enjeu majeur pour de nombreuses entreprises. Chez Platane, nous accompagnons régulièrement nos clients dans l'implémentation de solutions de paiement adaptées à leurs besoins spécifiques. Aujourd'hui, nous souhaitons partager notre expertise sur l'intégration de Viva Wallet Smart Checkout pour les paiements récurrents.
Pourquoi choisir Viva Wallet pour les paiements récurrents ?
Viva Wallet s'est imposé comme une solution de paiement complète et flexible, particulièrement adaptée aux entreprises européennes. Parmi ses avantages :
- Conformité RGPD et PSD2 : essentielle pour les entreprises opérant en Europe
- Support multi-devises : idéal pour les entreprises à visée internationale
- Frais compétitifs : notamment pour les transactions intra-européennes
- API robuste et bien documentée : facilitant l'intégration technique
- Smart Checkout : une solution clé en main qui simplifie la gestion des paiements
Architecture technique d'une intégration Viva Wallet pour paiements récurrents
L'implémentation d'un système de paiement récurrent avec Viva Wallet repose sur une architecture en plusieurs étapes. Voici comment nous procédons généralement chez Platane :
1. Mise en place du backend
Pour une intégration robuste, nous recommandons un backend Node.js, que ce soit avec Express, NestJS ou un framework léger. Cette approche offre plusieurs avantages :
// Exemple simplifié d'initialisation avec Express
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
// Configuration des clés d'API Viva Wallet
const VIVA_CLIENT_ID = process.env.VIVA_CLIENT_ID;
const VIVA_CLIENT_SECRET = process.env.VIVA_CLIENT_SECRET;
const VIVA_SOURCE_CODE = process.env.VIVA_SOURCE_CODE;
2. Création d'une commande avec option de récurrence
La première étape consiste à créer une commande via l'API Viva Wallet en spécifiant l'option allowRecurring: true
:
app.post('/create-payment', async (req, res) => {
try {
// Obtention du token d'authentification
const authToken = await getVivaWalletAuthToken();
// Création de la commande
const paymentOrder = await axios.post(
'https://api.vivawallet.com/checkout/v2/orders',
{
amount: req.body.amount * 100, // Montant en centimes
customerTrns: req.body.description,
customer: {
email: req.body.email,
fullName: req.body.fullName,
},
paymentTimeout: 300, // 5 minutes
allowRecurring: true, // Activation du paiement récurrent
merchantTrns: generateUniqueId(), // ID unique pour la transaction
sourceCode: VIVA_SOURCE_CODE
},
{
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json'
}
}
);
// Retourne l'URL de paiement et l'orderCode
res.json({
checkoutUrl: paymentOrder.data.orderCode
? `https://www.vivapayments.com/web/checkout?ref=${paymentOrder.data.orderCode}`
: null,
orderCode: paymentOrder.data.orderCode
});
} catch (error) {
console.error('Erreur lors de la création du paiement:', error);
res.status(500).json({ error: 'Erreur lors de la création du paiement' });
}
});
3. Configuration des webhooks pour suivre les paiements
Les webhooks sont essentiels pour recevoir les notifications de paiement en temps réel :
app.post('/webhooks/viva-wallet', async (req, res) => {
// Vérification de la signature du webhook (recommandé)
if (!verifyVivaWebhookSignature(req)) {
return res.status(401).send('Signature invalide');
}
const eventData = req.body;
// Traitement selon le type d'événement
switch (eventData.EventTypeId) {
case 1791: // Transaction créée avec succès
// Enregistrer les informations de transaction pour les paiements récurrents
await storeTransactionInfo({
transactionId: eventData.TransactionId,
userId: eventData.Metadata.userId,
amount: eventData.Amount / 100, // Conversion en unités monétaires
status: 'success',
date: new Date()
});
// Activer l'abonnement dans votre système
await activateSubscription(eventData.Metadata.userId);
break;
case 1792: // Échec de transaction
// Gérer l'échec (notification utilisateur, tentative de nouveau paiement, etc.)
await handleFailedPayment(eventData);
break;
// Autres cas selon les besoins
}
res.status(200).send('Webhook reçu');
});
4. Implémentation des paiements récurrents automatiques
Pour les paiements suivants, vous utiliserez l'API REST de Viva Wallet sans interaction utilisateur :
async function processRecurringPayment(userId, amount, description) {
try {
// Récupération des informations de transaction initiale
const initialTransaction = await getInitialTransactionInfo(userId);
if (!initialTransaction) {
throw new Error('Aucune transaction initiale trouvée');
}
const authToken = await getVivaWalletAuthToken();
// Création du paiement récurrent
const recurringPayment = await axios.post(
'https://api.vivawallet.com/recurring/v1/transactions',
{
amount: amount * 100, // Montant en centimes
customerTrns: description,
merchantTrns: generateUniqueId(),
initialTransactionId: initialTransaction.transactionId,
installments: 1, // Paiement unique
sourceCode: VIVA_SOURCE_CODE
},
{
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json'
}
}
);
return {
success: true,
transactionId: recurringPayment.data.transactionId
};
} catch (error) {
console.error('Erreur lors du paiement récurrent:', error);
return {
success: false,
error: error.message
};
}
}
5. Mise en place d'un système de planification des paiements
Pour automatiser les paiements à intervalles réguliers, nous recommandons l'utilisation d'un système de cron jobs :
// Utilisation de node-cron pour planifier les paiements
const cron = require('node-cron');
// Exécution tous les jours à minuit
cron.schedule('0 0 * * *', async () => {
console.log('Vérification des paiements récurrents à effectuer...');
// Récupération des abonnements à facturer aujourd'hui
const subscriptionsDue = await getSubscriptionsDueToday();
for (const subscription of subscriptionsDue) {
try {
// Traitement du paiement récurrent
const paymentResult = await processRecurringPayment(
subscription.userId,
subscription.amount,
`Paiement récurrent - ${subscription.planName}`
);
// Mise à jour du statut de l'abonnement
if (paymentResult.success) {
await updateSubscriptionStatus(subscription.id, 'active', paymentResult.transactionId);
} else {
// Gestion des échecs (notification, tentatives supplémentaires, etc.)
await handleFailedRecurringPayment(subscription, paymentResult.error);
}
} catch (error) {
console.error(`Erreur lors du traitement de l'abonnement ${subscription.id}:`, error);
}
}
});
Bonnes pratiques de sécurité
La sécurité est primordiale lorsqu'il s'agit de paiements en ligne. Voici les mesures que nous mettons systématiquement en place chez Platane :
1. Protection des données sensibles
// Utilisation de variables d'environnement pour les clés d'API
require('dotenv').config();
// Jamais de stockage en dur des clés d'API
const config = {
vivaWallet: {
clientId: process.env.VIVA_CLIENT_ID,
clientSecret: process.env.VIVA_CLIENT_SECRET,
sourceCode: process.env.VIVA_SOURCE_CODE,
environment: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox'
}
};
2. Validation des webhooks
function verifyVivaWebhookSignature(req) {
const signature = req.headers['x-viva-signature'];
if (!signature) return false;
// Implémentation de la vérification de signature selon la documentation Viva Wallet
// ...
return true;
}
3. Gestion sécurisée des identifiants de transaction
// Utilisation d'une base de données sécurisée pour stocker les identifiants
async function storeTransactionInfo(transactionData) {
// Chiffrement des données sensibles avant stockage
const encryptedTransactionId = encrypt(transactionData.transactionId);
// Stockage dans la base de données
await db.transactions.create({
userId: transactionData.userId,
encryptedTransactionId,
amount: transactionData.amount,
status: transactionData.status,
date: transactionData.date
});
}
// Récupération sécurisée
async function getInitialTransactionInfo(userId) {
const transaction = await db.transactions.findOne({
where: { userId, status: 'success' },
order: [['date', 'ASC']]
});
if (!transaction) return null;
return {
...transaction,
transactionId: decrypt(transaction.encryptedTransactionId)
};
}
Retour d'expérience : cas concrets d'intégration
Chez Platane, nous avons eu l'occasion de mettre en œuvre ce type d'intégration pour plusieurs clients aux besoins variés. Par exemple, pour Easop, une plateforme de gestion de stock options (revendue plusieurs millions à Remote), nous avons implémenté un système de paiement récurrent robuste qui a traité des milliers de transactions sans incident.
De même, pour Dealt, une marketplace de services professionnels, nous avons développé une architecture de paiement complète intégrant des fonctionnalités de paiement récurrent, contribuant significativement à la croissance de leur chiffre d'affaires.
Ces expériences nous ont permis d'affiner notre approche et de développer une expertise pointue dans l'intégration de systèmes de paiement, notamment avec Viva Wallet.
Gestion des cas d'erreur
Un système de paiement robuste doit anticiper et gérer efficacement les cas d'erreur :
async function handleFailedRecurringPayment(subscription, errorMessage) {
// Enregistrement de l'échec
await logPaymentFailure(subscription.id, errorMessage);
// Notification à l'utilisateur
await sendPaymentFailureNotification(
subscription.userId,
subscription.email,
errorMessage
);
// Planification d'une nouvelle tentative si approprié
if (subscription.retryCount < MAX_RETRY_ATTEMPTS) {
await schedulePaymentRetry(subscription.id, calculateNextRetryDate());
} else {
// Suspension de l'abonnement après plusieurs échecs
await updateSubscriptionStatus(subscription.id, 'suspended');
await sendSubscriptionSuspendedNotification(subscription.userId, subscription.email);
}
}
Tests et validation
Avant toute mise en production, nous recommandons vivement de tester exhaustivement l'intégration dans l'environnement sandbox de Viva Wallet :
// Configuration conditionnelle selon l'environnement
const VIVA_API_BASE_URL = process.env.NODE_ENV === 'production'
? 'https://api.vivawallet.com'
: 'https://demo-api.vivawallet.com';
Conclusion
L'intégration de Viva Wallet pour les paiements récurrents représente un défi technique qui nécessite une approche méthodique et une attention particulière à la sécurité. En suivant les bonnes pratiques présentées dans cet article, vous pourrez mettre en place un système fiable qui répondra aux attentes de vos utilisateurs tout en assurant la pérennité de votre modèle économique.
Chez Platane, nous combinons expertise technique et créativité pour développer des solutions sur mesure qui répondent précisément aux besoins de nos clients. Notre équipe maîtrise parfaitement les technologies modernes comme React, Node.js et les systèmes de paiement sécurisés, nous permettant de livrer des projets de haute qualité.
Vous avez un projet d'intégration de paiement ou souhaitez moderniser votre système actuel ? N'hésitez pas à prendre rendez-vous via notre formulaire de contact. Nous serons ravis d'échanger sur votre projet et de vous proposer une solution adaptée à vos besoins spécifiques. Collaborer avec Platane, c'est s'assurer d'un développement technique irréprochable, d'une expérience utilisateur optimale et d'un accompagnement personnalisé tout au long de votre projet.
WordPress et Elementor : Au-delà de l'intégration rapide, une question de qualité et d'expertise
Révolutionnez votre collection Pokémon avec un système de gradation automatisé sur WordPress
Développement Full Stack moderne : Maîtriser TypeScript, GraphQL et les architectures SPA pour des applications performantes
N'hésitez pas à nous contacter.
Nous aussi et c'est évidemment sans engagement !