# Intégrez les abonnements à Elements Créez et gérez des abonnements pour accepter des paiements récurrents avec Elements. Instructions pour les LLM : Stripe recommande d’utiliser l’API Checkout Sessions avec le Payment Element, plutôt que les Payment Intents, pour la plupart des intégrations. Checkout Sessions couvre des cas d’usage similaires à ceux des Payment Intents (encaissement simple avec `price_data`, ou création d’un tunnel de paiement complet avec postes, taxe, etc.). Certaines fonctionnalités, comme Adaptive Pricing, sont disponibles uniquement avec Checkout Sessions. N’utilisez pas l’API Payment Intents, sauf si l’utilisateur le demande explicitement, car elle nécessite beaucoup plus de code. Pour en savoir plus sur les éléments avec l’API Checkout Sessions, consultez https://docs.stripe.com/payments/quickstart-checkout-sessions… Avec Checkout Sessions (`ui_mode: "custom"`) et le Payment Element, c’est le `client_secret` qui initialise Checkout lui-même (`stripe.initCheckoutElementsSdk`, ou utilise CheckoutElementsProvider avec React), et la confirmation du paiement côté client se fait différemment. Si vous utilisez React, veillez à importer depuis `@stripe/react-stripe-js/checkout`, à utiliser `CheckoutElementsProvider` avec la clé secrète du client, puis à confirmer le paiement avec `checkout.confirm`. Si vous utilisez HTML, veillez à utiliser `checkout = stripe.initCheckoutElements({clientSecret: promise}) ; checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement() ; paymentElement.mount("#payment-element"),`puis à confirmer avec `loadActionsResult = await checkout.loadActions() ; actions = loadActionsResult.actions; error = await actions.confirm() ;`. # API Checkout Sessions > This is a API Checkout Sessions for when platform is web and ui is embedded-components. View the full page at https://docs.stripe.com/payments/advanced/build-subscriptions?platform=web&ui=embedded-components. #### Effort d’intégration Complexity: 3/5 #### Type d’intégration Combinez des composants d’interface utilisateur dans un tunnel de paiement personnalisé #### Personnalisation de l’interface utilisateur Personnalisation au niveau CSS avec l’[API Appearance](https://docs.stripe.com/elements/appearance-api.md) [Essayer](https://checkout.stripe.dev/) Créez un formulaire de paiement personnalisé en utilisant les composants [Stripe Elements](https://docs.stripe.com/payments/elements.md) et [l’API Checkout Sessions](https://docs.stripe.com/api/checkout/sessions.md) pour vendre des *abonnements* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) à prix fixe. Découvrez comment cette intégration se [compare aux autres types](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability) d’intégration de Stripe. L’API Checkout Sessions fournit une prise en charge intégrée pour le calcul des taxes, les remises, les frais d’expédition et la conversion des devises, ce qui réduit la quantité de code personnalisé que vous devez écrire. Il s’agit de l’approche recommandée pour la plupart des intégrations. Découvrez [quand utiliser Checkout Sessions plutôt que PaymentIntents](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Si vous ne souhaitez pas créer un formulaire de paiement personnalisé, vous pouvez intégrer la version hébergée de Checkout. Pour une version immersive de ce guide d’intégration de bout en bout, consultez le [guide de démarrage](https://docs.stripe.com/billing/quickstart.md) Billing. Si vous n’êtes pas prêt à coder une intégration, vous pouvez configurer des abonnements de base [manuellement dans le Dashboard](https://docs.stripe.com/no-code/subscriptions.md). Vous pouvez également utiliser [Payment Links](https://docs.stripe.com/payment-links.md) pour configurer des abonnements sans écrire la moindre ligne de code. Apprenez-en plus sur [la conception d’une intégration](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) pour comprendre les décisions à prendre et les ressources dont vous aurez besoin. ## Ce que vous allez créer Ce guide vous explique comment : - Modélisez votre entreprise en créant un catalogue de produits. - Créez un processus d’inscription qui génère automatiquement un client. - Créer des abonnements et collecter les informations de paiement de vos clients. - Tester et surveiller l’état des paiements et de l’abonnement. - Permettre aux clients de modifier leur offre ou de résilier l’abonnement. ### Définitions des objets API | Ressource | Définition | | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Compte configuré en tant que client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Représente un client dans l’API Accounts v2 qui souscrit un abonnement. Configurez un objet `Account` en tant que client et associez-le à un abonnement afin d’effectuer et de suivre des paiements récurrents, ainsi que de gérer les produits auxquels il est abonné. Pour plus d’informations, consultez le [guide d’utilisation des Accounts en tant que clients](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md). | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client dans l’API Customers qui souscrit un abonnement. Utilisez l’objet `Customer` associé à un abonnement pour effectuer et suivre des paiements récurrents, ainsi que pour gérer les produits auxquels il est abonné. | | [Entitlement](https://docs.stripe.com/api/entitlements/active-entitlement.md) | Représente l’accès d’un client à une fonctionnalité incluse dans un produit de service auquel il est abonné. Lorsque vous créez un abonnement représentant l’achat récurrent d’un produit par un client, un droit d’accès actif est automatiquement créé pour chaque fonctionnalité associée à ce produit. Lorsqu’un client accède à vos services, utilisez ses droits d’accès actifs pour activer les fonctionnalités incluses dans son abonnement. | | [Feature](https://docs.stripe.com/api/entitlements/feature.md) | Représente une fonctionnalité à laquelle vos clients peuvent accéder lorsqu’ils s’abonnent à un produit de service. Vous pouvez inclure des fonctionnalités dans un produit en créant des objets ProductFeatures. | | [Invoice](https://docs.stripe.com/api/invoices.md) | Relevé des montants dus par un client et qui suit les états des paiements, de l’ébauche initiale au paiement ou à la finalisation. Les abonnements génèrent automatiquement des factures. | | [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) | Un moyen de créer des tunnels de paiement dynamiques. Un PaymentIntent suit le cycle de vie du tunnel de paiement d’un client et déclenche des étapes d’authentification supplémentaires lorsque des mandats réglementaires, des règles Radar personnalisées de lutte contre la fraude, ou des moyens de paiement avec redirection l’exigent. Les objets Invoice créent automatiquement des PaymentIntents. | | [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) | Les moyens de paiement d’un client qu’il utilise pour payer vos produits. Par exemple, vous pouvez enregistrer une carte bancaire sur un objet `Account` configuré pour le client ou sur un objet `Customer`, puis l’utiliser pour effectuer des paiements récurrents pour ce client. Généralement utilisé avec les API Payment Intents ou Setup Intents. | | [Price](https://docs.stripe.com/api/prices.md) | Définit le tarif unitaire, la devise et le cycle de facturation d’un produit. | | [Product](https://docs.stripe.com/api/products.md) | Un bien ou un service que votre entreprise vend. Un produit de service peut comporter une ou plusieurs fonctionnalités. | | [ProductFeature](https://docs.stripe.com/api/product-feature.md) | Représente l’inclusion d’une fonctionnalité unique dans un produit unique. Chaque produit est associé à un objet ProductFeature pour chaque fonctionnalité qu’il inclut, et chaque fonctionnalité est associée à un objet ProductFeature pour chaque produit qui l’inclut. | | [Subscription](https://docs.stripe.com/api/subscriptions.md) | Représente l’achat récurrent et programmé d’un produit par un client. L’abonnement permet d’encaisser des paiements et de fournir des livraisons répétées ou un accès continu à un produit. | Voici un exemple de la manière dont les produits, les fonctionnalités et les droits d’accès fonctionnent ensemble. Imaginons que vous créez un service récurrent proposant deux niveaux : un produit standard avec des fonctionnalités de base et un produit Advanced qui ajoute des fonctionnalités étendues. 1. Vous créez deux fonctionnalités : `basic_features` et `extended_features`. 1. Vous créez deux produits : `standard_product` et `advanced_product`. 1. Pour le produit standard, vous créez un objet ProductFeature qui associe `basic_features` à `standard_product`. 1. Pour le produit avancé, vous créez deux objets ProductFeature : un qui associe `basic_features` à `advanced_product` et un qui associe `extended_features` à `advanced_product`. Un client, `first_customer`, s’abonne au produit standard. Lorsque vous créez l’abonnement, Stripe crée automatiquement un objet Entitlement qui associe `first_customer` à `basic_features`. Un autre client, `second_customer`, s’abonne au produit avancé. Lorsque vous créez l’objet Subscription correspondant, Stripe crée automatiquement deux objets Entitlement : un qui associe `second_customer` à `basic_features`, et un qui associe `second_customer` à `extended_features`. Pour savoir quelles fonctionnalités vous devez fournir à un client, [récupérez ses droits d’accès actifs ou écoutez l’événement Active Entitlement Summary](https://docs.stripe.com/billing/entitlements.md#entitlements). Il n’est pas nécessaire de récupérer ses abonnements, produits et fonctionnalités. ## Configurer Stripe Installez le client Stripe de votre choix : #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` Installez ensuite l’interface CLI Stripe. L’interface CLI permet de tester les webhooks et vous pouvez l’utiliser pour effectuer des appels à l’API vers Stripe. Ce guide explique comment utiliser l’interface CLI pour configurer un modèle de tarification dans une section ultérieure. Pour davantage d’options d’installation, consultez la page consacrée à l’[interface de ligne de commande Stripe](https://docs.stripe.com/stripe-cli.md). ## Créer le modèle tarifaire [Stripe CLI ou Dashboard] Les [modèles de tarification récurrents](https://docs.stripe.com/products-prices/pricing-models.md) représentent les produits ou services que vous vendez, leur coût, la devise que vous acceptez pour les paiements et la période de service pour les abonnements. Pour élaborer le modèle de tarification, créez des [produits](https://docs.stripe.com/api/products.md) (ce que vous vendez) et des [prix](https://docs.stripe.com/api/prices.md) (combien et à quelle fréquence facturer vos produits). Cet exemple utilise une tarification forfaitaire avec deux options de niveau de service différentes : basique et premium. Pour chaque option de niveau de service, vous devez créer un produit et un prix récurrent. Pour ajouter des frais uniques, tels que des frais d’installation, créez un troisième produit avec un prix unique. Chaque produit est facturé à intervalles mensuels. Le prix du produit basique est de 5 USD. Le prix du produit premium est de 15 USD. Voir le[ guide des tarifs forfaitaires ](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md)pour un exemple à trois niveaux. #### Dashboard Accédez à la page [Ajouter un produit](https://dashboard.stripe.com/test/products/create) et créez deux produits. Ajoutez un tarif pour chaque produit, avec une période de facturation mensuelle récurrente : - Produit Premium : service Premium avec fonctionnalités supplémentaires - Prix : Appuyez sur **Payer 15 USD**. - Produit de base : service de base avec fonctionnalités minimales - Prix : Forfaitaire | 5 USD Après avoir créé vos tarifs, enregistrez les ID de tarif de manière à pouvoir les utiliser dans d’autres étapes. Les ID de tarif se présentent sous la forme suivante : `price_G0FvDp6vZvdwRZ`. Lorsque vous le souhaitez, cliquez sur le bouton **Copier en mode production** en haut à droite de la page pour dupliquer votre produit de l’[environnement de test en mode production](https://docs.stripe.com/keys.md#test-live-modes). #### API Vous pouvez utiliser l’API pour créer les[ produits](https://docs.stripe.com/api/products.md) et les[ prix](https://docs.stripe.com/api/prices.md). Créez le produit premium : ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Premium Service" \ -d "description=Premium service with extra features" ``` Créez le produit de base : ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Basic Service" \ -d "description=Basic service with minimum features" ``` Enregistrez l’ID de chaque produit. Les ID de produit se présentent sous la forme suivante : ```json { "id": "prod_H94k5odtwJXMtQ", "object": "product", "active": true, "attributes": [ ], "created": 1587577341, "description": "Premium service with extra features", "images": [ ], "livemode": false, "metadata": { }, "name": "Billing Guide: Premium Service", "statement_descriptor": null, "type": "service", "unit_label": null, "updated": 1587577341 } ``` Utilisez les ID de produit afin de créer un tarif pour chaque produit. La valeur du champ [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) est exprimé en centimes, donc `1500` = 15 USD, par exemple. Créer le prix premium : ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{PREMIUM_PRODUCT_ID}} \ -d unit_amount=1500 \ -d currency=usd \ -d "recurring[interval]=month" ``` Créer le prix basique : ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{BASIC_PRODUCT_ID}} \ -d unit_amount=500 \ -d currency=usd \ -d "recurring[interval]=month" ``` Enregistrez l’ID de chaque tarif de manière à pouvoir l’utiliser par la suite. Les ID de tarif se présentent sous la forme suivante : ```json { "id": "price_HGd7M3DV3IMXkC", "object": "price", "product": "prod_HGd6W1VUqqXGvr", "type": "recurring", "currency": "usd", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "active": true, "billing_scheme": "per_unit", "created": 1589319695, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "unit_amount": 1500, "unit_amount_decimal": "1500", "tiers": null, "tiers_mode": null, "transform_quantity": null } ``` ## Créer l’objet Customer [Client et serveur] Stripe a besoin d’un client pour chaque abonnement. Dans le front-end de votre application, collectez les informations nécessaires auprès de vos clients et transmettez-les au back-end. Si vous avez besoin de collecter des données d’adresse, Address Element vous permet de collecter une adresse de livraison ou de facturation pour vos clients. Pour plus d’informations sur l’Address Element, voir la page [Address Element](https://docs.stripe.com/elements/address-element.md). ```html
``` ```javascript const emailInput = document.querySelector('#email'); fetch('/create-customer', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: emailInput.value, }), }).then(r => r.json()); ``` Sur le serveur, créez un objet pour représenter le client. Il peut s’agir d’un objet `Account` côté client ou d’un objet `Customer`. Enregistrez l’ID de l’objet pour l’utiliser dans la Checkout Session. > #### Utiliser l’API Accounts v2 pour représenter les clients > > L’API Accounts v2 est généralement disponible pour les utilisateurs de Connect et en aperçu public pour les autres utilisateurs de Stripe. Si vous avez accès à l’aperçu Accounts v2, vous devez [spécifier une version d’aperçu](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) dans votre code. > > Pour demander l’accès à l’aperçu Accounts v2, > > Dans la plupart des cas d’usage, nous vous recommandons de [modéliser vos clients en tant qu’objets Account configurés par le client](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), plutôt que d’utiliser des objets [Customer](https://docs.stripe.com/api/customers.md). #### Accounts v2 ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "identity": { "individual": { "given_name": "Jenny Rosen", "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } }, "configuration": { "customer": { "capabilities": { "automatic_indirect_tax": { "requested": true } }, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } } }, "include": [ "configuration.customer", "identity" ] }' ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ --data-urlencode "email=jenny.rosen@example.com" \ -d "name=Jenny Rosen" \ -d "shipping[address][city]=San Francisco" \ -d "shipping[address][country]=US" \ -d "shipping[address][line1]=123 Main Street" \ -d "shipping[address][postal_code]=9460" \ -d "shipping[address][state]=CA" \ -d "shipping[name]=Jenny Rosen" \ -d "address[city]=San Francisco" \ -d "address[country]=US" \ -d "address[line1]=123 Main Street" \ -d "address[postal_code]=9460" \ -d "address[state]=CA" ``` ## Créer une session Checkout [Serveur] Côté back-end, définissez un endpoint qui [crée la session](https://docs.stripe.com/api/checkout/sessions/create.md) et que le front-end pourra appeler. Cette étape nécessite l’identifiant de prix de l’abonnement choisi par le client, transmis automatiquement par votre front-end. Si vous avez créé un prix unique lors de l’[étape 2](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-pricing-model), transmettez également l’identifiant de ce prix. Après avoir créé une session Checkout, veillez à renvoyer la [clé secrète du client](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) au client dans la réponse. > Vous pouvez utiliser [lookup_keys](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) pour récupérer les prix plutôt que les identifiants de prix. Consultez cet [exemple concret](https://github.com/stripe-samples/subscription-use-cases/tree/main/fixed-price-subscriptions) pour plus de détails. #### Accounts v2 #### Ruby ```ruby require 'stripe' require 'sinatra' # This test secret API key is a placeholder. Don't include personal details in requests with this key. # To see your test secret API key embedded in code samples, sign in to your Stripe account. # You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys. # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. Stripe.api_key = '<>' Stripe.api_version = '2026-04-22.dahlia' set :static, true set :port, 4242 YOUR_DOMAIN = 'http://localhost:3000' post '/create-checkout-session' do content_type 'application/json' session = Stripe::Checkout::Session.create({ui_mode: 'elements', # Provide the Account ID of the account you previously created customer_account: '{{CUSTOMER_ACCOUNT_ID}}', line_items: [{ # Provide the exact Price ID (for example, price_1234) of the product you want to sell price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}', }) { clientSecret: session.client_secret }.to_json end ``` #### Customers v1 #### Ruby ```ruby require 'stripe' require 'sinatra' # This test secret API key is a placeholder. Don't include personal details in requests with this key. # To see your test secret API key embedded in code samples, sign in to your Stripe account. # You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys. # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>', stripe_version: '2026-04-22.dahlia') set :static, true set :port, 4242 YOUR_DOMAIN = 'http://localhost:3000' post '/create-checkout-session' do content_type 'application/json' session = client.v1.checkout.sessions.create({ui_mode: 'elements', # Provide the customer ID of the customer you previously created customer: '{{CUSTOMER_ID}}', line_items: [{ # Provide the exact Price ID (for example, price_1234) of the product you want to sell price: '{{PRICE_ID}}', quantity: 1, }], mode: 'subscription', return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}', }) { clientSecret: session.client_secret }.to_json end ``` Depuis votre [Dashboard](https://dashboard.stripe.com/settings/payment_methods),activez les moyens de paiement que vous souhaitez accepter de vos clients. Checkout prend en charge [plusieurs moyens de paiement](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support). ## Initialiser Checkout [Client] #### HTML + JS Appelez [initCheckoutElementsSdk](https://docs.stripe.com/js/custom_checkout/init), en transmettant `clientSecret`. `initCheckoutElementsSdk` renvoie un objet [Checkout](https://docs.stripe.com/js/custom_checkout) contenant les données de la Session Checkout et les méthodes pour les mettre à jour. Lisez le `total` et les `lineItems` de [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session), et affichez-les dans votre interface utilisateur. Cela vous permet d’activer de nouvelles fonctionnalités avec un minimum de modifications de code. Par exemple, l’ajout de [prix manuels des devises](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) ne nécessite aucune modification de l’interface utilisateur si vous affichez le `total`. ```html
``` ```javascript const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const session = loadActionsResult.actions.getSession(); const checkoutContainer = document.getElementById('checkout-container'); checkoutContainer.append(JSON.stringify(session.lineItems, null, 2)); checkoutContainer.append(document.createElement('br')); checkoutContainer.append(`Total: ${session.total.total.amount}`); } ``` #### React Encapsulez votre application avec le composant [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider), en lui transmettant `clientSecret` et l’instance `stripe`. ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const App = () => { return ( ); }; export default App; ``` Accédez à l’objet [Checkout](https://docs.stripe.com/js/custom_checkout) dans votre composant de formulaire de paiement en utilisant le hook `useCheckoutElements()`. L’objet `Checkout` contient les données de la Checkout Session et les méthodes pour la mettre à jour. Lisez le `total` et les `lineItems` de l’objet `Checkout`, et affichez-les dans votre interface utilisateur. Cela vous permet d’activer des fonctionnalités avec un minimum de modifications de code. Par exemple, l’ajout de [prix manuels des devises](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) ne nécessite aucune modification de l’interface utilisateur si vous affichez le `total`. ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount}
); }; ``` ## Collecter les informations de paiement [Client] Collectez les informations de paiement de votre client à l’aide de [Payment Element](https://docs.stripe.com/payments/payment-element.md). Payment Element est un composant d’interface utilisateur préconfiguré qui simplifie la collecte des informations pour de nombreux moyens de paiement. Le Payment Element contient un iframe qui envoie les informations de paiement à Stripe de manière sécurisée via une connexion HTTPS. Évitez de placer le Payment Element dans un autre iframe, car certains moyens de paiement nécessitent une redirection vers une autre page pour la confirmation du paiement. Si vous choisissez d’utiliser un iframe et que vous souhaitez accepter Apple Pay ou Google Pay, l’attribut [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) de l’iframe doit être défini sur égal à `"payment *"`. Pour que votre intégration fonctionne, l’adresse de la page de paiement doit commencer par `https://` et non par `http://`. Vous pouvez tester votre intégration sans utiliser le protocole HTTPS, mais n’oubliez pas de l’[activer](https://docs.stripe.com/security/guide.md#tls) lorsque vous souhaitez commencer à accepter des paiements réels. #### HTML + JS Tout d’abord, créez un élément DOM de conteneur pour monter le composant [Payment Element](https://docs.stripe.com/payments/payment-element.md). Créez ensuite une instance du `Payment Element` à l’aide de [checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) et montez-la en appelant [element.mount](https://docs.stripe.com/js/element/mount) et en fournissant soit un sélecteur CSS, soit l’élément DOM du conteneur. ```html
``` ```javascript const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element'); ``` Consultez la [documentation Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) pour connaître les options prises en charge. Vous pouvez [personnaliser l’apparence](https://docs.stripe.com/payments/checkout/customization/appearance.md) de tous les Elements en transmettant [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) lors de l’initialisation de Checkout sur le front-end. #### React Montez le composant [Payment Element](https://docs.stripe.com/payments/payment-element.md) dans le [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ```jsx import React from 'react';import {PaymentElement, useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount} ); }; export default CheckoutForm; ``` Consultez la [documentation Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) pour connaître les options prises en charge. Vous pouvez [personnaliser l’apparence](https://docs.stripe.com/payments/checkout/customization/appearance.md) de tous les Elements en transmettant [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) au composant [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ## Envoyer le paiement [Côté client] #### HTML + JS Affichez un bouton **Payer** qui appelle [confirm](https://docs.stripe.com/js/custom_checkout/confirm) depuis l’instance `Checkout` pour soumettre le paiement. ```html
``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); checkout.on('change', (session) => { document.getElementById('pay-button').disabled = !session.canConfirm; }); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React Affichez un bouton **Payer** qui appelle [confirm](https://docs.stripe.com/js/custom_checkout/confirm) depuis [useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements) pour soumettre le paiement. ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckoutElements(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type !== "success") { return null; } const handleClick = () => { setLoading(true);checkoutState.checkout.confirm().then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## Écouter les webhooks [Serveur] Pour compléter l’intégration, vous devez traiter les webhooks** envoyés par Stripe. Ces événements se déclenchent lorsqu’un statut change dans Stripe, par exemple quand un abonnement génère une nouvelle facture. Dans votre application, configurez un gestionnaire HTTP pour accepter les requêtes POST contenant l’événement de webhook et vérifiez la signature de l’événement : #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/webhook' do # You can use webhooks to receive information about asynchronous payment events. # For more about our webhook events check out https://stripe.com/docs/webhooks. webhook_secret = ENV['STRIPE_WEBHOOK_SECRET'] payload = request.body.read if !webhook_secret.empty? # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil begin event = Stripe::Webhook.construct_event( payload, sig_header, webhook_secret ) rescue JSON::ParserError => e # Invalid payload status 400 return rescue Stripe::SignatureVerificationError => e # Invalid signature puts '⚠️ Webhook signature verification failed.' status 400 return end else data = JSON.parse(payload, symbolize_names: true) event = Stripe::Event.construct_from(data) end # Get the type of webhook event sent - used to check the status of PaymentIntents. event_type = event['type'] data = event['data'] data_object = data['object'] if event_type == 'invoice.paid' # Used to provision services after the trial has ended. # The status of the invoice will show up as paid. Store the status in your # database to reference when a user accesses your service to avoid hitting rate # limits. # puts data_object end if event_type == 'invoice.payment_failed' # If the payment fails or the customer doesn't have a valid payment method, # an invoice.payment_failed event is sent, the subscription becomes past_due. # Use this webhook to notify your user that their payment has # failed and to retrieve new card details. # puts data_object end if event_type == 'customer.subscription.deleted' # handle subscription canceled automatically based # upon your subscription settings. Or if the user cancels it. # puts data_object end content_type 'application/json' { status: 'success' }.to_json end ``` Pendant le développement, utilisez la Stripe CLI pour [observer les webhooks et les transmettre à votre formulaire d’inscription](https://docs.stripe.com/webhooks.md#test-webhook). Exécutez ensuite la commande suivante dans un nouveau terminal pendant que votre application de développement est en cours d’exécution : #### curl ```bash stripe listen --forward-to localhost:4242/webhook ``` En production, configurez une URL d’endpoint webhook dans le Dashboard, ou utilisez l’[API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md). Vous devez écouter quelques événements pour effectuer les étapes restantes de ce guide. Consultez les[Événements d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) pour plus de détails sur les webhooks spécifiques aux abonnements. ## Fournir l'accès à votre service [Client et serveur] Maintenant que l’abonnement est actif, donnez à votre utilisateur l’accès à votre service. Pour ce faire, écoutez les événements `customer.subscription.created`, `customer.subscription.updated`, et `customer.subscription.deleted`. Ces événements transmettent un objet d’abonnement qui contient un champ `status` indiquant si l’abonnement est actif, en retard ou annulé. Pour obtenir la liste complète des états, consultez le [cycle de vie de l’abonnement](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle). Dans votre gestionnaire de webhooks : 1. Vérifiez l’état de l’abonnement. S’il est `active`, cela signifie que l’utilisateur a payé pour votre produit. 1. Vérifiez le produit auquel le client s’est abonné et accordez-lui l’accès à votre service. Le fait de contrôler le produit plutôt que le tarif vous offre plus de flexibilité si vous devez modifier la tarification ou la période de facturation. 1. Sauvegardez les `product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer_account.id` ou le `customer.id` déjà stocké. Vérifiez ce dossier au moment de décider des fonctionnalités à activer pour l’utilisateur dans votre application. L’état d’un abonnement peut changer à tout moment pendant sa durée de vie, même si votre application n’effectue aucun appel direct à Stripe. Par exemple, un renouvellement peut échouer en raison d’une carte bancaire expirée, ce qui place l’abonnement en état de retard. Ou, si vous implémentez le [portail client](https://docs.stripe.com/customer-management.md), un utilisateur peut annuler son abonnement sans passer directement par votre application. Une implémentation correcte de votre gestionnaire permet de synchroniser le statut de votre application avec celui de Stripe. ## Annuler l'abonnement [Client et serveur] Il est courant de laisser aux clients la possibilité d’annuler leur abonnement. Cet exemple montre comment ajouter une option d’annulation sur la page des paramètres du compte. ![Exemple d'interface de résiliation d'un abonnement.](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png) Paramètres d’un compte ayant la possibilité d’annuler son abonnement ```javascript function cancelSubscription(subscriptionId) { return fetch('/cancel-subscription', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, }), }) .then(response => { return response.json(); }) .then(cancelSubscriptionResponse => { // Display to the user that the subscription has been canceled. }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` Votre application reçoit un événement `customer.subscription.deleted`. Après la résiliation de l’abonnement, mettez à jour votre base de données pour supprimer l’identifiant de l’abonnement Stripe que vous aviez précédemment stocké, et limitez l’accès à votre service. Lorsqu’un abonnement est annulé, vous ne pouvez pas le réactiver. À la place, collectez les informations de facturation mises à jour auprès de votre client, actualisez son moyen de paiement par défaut et créez un nouvel abonnement à partir de son dossier client existant. ## Tester votre intégration ### Tester les moyens de paiement Utilisez le tableau suivant pour tester différents scénarios et moyens de paiement. | Moyen de paiement | Scénario | Méthode de test | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Prélèvement automatique BECS | Le montant dû est réglé par prélèvement automatique BECS. | Remplissez le formulaire à l’aide du numéro de compte `900123456` et du BSB `000000`. La confirmation de la demande de PaymentIntent passe d’abord à l’état `processing`, puis à l’état `succeeded` trois minutes plus tard. | | Prélèvement automatique BECS | Le paiement de votre client échoue avec un code d’erreur `account_closed`. | Remplissez le formulaire à l’aide du numéro de compte `111111113` et du BSB `000000`. | | Carte bancaire | Le paiement par carte bancaire aboutit et ne nécessite pas d’authentification. | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro de carte `4242 4242 4242 4242` ainsi que la date d’expiration, le CVC et le code postal de votre choix. | | Carte bancaire | Le paiement par carte bancaire requiert une *authentification* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro de carte `4000 0025 0000 3155` ainsi que la date d’expiration, le CVC et le code postal de votre choix. | | Carte bancaire | La carte est refusée avec un code de refus de type `insufficient_funds`. | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro `4000 0000 0000 9995` ainsi que la date d’expiration, le CVC et le code postal de votre choix… | | Prélèvement automatique SEPA | Le montant dû est réglé par prélèvement automatique SEPA. | Remplissez le formulaire à l’aide du numéro de compte `AT321904300235473204`. Le PaymentIntent confirmé passe d’abord à l’état processing, puis à l’état succeeded trois minutes plus tard. | | Prélèvement automatique SEPA | L’état du PaymentIntent de votre client passe de `processing` à `requires_payment_method`. | Remplissez le formulaire à l’aide du numéro de compte `AT861904300235473202`. | ### Écouter des événements Configurez des webhooks pour écouter les événements de changement d’abonnement, tels que les mises à niveau et les annulations. Apprenez-en plus sur les [webhooks d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md). Vous pouvez visualiser les événements dans le [Dashboard](https://dashboard.stripe.com/test/events) ou via la[Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook). Pour plus d’informations, voir la section[tester votre intégration Billing](https://docs.stripe.com/billing/testing.md). ## Optional: Permettre à vos clients de modifier leurs offres [Client et serveur] Pour permettre à vos clients de modifier leur abonnement, collectez l’identifiant de prix de l’option choisie, puis envoyez-le depuis votre front-end vers un endpoint du back-end. L’identifiant de l’abonnement est également transmis, mais vous pouvez aussi le récupérer depuis votre base de données pour l’utilisateur connecté. ```javascript function updateSubscription(priceId, subscriptionId) { return fetch('/update-subscription', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, newPriceId: priceId, }), }) .then(response => { return response.json(); }) .then(response => { return response; }); } ``` Sur votre back-end, définissez l’endpoint que votre front-end appellera et transmettez les identifiants de l’abonnement et du nouveau prix. L’abonnement est maintenant Premium, à 15 USD par mois, au lieu de Basic à 5 USD par mois. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) updated_subscription = client.v1.subscriptions.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: data['newPriceId'] } ] ) updated_subscription.to_json end ``` Votre application reçoit un événement `customer.subscription.updated`. ## Optional: Prévisualiser un changement de tarif [Client et serveur] Lorsqu’un client modifie son abonnement, le montant facturé est souvent réajusté, c’est ce qu’on appelle la [proration](https://docs.stripe.com/billing/subscriptions/prorations.md). Utilisez l’endpoint [create preview invoice](https://docs.stripe.com/api/invoices/create_preview.md) pour générer et afficher la facture mise à jour à vos clients. Sur le front-end, transmettez les informations de l’aperçu de création de la facture à un endpoint du back-end. #### Accounts v2 ```javascript function createPreviewInvoice( customerAccountId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerAccountId: customerAccountId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` #### Customers v1 ```javascript function createPreviewInvoice( customerId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerId: customerId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Accounts v2 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.create_preview( customer_account: data['customerAccountId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` #### Customers v1 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) invoice = client.v1.invoices.create_preview( customer: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` ## Optional: Afficher le moyen de paiement du client [Client et serveur] L’affichage de la marque et des quatre derniers chiffres de la carte bancaire de votre client peut aider ce dernier à savoir quelle carte bancaire est débitée, ou encore s’il doit mettre à jour son moyen de paiement. Sur votre front-end, envoyez l’ID du moyen de paiement à un endpoint du back-end qui récupère les informations du moyen de paiement. ```javascript function retrieveCustomerPaymentMethod(paymentMethodId) { return fetch('/retrieve-customer-payment-method', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ paymentMethodId: paymentMethodId, }), }) .then((response) => { return response.json(); }) .then((response) => { return response; }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId']) payment_method.to_json end ``` Exemple de réponse : ```json { "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 8, "exp_year": 2021, "fingerprint": "Xt5EWLLDS7FJjR1c", "funding": "credit", "generated_from": null, "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1588010536, "customer": "cus_HAxB7dVQxhoKLh", "livemode": false, "metadata": {}, "type": "card" } ``` > Nous vous recommandons d’enregistrer le `paymentMethod.id` et les `last4` dans votre base de données, par exemple `paymentMethod.id` dans l’objet `stripeCustomerPaymentMethod` de votre collection ou table `users`. Vous pouvez également stocker, si nécessaire : `exp_month`, `exp_year`, `fingerprint`, `billing_details`. Cela permet de limiter le nombre d’appels effectués vers Stripe, d’optimiser les performances et d’éviter les risques de limite d’appels. ## Divulguer Stripe à vos clients Stripe recueille des informations sur les interactions des clients avec Elements afin de vous fournir des services, de prévenir la fraude et d’améliorer ses services. Cela inclut l’utilisation de cookies et d’adresses IP pour identifier les Elements qu’un client a vus au cours d’une même session Checkout. Vous êtes responsable de la divulgation et de l’obtention de tous les droits et consentements nécessaires pour que Stripe puisse utiliser les données à cette fin. Pour en savoir plus, visitez notre [Centre de confidentialité](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe). # API Payment Intents > This is a API Payment Intents for when platform is web and ui is elements. View the full page at https://docs.stripe.com/payments/advanced/build-subscriptions?platform=web&ui=elements. #### Effort d’intégration Complexity: 4/5 #### Type d’intégration Combinez des composants d’interface utilisateur dans un tunnel de paiement personnalisé #### Personnalisation de l’interface utilisateur Personnalisation au niveau CSS avec l’[API Appearance](https://docs.stripe.com/elements/appearance-api.md) Créez un formulaire de paiement personnalisé en utilisant les composants [Stripe Elements](https://docs.stripe.com/payments/elements.md) et [l’API Payment Intents](https://docs.stripe.com/api/payment_intents.md) pour vendre des *abonnements* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) à prix fixe. Découvrez comment cette intégration se [compare aux autres types](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability) d’intégration de Stripe. L’API Payment Intents est une API de bas niveau que vous pouvez utiliser pour construire votre propre flux de paiement, mais elle nécessite beaucoup plus de code et une maintenance continue. Nous recommandons d’utiliser [Payment Element avec Checkout Sessions](https://docs.stripe.com/payments/quickstart-checkout-sessions.md) pour la plupart des intégrations, car il couvre des flux de paiement similaires à ceux de Payment Intents. En savoir plus sur les cas [où il convient d’utiliser Checkout Sessions plutôt que Payment Intents](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Si vous ne souhaitez pas créer un formulaire de paiement personnalisé, vous pouvez intégrer la version hébergée de Checkout. Pour une version immersive de ce guide d’intégration de bout en bout, consultez le [guide de démarrage](https://docs.stripe.com/billing/quickstart.md) Billing. Si vous n’êtes pas prêt à coder une intégration, vous pouvez configurer des abonnements de base [manuellement dans le Dashboard](https://docs.stripe.com/no-code/subscriptions.md). Vous pouvez également utiliser [Payment Links](https://docs.stripe.com/payment-links.md) pour configurer des abonnements sans écrire la moindre ligne de code. Apprenez-en plus sur [la conception d’une intégration](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) pour comprendre les décisions à prendre et les ressources dont vous aurez besoin. ## Ce que vous allez créer Ce guide vous explique comment : - Créer un catalogue de produits. - Créez un processus d’inscription qui génère automatiquement un client. - Créer des abonnements et collecter les informations de paiement de vos clients. - Tester et surveiller l’état des paiements et de l’abonnement. - Permettre aux clients de modifier leur offre ou de résilier l’abonnement. - Apprenez à utiliser le [mode de facturation flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) pour accéder à un comportement de facturation amélioré et à des fonctionnalités supplémentaires. ## Comment développer avec Stripe Les[abonnements](https://docs.stripe.com/api/subscriptions.md) simplifient votre facturation en créant automatiquement pour vous des *factures* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) et des[PaymentIntents](https://docs.stripe.com/api/payment_intents.md). Pour créer et activer un abonnement, vous devez d’abord créer un *Produit* (Products represent what your business sells—whether that's a good or a service) pour définir ce que vous vendez, et un *Prix* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions), qui détermine le montant à débiter et la fréquence. Vous avez également besoin d’un objet `Account` côté client ou d’un objet `Customer` pour stocker les *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilisées pour effectuer chaque paiement récurrent. #### Accounts v2 Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/payments/advanced/build-subscriptions) #### Customer v1 Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/payments/advanced/build-subscriptions) ### Définitions des objets API | Ressource | Définition | | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Compte configuré en tant que client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Représente un client dans l’API Accounts v2 qui souscrit un abonnement. Configurez un objet `Account` en tant que client et associez-le à un abonnement afin d’effectuer et de suivre des paiements récurrents, ainsi que de gérer les produits auxquels il est abonné. Pour plus d’informations, consultez le [guide d’utilisation des Accounts en tant que clients](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md). | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client dans l’API Customers qui souscrit un abonnement. Utilisez l’objet `Customer` associé à un abonnement pour effectuer et suivre des paiements récurrents, ainsi que pour gérer les produits auxquels il est abonné. | | [Entitlement](https://docs.stripe.com/api/entitlements/active-entitlement.md) | Représente l’accès d’un client à une fonctionnalité incluse dans un produit de service auquel il est abonné. Lorsque vous créez un abonnement représentant l’achat récurrent d’un produit par un client, un droit d’accès actif est automatiquement créé pour chaque fonctionnalité associée à ce produit. Lorsqu’un client accède à vos services, utilisez ses droits d’accès actifs pour activer les fonctionnalités incluses dans son abonnement. | | [Feature](https://docs.stripe.com/api/entitlements/feature.md) | Représente une fonctionnalité à laquelle vos clients peuvent accéder lorsqu’ils s’abonnent à un produit de service. Vous pouvez inclure des fonctionnalités dans un produit en créant des objets ProductFeatures. | | [Invoice](https://docs.stripe.com/api/invoices.md) | Relevé des montants dus par un client et qui suit les états des paiements, de l’ébauche initiale au paiement ou à la finalisation. Les abonnements génèrent automatiquement des factures. | | [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) | Un moyen de créer des tunnels de paiement dynamiques. Un PaymentIntent suit le cycle de vie du tunnel de paiement d’un client et déclenche des étapes d’authentification supplémentaires lorsque des mandats réglementaires, des règles Radar personnalisées de lutte contre la fraude, ou des moyens de paiement avec redirection l’exigent. Les objets Invoice créent automatiquement des PaymentIntents. | | [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) | Les moyens de paiement d’un client qu’il utilise pour payer vos produits. Par exemple, vous pouvez enregistrer une carte bancaire sur un objet `Account` configuré pour le client ou sur un objet `Customer`, puis l’utiliser pour effectuer des paiements récurrents pour ce client. Généralement utilisé avec les API Payment Intents ou Setup Intents. | | [Price](https://docs.stripe.com/api/prices.md) | Définit le tarif unitaire, la devise et le cycle de facturation d’un produit. | | [Product](https://docs.stripe.com/api/products.md) | Un bien ou un service que votre entreprise vend. Un produit de service peut comporter une ou plusieurs fonctionnalités. | | [ProductFeature](https://docs.stripe.com/api/product-feature.md) | Représente l’inclusion d’une fonctionnalité unique dans un produit unique. Chaque produit est associé à un objet ProductFeature pour chaque fonctionnalité qu’il inclut, et chaque fonctionnalité est associée à un objet ProductFeature pour chaque produit qui l’inclut. | | [Subscription](https://docs.stripe.com/api/subscriptions.md) | Représente l’achat récurrent et programmé d’un produit par un client. L’abonnement permet d’encaisser des paiements et de fournir des livraisons répétées ou un accès continu à un produit. | Voici un exemple de la manière dont les produits, les fonctionnalités et les droits d’accès fonctionnent ensemble. Imaginons que vous créez un service récurrent proposant deux niveaux : un produit standard avec des fonctionnalités de base et un produit Advanced qui ajoute des fonctionnalités étendues. 1. Vous créez deux fonctionnalités : `basic_features` et `extended_features`. 1. Vous créez deux produits : `standard_product` et `advanced_product`. 1. Pour le produit standard, vous créez un objet ProductFeature qui associe `basic_features` à `standard_product`. 1. Pour le produit avancé, vous créez deux objets ProductFeature : un qui associe `basic_features` à `advanced_product` et un qui associe `extended_features` à `advanced_product`. Un client, `first_customer`, s’abonne au produit standard. Lorsque vous créez l’abonnement, Stripe crée automatiquement un objet Entitlement qui associe `first_customer` à `basic_features`. Un autre client, `second_customer`, s’abonne au produit avancé. Lorsque vous créez l’objet Subscription correspondant, Stripe crée automatiquement deux objets Entitlement : un qui associe `second_customer` à `basic_features`, et un qui associe `second_customer` à `extended_features`. Pour savoir quelles fonctionnalités vous devez fournir à un client, [récupérez ses droits d’accès actifs ou écoutez l’événement Active Entitlement Summary](https://docs.stripe.com/billing/entitlements.md#entitlements). Il n’est pas nécessaire de récupérer ses abonnements, produits et fonctionnalités. ## Configurer Stripe Installez le client Stripe de votre choix : #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` Installez ensuite la Stripe CLI. Elle vous permet de tester vos webhooks et d’effectuer des appels API vers Stripe. Dans une section suivante, ce guide vous montre comment utiliser la CLI pour mettre en place un modèle de tarification. Pour davantage d’options d’installation, consultez la page consacrée à l’[interface de ligne de commande Stripe](https://docs.stripe.com/stripe-cli.md). ## Créer le modèle tarifaire [Stripe CLI ou Dashboard] Les [modèles de tarification récurrents](https://docs.stripe.com/products-prices/pricing-models.md) représentent les produits ou services que vous vendez, leur coût, la devise que vous acceptez pour les paiements et la période de service pour les abonnements. Pour élaborer le modèle de tarification, créez des [produits](https://docs.stripe.com/api/products.md) (ce que vous vendez) et des [prix](https://docs.stripe.com/api/prices.md) (combien et à quelle fréquence facturer vos produits). Cet exemple utilise une tarification forfaitaire avec deux options de niveau de service différentes : basique et premium. Pour chaque option de niveau de service, vous devez créer un produit et un prix récurrent. Pour ajouter des frais uniques, tels que des frais d’installation, créez un troisième produit avec un prix unique. Chaque produit est facturé à intervalles mensuels. Le prix du produit basique est de 5 USD. Le prix du produit premium est de 15 USD. Voir le[ guide des tarifs forfaitaires ](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md)pour un exemple à trois niveaux. #### Dashboard Accédez à la page [Ajouter un produit](https://dashboard.stripe.com/test/products/create) et créez deux produits. Ajoutez un tarif pour chaque produit, avec une période de facturation mensuelle récurrente : - Produit Premium : service Premium avec fonctionnalités supplémentaires - Prix : Appuyez sur **Payer 15 USD**. - Produit de base : service de base avec fonctionnalités minimales - Prix : Forfaitaire | 5 USD Après avoir créé vos tarifs, enregistrez les ID de tarif de manière à pouvoir les utiliser dans d’autres étapes. Les ID de tarif se présentent sous la forme suivante : `price_G0FvDp6vZvdwRZ`. Lorsque vous le souhaitez, cliquez sur le bouton **Copier en mode production** en haut à droite de la page pour dupliquer votre produit de l’[environnement de test en mode production](https://docs.stripe.com/keys.md#test-live-modes). #### API Vous pouvez utiliser l’API pour créer les[ produits](https://docs.stripe.com/api/products.md) et les[ prix](https://docs.stripe.com/api/prices.md). Créez le produit premium : ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Premium Service" \ -d "description=Premium service with extra features" ``` Créez le produit de base : ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ --data-urlencode "name=Billing Guide: Basic Service" \ -d "description=Basic service with minimum features" ``` Enregistrez l’ID de chaque produit. Les ID de produit se présentent sous la forme suivante : ```json { "id": "prod_H94k5odtwJXMtQ", "object": "product", "active": true, "attributes": [ ], "created": 1587577341, "description": "Premium service with extra features", "images": [ ], "livemode": false, "metadata": { }, "name": "Billing Guide: Premium Service", "statement_descriptor": null, "type": "service", "unit_label": null, "updated": 1587577341 } ``` Utilisez les ID de produit afin de créer un tarif pour chaque produit. La valeur du champ [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) est exprimé en centimes, donc `1500` = 15 USD, par exemple. Créer le prix premium : ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{PREMIUM_PRODUCT_ID}} \ -d unit_amount=1500 \ -d currency=usd \ -d "recurring[interval]=month" ``` Créer le prix basique : ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d product={{BASIC_PRODUCT_ID}} \ -d unit_amount=500 \ -d currency=usd \ -d "recurring[interval]=month" ``` Enregistrez l’ID de chaque tarif de manière à pouvoir l’utiliser par la suite. Les ID de tarif se présentent sous la forme suivante : ```json { "id": "price_HGd7M3DV3IMXkC", "object": "price", "product": "prod_HGd6W1VUqqXGvr", "type": "recurring", "currency": "usd", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "active": true, "billing_scheme": "per_unit", "created": 1589319695, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "unit_amount": 1500, "unit_amount_decimal": "1500", "tiers": null, "tiers_mode": null, "transform_quantity": null } ``` ## Créer l’objet Customer [Client et serveur] Stripe a besoin d’un client pour chaque abonnement. Dans le front-end de votre application, collectez les informations nécessaires auprès de vos clients et transmettez-les au back-end. Si vous avez besoin de collecter des données d’adresse, Address Element vous permet de collecter une adresse de livraison ou de facturation pour vos clients. Pour plus d’informations sur l’Address Element, voir la page [Address Element](https://docs.stripe.com/elements/address-element.md). ```html
``` ```javascript const emailInput = document.querySelector('#email'); fetch('/create-customer', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: emailInput.value, }), }).then(r => r.json()); ``` Sur le serveur, créez un objet pour représenter le client. Il peut s’agir d’un objet `Account` côté client ou d’un objet `Customer`. Enregistrez l’ID de l’objet pour l’utiliser dans la Checkout Session. > #### Utiliser l’API Accounts v2 pour représenter les clients > > L’API Accounts v2 est généralement disponible pour les utilisateurs de Connect et en aperçu public pour les autres utilisateurs de Stripe. Si vous avez accès à l’aperçu Accounts v2, vous devez [spécifier une version d’aperçu](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) dans votre code. > > Pour demander l’accès à l’aperçu Accounts v2, > > Dans la plupart des cas d’usage, nous vous recommandons de [modéliser vos clients en tant qu’objets Account configurés par le client](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), plutôt que d’utiliser des objets [Customer](https://docs.stripe.com/api/customers.md). #### Accounts v2 ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "identity": { "individual": { "given_name": "Jenny Rosen", "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } }, "configuration": { "customer": { "capabilities": { "automatic_indirect_tax": { "requested": true } }, "shipping": { "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "postal_code": "94605", "state": "CA" } } } }, "include": [ "configuration.customer", "identity" ] }' ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ --data-urlencode "email=jenny.rosen@example.com" \ -d "name=Jenny Rosen" \ -d "shipping[address][city]=San Francisco" \ -d "shipping[address][country]=US" \ -d "shipping[address][line1]=123 Main Street" \ -d "shipping[address][postal_code]=9460" \ -d "shipping[address][state]=CA" \ -d "shipping[name]=Jenny Rosen" \ -d "address[city]=San Francisco" \ -d "address[country]=US" \ -d "address[line1]=123 Main Street" \ -d "address[postal_code]=9460" \ -d "address[state]=CA" ``` ## Créer l'abonnement [Client et serveur] > Si vous souhaitez afficher le composant Payment Element sans créer d’abonnement au préalable, consultez la section[Collecter les informations de paiement avant de créer un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription). Permettez à votre client de choisir une offre, puis créez l’abonnement. Dans l’exemple de ce guide, le client choisit entre une offre Basic et une offre Premium. Sur le front-end, transmettez l’identifiant de prix sélectionné ainsi que l’identifiant d’enregistrement du client au back-end. #### Accounts v2 ```javascript fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerAccountId: customerAccountId, }), }) ``` #### Customers v1 ```javascript fetch('/create-subscription', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), }) ``` Dans le back-end, créez l’abonnement avec l’état `incomplete` en utilisant `payment_behavior=default_incomplete`. Ensuite, renvoyez le `client_secret` du premier [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md) de l’abonnement au front-end pour exécuter le paiement. Pour ce faire, développez le [confirmation_secret](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) de la dernière facture de l’abonnement. Pour activer [le comportement amélioré des abonnements](https://docs.stripe.com/billing/subscriptions/billing-mode.md), définissez `billing_mode[type]` sur `flexible`. Vous devez utiliser la version de l’API Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) ou une version ultérieure. Définissez [save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) sur `on_subscription` pour enregistrer le moyen de paiement comme moyen par défaut pour un abonnement lorsqu’un paiement est effectué avec succès. L’enregistrement d’un moyen de paiement par défaut augmente le taux de réussite des futurs paiements d’abonnement. L’exemple suivant crée un `Subscription` et étend le `confirmation_secret` de sa dernière facture dans la réponse. Vous pouvez ainsi transmettre ce secret au front-end pour confirmer le paiement. #### Accounts v2 ```curl curl https://api.stripe.com/v1/subscriptions \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "items[0][price]={{PRICE_ID}}" \ -d payment_behavior=default_incomplete \ -d "payment_settings[save_default_payment_method]=on_subscription" \ -d "billing_mode[type]=flexible" \ -d "expand[0]=latest_invoice.confirmation_secret" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/subscriptions \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "items[0][price]={{PRICE_ID}}" \ -d payment_behavior=default_incomplete \ -d "payment_settings[save_default_payment_method]=on_subscription" \ -d "billing_mode[type]=flexible" \ -d "expand[0]=latest_invoice.confirmation_secret" ``` > Si vous utilisez un *prix multidevises* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration), utilisez le paramètre [currency](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) pour indiquer à l’abonnement laquelle des devises prises en charge doit être utilisée. Si vous omettez le paramètre `currency`, l’abonnement utilise la devise par défaut. L’abonnement est maintenant `inactive` et en attente du paiement. L’exemple de réponse ci-dessous met en évidence les champs minimaux à sauvegarder, mais vous pouvez sauvegarder les champs auxquels votre formulaire d’inscription accède fréquemment. #### Accounts v2 ```json {"id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": "null" }, "billing_cycle_anchor": 1623873347, "billing_cycle_anchor_config": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": { "comment": null, "feedback": null, "reason": null }, "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd","customer_account": identifier("customerAccount"), "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "discounts": [], "ended_at": null, "invoice_customer_balance_settings": { "account_tax_ids": null, "issuer": { "type": "self" } }, "items": { "object": "list", "data": [ { "id": "si_JgRjmS4Ur1khEx", "object": "subscription_item", "created": 1623873347,"current_period_end": 1626465347, "current_period_start": 1623873347, "discounts": [], "metadata": { }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "subscription": "sub_JgRjFjhKbtD2qz", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz" }, "latest_invoice": { "id": "in_1J34pzGPZ1iASj5zB87qdBNZ", "object": "invoice", "account_country": "US", "account_name": "Angelina's Store", "account_tax_ids": null, "amount_due": 2000, "amount_overpaid": 0, "amount_paid": 0, "amount_remaining": 2000, "amount_shipping": 0, "attempt_count": 0, "attempted": false, "auto_advance": false, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": null, "status": null }, "automatically_finalizes_at": null, "billing_reason": "subscription_update", "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd", "custom_fields": null, "customer_account": identifier("customerAccount"), "customer_address": null, "customer_email": "angelina@stripe.com", "customer_name": null, "customer_phone": null, "customer_shipping": { "address": { "city": "", "country": "US", "line1": "Berry", "line2": "", "postal_code": "", "state": "" }, "name": "", "phone": null }, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "description": null, "discounts": [], "due_date": null, "effective_at": "1623873347", "ending_balance": 0, "footer": null, "from_invoice": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf", "last_finalization_error": null, "latest_revision": null, "lines": { "object": "list", "data": [ { "id": "il_1N2CjMBwKQ696a5NeOawRQP2", "object": "line_item", "amount": 2000, "currency": "usd", "description": "1 × Gold Special (at $20.00 / month)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "livemode": false, "metadata": { }, "parent": { "invoice_item_details": null, "subscription_item_details": { "invoice_item": null, "proration": false, "proration_details": { "credited_items": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subscription_item": "si_JgRjmS4Ur1khEx" }, "type": "subscription_item_details" }, "period": { "end": 1626465347, "start": 1623873347 }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "taxes": [] } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "C008FC2-0354", "on_behalf_of": null, "parent": { "quote_details": null, "subscription_details": { "metadata": {}, "pause_collection": null, "subscription": "sub_JgRjFjhKbtD2qz" } }, "payment_intent": { "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6", "object": "payment_intent", "allowed_source_types": [ "card" ], "amount": 2000, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6" }, "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu", "confirmation_method": "automatic", "created": 1623873347, "currency": "usd", "customer": "cus_CMqDWO2xODTZqt", "description": "Subscription creation", "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "next_source_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "receipt_email": null, "review": null, "setup_future_usage": "off_session", "shipping": null, "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ", "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null }, "payment_settings": { "payment_method_options": null, "payment_method_types": null, "save_default_payment_method": "on_subscription" }, "period_end": 1623873347, "period_start": 1623873347, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "open", "status_transitions": { "finalized_at": 1623873347, "marked_uncollectible_at": null, "paid_at": null, "voided_at": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subtotal": 2000, "tax": null, "tax_percent": null, "total": 2000, "total_discount_amounts": [], "total_tax_amounts": [], "transfer_data": null, "webhooks_delivered_at": 1623873347 }, "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start": 1623873347, "start_date": 1623873347, "status": "incomplete", "tax_percent": null, "transfer_data": null, "trial_end": null, "trial_start": null } ``` #### Customers v1 ```json {"id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": "null" }, "billing_cycle_anchor": 1623873347, "billing_cycle_anchor_config": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": { "comment": null, "feedback": null, "reason": null }, "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd","customer": identifier("customer"), "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "discounts": [], "ended_at": null, "invoice_customer_balance_settings": { "account_tax_ids": null, "issuer": { "type": "self" } }, "items": { "object": "list", "data": [ { "id": "si_JgRjmS4Ur1khEx", "object": "subscription_item", "created": 1623873347,"current_period_end": 1626465347, "current_period_start": 1623873347, "discounts": [], "metadata": { }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "subscription": "sub_JgRjFjhKbtD2qz", "tax_rates": [ ] } ], "has_more": false, "total_count": 1, "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz" }, "latest_invoice": { "id": "in_1J34pzGPZ1iASj5zB87qdBNZ", "object": "invoice", "account_country": "US", "account_name": "Angelina's Store", "account_tax_ids": null, "amount_due": 2000, "amount_overpaid": 0, "amount_paid": 0, "amount_remaining": 2000, "amount_shipping": 0, "attempt_count": 0, "attempted": false, "auto_advance": false, "automatic_tax": { "disabled_reason": null, "enabled": false, "liability": null, "status": null }, "automatically_finalizes_at": null, "billing_reason": "subscription_update", "collection_method": "charge_automatically", "created": 1623873347, "currency": "usd", "custom_fields": null, "customer": identifier("customer"), "customer_address": null, "customer_email": "angelina@stripe.com", "customer_name": null, "customer_phone": null, "customer_shipping": { "address": { "city": "", "country": "US", "line1": "Berry", "line2": "", "postal_code": "", "state": "" }, "name": "", "phone": null }, "customer_tax_exempt": "none", "customer_tax_ids": [ ], "default_payment_method": null, "default_source": null, "default_tax_rates": [ ], "description": null, "discounts": [], "due_date": null, "effective_at": "1623873347", "ending_balance": 0, "footer": null, "from_invoice": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf", "last_finalization_error": null, "latest_revision": null, "lines": { "object": "list", "data": [ { "id": "il_1N2CjMBwKQ696a5NeOawRQP2", "object": "line_item", "amount": 2000, "currency": "usd", "description": "1 × Gold Special (at $20.00 / month)", "discount_amounts": [ ], "discountable": true, "discounts": [ ], "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "livemode": false, "metadata": { }, "parent": { "invoice_item_details": null, "subscription_item_details": { "invoice_item": null, "proration": false, "proration_details": { "credited_items": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subscription_item": "si_JgRjmS4Ur1khEx" }, "type": "subscription_item_details" }, "period": { "end": 1626465347, "start": 1623873347 }, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "price": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "livemode": false, "lookup_key": null, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "recurring": { "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed" }, "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 2000, "unit_amount_decimal": "2000" }, "quantity": 1, "taxes": [] } ], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines" }, "livemode": false, "metadata": { }, "next_payment_attempt": null, "number": "C008FC2-0354", "on_behalf_of": null, "parent": { "quote_details": null, "subscription_details": { "metadata": {}, "pause_collection": null, "subscription": "sub_JgRjFjhKbtD2qz" } }, "payment_intent": { "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6", "object": "payment_intent", "allowed_source_types": [ "card" ], "amount": 2000, "amount_capturable": 0, "amount_received": 0, "application": null, "application_fee_amount": null, "canceled_at": null, "cancellation_reason": null, "capture_method": "automatic", "charges": { "object": "list", "data": [ ], "has_more": false, "total_count": 0, "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6" }, "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu", "confirmation_method": "automatic", "created": 1623873347, "currency": "usd", "customer": "cus_CMqDWO2xODTZqt", "description": "Subscription creation", "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ", "last_payment_error": null, "livemode": false, "metadata": { }, "next_action": null, "next_source_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_options": { "card": { "installments": null, "network": null, "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "receipt_email": null, "review": null, "setup_future_usage": "off_session", "shipping": null, "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ", "statement_descriptor": null, "statement_descriptor_suffix": null, "status": "requires_confirmation", "transfer_data": null, "transfer_group": null }, "payment_settings": { "payment_method_options": null, "payment_method_types": null, "save_default_payment_method": "on_subscription" }, "period_end": 1623873347, "period_start": 1623873347, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "receipt_number": null, "starting_balance": 0, "statement_descriptor": null, "status": "open", "status_transitions": { "finalized_at": 1623873347, "marked_uncollectible_at": null, "paid_at": null, "voided_at": null }, "subscription": "sub_JgRjFjhKbtD2qz", "subtotal": 2000, "tax": null, "tax_percent": null, "total": 2000, "total_discount_amounts": [], "total_tax_amounts": [], "transfer_data": null, "webhooks_delivered_at": 1623873347 }, "livemode": false, "metadata": { }, "next_pending_invoice_item_invoice": null, "pause_collection": null, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": { "id": "price_1J32RfGPZ1iASj5zHHp57z7C", "object": "plan", "active": true, "amount": 2000, "amount_decimal": "2000", "billing_scheme": "per_unit", "created": 1623864151, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": { }, "nickname": null, "product": "prod_JgPF5xnq7qBun3", "tiers": null, "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed" }, "quantity": 1, "schedule": null, "start": 1623873347, "start_date": 1623873347, "status": "incomplete", "tax_percent": null, "transfer_data": null, "trial_end": null, "trial_start": null } ``` ## Collecter les informations de paiement [Client] Utilisez les [Stripe Elements](https://docs.stripe.com/payments/elements.md) pour collecter les détails du paiement et activer l’abonnement. Vous pouvez personnaliser les Elements pour qu’ils correspondent à l’aspect et à la convivialité de votre formulaire d’inscription. Le [composant Element Payment](https://docs.stripe.com/payments/payment-element.md) prend en charge [Link](https://docs.stripe.com/payments/link.md), les cartes bancaires, le prélèvement automatique SEPA et le prélèvement automatique BECS pour les abonnements. Vous pouvez afficher les moyens de paiement activés et collecter en toute sécurité les informations de paiement en fonction de la sélection de votre client. ### Configurer les Stripe Elements Le Payment Element est automatiquement disponible en tant que fonctionnalité de Stripe.js. Intégrez le script Stripe.js à votre page de paiement en l’ajoutant à la section `head` de votre fichier HTML. Chargez toujours Stripe.js directement depuis js.stripe.com pour rester conforme aux normes PCI. N’incluez pas ce script dans un lot et n’en hébergez pas de copie. ```html Checkout ``` Sur votre page de paiement, créez une instance de Stripe avec le code JavaScript suivant : ```javascript // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` ### Ajouter le Payment Element à votre page Le Payment Element doit avoir un emplacement dédié dans votre page de paiement. Créez un nœud DOM (conteneur) vide avec un identifiant unique dans votre formulaire de paiement. ```html
``` Après le chargement du formulaire, créez une instance du Payment Element et montez-la dans le nœud DOM du conteneur. Lorsque vous [avez créé l’abonnement](https://docs.stripe.com/payments/advanced/build-subscriptions.md#create-subscription), vous avez transmis la valeur `client_secret` au front-end. Passez cette valeur en tant qu’option lorsque vous créez une instance d’Elements. ```javascript const options = { clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in the payment form, passing the client secret obtained in step 5 const elements = stripe.elements(options); const paymentElementOptions = { layout: "tabs", }; // Create and mount the Payment Element const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` Le Payment Element affiche un formulaire dynamique qui permet à votre client de sélectionner un moyen de paiement. Le formulaire collecte automatiquement toutes les informations de paiement nécessaires pour le moyen de paiement sélectionné. #### Configurations facultatives du Payment Element Vous pouvez éventuellement effectuer les opérations suivantes : - Personnalisez le composant Payment Element pour qu’il corresponde au design de votre site en transmettant l’[appearance object](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-appearance)]dans les `options`lors de la création d’une instance d’Elements. - Configurez l’interface Apple Pay pour qu’elle renvoie un[token marchand](https://docs.stripe.com/apple-pay/merchant-tokens.md?pay-element=web-pe) afin de prendre en charge les paiements récurrents, les recharges automatiques et les paiements différés. ### Finaliser le paiement Utilisez `stripe.confirmPayment` pour finaliser le paiement à partir des informations du composant Payment Element et activer l’abonnement. Cette opération crée un PaymentMethod, confirme le premier PaymentIntent de l’abonnement incomplet et déclenche un débit. Si une *Strong Customer Authentication* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) (SCA) est nécessaire, le Payment Element prend en charge le processus avant de confirmer le PaymentIntent. Fournissez un [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) pour indiquer où Stripe doit rediriger l’utilisateur après l’exécution du paiement. Il se peut que votre utilisateur soit d’abord redirigé vers un site intermédiaire (par ex. une page d’autorisation bancaire), avant d’être renvoyé vers le `return_url`. Les paiements par carte bancaire redirigent immédiatement vers le `return_url` lorsque le paiement est effectué avec succès. ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, confirmParams: { return_url: "https://example.com/order/123/complete", } }); if (error) { // This point is reached only if there's an immediate error when // confirming the payment. Show an error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer redirects to your `return_url`. For some payment // methods, such as iDEAL, your customer redirects to an intermediate // site first to authorize the payment, and then redirects to the `return_url`. } }); ``` Lorsque votre client effectue un paiement, Stripe le redirige vers l’URL `return_url` et inclut les paramètres de requête d’URL suivants. La page de redirection peut utiliser ces paramètres pour récupérer l’état du PaymentIntent et ainsi afficher l’état du paiement pour le client. Lorsque vous spécifiez une URL `return_url`, vous pouvez également ajouter vos propres paramètres de requête à utiliser sur la page de redirection. | Paramètre | Description | | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent` | Identifiant unique du `PaymentIntent`. | | `payment_intent_client_secret` | La [clé secrète du client](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) de l’objet `PaymentIntent`. Pour les intégrations d’abonnements, le client_secret est également exposé sur l’objet `Invoice` via [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) | Lorsque le client est redirigé vers votre site, vous pouvez utiliser le `payment_intent_client_secret` pour interroger le PaymentIntent et communiquer l’état de la transaction à votre client. > Si vous utilisez des outils pour suivre la session navigateur de vos clients, pensez à ajouter le domaine `stripe.com` à la liste d’exclusion des référents. Sans cela, les redirections peuvent déclencher la création de nouvelles sessions et perturber le suivi complet du parcours utilisateur. Utilisez l’un des paramètres de requête pour récupérer le PaymentIntent. Contrôlez [l’état du PaymentIntent](https://docs.stripe.com/payments/paymentintents/lifecycle.md) pour décider de ce que vous allez montrer à vos clients. Vous pouvez également ajouter vos propres paramètres de requête lorsque vous fournissez le `return_url`, qui est conservé dans le processus de redirection. ```javascript // Initialize Stripe.js using your publishable key const stripe = Stripe('<>'); // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { const message = document.querySelector('#message') // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods [immediately succeed or fail][0] upon // confirmation, while others first enter a `processing` status. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': message.innerText = 'Success! Payment received.'; break; case 'processing': message.innerText = "Payment processing. We'll update you when payment is received."; break; case 'requires_payment_method': message.innerText = 'Payment failed. Please try another payment method.'; // Redirect your user back to your payment page to attempt collecting // payment again break; default: message.innerText = 'Something went wrong.'; break; } }); ``` ## Écouter les webhooks [Serveur] Afin de compléter votre intégration, vous devez traiter les webhooks** envoyés par Stripe. Ces événements se déclenchent lorsqu’un état change dans Stripe, par exemple lorsqu’un abonnement génère une nouvelle facture. Dans votre application, configurez un gestionnaire HTTP pour accepter les requêtes POST contenant l’événement de webhook et vérifiez la signature de l’événement. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/webhook' do # You can use webhooks to receive information about asynchronous payment events. # For more about our webhook events, see https://stripe.com/docs/webhooks. webhook_secret = ENV['STRIPE_WEBHOOK_SECRET'] payload = request.body.read if !webhook_secret.empty? # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured. sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil begin event = Stripe::Webhook.construct_event( payload, sig_header, webhook_secret ) rescue JSON::ParserError => e # Invalid payload status 400 return rescue Stripe::SignatureVerificationError => e # Invalid signature puts '⚠️ Webhook signature verification failed.' status 400 return end else data = JSON.parse(payload, symbolize_names: true) event = Stripe::Event.construct_from(data) end # Get the type of webhook event sent - used to check the status of PaymentIntents. event_type = event['type'] data = event['data'] data_object = data['object'] if event_type == 'invoice.paid' # Used to provision services after the trial has ended. # The status of the invoice shows up as paid. Store the status in your # database to reference when a user accesses your service to avoid hitting rate # limits. # puts data_object end if event_type == 'invoice.payment_failed' # If the payment fails or the customer doesn't have a valid payment method, # an invoice.payment_failed event is sent and the subscription becomes past_due. # Use this webhook to notify your user that their payment has # failed and to retrieve new card details. # puts data_object end if event_type == 'customer.subscription.deleted' # handle subscription canceled automatically based # upon your subscription settings. Or if the user cancels it. # puts data_object end content_type 'application/json' { status: 'success' }.to_json end ``` Pendant le développement, utilisez la Stripe CLI pour [observer les webhooks et les transmettre à votre formulaire d’inscription](https://docs.stripe.com/webhooks.md#test-webhook). Exécutez ensuite la commande suivante dans un nouveau terminal pendant que votre application de développement est en cours d’exécution : #### curl ```bash stripe listen --forward-to localhost:4242/webhook ``` Pour la production, configurez un endpoint webhook dans [Workbench](https://docs.stripe.com/workbench.md), ou utilisez l’[API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md). Écoutez quelques événements pour terminer les étapes restantes de ce guide. Consultez la section [Événements d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) pour plus d’informations sur les webhooks spécifiques à l’abonnement. ## Fournir l'accès à votre service [Client et serveur] Maintenant que l’abonnement est actif, donnez à votre utilisateur l’accès à votre service. Pour ce faire, écoutez les événements `customer.subscription.created`, `customer.subscription.updated`, et `customer.subscription.deleted`. Ces événements transmettent un objet `Subscription` qui contient un champ `status` indiquant si l’abonnement est actif, en retard ou annulé. Pour obtenir la liste complète des états, consultez le [cycle de vie de l’abonnement](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle). Dans votre gestionnaire de webhooks : 1. Vérifiez l’état de l’abonnement. S’il s’agit de `active`, votre utilisateur a payé pour votre produit. 1. Vérifiez le produit auquel le client s’est abonné et accordez-lui l’accès à votre service. Le contrôle basé sur le produit, plutôt que sur le prix, vous offre plus de flexibilité si vous devez modifier la tarification ou la période de facturation. 1. Sauvegardez les `product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer_account.id` ou le `customer.id` déjà stocké. Vérifiez ce dossier au moment de décider des fonctionnalités à activer pour l’utilisateur dans votre application. L’état d’un abonnement peut évoluer à tout moment pendant sa durée de vie, même si votre application n’effectue aucun appel direct à Stripe. Par exemple, un renouvellement peut échouer en raison d’une carte de crédit expirée, ce qui place l’abonnement en état `past due`. Ou encore, si vous implémentez le [portail client](https://docs.stripe.com/customer-management.md), un utilisateur peut annuler son abonnement sans passer par votre application. Une implémentation correcte de votre gestionnaire garantit la synchronisation de l’état de votre application avec Stripe. ## Annuler l'abonnement [Client et serveur] Donnez à vos clients la possibilité d’annuler leur abonnement. L’exemple ci-dessous ajoute une option d’annulation directement sur la page des paramètres du compte. ![Exemple d'interface de résiliation d'abonnement](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png) Paramètres d’un compte ayant la possibilité d’annuler son abonnement ```javascript function cancelSubscription(subscriptionId) { return fetch('/cancel-subscription', { method: 'post', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, }), }) .then(response => { return response.json(); }) .then(cancelSubscriptionResponse => { // Display to the user that the subscription has been canceled. }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` Votre application reçoit un événement `customer.subscription.deleted`. Après la résiliation de l’abonnement, mettez à jour votre base de données pour supprimer l’identifiant de l’abonnement Stripe précédemment sauvegardé, et limitez l’accès à votre service. Une fois un abonnement annulé, il ne peut plus être réactivé. Collectez dès lors les informations de facturation actualisées de votre client, mettez à jour son moyen de paiement par défaut et créez un nouvel abonnement à partir du dossier client existant. ## Tester votre intégration ### Tester les moyens de paiement Utilisez le tableau suivant pour tester différents scénarios et moyens de paiement. | Moyen de paiement | Scénario | Méthode de test | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Prélèvement automatique BECS | Le montant dû est réglé par prélèvement automatique BECS. | Remplissez le formulaire à l’aide du numéro de compte `900123456` et du BSB `000000`. La confirmation de la demande de PaymentIntent passe d’abord à l’état `processing`, puis à l’état `succeeded` trois minutes plus tard. | | Prélèvement automatique BECS | Le paiement de votre client échoue avec un code d’erreur `account_closed`. | Remplissez le formulaire à l’aide du numéro de compte `111111113` et du BSB `000000`. | | Carte bancaire | Le paiement par carte bancaire aboutit et ne nécessite pas d’authentification. | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro de carte `4242 4242 4242 4242` ainsi que la date d’expiration, le CVC et le code postal de votre choix. | | Carte bancaire | Le paiement par carte bancaire requiert une *authentification* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro de carte `4000 0025 0000 3155` ainsi que la date d’expiration, le CVC et le code postal de votre choix. | | Carte bancaire | La carte est refusée avec un code de refus de type `insufficient_funds`. | Remplissez le formulaire de paiement par carte bancaire en saisissant le numéro `4000 0000 0000 9995` ainsi que la date d’expiration, le CVC et le code postal de votre choix… | | Prélèvement automatique SEPA | Le montant dû est réglé par prélèvement automatique SEPA. | Remplissez le formulaire à l’aide du numéro de compte `AT321904300235473204`. Le PaymentIntent confirmé passe d’abord à l’état processing, puis à l’état succeeded trois minutes plus tard. | | Prélèvement automatique SEPA | L’état du PaymentIntent de votre client passe de `processing` à `requires_payment_method`. | Remplissez le formulaire à l’aide du numéro de compte `AT861904300235473202`. | ### Écouter des événements Configurez des webhooks pour écouter les événements de changement d’abonnement, tels que les mises à niveau et les annulations. Apprenez-en plus sur les [webhooks d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md). Vous pouvez visualiser les événements dans le [Dashboard](https://dashboard.stripe.com/test/events) ou via la[Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook). Pour plus d’informations, voir la section[tester votre intégration Billing](https://docs.stripe.com/billing/testing.md). ## Optional: Permettre à vos clients de modifier leurs offres [Client et serveur] Pour permettre à vos clients de modifier leur abonnement, collectez l’identifiant de prix de l’option choisie. Ensuite, envoyez ce nouvel identifiant de prix du front-end vers un endpoint du back-end. L’exemple ci-dessous transmet également l’identifiant de l’abonnement, mais vous pouvez aussi le récupérer depuis votre base de données pour votre utilisateur connecté. ```javascript function updateSubscription(priceId, subscriptionId) { return fetch('/update-subscription', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, newPriceId: priceId, }), }) .then(response => { return response.json(); }) .then(response => { return response; }); } ``` Sur le back-end, définissez l’endpoint que le front-end doit appeler en transmettant l’identifiant de l’abonnement et le nouvel identifiant de prix. L’abonnement passe ainsi en Premium à 15 USD par mois, au lieu de l’offre Basic à 5 USD par mois. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) updated_subscription = client.v1.subscriptions.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: data['newPriceId'] } ] ) updated_subscription.to_json end ``` Votre application reçoit un événement `customer.subscription.updated`. ## Optional: Prévisualiser un changement de tarif [Client et serveur] Lorsqu’un client modifie son abonnement, le montant facturé est souvent réajusté, c’est ce qu’on appelle la [proration](https://docs.stripe.com/billing/subscriptions/prorations.md). Utilisez l’endpoint [create preview invoice](https://docs.stripe.com/api/invoices/create_preview.md) pour générer et afficher la facture mise à jour à vos clients. Sur le front-end, transmettez les informations de`create preview invoice` à un endpoint du back-end. #### Accounts v2 ```javascript function createPreviewInvoice( customerAccountId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerAccountId: customerAccountId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` #### Customers v1 ```javascript function createPreviewInvoice( customerId, subscriptionId, newPriceId, trialEndDate ) { return fetch('/create-preview-invoice', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ customerId: customerId, subscriptionId: subscriptionId, newPriceId: newPriceId, }), }) .then(response => { return response.json(); }) .then((invoice) => { return invoice; }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Accounts v2 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) invoice = Stripe::Invoice.create_preview( customer_account: data['customerAccountId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` #### Customers v1 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-preview-invoice' do content_type 'application/json' data = JSON.parse request.body.read subscription = client.v1.subscriptions.retrieve(data['subscriptionId']) invoice = client.v1.invoices.create_preview( customer: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: data['newPriceId'], deleted: false } ] } ) invoice.to_json end ``` ## Optional: Afficher le moyen de paiement du client [Client et serveur] L’affichage de la marque et des quatre derniers chiffres de la carte bancaire de votre client peut aider ce dernier à savoir quelle carte bancaire est débitée, ou encore s’il doit mettre à jour son moyen de paiement. Sur votre front-end, envoyez l’ID du moyen de paiement à un endpoint du back-end qui récupère les informations du moyen de paiement. ```javascript function retrieveCustomerPaymentMethod(paymentMethodId) { return fetch('/retrieve-customer-payment-method', { method: 'post', headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ paymentMethodId: paymentMethodId, }), }) .then((response) => { return response.json(); }) .then((response) => { return response; }); } ``` Sur le back-end, définissez le endpoint que votre front-end doit appeler. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId']) payment_method.to_json end ``` Exemple de réponse : ```json { "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 8, "exp_year": 2021, "fingerprint": "Xt5EWLLDS7FJjR1c", "funding": "credit", "generated_from": null, "last4": "4242", "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1588010536, "customer": "cus_HAxB7dVQxhoKLh", "livemode": false, "metadata": {}, "type": "card" } ``` > Nous vous recommandons d’enregistrer les valeurs `paymentMethod.id` et `last4` dans votre base de données, par exemple, `paymentMethod.id` sous `stripeCustomerPaymentMethodId` dans la collection ou la table `users`. Vous pouvez aussi, si nécessaire, stocker `exp_month`, `exp_year`, `fingerprint`, `billing_details`. Cela permet de réduire le nombre d’appels envoyés à Stripe, d’améliorer les performances et d’éviter d’éventuelles limitations de débit. ## Divulguer Stripe à vos clients Stripe recueille des informations sur les interactions des clients avec Elements afin de vous fournir des services, de prévenir la fraude et d’améliorer ses services. Cela inclut l’utilisation de cookies et d’adresses IP pour identifier les Elements qu’un client a vus au cours d’une même session Checkout. Vous êtes responsable de la divulgation et de l’obtention de tous les droits et consentements nécessaires pour que Stripe puisse utiliser les données à cette fin. Pour en savoir plus, visitez notre [Centre de confidentialité](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).