Traductions de l'article Markdown en français

J'ai configuré les intégrations Stripe probablement une douzaine de fois au cours des dernières années, et voici ce que j'ai appris : le tutoriel de démarrage est la partie facile. La partie difficile consiste à exécuter quatre modèles de tarification complètement différents dans la même organisation, gérer les devises de plus de 30 pays sans erreurs d'arrondi, et s'assurer que vos gestionnaires de webhook ne s'arrêtent pas silencieusement à 3 heures du matin un samedi.

Ce n'est pas un autre article « créer une session de paiement en 5 minutes ». Nous allons parcourir quatre modèles de tarification de production que nous avons construits et exploités - les abonnements échelonnés avec tarification régionale, les commissions de place de marché via Stripe Connect, les dons récurrents liés à des entités spécifiques, et les paiements de services ponctuels. Chacun a son propre ensemble de pièges, et je partagerai les modèles de code spécifiques et les décisions de configuration qui nous ont sauvés de bugs douloureux.

Table des matières

Meilleure configuration Stripe pour une entreprise d'abonnement : 4 modèles que nous utilisons

Pourquoi une seule configuration Stripe n'est pas adaptée à tous

La documentation Stripe est excellente pour les entreprises à modèle unique. Vous choisissez les abonnements ou les paiements ponctuels, suivez le guide, et vous êtes en direct. Mais la plupart des entreprises réelles ne restent pas aussi simples longtemps.

Nous opérons sur plusieurs produits : une plateforme SaaS avec des abonnements échelonnés, une place de marché qui prélève des commissions auprès des prestataires, une initiative caritative avec des parrainage récurrents, et un système de réservation de consultation avec des paiements ponctuels. Chacune de ces activités se trouve sous le même compte Stripe mais nécessite des configurations fondamentalement différentes pour les produits, la tarification, les webhooks et la gestion des clients.

La plus grande erreur que je vois les équipes faire est d'essayer de forcer toute leur facturation dans un seul modèle. Une architecture centrée sur l'abonnement s'effondre quand vous avez besoin de paiements ponctuels. Une approche basée uniquement sur la session de paiement s'effondre quand vous avez besoin de facturation récurrente avec prorata. Vous devez penser à votre configuration Stripe comme un portefeuille de modèles de facturation.

Si vous créez quelque chose de similaire - surtout sur une architecture headless avec Next.js ou Astro en frontend - ces modèles vous économiseront des semaines de débogage.

Modèle 1 : Abonnements échelonnés avec tarification régionale

C'est le modèle le plus complexe que nous gérons, et c'est celui qui nous a enseigné les leçons les plus douloureuses. La configuration : quatre tiers (Gratuit, Basic, Pro, Premium) avec une tarification qui varie selon plus de 30 pays.

La structure des produits dans Stripe

Dans Stripe, chaque tier est un Produit séparé. Chaque Produit possède plusieurs Prix - un par combinaison devise/région. C'est important : ne tentez pas d'utiliser un seul Prix et de faire la conversion de devise vous-même. La tarification multi-devises de Stripe est spécialement conçue pour cela.

// Configuration de tarification régionale
const REGIONAL_PRICING = {
  pro: {
    USD: { monthly: 2900, yearly: 29000 },  // $29/mois, $290/an
    EUR: { monthly: 2700, yearly: 27000 },  // €27/mois, €270/an
    GBP: { monthly: 2300, yearly: 23000 },  // £23/mois, £230/an
    JPY: { monthly: 4200, yearly: 42000 },  // ¥4 200/mois -- PAS ¥42.00!
    KRW: { monthly: 38000, yearly: 380000 }, // ₩38 000/mois
    INR: { monthly: 190000, yearly: 1900000 }, // ₹1 900/mois
    BRL: { monthly: 14900, yearly: 149000 }, // R$149/mois
  },
  // ... répéter pour basic, premium
};

Remarquez ces valeurs JPY et KRW ? J'y reviendrai en détail plus tard, mais en résumé : ce sont des devises sans décimale. Quand vous passez 4200 pour JPY, Stripe l'interprète comme ¥4 200 - pas ¥42.00. Si vous multipliez par 100 comme vous le faites pour USD, vous venez de facturer quelqu'un ¥420 000 ($2 800) au lieu de ¥4 200 ($28). Demandez-moi comment je sais.

Logique de période d'essai régionale

Chaque région ne bénéficie pas d'une période d'essai gratuite. Nous l'avons appris à nos dépens avec certains marchés d'Asie du Sud-Est où les abus d'essai étaient nettement plus élevés que dans d'autres régions. Notre configuration ressemble à ceci :

const TRIAL_CONFIG = {
  default_trial_days: 14,
  excluded_regions: ['VN', 'PH', 'ID', 'TH', 'MM', 'KH', 'LA'],
  reduced_trial_regions: {
    IN: 7,
    BR: 7,
  },
};

function getTrialDays(countryCode) {
  if (TRIAL_CONFIG.excluded_regions.includes(countryCode)) {
    return 0;
  }
  return TRIAL_CONFIG.reduced_trial_regions[countryCode] 
    ?? TRIAL_CONFIG.default_trial_days;
}

Ceci est passé à la création de l'abonnement :

const subscription = await stripe.subscriptions.create({
  customer: customerId,
  items: [{ price: regionalPriceId }],
  trial_period_days: getTrialDays(customer.address.country),
  payment_behavior: 'default_incomplete',
  payment_settings: {
    save_default_payment_method: 'on_subscription',
  },
  expand: ['latest_invoice.payment_intent'],
});

Comportement du prorata

Quand quelqu'un passe de Basic à Pro en milieu de cycle, vous devez décider : paie-t-il la différence immédiatement, ou lors du prochain cycle de facturation ? Nous utilisons create_prorations avec paiement immédiat :

const updatedSubscription = await stripe.subscriptions.update(subscriptionId, {
  items: [{
    id: existingItemId,
    price: newPriceId,
  }],
  proration_behavior: 'create_prorations',
  payment_behavior: 'pending_if_incomplete',
});

Pour les rétrogradations, nous planifions le changement pour la fin de la période de facturation. Personne ne veut un calcul de crédit surprise sur sa facture.

Portail client

Le Portail Client de Stripe est sous-estimé. Au lieu de créer votre propre interface de gestion des abonnements, configurez le portail et redirigez les utilisateurs là-bas :

const portalSession = await stripe.billingPortal.sessions.create({
  customer: customerId,
  return_url: `${process.env.APP_URL}/settings/billing`,
});

Configurez-le dans le Tableau de bord Stripe pour permettre les changements de plan, l'annulation (avec une enquête sur les raisons d'annulation - les données sont précieuses), et les mises à jour de mode de paiement. Cela seul nous a économisé probablement 40 heures de développement frontend.

Modèle 2 : Commissions de place de marché avec Stripe Connect

Notre modèle de place de marché utilise Stripe Connect pour faciliter les paiements entre les clients et les prestataires de services. La plateforme prélève une commission sur chaque transaction. C'est la configuration Stripe Connect que la plupart des tutoriels passent sous silence.

Intégration des prestataires

Chaque prestataire sur la place de marché a besoin d'un compte Stripe Express. Le flux d'intégration crée le compte et les redirige vers l'intégration hébergée de Stripe :

const account = await stripe.accounts.create({
  type: 'express',
  country: provider.country,
  email: provider.email,
  capabilities: {
    card_payments: { requested: true },
    transfers: { requested: true },
  },
  business_type: 'individual',
  metadata: {
    provider_id: provider.id,
    platform: 'fme',
  },
});

const accountLink = await stripe.accountLinks.create({
  account: account.id,
  refresh_url: `${process.env.APP_URL}/provider/onboarding/refresh`,
  return_url: `${process.env.APP_URL}/provider/onboarding/complete`,
  type: 'account_onboarding',
});

Le détail clé : refresh_url est l'endroit où Stripe envoie les utilisateurs si le lien expire. Cela arrive plus souvent qu'on ne le pense - si quelqu'un commence l'intégration sur son téléphone, se distrait, et revient plus tard. Traitez toujours cela correctement en générant un nouveau lien.

Structure de commission

Quand un client réserve un service, nous créons un PaymentIntent avec un application_fee_amount :

const paymentIntent = await stripe.paymentIntents.create({
  amount: bookingAmountInCents,
  currency: 'usd',
  application_fee_amount: Math.round(bookingAmountInCents * 0.15), // Frais de plateforme 15%
  transfer_data: {
    destination: providerStripeAccountId,
  },
  metadata: {
    booking_id: booking.id,
    provider_id: provider.id,
    customer_id: customer.id,
  },
});

La commission de 15% va à la plateforme. Les 85% restants (moins les frais de traitement de Stripe) vont au compte Express du prestataire.

Planification des versements

Par défaut, Stripe verse les comptes Express sur une base continue. Nous remplaçons cela par des versements hebdomadaires, ce qui nous donne une marge de manœuvre pour les remboursements et les contestations :

await stripe.accounts.update(providerStripeAccountId, {
  settings: {
    payouts: {
      schedule: {
        interval: 'weekly',
        weekly_anchor: 'friday',
      },
    },
  },
});

Les versements du vendredi signifient que les prestataires voient l'argent dans leurs comptes bancaires d'ici lundi. C'est une petite chose mais c'est énormément important pour la satisfaction et la rétention des prestataires.

Webhooks spécifiques à Connect

Avec Stripe Connect, vous recevez des webhooks pour votre plateforme ET vos comptes connectés. Vous avez besoin d'un point de terminaison webhook séparé pour les événements Connect :

// Point de terminaison webhook régulier
app.post('/webhooks/stripe', handlePlatformWebhooks);

// Point de terminaison webhook Connect
app.post('/webhooks/stripe-connect', handleConnectWebhooks);

Le gestionnaire de webhook Connect doit vérifier l'événement différemment et vérifier le champ account :

async function handleConnectWebhooks(req, res) {
  const event = stripe.webhooks.constructEvent(
    req.body,
    req.headers['stripe-signature'],
    process.env.STRIPE_CONNECT_WEBHOOK_SECRET // Secret différent!
  );
  
  const connectedAccountId = event.account;
  // Maintenant gérer l'événement dans le contexte du compte connecté
}

Meilleure configuration Stripe pour une entreprise d'abonnement : 4 modèles que nous utilisons - architecture

Modèle 3 : Dons récurrents liés à des entités

Celui-ci s'adresse à une initiative caritative pour animaux que nous créons - pensez à « parrainer un animal spécifique » avec des dons mensuels récurrents. Le donateur choisit un animal, définit un montant mensuel, et reçoit des mises à jour photo.

Abonnements liés à une entité

L'astuce ici est de lier un abonnement Stripe à une entité spécifique (animal) dans votre base de données. Nous le faisons entièrement via les métadonnées :

const subscription = await stripe.subscriptions.create({
  customer: donorCustomerId,
  items: [{
    price_data: {
      currency: 'usd',
      product: sponsorshipProductId,
      unit_amount: donorChosenAmount, // Le donateur choisit son montant
      recurring: {
        interval: 'month',
      },
    },
  }],
  metadata: {
    entity_id: animal.id,
    entity_type: 'animal',
    entity_name: animal.name,
    sponsor_email: donor.email,
  },
});

Utiliser price_data au lieu d'un Prix pré-créé permet aux donateurs de choisir leur propre montant mensuel. C'est plus propre que de créer des centaines d'objets Prix.

Emails de mise à jour mensuelle

Quand invoice.paid se déclenche pour un abonnement de parrainage, nous déclenchons le flux de mise à jour mensuelle :

async function handleSponsorshipInvoicePaid(invoice) {
  const subscription = await stripe.subscriptions.retrieve(invoice.subscription);
  const entityId = subscription.metadata.entity_id;
  
  // Mettre en queue l'email de mise à jour mensuelle avec les dernières photos
  await emailQueue.add('sponsorship-update', {
    donorEmail: subscription.metadata.sponsor_email,
    entityId,
    invoiceAmount: invoice.amount_paid,
    invoicePdf: invoice.invoice_pdf,
  });
}

L'email inclut le PDF de la facture (Stripe les génère automatiquement), les photos récentes de l'animal parrainé, et une mise à jour des soins. C'est une petite touche qui réduit considérablement le taux d'attrition des dons récurrents.

Gestion des annulations de dons

Quand quelqu'un annule son parrainage, vous devez le traiter différemment qu'une annulation SaaS. Il n'y a pas de « rétrogradation » - c'est annuler ou rien. Mais vous voulez que ce soit facile de se réinscrire plus tard :

async function handleSponsorshipCancellation(subscription) {
  const entityId = subscription.metadata.entity_id;
  
  // Marquer le parrainage comme inactif, pas supprimé
  await db.sponsorships.update({
    where: { stripeSubscriptionId: subscription.id },
    data: { 
      status: 'inactive',
      cancelledAt: new Date(),
    },
  });
  
  // Envoyer un email « nous vous regretterez » avec un lien facile pour vous réinscrire
  await sendCancellationEmail(subscription.metadata.sponsor_email, entityId);
}

Modèle 4 : Paiements de services ponctuels

Le modèle le plus simple, mais il y a encore des détails qui comptent. Ce modèle est pour les réservations de consultation où quelqu'un paie une fois et obtient un service - pas de facturation récurrente.

Session de paiement avec données de réservation

const session = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: [{
    price: consultationPriceId,
    quantity: 1,
  }],
  customer_email: customer.email,
  metadata: {
    booking_id: booking.id,
    service_type: 'consultation',
    appointment_date: booking.date.toISOString(),
    practitioner_id: booking.practitionerId,
  },
  success_url: `${process.env.APP_URL}/booking/confirmed?session_id={CHECKOUT_SESSION_ID}`,
  cancel_url: `${process.env.APP_URL}/booking/${booking.id}`,
  expires_after: 1800, // 30 minutes
  payment_intent_data: {
    metadata: {
      booking_id: booking.id,
    },
  },
});

Deux choses à noter. Premièrement : expires_after empêche les sessions de paiement abandonnées de s'éterniser. Un créneau de réservation ne devrait pas être bloqué indéfiniment. Deuxièmement : nous dupliquons le booking_id dans payment_intent_data.metadata car les métadonnées PaymentIntent sont séparées des métadonnées de la session de paiement. Quand vous recevez le webhook payment_intent.succeeded, vous voudrez cet ID de réservation juste là.

Confirmation de paiement + réservation

Sur checkout.session.completed, nous confirmez la réservation et envoyons tout d'un coup :

async function handleCheckoutComplete(session) {
  const bookingId = session.metadata.booking_id;
  
  // Confirmer la réservation
  const booking = await db.bookings.update({
    where: { id: bookingId },
    data: { 
      status: 'confirmed',
      paymentSessionId: session.id,
      paidAt: new Date(),
    },
  });
  
  // Envoyer la confirmation au client
  await sendBookingConfirmation(session.customer_email, booking);
  
  // Notifier le praticien
  await notifyPractitioner(booking.practitionerId, booking);
}

Architecture de webhook qui fonctionne réellement

Selon tous les quatre modèles, les webhooks sont la colonne vertébrale. Voici l'architecture sur laquelle nous nous sommes établis après trop de sessions de débogage :

const WEBHOOK_HANDLERS = {
  'checkout.session.completed': handleCheckoutComplete,
  'invoice.paid': handleInvoicePaid,
  'invoice.payment_failed': handlePaymentFailed,
  'customer.subscription.created': handleSubscriptionCreated,
  'customer.subscription.updated': handleSubscriptionUpdated,
  'customer.subscription.deleted': handleSubscriptionDeleted,
  'account.updated': handleConnectAccountUpdated,
  'payment_intent.succeeded': handlePaymentSucceeded,
};

async function webhookHandler(req, res) {
  let event;
  try {
    event = stripe.webhooks.constructEvent(
      req.rawBody, // Vous avez besoin du corps brut, pas du JSON analysé
      req.headers['stripe-signature'],
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    console.error('Webhook signature verification failed:', err.message);
    return res.status(400).send();
  }

  // Idempotence : vérifier si nous avons déjà traité cet événement
  const processed = await db.webhookEvents.findUnique({
    where: { stripeEventId: event.id },
  });
  if (processed) {
    return res.status(200).json({ received: true, duplicate: true });
  }

  const handler = WEBHOOK_HANDLERS[event.type];
  if (handler) {
    try {
      await handler(event.data.object, event);
      await db.webhookEvents.create({
        data: { stripeEventId: event.id, type: event.type, processedAt: new Date() },
      });
    } catch (err) {
      console.error(`Error processing ${event.type}:`, err);
      return res.status(500).send(); // Stripe réessayera
    }
  }

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

La vérification d'idempotence est critique. Stripe réessayera les webhooks échoués, et vous ne voulez absolument pas traiter le même événement deux fois - surtout pour les choses comme la création de réservations ou le déclenchement de versements.

Logique de relance des paiements échoués et dunning

Stripe a des Relances Intelligentes intégrées, mais vous devez ajouter votre propre logique de dunning par-dessus :

async function handlePaymentFailed(invoice) {
  const attemptCount = invoice.attempt_count;
  const subscription = await stripe.subscriptions.retrieve(invoice.subscription);
  
  if (attemptCount === 1) {
    // Premier échec : coup de pouce doux
    await sendEmail(invoice.customer_email, 'payment-failed-soft', {
      updatePaymentUrl: await createPortalLink(invoice.customer),
    });
  } else if (attemptCount === 2) {
    // Deuxième échec : plus urgent
    await sendEmail(invoice.customer_email, 'payment-failed-urgent', {
      updatePaymentUrl: await createPortalLink(invoice.customer),
      daysUntilCancellation: 7,
    });
  } else if (attemptCount >= 3) {
    // Dernier avertissement
    await sendEmail(invoice.customer_email, 'payment-failed-final', {
      updatePaymentUrl: await createPortalLink(invoice.customer),
    });
  }
}

Configurez le calendrier de relance de Stripe dans Tableau de bord → Paramètres → Abonnements et emails → Gérer les paiements échoués. Nous utilisons 3 relances sur 14 jours avant l'annulation.

Le bug de devise sans décimale qui nous a coûté de l'argent

Cela mérite sa propre section car c'est un bug qui mordra tout le monde éventuellement. Stripe utilise les centimes (plus petite unité de devise) pour la plupart des devises. $29.00 devient 2900. Mais certaines devises n'ont pas de décimales.

Voici les devises sans décimale qui comptent :

Devise Code Exemple : équivalent « $29 » Ce que vous passez à Stripe
Yen japonais JPY ¥4 200 4200 (PAS 420000)
Won coréen KRW ₩38 000 38000 (PAS 3800000)
Dong vietnamien VND ₫700 000 700000
Peso chilien CLP $25 000 25000
Guaraní paraguayen PYG ₲200 000 200000

Voici la fonction utilitaire que nous utilisons partout :

const ZERO_DECIMAL_CURRENCIES = [
  'BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW',
  'MGA', 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF',
  'XOF', 'XPF',
];

function toStripeAmount(amount, currency) {
  const curr = currency.toUpperCase();
  if (ZERO_DECIMAL_CURRENCIES.includes(curr)) {
    return Math.round(amount); // Déjà dans la plus petite unité
  }
  return Math.round(amount * 100);
}

function fromStripeAmount(stripeAmount, currency) {
  const curr = currency.toUpperCase();
  if (ZERO_DECIMAL_CURRENCIES.includes(curr)) {
    return stripeAmount;
  }
  return stripeAmount / 100;
}

Utilisez cela partout. Dans votre création de paiement, dans vos gestionnaires de webhook, dans les affichages de votre tableau de bord. Partout. La seule fois où vous oubliez est le moment où vous facturez à quelqu'un 100 fois ce qu'il attendait.

Comparaison des quatre modèles

Aspect Abonnements échelonnés Place de marché Don récurrent Paiement ponctuel
Produit Stripe Plusieurs produits, plusieurs Prix par produit Un seul produit par type de service Un seul produit, tarification dynamique Un seul produit, Prix fixe
Mode de facturation subscription payment avec Connect subscription payment
Complexité des webhooks Élevée (événements de cycle de vie) Élevée (événements Connect) Moyenne Basse
Gestion des devises Matrice de tarification régionale Devise du prestataire Devise du donateur Devise unique
Support d'essai Oui, dépend de la région N/A N/A N/A
Prorata Oui, lors des mises à niveau N/A N/A N/A
Complexité du remboursement Calculs au prorata Inversion des frais de plateforme Remboursement complet simple Remboursement complet simple
Portail client Essentiel Non nécessaire Agréable à avoir Non nécessaire
Frais Stripe (2025) 2,9 % + 30¢ 2,9 % + 30¢ + 0,5 % Connect 2,9 % + 30¢ 2,9 % + 30¢

FAQ

Combien de Produits Stripe dois-je créer pour la tarification échelonnée ?

Un produit par tier. Donc si vous avez Gratuit, Basic, Pro, et Premium, c'est quatre produits. Chaque produit a alors plusieurs Prix - un par devise et intervalle de facturation. Un tier Pro avec facturation mensuelle et annuelle sur 10 devises signifie 20 objets Prix sur ce produit unique. Cela semble beaucoup, mais Stripe le gère bien et cela garde votre catalogue organisé.

Puis-je utiliser Stripe Checkout pour les abonnements avec tarification régionale ?

Oui, mais vous devez déterminer la région du client avant de créer la session de paiement pour pouvoir passer le correct ID de Prix. Nous utilisons la géolocalisation IP (via les en-têtes Cloudflare) pour présélectionner la devise, puis permettons au client de confirmer ou de la changer. Ne vous fiez pas à la devise automatique de Checkout - vous voulez contrôler quel Prix ils voient.

Quelle est la différence entre les comptes Stripe Connect Express et Custom ?

Les comptes Express permettent à Stripe de gérer l'intégration, la vérification d'identité et le tableau de bord pour vos prestataires. Les comptes Custom vous donnent le contrôle total mais vous obligent à construire tout cela vous-même. Pour la plupart des places de marché, Express est le bon choix. Nous n'avons jamais eu de cas où la perte de contrôle justifiait le coût d'ingénierie des comptes Custom. Les comptes Express gèrent également les déclarations fiscales (1099 aux États-Unis) automatiquement, ce qui est un énorme gain de conformité.

Comment gérer les paiements d'abonnement échoués sans perdre les clients ?

Combinez trois choses : les Relances Intelligentes de Stripe (activées dans le Tableau de bord), les emails de dunning personnalisés déclenchés par les webhooks invoice.payment_failed, et une période de grâce avant l'annulation. Nous donnons 14 jours sur 3 tentatives de relance. Le premier email est amical (« hey, votre carte a peut-être expiré »), le deuxième est urgent, et le troisième est un dernier avertissement. Incluez un lien direct au Portail Client où ils peuvent mettre à jour leur mode de paiement. Cela seul récupère environ 30-40 % des paiements échoués.

Ai-je besoin de points de terminaison webhook séparés pour Stripe Connect ?

Oui. Les événements de plateforme et les événements de compte Connect utilisent des secrets webhook différents et des structures d'événement différentes. Les événements Connect incluent un champ account identifiant le compte connecté auquel l'événement se rapporte. Enregistrez deux points de terminaison dans votre Tableau de bord Stripe : un pour les événements de plateforme, un pour les événements Connect. Cette séparation rend également le débogage beaucoup plus facile.

Que sont les devises sans décimale et pourquoi dois-je m'en préoccuper ?

Les devises sans décimale comme JPY (Yen japonais) et KRW (Won coréen) n'utilisent pas d'unités fractionnaires. Quand Stripe dit « montant dans la plus petite unité de devise », pour USD c'est les centimes (2900 = $29.00), mais pour JPY c'est le yen (4200 = ¥4 200). Si vous multipliez par 100 comme vous le faites pour USD, vous facturez ¥420 000 au lieu de ¥4 200. Utilisez toujours une fonction d'aide qui vérifie la devise avant de convertir. Stripe maintient la liste officielle des devises sans décimale dans sa documentation.

Dois-je utiliser le Portail Client de Stripe Billing ou en construire un personnalisé ?

Utilisez le Portail Client pour la gestion des abonnements sauf si vous avez des exigences d'interface utilisateur très spécifiques. Il gère les changements de plan, les annulations, les mises à jour de mode de paiement, et l'historique des factures immédiatement. Vous pouvez personnaliser la marque et configurer les actions autorisées. Construire votre propre portail signifie gérer les calculs de prorata, la tokenisation des modes de paiement, et les flux SCA/3D Secure vous-même. Le portail est gratuit - c'est inclus dans vos frais d'abonnement Stripe.

Comment tester la tarification régionale et la gestion des devises en local ?

Le mode test de Stripe supporte toutes les devises. Créez des Prix de test dans chaque devise que vous prévoyez de supporter, puis utilisez Stripe CLI pour transférer les webhooks vers votre serveur local : stripe listen --forward-to localhost:3000/webhooks/stripe. Pour tester spécifiquement les devises sans décimale, créez un Prix JPY et vérifiez les montants dans vos journaux de gestionnaire de webhook avant de passer en direct. Nous maintenons également une suite de tests qui exécute toStripeAmount et fromStripeAmount contre chaque devise supportée - elle a attrapé des problèmes plus d'une fois.

Si vous créez un produit basé sur l'abonnement et avez besoin d'aide avec l'architecture de facturation, ou si vous intégrez Stripe avec une configuration CMS headless, contactez-nous. Nous avons construit ces modèles sur plusieurs projets CMS headless et pouvons vous aider à éviter les erreurs coûteuses. Consultez notre page de tarification pour les modèles d'engagement - nous effectuons des builds basés sur des projets et du conseil en cours.