> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Mettre en place un flux Stripe Checkout

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Créer un flux Stripe Checkout" description="Confiez à Devin une spécification de flux de paiement avec vos clés sandbox Stripe et obtenez un flux de paiement fonctionnel — page de tarification, session de paiement, gestionnaire de webhook et page de confirmation — vérifié dans le navigateur." prompt="Implémente un flux Stripe Checkout pour notre application SaaS. Page de tarification sur /pricing avec trois offres : Starter 19 $ / mois (5 projets, 10 Go, support par e‑mail), Pro 49 $ / mois (projets illimités, 100 Go, support prioritaire), Team 99 $ / mois (Pro + gestion d’équipe, SSO, journal d’audit). Chaque carte a un bouton « Subscribe » qui crée une session Stripe Checkout via POST /api/checkout/sessions. Le webhook sur /api/webhooks/stripe gère checkout.session.completed — mets à jour le plan de l’utilisateur et subscription_id dans la base de données, vérifie la signature avec STRIPE_WEBHOOK_SECRET. La page de réussite sur /checkout/success affiche le nom du plan, le montant et un bouton « Go to Dashboard ». Avant d’écrire du code, présente ton plan pour validation. Utilise notre application Next.js, Prisma ORM, et suis les patterns dans src/pages/settings/billing.tsx. STRIPE_SECRET_KEY et STRIPE_WEBHOOK_SECRET proviennent des variables d’environnement. Écris des tests pour la vérification du webhook, la création de session et la logique de mise à jour du plan. Lance le serveur de développement et vérifie l’ensemble du flux dans le navigateur avec la carte de test Stripe 4242 4242 4242 4242. N’ouvre pas de PR tant que tout ne fonctionne pas de bout en bout." category="Développement de fonctionnalités" features="" />

<div className="uc-detail-wrapper">
  <Tip>Vous ne souhaitez pas effectuer cette configuration manuellement ? Collez un lien vers cette page dans une session Devin et demandez-lui de tout configurer pour vous.</Tip>

  <Steps>
    <Step title="(Facultatif) Définir la portée de la base de code avec Ask Devin">
      Si vous ne savez pas comment votre application gère les paiements à l'heure actuelle — ni à quels fichiers et patterns vous référer dans votre spécification — utilisez [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) pour commencer votre investigation :

      <PromptBlock agent="ada">
        ```txt Définir le périmètre de l'implémentation du checkout theme={null}
        Comment notre application gère-t-elle actuellement la facturation ? Indique-moi :
        1. Où les offres/abonnements des utilisateurs sont stockés dans la base de données
        2. Tous les fichiers d'intégration Stripe existants ou routes d'API
        3. Comment les autres pages liées au paiement sont structurées (par ex. paramètres/facturation)
        4. Quel ORM nous utilisons et comment les migrations sont généralement créées
        ```
      </PromptBlock>

      Utilisez les réponses pour compléter votre spécification — faites référence à des fichiers, noms de tables et patterns précis afin que Devin construise quelque chose qui s'intègre naturellement à votre base de code. Vous pouvez aussi démarrer une session Devin directement depuis Ask Devin, et celle-ci conservera tout ce qu'il a appris comme contexte.
    </Step>

    <Step title="Ajouter les clés de test Stripe">
      Devin a besoin de clés Stripe en **mode test** pour créer des sessions de paiement et vérifier le gestionnaire de webhook. Utilisez toujours des identifiants d'environnement de test (sandbox) — ne donnez jamais à Devin de clés Stripe de production.

      La façon la plus simple de procéder est de les stocker en tant que [secrets d'organisation](/fr/product-guides/secrets) avant de démarrer la session :

      1. Allez dans **Settings > Secrets** et ajoutez :
         * `STRIPE_SECRET_KEY` — votre clé secrète en mode test depuis le [Stripe Dashboard](https://dashboard.stripe.com/test/apikeys)
         * `STRIPE_WEBHOOK_SECRET` — le secret de signature de votre [point de terminaison webhook](https://dashboard.stripe.com/test/webhooks)
      2. Devin y accède sous forme de variables d'environnement, de sorte qu'elles ne se retrouvent jamais en dur dans votre code source.

      <Note>Les secrets d'organisation doivent être ajoutés **avant** de démarrer la session — ils sont injectés au démarrage de la session. Vous pouvez aussi fournir des secrets pendant la session via le chat, et Devin vous demandera de manière proactive tous les identifiants dont il a besoin lorsqu'il rencontre des variables d'environnement manquantes.</Note>
    </Step>

    <Step title="Transmettez les spécifications de votre checkout">
      Collez votre spécification — à partir d'un PRD, d'un ticket Linear ou d'un message Slack détaillé — directement dans Devin. Une bonne spécification de checkout couvre les paliers tarifaires, le flux de paiement et ce qui se passe après un paiement réussi. Plus c'est structuré, mieux c'est.

      <PromptBlock>
        ```txt Implémenter le flux de paiement Stripe theme={null}
        Implémenter un flux de paiement Stripe pour notre application SaaS :

        ## Page de tarification
        - Nouvelle route à /pricing avec trois cartes de palier :
          - Starter : 19 $/mois — 5 projets, 10 Go de stockage, support par e-mail
          - Pro : 49 $/mois — projets illimités, 100 Go de stockage, support prioritaire
          - Team : 99 $/mois — tout ce qui est dans Pro + gestion d'équipe, SSO, journal d'audit
        - Chaque carte a un bouton "Subscribe" qui lance le checkout

        ## Checkout
        - POST /api/checkout/sessions — crée une session Stripe Checkout
          avec l'ID de prix sélectionné, l'e-mail du client et les URL de succès/annulation
        - Rediriger l'utilisateur vers la page de checkout hébergée par Stripe
        - En cas de succès, rediriger vers /checkout/success?session_id={CHECKOUT_SESSION_ID}

        ## Webhook
        - POST /api/webhooks/stripe — reçoit les événements Stripe
        - Gérer checkout.session.completed : mettre à jour le plan de l'utilisateur et
          subscription_id dans la base de données
        - Vérifier la signature du webhook en utilisant STRIPE_WEBHOOK_SECRET

        ## Page de succès
        - /checkout/success — récupérer les détails de la session depuis Stripe,
          afficher le nom du plan, le montant et un bouton "Go to Dashboard"

        ## Planification
        - Avant d'écrire la moindre ligne de code, esquissez votre plan d'implémentation et partagez-le
          avec moi pour validation. Listez les fichiers que vous créerez ou modifierez,
          les changements de base de données et l'ordre d'implémentation.

        ## Notes techniques
        - Suivre les patterns dans src/pages/settings/billing.tsx pour l'UI
        - Utiliser Prisma : ajouter une table subscriptions (id, user_id, stripe_subscription_id,
          plan, status, current_period_end)
        - STRIPE_SECRET_KEY et STRIPE_WEBHOOK_SECRET sont disponibles en variables d'environnement

        ## Tests & vérification
        - Écrire des tests pour la vérification de la signature du webhook, la création de session,
          et la logique de mise à jour du plan
        - Après l'implémentation, démarrer le serveur de développement local et vérifier
          l'ensemble du flux dans le navigateur : naviguer vers /pricing, cliquer sur S'abonner,
          effectuer un paiement test avec la carte de test de Stripe (4242 4242 4242 4242),
          confirmer que la page de succès s'affiche, et vérifier que la base de données a été mise à jour
        - Ne pas ouvrir de PR avant d'avoir confirmé que tout fonctionne de bout en bout
        ```
      </PromptBlock>

      Une bonne spécification pour Devin comprend trois éléments : **quoi** construire (niveaux de tarification, flux de paiement, gestionnaire de webhook), **où** cela se trouve (routes, tables, fichiers), et **comment** cela s'intègre (patterns existants à suivre). Vous n'avez pas besoin de spécifier chaque détail d'implémentation — Devin explore votre base de code pour combler les lacunes.
    </Step>

    <Step title="Devin builds and verifies in the browser">
      Devin lit votre spécification, explore la base de code pour trouver des patterns correspondants, puis implémente sur l'ensemble de la pile. Avant d'ouvrir une PR, il exécute votre application localement et ouvre son [navigateur intégré](/fr/work-with-devin/devin-session-tools) pour vérifier que le flux de paiement fonctionne de bout en bout.

      Voici à quoi cela ressemble pour l'exemple de paiement Stripe :

      1. **Crée la migration** — Ajoute la table `subscriptions` avec des colonnes pour `user_id`, `stripe_subscription_id`, `plan`, `status`, et `current_period_end`
      2. **Construit la page de tarification** — Crée les cartes de tarification à trois niveaux sur `/pricing`, chacune avec un bouton « S'abonner » qui envoie une requête à l'API de paiement
      3. **Implémente la création de session de paiement** — Construit `POST /api/checkout/sessions` qui crée une session Stripe Checkout avec le bon identifiant de prix, l'e-mail du client et les URLs de redirection
      4. **Ajoute le gestionnaire de webhook** — Implémente `POST /api/webhooks/stripe` avec la vérification de signature, la gestion de l'événement `checkout.session.completed`, et les mises à jour de la base de données
      5. **Construit la page de succès** — Crée `/checkout/success` qui récupère la session Stripe, affiche le nom du plan, le montant facturé, et un lien « Aller au tableau de bord »
      6. **Écrit les tests** — Tests pour la vérification de la signature du webhook (valide, invalide, manquante), la création de session de paiement, et la logique de mise à jour du plan dans la base de données
      7. **Ouvre le navigateur** — Démarre le serveur de développement, navigue vers `/pricing`, clique sur « S'abonner » pour le niveau Pro, vérifie que la redirection Stripe Checkout fonctionne, et s'assure que la page de succès s'affiche correctement après un paiement test
      8. **Ouvre une PR** — Livre toutes les modifications avec un résumé de ce qui a été implémenté et comment cela a été vérifié

      L'étape de vérification dans le navigateur détecte des problèmes que les tests unitaires manquent — une carte de tarification qui ne déclenche pas le paiement, une URL de redirection qui renvoie une erreur 404, ou une page de succès qui ne parvient pas à charger les détails de la session. Si vous avez défini un [skill de test local](/fr/product-guides/skills), Devin suit ces étapes automatiquement pour chaque fonctionnalité qu'il construit.
    </Step>

    <Step title="Iterate from the PR">
      Une fois la PR ouverte, envoyez des invites de suivi dans la même session pour étendre ou ajuster le flux de paiement.

      <PromptBlock>
        ```txt Ajouter la gestion des abonnements theme={null}
        Ajouter une section « Gérer l'abonnement » à /settings/billing qui affiche le
        plan actuel, la prochaine date de facturation, et un bouton « Annuler l'abonnement ».
        Utiliser le portail client Stripe pour l'annulation — créer une session de portail
        et rediriger l'utilisateur.
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Ajouter le basculement vers la tarification annuelle theme={null}
        Ajouter un basculement mensuel/annuel sur la page de tarification. Les plans annuels bénéficient d'une remise de 20 %.
        Afficher le prix mensuel avec une note « facturé annuellement » et un
        badge « Économisez 20 % » sur chaque carte lorsque l'option annuelle est sélectionnée.
        ```
      </PromptBlock>
    </Step>

    <Step title="Review the PR with Devin Review">
      Une fois que Devin ouvre la PR, utilisez [Devin Review](https://app.devin.ai/review?utm_source=docs\&utm_medium=use-case-gallery) pour examiner les modifications. Devin Review dispose du contexte complet de votre base de code et peut détecter des bugs, des problèmes de sécurité et des incohérences de style dans le diff. Vous pouvez poser des questions de suivi dans le chat de révision — par exemple, "Le gestionnaire de webhook valide-t-il le type d'événement avant de le traiter ?" — et Devin répondra en se basant sur le code réel.
    </Step>
  </Steps>
</div>
