Intégration

Plans & Abonnements

Créez des plans SaaS pour votre projet et permettez à vos clients de s'y abonner via l'app ou le web.

Plans & Abonnements

Le système de billing ash-gate vous permet de transformer votre app en SaaS : créez des plans d'abonnement, déclenchez les paiements depuis votre app Flutter, et gérez le cycle de vie des souscriptions depuis votre backend.


Architecture du flux

Votre Backend          ash-gate              App Flutter / Web
     │                     │                        │
     │ POST /billing-plans  │                        │
     │ (Secret Key)         │                        │
     │─────────────────────►│                        │
     │◄─────────────────────│                        │
     │ Plan créé            │                        │
                            │                        │
                            │ GET /public/plans/pk_  │
                            │◄───────────────────────│
                            │────────────────────────►
                            │ [{id, name, amount...}]│
                                                     │
                                    Utilisateur choisit un plan
                                                     │
                            │ POST /fedapay/subsc...  │
                            │◄───────────────────────│
                            │ (Public Key)            │
                            │─────────────────────────►
                            │ {paymentUrl}            │
                                                     │
                                         WebView → paiement FedaPay
                                                     │
     │                     │  Webhook transaction.approved
     │◄─────────────────────│
     │ → Activer l'accès    │

Matrice d'accès

OpérationRouteAuth
Lister les plans publicsGET /public/plans/:publicKeyAucune
Voir l'abonnement d'un clientGET /public/subscriptions/:publicKey/current?userId=Aucune
Souscrire à un planPOST /fedapay/subscriptionsPublic Key
Générer une facturePOST /fedapay/subscriptions/:id/invoicePublic Key
Lister ses abonnementsGET /fedapay/subscriptionsPublic Key
Créer / modifier un planPOST/PATCH /fedapay/billing-plansSecret Key
Annuler un abonnementPATCH /fedapay/subscriptions/:id/cancelSecret Key
Générer les plans par défautPOST /fedapay/billing-plans/seedSecret Key

1. Créer des plans (Backend → Secret Key)

# Créer un plan depuis votre serveur
curl -X POST https://app.ashgateway.com/fedapay/billing-plans \
  -H "X-Feda-Project-Secret: sk_cloud_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pack Pro",
    "description": "Accès illimité - Support prioritaire",
    "amount": 5000,
    "currency": "XOF",
    "interval": "monthly",
    "trialDays": 14,
    "isPublic": true
  }'
# Ou générer 3 plans par défaut en une commande CLI
wallet billing seed
# - Créé : Pack Basic (2 000 XOF/mois)
# - Créé : Pack Pro (5 000 XOF/mois - 14j d'essai)
# - Créé : Pack Business (15 000 XOF/mois - 30j d'essai)

2. Afficher les plans dans l'app (Flutter → Sans auth)

import 'package:dio/dio.dart';

class BillingService {
  final _dio = Dio();
  final _publicKey = 'pk_sandbox_xxx';
  final _baseUrl = 'https://app.ashgateway.com';

  Future<List<Map<String, dynamic>>> getPlans() async {
    final response = await _dio.get('$_baseUrl/public/plans/$_publicKey');
    return List<Map<String, dynamic>>.from(response.data['plans']);
  }
}

// Dans votre widget pricing page :
FutureBuilder<List<Map<String, dynamic>>>(
  future: BillingService().getPlans(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) return const CircularProgressIndicator();
    return ListView.builder(
      itemCount: snapshot.data!.length,
      itemBuilder: (_, i) {
        final plan = snapshot.data![i];
        return PlanCard(
          name: plan['name'],
          price: '${plan['amount']} XOF / mois',
          trialDays: plan['trialDays'],
          onSubscribe: () => subscribeToPlan(plan['id']),
        );
      },
    );
  },
)

3. Souscrire à un plan (Flutter → Public Key)

Future<String?> subscribeToPlan(String planId) async {
  final response = await _dio.post(
    '$_baseUrl/fedapay/subscriptions',
    options: Options(headers: {'X-Feda-Project-Key': _publicKey}),
    data: {
      'billingPlanId': planId,
      'userId': currentUser.id,      // ID dans VOTRE système
      'email': currentUser.email,
    },
  );

  final paymentUrl = response.data['paymentUrl'];
  if (paymentUrl != null) {
    // Ouvrir dans un WebView pour le paiement mobile
    await launchUrl(Uri.parse(paymentUrl));
  }
  return paymentUrl;
}

4. Vérifier l'abonnement au démarrage (Flutter → Sans auth)

Future<bool> hasActiveSubscription() async {
  final response = await _dio.get(
    '$_baseUrl/public/subscriptions/$_publicKey/current',
    queryParameters: {'userId': currentUser.id},
  );

  // Possible statuses: 'active' | 'trialing' | 'past_due' | 'cancelled' | 'none'
  return response.data['hasActiveSubscription'] == true;
}

5. Annuler depuis votre backend (Secret Key)

// Node.js / NestJS
const response = await axios.patch(
  `https://app.ashgateway.com/fedapay/subscriptions/${subscriptionId}/cancel`,
  {},
  { headers: { 'X-Feda-Project-Secret': process.env.FEDA_PROJECT_SECRET } },
);
// → subscription.status = 'cancelled'

Cycle de vie d'un abonnement

Création
   │
   ▼
trialing ──(trialDays jours)──► active
   │                                │
   │                          (fin de période)
   │                                │
   │                          invoice générée → paymentUrl
   │                                │
   │                       ┌────────┴────────┐
   │                 Payé (webhook)    Non payé
   │                       │                 │
   │                    active           past_due
   │                                         │
   │                                  (gracePeriod jours)
   │                                         │
   └─────────────────────────────────► cancelled

Suivant : Authentification & Clés ->