Passer au contenu principal
Apprenez à implémenter la collecte de paiements pour une plateforme Software-as-a-Service (SaaS) avec Yabetoo. Ce guide couvre la gestion des abonnements, les paiements ponctuels et les changements de forfait.

Aperçu

Les plateformes SaaS ont besoin de solutions de paiement flexibles pour gérer :
  • La facturation mensuelle et annuelle des abonnements
  • Les achats ponctuels (modules complémentaires, crédits)
  • Les montées et descentes en gamme
  • La gestion des périodes d’essai
  • La gestion des échecs de paiement
Yabetoo supporte actuellement les paiements ponctuels. Pour la facturation récurrente, vous devrez implémenter une tâche planifiée (cron) qui crée des intentions de paiement à intervalles réguliers.

Architecture

Implémentation

1. Définir vos forfaits tarifaires

D’abord, définissez vos niveaux d’abonnement :
// pricing.ts
export const PLANS = {
  starter: {
    id: 'starter',
    name: 'Starter',
    monthlyPrice: 5000,   // 5 000 XAF/mois
    annualPrice: 50000,   // 50 000 XAF/an (2 mois gratuits)
    features: ['5 utilisateurs', '10Go stockage', 'Support email']
  },
  professional: {
    id: 'professional',
    name: 'Professionnel',
    monthlyPrice: 15000,  // 15 000 XAF/mois
    annualPrice: 150000,  // 150 000 XAF/an
    features: ['25 utilisateurs', '100Go stockage', 'Support prioritaire', 'Accès API']
  },
  enterprise: {
    id: 'enterprise',
    name: 'Entreprise',
    monthlyPrice: 50000,  // 50 000 XAF/mois
    annualPrice: 500000,  // 500 000 XAF/an
    features: ['Utilisateurs illimités', '1To stockage', 'Support 24/7', 'Intégrations personnalisées']
  }
};

2. Créer un paiement d’abonnement

Quand un utilisateur s’abonne, créez une intention de paiement :
import Yabetoo from '@yabetoo/sdk-js';

const yabetoo = new Yabetoo(process.env.YABETOO_SECRET_KEY!);

async function createSubscriptionPayment(
  userId: string,
  planId: string,
  billingCycle: 'monthly' | 'annual'
) {
  const plan = PLANS[planId];
  const amount = billingCycle === 'monthly' ? plan.monthlyPrice : plan.annualPrice;

  // Créer l'intention de paiement
  const intent = await yabetoo.payments.create({
    amount,
    currency: 'XAF',
    description: `Forfait ${plan.name} - Abonnement ${billingCycle === 'monthly' ? 'mensuel' : 'annuel'}`,
    metadata: {
      userId,
      planId,
      billingCycle,
      subscriptionStart: new Date().toISOString(),
      type: 'subscription'
    }
  });

  // Stocker l'abonnement en attente
  await db.pendingSubscriptions.create({
    userId,
    planId,
    billingCycle,
    paymentIntentId: intent.id,
    status: 'pending'
  });

  return intent;
}

3. Gestionnaire Webhook pour l’activation

Configurez un webhook pour activer les abonnements quand le paiement réussit :
app.post('/webhooks/yabetoo', async (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'payment_intent.succeeded':
      await handlePaymentSuccess(event.data);
      break;
    case 'payment_intent.failed':
      await handlePaymentFailure(event.data);
      break;
  }

  res.json({ received: true });
});

async function handlePaymentSuccess(data: any) {
  const { metadata } = data;

  if (metadata.type === 'subscription') {
    // Activer l'abonnement
    const subscription = await db.subscriptions.create({
      userId: metadata.userId,
      planId: metadata.planId,
      billingCycle: metadata.billingCycle,
      status: 'active',
      currentPeriodStart: new Date(),
      currentPeriodEnd: calculatePeriodEnd(metadata.billingCycle),
      paymentIntentId: data.id
    });

    // Accorder l'accès aux fonctionnalités
    await grantPlanFeatures(metadata.userId, metadata.planId);

    // Envoyer email de confirmation
    await sendSubscriptionConfirmation(metadata.userId, subscription);
  }
}

function calculatePeriodEnd(billingCycle: string): Date {
  const now = new Date();
  if (billingCycle === 'monthly') {
    return new Date(now.setMonth(now.getMonth() + 1));
  }
  return new Date(now.setFullYear(now.getFullYear() + 1));
}

4. Facturation récurrente

Configurez une tâche planifiée pour gérer les paiements récurrents :
// cron-job.ts (exécuté quotidiennement)
async function processRecurringBilling() {
  // Trouver les abonnements expirant dans les 3 prochains jours
  const expiringSubscriptions = await db.subscriptions.findMany({
    where: {
      status: 'active',
      currentPeriodEnd: {
        lte: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000)
      }
    }
  });

  for (const subscription of expiringSubscriptions) {
    const plan = PLANS[subscription.planId];
    const amount = subscription.billingCycle === 'monthly'
      ? plan.monthlyPrice
      : plan.annualPrice;

    // Créer le paiement de renouvellement
    const intent = await yabetoo.payments.create({
      amount,
      currency: 'XAF',
      description: `Forfait ${plan.name} - Renouvellement`,
      metadata: {
        userId: subscription.userId,
        planId: subscription.planId,
        billingCycle: subscription.billingCycle,
        subscriptionId: subscription.id,
        type: 'renewal'
      }
    });

    // Notifier l'utilisateur du renouvellement à venir
    await sendRenewalReminder(subscription.userId, intent);
  }
}

Flux d’abonnement complet

1

L'utilisateur choisit un forfait

L’utilisateur sélectionne un forfait et une période de facturation sur votre page de tarifs.
2

Création de l'intention de paiement

Votre backend crée une intention de paiement avec les métadonnées d’abonnement.
3

Collecte des informations de paiement

L’utilisateur saisit son numéro mobile money et confirme le paiement.
4

Traitement du paiement

Yabetoo traite le paiement via MTN ou Airtel Money.
5

Notification Webhook

Yabetoo envoie un webhook quand le paiement réussit ou échoue.
6

Activation de l'abonnement

Votre gestionnaire webhook active l’abonnement et accorde l’accès.
7

Facturation récurrente

Une tâche planifiée crée les paiements de renouvellement avant chaque fin de période.

Bonnes pratiques

Implémentez une période de grâce (3-7 jours) pour les échecs de renouvellement avant de suspendre l’accès.
Envoyez des rappels 7 jours, 3 jours et 1 jour avant le renouvellement.
Réessayez automatiquement les paiements échoués (3 tentatives sur 7 jours) avant d’annuler.
Calculez équitablement les montants au prorata lors des changements de forfait en cours de cycle.

Ressources associées