# Créer une intégration pour les abonnements Créez et gérez des abonnements pour les paiements récurrents. Instructions pour les LLM : Stripe publie fréquemment de nouveaux produits et fonctionnalités. Récupérez les Bonnes pratiques Stripe auprès de https://raw.githubusercontent.com/stripe/ai/refs/heads/main/skills/stripe-best-practices/SKILL.md avant l’implémentation. #### Checkout #### Page hébergée par Stripe # Page hébergée > This is a Page hébergée for when platform is web and ui is stripe-hosted. View the full page at https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=stripe-hosted. #### Effort d’intégration Complexity: 2/5 #### Personnalisation de l’interface utilisateur Personnalisation limitée - 20 polices prédéfinies - 3 rayons de bordure prédéfinis - Couleur d’arrière-plan et de bordure personnalisée - Logo personnalisé #### Type d’intégration Utilisez des pages hébergées prédéfinies pour collecter les paiements et gérer vos *abonnements*. [Essayer](https://checkout.stripe.dev/) ## Ce que vous allez créer Ce guide décrit comment vendre des abonnements mensuels à prix fixe en utilisant [Stripe Checkout](https://docs.stripe.com/payments/checkout.md). Ce guide vous explique comment : - Modélisez votre entreprise en créant un catalogue de produits. - Ajoutez une session Checkout à votre site, avec un bouton et des pages de confirmation et d’annulation. - Surveillez les événements d’abonnement et fournissez l’accès à votre service. - Configurez le [portail client](https://docs.stripe.com/customer-management.md). - Ajoutez une session de portail client à votre site, avec un bouton et une redirection. - Permettre à vos clients de gérer leurs abonnements sur le portail. - 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. Si vous n’êtes pas prêt à coder une intégration, vous pouvez configurer les abonnements de base [manuellement](https://docs.stripe.com/no-code/subscriptions.md) ou utiliser [Payment Links](https://docs.stripe.com/payment-links.md) pour configurer les abonnements sans écrire de code. En savoir plus sur la [conception d’une intégration](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) pour comprendre les décisions et les ressources nécessaires à une intégration complète. Une fois l’intégration terminée, vous pouvez l’étendre pour : - Affichez les [taxes](https://docs.stripe.com/payments/checkout/taxes.md) - Appliquez des [ réductions](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout). - Offrez à vos clients une [période d’essai gratuite](https://docs.stripe.com/billing/subscriptions/trials.md) - Ajoutez des [moyens de paiement](https://docs.stripe.com/payments/payment-methods/integration-options.md) - Intégrez la [page de facture hébergée](https://docs.stripe.com/invoicing/hosted-invoice-page.md). - Utilisez Checkout dans le [mode de configuration](https://docs.stripe.com/payments/save-and-reuse.md) - Établissez la [facturation à l’usage](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing), les[ niveaux de tarification](https://docs.stripe.com/products-prices/pricing-models.md#tiered-pricing) et la[tarification à l’usage](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing) - Gérez les [prorata](https://docs.stripe.com/billing/subscriptions/prorations.md) - Autorisez les clients à[s’abonner à plusieurs produits](https://docs.stripe.com/billing/subscriptions/quantities.md#multiple-product-sub). - Intégrez les[droits](https://docs.stripe.com/billing/entitlements.md) pour gérer l’accès aux fonctionnalités de votre produit. ## 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' ``` En option, installez la Stripe CLI. La CLI permet de tester les [webhooks](https://docs.stripe.com/webhooks.md#test-webhook), et vous pouvez l’exécuter pour créer vos produits et tarifs. 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 [Dashboard ou Stripe CLI] 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 } ``` Si vous proposez plusieurs périodes de facturation, utilisez Checkout pour [inciter](https://docs.stripe.com/payments/checkout/upsells.md)les clients à opter pour des périodes de facturation plus longues et percevoir davantage de revenus à l’avance. Pour d’autres modèles de tarification, voir la section[Exemples de facturation](https://docs.stripe.com/products-prices/pricing-models.md). ## Créer une session Checkout [Client et serveur] Ajoutez à votre site internet un bouton de paiement qui appelle un endpoint côté serveur afin de créer une session Checkout. ```html Checkout
``` Sur le back-end de votre application, définissez un endpoint qui [crée la session](https://docs.stripe.com/api/checkout/sessions/create.md) pour que votre front-end l’appelle. Vous avez besoin de ces valeurs : - L’identifiant du prix de l’abonnement que souscrit votre client (votre front-end transmet cette valeur) - Votre `success_url`, qui est une page de votre site internet à laquelle Checkout renvoie votre client après l’exécution du paiement. Vous pouvez éventuellement : - Configurez une [date de début](https://docs.stripe.com/billing/subscriptions/billing-cycle.md) de cycle de facturation pour votre abonnement dans cet appel. - Use [custom text](https://docs.stripe.com/payments/checkout/custom-components.md?ui=embedded-form#customize-payment-method-reuse-agreement-and-subscription-terms) to include your subscription and cancellation terms, and a link to where your customers can update or cancel their subscription. We recommend configuring [email reminders and notifications](https://docs.stripe.com/invoicing/send-email.md#email-configuration) for your subscribers. Si vous avez créé un prix unique lors de[é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, redirigez votre client vers l’[URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) renvoyée dans la réponse. Vous pouvez activer un comportement d’abonnement plus précis et prévisible lorsque vous créez une session Checkout en paramétrant le [mode de facturation](https://docs.stripe.com/billing/subscriptions/billing-mode.md) 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. > Vous pouvez utiliser [lookup_keys](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) pour récupérer des prix plutôt que des 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. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # The price ID passed from the front end. # price_id = params['priceId'] price_id = '{{PRICE_ID}}' session = Stripe::Checkout::Session.create({ success_url: 'https://example.com/success.html?session_id={CHECKOUT_SESSION_ID}', mode: 'subscription', line_items: [{ # For usage-based billing, don't pass quantity quantity: 1, price: price_id }], subscription_data: { billing_mode: { type: 'flexible' } } }) # Redirect to the URL returned on the session # redirect session.url, 303 ``` Cet exemple personnalise l’adresse `success_url` en y ajoutant l’identifiant de la session. Apprenez-en davantage sur la [personnalisation de votre page de succès](https://docs.stripe.com/payments/checkout/custom-success-page.md). 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). ## Fournir l'accès au service et suivre les abonnements [Serveur] Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Une fois l’inscription à l’abonnement réussie, le client revient sur votre site internet à l’adresse `success_url`, ce qui déclenche un webhook `checkout.session.completed`. À la réception de cet événement `checkout.session.completed`, utilisez [entitlements](https://docs.stripe.com/billing/entitlements.md) pour provisionner l’abonnement. Continuez à le provisionner chaque mois (en cas de facturation mensuelle) lorsque vous recevez des événements `invoice.paid`. Si vous recevez un événement `invoice.payment_failed`, informez votre client et redirigez-le vers le portail client pour qu’il mette à jour son moyen de paiement. Pour déterminer l’étape suivante de la logique de votre système, vérifiez le type d’événement et analysez les données utiles de chaque [event object](https://docs.stripe.com/api/events/object.md), tel que `invoice.paid`. Sauvegardez les objets `subscription.id` et `customer.id` dans votre base de données pour vérification. À des fins de test, vous pouvez surveiller les événements dans l’[onglet d’événements](https://dashboard.stripe.com/workbench/events) de [Workbench](https://docs.stripe.com/workbench.md). Pour la production, configurez un endpoint webhook et abonnez-vous aux types d’événements appropriés. Si vous ne connaissez pas votre clé `STRIPE_WEBHOOK_SECRET`, allez dans la vue des détails de destination de l’[onglet webhooks](https://dashboard.stripe.com/workbench/webhooks) dans Workbench pour la consulter. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/webhook' do webhook_secret = '{{STRIPE_WEBHOOK_SECRET}}' # Exemple : whsec_c7681Dm 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 event_type = event['type'] data = event['data'] data_object = data['object'] case event_type when 'checkout.session.completed' # Payment is successful and the subscription is created. # You should provision the subscription and save the customer ID to your database. when 'invoice.paid' # Continue to provision the subscription as payments continue to be made. # Store the status in your database and check when a user accesses your service. # This approach helps you avoid hitting rate limits. when 'invoice.payment_failed' # The payment failed or the customer doesn't have a valid payment method. # The subscription becomes past_due. Notify your customer and send them to the # customer portal to update their payment information. else puts "Unhandled event type: \#{event.type}" end status 200 end ``` Voici les types d’événement à suivre, a minima : | Nom de l’événement | Description | | ---------------------------- | ---------------------------------------------------------------------------------------------------- | | `checkout.session.completed` | Envoyé lorsqu’un client termine avec succès la session Checkout, vous informant d’un nouvel achat. | | `invoice.paid` | Envoyé à chaque période de facturation lorsqu’un paiement réussit. | | `invoice.payment_failed` | Envoyé à chaque période de facturation en cas de problème avec le moyen de paiement de votre client. | Pour plus d’événements à surveiller, voir les[webhooks d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md) ## Configurer le portail client [Dashboard] Le [portail client](https://docs.stripe.com/customer-management.md) permet à vos clients de gérer directement leurs abonnements et factures existants. Utilisez le [Dashboard](https://dashboard.stripe.com/test/settings/billing/portal) pour configurer le portail. Veillez au minimum à [configurer le portail](https://docs.stripe.com/customer-management.md) afin que les clients puissent mettre à jour leurs moyens de paiement. ## Créez une session de portail [Serveur] Définissez un endpoint qui [crée la session du portail client](https://docs.stripe.com/api/customer_portal/sessions/create.md) pour que votre front-end l’appelle. L’identifiant `CUSTOMER_ID` fait référence à l’identifiant du client créé par une session Checkout que vous avez enregistré en traitant l’événement `checkout.session.completed`. Vous pouvez également définir un lien de redirection par défaut pour le portail dans le Dashboard. Transmettez une valeur facultative `return_url` pour la page de votre site vers laquelle rediriger votre client une fois qu’il a terminé la gestion de son abonnement : #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # Exemple : http://exemple.com customer_id = '{{CUSTOMER_ID}}' # Exemple : cus_GBV60HKsE0mb5v session = Stripe::BillingPortal::Session.create({ customer: customer_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` ## Redirigez les clients vers le portail client [Client] Sur votre front-end, ajoutez un bouton sur la page `success_url` qui redirige vers le portail client : ```html Manage Billing
``` Après avoir quitté le portail client, votre client revient sur votre site Web à l’URL : `return_url`. Continuez à [surveiller les événements](https://docs.stripe.com/billing/subscriptions/webhooks.md) pour suivre l’état de l’abonnement du client. Si vous configurez le portail client pour permettre des actions telles que l’annulation d’un abonnement, [surveillez les événements supplémentaires](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks) ## 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. Vous pouvez visualiser les[événements webhook d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md)dans le[Dashboard](https://dashboard.stripe.com/test/events) ou avec la[Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook). Apprenez-en davantage sur le [test de votre intégration de facturation](https://docs.stripe.com/billing/testing.md) ## See also - [Proposez à vos clients une période d’essai gratuite](https://docs.stripe.com/billing/subscriptions/trials.md) - Appliquez [des réductions](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout) - [Gérer les calculs au prorata](https://docs.stripe.com/billing/subscriptions/prorations.md) - [Intégrez les droits pour gérer l’accès aux fonctionnalités de votre produit](https://docs.stripe.com/billing/entitlements.md). #### Formulaire intégré # Page intégrée > This is a Page intégrée for when platform is web and ui is embedded-form. View the full page at https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=embedded-form. #### Effort d’intégration Complexity: 2/5 #### Personnalisation de l’interface utilisateur Personnalisez l’apparence. #### Type d’intégration Utilisez les formulaires intégrés préconfigurés pour encaisser les paiements et gérer les abonnements**. ## Configurez le serveur ### 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' ``` ### Créez un produit et un tarif 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 } ``` Si vous proposez plusieurs périodes de facturation, utilisez Checkout pour [inciter](https://docs.stripe.com/payments/checkout/upsells.md)les clients à opter pour des périodes de facturation plus longues et percevoir davantage de revenus à l’avance. Pour d’autres modèles de tarification, voir la section[Exemples de facturation](https://docs.stripe.com/products-prices/pricing-models.md). ### Créer une session Checkout Ajoutez un endpoint sur votre serveur qui crée une session Checkout**. Lorsque vous créez la session [Checkout](https://docs.stripe.com/api/checkout/sessions/create.md), transmettez les paramètres suivants : - Pour utiliser le formulaire de paiement embedded, définissez [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) sur `embedded`. - Pour créer des abonnements lorsque votre client paie, réglez le [mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) sur `subscription`. - Pour définir la page sur laquelle votre client retourne après avoir effectué ou tenté d’effectuer un paiement, spécifiez une [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) Incluez la variable de modèle `{CHECKOUT_SESSION_ID}` dans l’URL. Checkout remplace cette variable par l’identifiant de la session Checkout avant de rediriger votre client. Vous créez et hébergez la page de retour sur votre site internet. - To include your subscription and cancellation terms, and a link to where your customers can update or cancel their subscription, optionally use [custom text](https://docs.stripe.com/payments/checkout/custom-components.md?ui=embedded-form#customize-payment-method-reuse-agreement-and-subscription-terms). We recommend configuring [email reminders and notifications](https://docs.stripe.com/invoicing/send-email.md#email-configuration) for your subscribers. Pour monter Checkout, utilisez le `client_secret` de la session Checkout renvoyé dans la réponse. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d mode=subscription \ -d "line_items[0][price]"="{{PRICE_ID}}" \ -d "line_items[0][quantity]"=1 \ -d ui_mode=embedded \ --data-urlencode return_url="https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" ``` ## Créez votre page d'abonnement [Client] ### Monter Checkout #### HTML + JS #### Charger Stripe.js Utilisez *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) pour rester en conformité avec la *norme PCI* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) en veillant à ce que les informations de paiement soient envoyées directement à Stripe sans passer par votre serveur. Chargez toujours Stripe.js directement à partir de js.stripe.com pour maintenir votre conformité. Vous ne devez pas inclure ce script dans un lot ni en héberger de copie. #### Définir le formulaire de paiement Pour collecter les informations du client en toute sécurité, créez un espace réservé vide `div`. Stripe insère un iframe dans le `div`. Checkout est disponible dans : [Stripe.js](https://docs.stripe.com/js.md). Ajoutez le script Stripe.js à votre page en l’insérant dans l’en-tête de votre fichier HTML. Ensuite, créez un nœud DOM vide (conteneur) à utiliser pour le montage. ```html Accept a payment
``` #### Initialiser Stripe.js Initialisez Stripe.js avec votre clé API publique. #### Récupérez une clé secrète client de session Checkout Créez une fonction asynchrone `fetchClientSecret` qui envoie une requête à votre serveur[ pour créer une session Checkout](https://docs.stripe.com/api/checkout/sessions/create.md) et récupérer la clé secrète du client. #### Initialiser Checkout Initialisez Checkout avec votre fonction `fetchClientSecret` et montez-la sur le placeholder `
` dans votre formulaire de paiement. Checkout est affiché dans un iframe qui envoie de façon sécurisée les informations de paiement à Stripe via une connexion HTTPS. Évitez de placer Checkout dans un autre iframe, car certains moyens de paiement nécessitent une redirection vers une autre page pour la confirmation du paiement. ```javascript // Initialize Stripe.js const stripe = Stripe('<>'); initialize(); // Fetch Checkout Session and retrieve the client secret async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Initialize Checkout const checkout = await stripe.initEmbeddedCheckout({ fetchClientSecret, }); // Mount Checkout checkout.mount('#checkout'); } ``` #### React #### Ajoutez Stripe à votre application React Installez [React-Stripe.js](https://docs.stripe.com/sdks/stripejs-react.md) pour rester conforme aux normes PCI en vous assurant que les détails du paiement vont directement à Stripe et n’atteignent jamais votre serveur. ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` #### Charger Stripe.js Pour configurer la bibliothèque Stripe, appelez `loadStripe()` avec votre clé API publique Stripe. Créez un `EmbeddedCheckoutProvider`. Transmettez au fournisseur la `Promise` renvoyée. #### Récupérez une clé secrète client de session Checkout Créez une fonction asynchrone `fetchClientSecret` qui envoie une requête à votre serveur[ pour créer une session Checkout](https://docs.stripe.com/api/checkout/sessions/create.md) et récupérer la clé secrète du client. #### Initialiser Checkout Pour permettre aux composants enfants d’accéder au service Stripe via le client Checkout intégré, transmettez la promesse renvoyée par`loadStripe`, et la fonction `fetchClientSecret` comme `option` au fournisseur Checkout intégré. ```jsx import * as React from 'react'; import {loadStripe} from '@stripe/stripe-js'; import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-stripe-js'; // Make sure to call `loadStripe` outside of a component's render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('pk_test_123', { }); const App = ({fetchClientSecret}) => { const options = {fetchClientSecret}; return ( ) } ``` ## Afficher une page de retour Après que votre client a tenté d’effectuer un paiement, Stripe le redirige vers une page de retour que vous hébergez sur votre site. Lorsque vous avez créé la session Checkout, vous avez spécifié l’URL de cette page de retour dans le paramètre [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url). > Lors du paiement, certains moyens de paiement redirigent le client vers une page intermédiaire, comme par exemple une page d’autorisation bancaire. Une fois cette étape validée, Stripe redirige le client vers votre page de retour. #### Créer un endpoint pour récupérer une session Checkout Ajoutez un endpoint pour récupérer l’état d’une session Checkout avec l’identifiant de session Checkout dans l’URL. #### Récupérez une session Checkout Pour exploiter les informations de la session Checkout, envoyez immédiatement une requête à l’endpoint de votre serveur pour [récupérer la session Checkout](https://docs.stripe.com/api/checkout/sessions/retrieve.md), en utilisant l’identifiant de la session Checkout présent dans l’URL, dès le chargement de votre page de retour. #### Gérer la session Traitez le résultat établi en fonction de l’état de la session : - `complete` : le paiement a abouti. Utilisez les informations de la session Checkout pour afficher une page de confirmation. - `open` : le paiement a échoué ou a été annulé. Montez à nouveau Checkout pour que votre client puisse effectuer une nouvelle tentative. ```js // Retrieve a Checkout Session // Use the session ID initialize(); async function initialize() { const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const sessionId = urlParams.get('session_id'); const response = await fetch(`/session-status?session_id=${sessionId}`); const session = await response.json(); // Handle the session according to its status if (session.status == 'open') { // Remount embedded Checkout window.location.replace('http://localhost:4242/checkout.html') } else if (session.status == 'complete') { document.getElementById('success').classList.remove('hidden'); document.getElementById('customer-email').textContent = session.customer_email; // Show success page // Optionally use session.payment_status or session.customer_email // to customize the success page } } ``` ```javascript // Add an endpoint to fetch the Checkout Session status app.get('/session_status', async (req, res) => { const session = await stripe.checkout.sessions.retrieve(req.query.session_id); const customer = await stripe.customers.retrieve(session.customer); res.send({ status: session.status, payment_status: session.payment_status, customer_email: customer.email }); }); ``` ## Optional: Configurer le portail client Vous pouvez configurer le portail client** pour permettre à vos clients de gérer directement leurs abonnements et factures existants. Vous pouvez configurer le portail dans le Dashboard. Pour réduire le taux d’attrition, configurez le portail afin de permettre aux clients de mettre à jour leurs moyens de paiement en cas d’échec de paiement. Pour faciliter la recherche des clients, ajoutez sur votre site internet un bouton de redirection vers le portail client, afin de leur permettre de gérer leur abonnement. Lorsqu’ils cliquent sur ce bouton, vos clients sont redirigés vers la page du portail client hébergée par Stripe. Apprenez-en davantage sur le [ portail client](https://docs.stripe.com/customer-management.md)et les autres options de gestion des clients. #### Créez une session de portail Pour ajouter un portail client, définissez un endpoint qui [crée la session du portail client](https://docs.stripe.com/api/customer_portal/sessions/create.md) pour que votre front-end l’appelle. L’identifiant `CUSTOMER_ID` correspond à l’identifiant client créé par une session Checkout et que vous avez enregistré lors du traitement du webhook `checkout.session.completed`. Vous pouvez également définir un lien de redirection par défaut pour le portail dans le Dashboard. Transmettez une valeur facultative `return_url` pour la page de votre site vers laquelle rediriger votre client une fois qu’il a terminé la gestion de son abonnement : #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # This is the URL that users are redirected to after they're done # managing their billing. return_url = '{{DOMAIN_URL}}' # Exemple : http://exemple.com customer_id = '{{CUSTOMER_ID}}' # Exemple : cus_GBV60HKsE0mb5v session = Stripe::BillingPortal::Session.create({ customer: customer_id, return_url: return_url, }) # Redirect to the URL for the session # redirect session.url, 303 ``` #### Redirigez les clients vers le portail client Sur votre interface, ajoutez un bouton sur la page à l’adresse `success_url`, afin de fournir un lien vers le portail client. ```html Manage Billing
``` Après avoir quitté le portail client, votre client revient sur votre site Web à l’URL : `return_url`. Continuez à [surveiller les événements](https://docs.stripe.com/billing/subscriptions/webhooks.md) pour suivre l’état de l’abonnement du client. Si vous configurez le portail client pour permettre des actions telles que l’annulation d’un abonnement, veillez à surveiller [ les événements supplémentaires ](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks). ## Fourniture de l'accès Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Lorsque 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). Pour gérer l’accès aux fonctionnalités de votre produit, découvrez [ comment intégrer les droits d’accès](https://docs.stripe.com/billing/entitlements.md). 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 votre client s’est abonné et donnez-lui accès à votre service. La vérification du produit plutôt que du tarif vous permet de modifier la tarification ou la période de facturation si nécessaire. 1. Sauvegardez les `product.id`, `subscription.id` et `subscription.status` dans votre base de données, ainsi que `customer.id` que vous avez déjà enregistré. Vérifiez cet enregistrement 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 bancaire expirée, ce qui place l’abonnement en état de paiement en retard. Ou encore, 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 garantit la synchronisation de l’état de votre application avec Stripe. ## 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. Vous pouvez visualiser les[événements webhook d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md)dans le[Dashboard](https://dashboard.stripe.com/test/events) ou avec la[Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook). Apprenez-en davantage sur le [test de votre intégration de facturation](https://docs.stripe.com/billing/testing.md) #### Elements #### API Checkout Sessions #### 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 | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client qui achète un abonnement. Utilisez l’objet Customer associé à un abonnement pour effectuer et suivre ses paiements récurrents et 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 qu’un client utilise pour payer vos produits. Vous pouvez par exemple enregistrer une carte bancaire dans un objet Customer et l’utiliser pour les paiements récurrents de ce client. Généralement utilisés 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 le Client [Client et serveur] Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Stripe a besoin d’un objet *Client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pour chaque abonnement. Sur le front-end de votre formulaire d’inscription, collectez toutes les informations nécessaires sur vos utilisateurs et transmettez-les à votre 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 l’objet Stripe Customer. > Veillez à stocker l’[ID client](https://docs.stripe.com/api/customers/object.md#customer_object-id) pour l’utiliser dans la session Checkout ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} \ -d "shipping[address][city]"=Brothers \ -d "shipping[address][country]"=US \ -d "shipping[address][line1]"="27 Fredrick Ave" \ -d "shipping[address][postal_code]"=97712 \ -d "shipping[address][state]"=CA \ -d "shipping[name]"={{CUSTOMER_NAME}} \ -d "address[city]"=Brothers \ -d "address[country]"=US \ -d "address[line1]"="27 Fredrick Ave" \ -d "address[postal_code]"=97712 \ -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. #### 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. Stripe.api_key = '<>' Stripe.api_version = '2026-02-25.clover' 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: 'custom', # 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 [initCheckout](https://docs.stripe.com/js/custom_checkout/init) et transmettez `clientSecret`. `initCheckout` renvoie un objet [Checkout](https://docs.stripe.com/js/custom_checkout) contenant les données de la Checkout Session ainsi que des méthodes permettant de la 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.initCheckout({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 [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider), en passant `clientSecret` et l’instance `stripe`. ```jsx import React from 'react'; import {CheckoutProvider} 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 `useCheckout()`. 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 {useCheckout} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckout(); 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 [Element Payment](https://docs.stripe.com/payments/payment-element.md) dans le [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ```jsx import React from 'react';import {PaymentElement, useCheckout} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckout(); 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) d’Elements dans son entièreté en transmettant [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) au [CheckoutProvider](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.initCheckout({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 [useCheckout](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout) pour soumettre le paiement. ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckout(); 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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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. Enregistrez les`product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer.id` que vous avez déjà enregistré. Utilisez cet enregistrement pour déterminer quelles 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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = Stripe::Subscription.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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) updated_subscription = Stripe::Subscription.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: 'price_H1NlVtpo6ubk0m' } ] ) 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. ```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. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: ENV[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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = Stripe::PaymentMethod.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 #### 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) Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. 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 [Customer](https://docs.stripe.com/api/customers.md) 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. Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions) ### Définitions des objets API | Ressource | Définition | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client qui achète un abonnement. Utilisez l’objet Customer associé à un abonnement pour effectuer et suivre ses paiements récurrents et 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 qu’un client utilise pour payer vos produits. Vous pouvez par exemple enregistrer une carte bancaire dans un objet Customer et l’utiliser pour les paiements récurrents de ce client. Généralement utilisés 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 le Client [Client et serveur] Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Stripe a besoin d’un objet *Client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pour chaque abonnement. Sur le front-end de votre formulaire d’inscription, collectez toutes les informations nécessaires sur vos utilisateurs et transmettez-les à votre 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 l’objet Stripe Customer. > Veillez à stocker l’[ID client](https://docs.stripe.com/api/customers/object.md#customer_object-id) pour l’utiliser dans la session Checkout ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} \ -d "shipping[address][city]"=Brothers \ -d "shipping[address][country]"=US \ -d "shipping[address][line1]"="27 Fredrick Ave" \ -d "shipping[address][postal_code]"=97712 \ -d "shipping[address][state]"=CA \ -d "shipping[name]"={{CUSTOMER_NAME}} \ -d "address[city]"=Brothers \ -d "address[country]"=US \ -d "address[line1]"="27 Fredrick Ave" \ -d "address[postal_code]"=97712 \ -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. ```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. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/create-subscription' do content_type 'application/json' data = JSON.parse(request.body.read) customer_id = cookies[:customer] price_id = data['priceId'] # Create the subscription. Note we're expanding the Subscription's # latest invoice and that invoice's confirmation_secret # so we can pass it to the front end to confirm the payment subscription = Stripe::Subscription.create( customer: customer_id, items: [{ price: price_id, }], payment_behavior: 'default_incomplete', payment_settings: {save_default_payment_method: 'on_subscription'}, billing_mode: {type: 'flexible'}, expand: ['latest_invoice.confirmation_secret'] ) { subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.confirmation_secret.client_secret }.to_json end ``` > 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. ```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": "cus_CMqDWO2xODTZqt", "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": "cus_CMqDWO2xODTZqt", "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[Payment Element](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/billing/subscriptions/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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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. Enregistrez les`product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer.id` que vous avez déjà enregistré. Utilisez cet enregistrement pour déterminer quelles 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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = Stripe::Subscription.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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) updated_subscription = Stripe::Subscription.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: 'price_H1NlVtpo6ubk0m' } ] ) 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. ```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. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: ENV[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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = Stripe::PaymentMethod.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). #### Mobile #### iOS Apprenez à vendre des *abonnements* à tarif fixe. Vous apprendrez à utiliser le composant [Element Mobile Payment](https://docs.stripe.com/payments/accept-a-payment.md) pour créer un formulaire de paiement personnalisé que vous intégrerez à votre application. ![Page d'abonnement à tarif fixe avec Stripe Checkout](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png) > Si vous vendez des produits ou des services numériques dont l’utilisation a lieu dans votre application (par exemple, des abonnements, des devises de jeu, des niveaux de jeu, l’accès à du contenu premium ou le déverrouillage d’une version complète), vous devez utiliser les API d’achats intégrés d’Apple. Cette règle comporte quelques exceptions : par exemple, les services personnels sur mesure et les [applications accessibles dans des régions spécifiques](https://support.stripe.com/questions/changes-to-mobile-app-store-rules) ne sont pas concernés. Pour en savoir plus, consultez les [directives de vérification de l’App Store](https://developer.apple.com/app-store/review/guidelines/#payments). ## Créer votre abonnement Ce guide vous explique comment : - Modéliser votre offre en créant un catalogue de produits. - Créer un processus d’enregistrement pour ajouter des clients. - Créer des abonnements et collecter les informations de paiement de vos clients. - Tester et surveiller l’état des paiements et des abonnements. - Permettre aux clients de modifier leur plan ou d’annuler l’abonnement. - Découvrez comment utiliser [mode de facturation flexible](https://docs.stripe.com/facturation/Subscriptions/mode-facturation.md) pour accéder à un comportement de facturation amélioré et à des fonctionnalités supplémentaires. ## Comment modéliser un abonnement sur Stripe Les [abonnements](https://docs.stripe.com/api/subscriptions.md) simplifient votre facturation en créant automatiquement 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 objet *Produit* (Products represent what your business sells—whether that's a good or a service) pour modéliser ce qui est vendu, ainsi qu’un objet *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) pour déterminer l’intervalle et le montant à facturer. Vous avez également besoin d’un objet [Customer](https://docs.stripe.com/api/customers.md) pour enregistrer les *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilisés dans le cadre des paiements récurrents. Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions) ### Définitions des objets API | Ressource | Définition | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client qui achète un abonnement. Utilisez l’objet Customer associé à un abonnement pour effectuer et suivre ses paiements récurrents et 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 qu’un client utilise pour payer vos produits. Vous pouvez par exemple enregistrer une carte bancaire dans un objet Customer et l’utiliser pour les paiements récurrents de ce client. Généralement utilisés 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 Le [SDK iOS de Stripe](https://github.com/stripe/stripe-ios) est disponible en open source et [fait l’objet d’une documentation complète](https://stripe.dev/stripe-ios/index.html). Il est également compatible avec les applications prenant en charge iOS 13 et les versions ultérieures. #### Swift Package Manager Pour installer le SDK, veuillez suivre les étapes ci-dessous : 1. Dans Xcode, sélectionnez **File** > **Add Package Dependencies…** puis saisissez `https://github.com/stripe/stripe-ios-spm` en tant qu’URL du référentiel. 1. Sélectionnez le dernier numéro de version, visible sur notre [page des versions](https://github.com/stripe/stripe-ios/releases). 1. Ajoutez le produit **StripePaymentSheet** à la [cible de votre application](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app). #### CocoaPods 1. Si vous ne l’avez pas encore fait, installez la version la plus récente de [CocoaPods](https://guides.cocoapods.org/using/getting-started.html). 1. Si vous n’avez pas de fichier [Podfile](https://guides.cocoapods.org/syntax/podfile.html), exécutez la commande suivante pour en créer un : ```bash pod init ``` 1. Ajoutez cette ligne à votre `Podfile` : ```podfile pod 'StripePaymentSheet' ``` 1. Exécutez la commande suivante : ```bash pod install ``` 1. À partir de maintenant, n’oubliez pas d’utiliser le fichier .xcworkspace au lieu du fichier .xcodeproj pour ouvrir votre projet dans Xcode. 1. Pour mettre à jour ultérieurement le SDK vers la version la plus récente, il vous suffit d’exécuter : ```bash pod update StripePaymentSheet ``` #### Carthage 1. Si vous ne l’avez pas encore fait, installez la version la plus récente de [Carthage](https://github.com/Carthage/Carthage#installing-carthage). 1. Ajoutez cette ligne à votre `Cartfile` : ```cartfile github "stripe/stripe-ios" ``` 1. Suivez les [instructions d’installation de Carthage](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Veillez à intégrer tous les cadres requis listés [ici](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking). 1. Pour mettre à jour ultérieurement le SDK vers la version la plus récente, exécutez la commande suivante : ```bash carthage update stripe-ios --platform ios ``` #### Cadre manuel 1. Accédez à notre [page des versions GitHub](https://github.com/stripe/stripe-ios/releases/latest), puis téléchargez et décompressez **Stripe.xcframework.zip**. 1. Faites glisser **StripePaymentSheet.xcframework** vers la section **Embedded Binaries (Fichiers binaires incorporés)** des paramètres **General (Général)** de votre projet Xcode. Veillez à sélectionner **Copy items if needed (Copier les éléments si nécessaire)**. 1. Répétez l’étape 2 pour tous les cadres requis listés [ici](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking). 1. À l’avenir, pour mettre à jour vers la version la plus récente de notre SDK, répétez les étapes 1 à 3. > Pour obtenir de plus amples informations sur la version la plus récente du SDK et ses versions antérieures, consultez la page des [versions](https://github.com/stripe/stripe-ios/releases) sur GitHub. Pour recevoir une notification lors de la publication d’une nouvelle version, [surveillez les versions](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository) à partir du référentiel. Configurez le SDK avec votre [clé publiable](https://dashboard.stripe.com/test/apikeys) Stripe au démarrage de votre application. Cela lui permet d’envoyer des requêtes à l’API Stripe. #### Swift ```swift import UIKitimportStripePaymentSheet @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<>" // do any other necessary launch configuration return true } } ``` > Utilisez vos [clés de test](https://docs.stripe.com/keys.md#obtain-api-keys) lors de vos activités de test et de développement et vos clés du [mode production](https://docs.stripe.com/keys.md#test-live-modes) pour la publication de votre application. 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 [Interface de ligne de commande Stripe 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 objet *client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pour chaque abonnement. Sur le front-end de votre application, collectez toutes les informations nécessaires sur vos utilisateurs et transmettez-les à votre back-end. > #### Comparer les références Customers v1 et Accounts v2 > > Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Si vous avez besoin de recueillir une adresse, le composant Address Element vous permet de recueillir l’adresse de livraison ou de facturation de vos clients. Pour plus d’informations sur ce composant, consultez la page consacrée à [Address Element](https://docs.stripe.com/elements/address-element.md). ```swift struct RegisterView: View { @State var email = "" var body: some View { VStack { TextField(text: $email) { Text("Email") } Button { Task { var request = URLRequest(url: URL(string: "http://localhost:4242/create-customer")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["email": email]) let (data, _) = try! await URLSession.shared.data(for: request) let responseJSON = try! JSONSerialization.jsonObject(with: data) as! [String: Any] // Return the customer ID here print(responseJSON["customer"]) } } label: { Text("Submit") } } } } ``` Sur le serveur, créez l’objet Customer Stripe. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} \ -d "shipping[address][city]"=Brothers \ -d "shipping[address][country]"=US \ -d "shipping[address][line1]"="27 Fredrick Ave" \ -d "shipping[address][postal_code]"=97712 \ -d "shipping[address][state]"=CA \ -d "shipping[name]"={{CUSTOMER_NAME}} \ -d "address[city]"=Brothers \ -d "address[country]"=US \ -d "address[line1]"="27 Fredrick Ave" \ -d "address[postal_code]"=97712 \ -d "address[state]"=CA ``` ## Créer l'abonnement [Client et serveur] > Si vous souhaitez afficher le Payment Element sans créer d’abonnement au préalable, consultez [Collecter les informations de paiement avant de créer un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription). Laissez votre nouveau client choisir une offre, puis créez l’abonnement. Dans ce guide, le client a le choix entre l’option de base et l’option Premium. Dans votre application, transmettez l’ID du tarif sélectionné et l’ID du dossier client à votre back-end. ```swift func createSubscription(priceId: String, customerId: String) async -> SubscriptionsResponse { var request = URLRequest(url: URL(string: "http://localhost:4242/create-subscription")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["customerId": customerId, "priceId": priceId]) let (responseData, _) = try! await URLSession.shared.data(for: request) // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend. // It should include the client_secret, as discussed below. let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData) return subscriptionsResponse } ``` Sur votre back-end, créez l’abonnement à l’état `incomplete` à l’aide de `payment_behavior=default_incomplete`. Renvoyez ensuite le `client_secret` du premier [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md) de l’abonnement vers le front-end pour finaliser le paiement en développant le [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) sur la dernière facture de l’abonnement. Pour activer [comportement d’abonnement amélioré](https://docs.stripe.com/billing/Subscriptions/billing-mode.md), définissez `billing_mode[type]` sur `flexible`. Vous devez utiliser Stripe API version [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` afin d’enregistrer un moyen de paiement comme moyen de paiement par défaut pour l’abonnement lorsque le paiement aboutit. L’enregistrement d’un moyen de paiement par défaut augmente le taux de réussite des paiements futurs. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/create-subscription' do content_type 'application/json' data = JSON.parse(request.body.read) customer_id = cookies[:customer] price_id = data['priceId'] # Create the subscription. Note we're expanding the Subscription's # latest invoice and that invoice's confirmation_secret # so we can pass it to the front end to confirm the payment subscription = Stripe::Subscription.create( customer: customer_id, items: [{ price: price_id, }], payment_behavior: 'default_incomplete', payment_settings: {save_default_payment_method: 'on_subscription'}, billing_mode: {type: 'flexible'}, expand: ['latest_invoice.confirmation_secret'] ) { subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.confirmation_secret.client_secret }.to_json end ``` > Si vous utilisez un *tarif multidevise* (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 quelle devise utiliser. (Si vous omettez le paramètre `currency`, l’abonnement utilise la devise par défaut associée au tarif.) L’abonnement est maintenant `inactive` et en attente de paiement. L’exemple de réponse ci-dessous met en évidence les champs minimaux à sauvegarder, mais vous pouvez sauvegarder tout ce à quoi votre application accède fréquemment. ```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": "cus_CMqDWO2xODTZqt", "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": "cus_CMqDWO2xODTZqt", "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 } ``` ### Mettez à jour l’endpoint de votre serveur Ajoutez la création d’une clé éphémère à l’endpoint d’abonnement et renvoyez-la dans la réponse : #### Ruby ```ruby ephemeral_key = Stripe::EphemeralKey.create( {customer: customer_id}, {stripe_version: '2025-06-30.basil'} ) { subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.confirmation_secret.client_secret, ephemeralKey: ephemeral_key.secret, customerId: customer_id, }.to_json ``` ### Mettez à jour votre modèle de réponse ```swift struct SubscriptionsResponse: Decodable { let subscriptionId: String let clientSecret: String let ephemeralKey: String let customerId: String } ``` ### Transmettez la configuration client à PaymentSheet Ajoutez ce qui suit lors de la configuration de PaymentSheet : ```swift config.customer = .init(id: customerId, ephemeralKeySecret: ephemeralKey) ``` ## Collecter les informations de paiement [Client] Utilisez la [Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) pour recueillir les informations de paiement et activer l’abonnement. Vous pouvez personnaliser les Elements pour correspondre à l’identité visuelle de votre application. La Payment Sheet collecte en toute sécurité tous les détails nécessaires au paiement pour un large éventail de moyens de paiement. Découvrez les [moyens de paiement pris en charge par](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) pour la Payment Sheet et les Abonnements. ### Ajouter le composant Payment Element à votre application > Cette étape présente une façon de démarrer, mais vous pouvez utiliser n’importe quelle [intégration de paiements in-app](https://docs.stripe.com/payments/mobile.md). Initialiser et présenter le composant Mobile Payment Element à l’aide de la classe PaymentSheet. ```swift struct SubscribeView: View { let paymentSheet: PaymentSheet @State var isPaymentSheetPresented = false init(clientSecret: String) { var config = PaymentSheet.Configuration() // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. config.allowsDelayedPaymentMethods = true config.primaryButtonLabel = "Subscribe for $15/month" self.paymentSheet = PaymentSheet(paymentIntentClientSecret: clientSecret, configuration: config) } var body: some View { Button { isPaymentSheetPresented = true } label: { Text("Subscribe") }.paymentSheet(isPresented: $isPaymentSheetPresented, paymentSheet: paymentSheet) { result in switch result { case .completed: // Handle completion case .canceled: break case .failed(let error): // Handle error } } } } ``` Le composant Mobile Payment Element affiche un formulaire qui permet à votre client de sélectionner un moyen de paiement. Le formulaire collecte automatiquement toutes les informations de paiement requises pour le moyen de paiement sélectionné. Si vous définissez `allowsDelayedPaymentMethods` sur true, les moyens de paiement à [notification différée](https://docs.stripe.com/payments/payment-methods.md#payment-notification), comme les comptes bancaires étasuniens, seront acceptés. Pour ces moyens de paiement, l’état final du paiement n’est pas connu une fois le processus du `PaymentSheet` achevé, et le paiement peut plus tard aboutir comme échouer. Si vous prenez en charge ces types de moyens de paiement, informez votre client que sa commande est confirmée et ne la traitez (en lui expédiant son produit, par exemple) qu’une fois le paiement reçu. Vous pouvez personnaliser le Payment Element afin qu’il corresponde au design de votre application en utilisant la propriété [`appearance`](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) de votre objet `PaymentSheet.Configuration`. ### Confirmer le paiement Le composant Mobile Payment Element crée un PaymentMethod et le premier PaymentIntent de l’abonnement incomplet est confirmé, ce qui déclenche le processus de paiement. Si une *authentication forte du client* (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 requise pour le paiement, le composant Payment Element gère le processus d’authentification avant de confirmer le PaymentIntent. ## Configurer une URL de redirection [Côté client] Le client peut quitter votre application pour s’authentifier (par exemple, dans Safari ou dans son application bancaire). Pour lui permettre de revenir automatiquement sur votre application après s’être authentifié, [configurez un schéma d’URL personnalisé](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) et configurez votre délégué d’application pour qu’il transmette l’URL au SDK. Stripe ne prend pas en charge les [liens universels](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content). #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` Définissez également le paramètre [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) correspondant à votre objet [PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) sur l’URL de votre application. ```swift var configuration = PaymentSheet.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## Optional: Activer Apple Pay ### Demander un ID de marchand Apple Pour obtenir un ID de marchand Apple, [demandez un nouvel identifiant](https://developer.apple.com/account/resources/identifiers/add/merchant) sur le site Web Apple Developer. Renseignez le formulaire en indiquant une description et un identifiant. La description n’est destinée qu’à votre propre information et vous pourrez la modifier ultérieurement au besoin. En ce qui concerne l’identifiant, Stripe vous recommande d’utiliser le nom de votre application (par exemple, `merchant.com.{{YOUR_APP_NAME}}`). ### Créer un nouveau certificat Apple Pay Créez un certificat permettant à votre application de chiffrer les données de paiement. Accédez aux [paramètres des certificats iOS](https://dashboard.stripe.com/settings/ios_certificates) dans le Dashboard, cliquez sur **Ajouter une nouvelle application** et suivez le guide. Téléchargez un fichier CSR (Certificate Signing Request) pour obtenir d’Apple un certificat sécurisé vous autorisant à utiliser Apple Pay. Un fichier CSR peut émettre exactement un certificat. Si vous changez d’ID de marchand Apple, vous devez accéder aux [paramètres des certificats iOS](https://dashboard.stripe.com/settings/ios_certificates) dans le Dashboard pour obtenir un nouveau fichier CSR et un nouveau certificat. ### Réaliser une intégration avec Xcode Ajoutez la fonctionnalité Apple Pay à votre application. Dans Xcode, ouvrez vos paramètres de projet, cliquez sur l’onglet **Signature et fonctionnalités**, puis ajoutez **Apple Pay**. Vous serez peut-être alors invité(e) à vous connecter à votre compte développeur. Sélectionnez l’ID du marchand créé plus tôt. Il est désormais possible d’utiliser Apple Pay sur votre application. ![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png) Activez la fonctionnalité Apple Pay dans Xcode ### Ajouter Apple Pay #### Paiements récurrents Pour ajouter Apple Pay à PaymentSheet, définissez [applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) après avoir initialisé `PaymentSheet.Configuration` avec votre ID de marchand Apple et le [code pays de votre entreprise](https://dashboard.stripe.com/settings/account). Conformément aux [directives d’Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) pour les paiements récurrents, vous devez également définir des attributs supplémentaires sur la `PKPaymentRequest`. Ajoutez un gestionnaire dans [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) pour configurer les [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) avec le montant que vous avez l’intention de facturer (par exemple, 9,95 USD par mois). Vous pouvez également adopter des [tokens de marchand](https://developer.apple.com/apple-pay/merchant-tokens/) en définissant les propriétés `recurringPaymentRequest` ou `automaticReloadPaymentRequest` dans `PKPaymentRequest`. Pour en savoir plus sur l’utilisation des paiements récurrents avec Apple Pay, consultez la [documentation PassKit d’Apple](https://developer.apple.com/documentation/passkit/pkpaymentrequest). #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( paymentRequestHandler: { request in // PKRecurringPaymentSummaryItem is available on iOS 15 or later if #available(iOS 15.0, *) { let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99")) // Payment starts today billing.startDate = Date() // Payment ends in one year billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365) // Pay once a month. billing.intervalUnit = .month billing.intervalCount = 1 // recurringPaymentRequest is only available on iOS 16 or later if #available(iOS 16.0, *) { request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring", regularBilling: billing, managementURL: URL(string: "https://my-backend.example.com/customer-portal")!) request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'" } request.paymentSummaryItems = [billing] request.currencyCode = "USD" } else { // On older iOS versions, set alternative summary items. request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)] } return request } ) var configuration = PaymentSheet.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ### Suivi de commande Pour ajouter des informations de [suivi de commande](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) dans iOS 16 ou version ultérieure, configurez un [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) dans votre `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe effectue un appel vers votre implémentation une fois le paiement effectué, mais avant qu’iOS ne ferme la fiche Apple Pay. Dans votre déploiement `authorizationResultHandler`, récupérez les détails de la commande finalisée sur votre serveur. Ajoutez ces informations au [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) spécifié, et renvoyez le résultat modifié. Pour en savoir plus sur le suivi des commandes, consultez la [documentation Apple’s Wallet Orders](https://developer.apple.com/documentation/walletorders). #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( authorizationResultHandler: { result in do { // Fetch the order details from your service let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID) result.orderDetails = PKPaymentOrderDetails( orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order" orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111" webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend" authenticationToken: myOrderDetails.authenticationToken) // "abc123" // Return your modified PKPaymentAuthorizationResult return result } catch { return PKPaymentAuthorizationResult(status: .failure, errors: [error]) } } ) var configuration = PaymentSheet.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ## Écouter les webhooks [Serveur] Afin de compléter votre intégration, vous devez traiter les *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) envoyés par Stripe. Les webhooks sont des événements qui se déclenchent lorsqu’un état change dans Stripe, par exemple lorsque des abonnements créent de nouvelles factures. Dans votre application, configurez un gestionnaire HTTP de sorte qu’il accepte 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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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 does not 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 l’interface de ligne de commande de Stripe pour [observer les webhooks et les transférer vers votre application](https://docs.stripe.com/webhooks.md#test-webhook). Exécutez 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 le mode production, définissez une URL d’endpoint de webhook dans le Dashboard, ou utilisez [l’API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md). Les étapes restantes de ce guide vont vous amener à écouter quelques événements. Pour plus d’informations sur les webhooks spécifiques aux abonnements, consultez notre documentation consacrée aux [événements Subscription](https://docs.stripe.com/billing/subscriptions/webhooks.md#events). ## 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 fournissez l’accès à votre service. Le fait de vérifier le produit plutôt que le tarif vous assure une plus grande souplesse si vous devez modifier la tarification ou la fréquence de facturation. 1. Enregistrez les`product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer.id` que vous avez déjà enregistré. Utilisez cet enregistrement pour déterminer quelles 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 de retard de paiement. 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] Il est courant de laisser aux clients la possibilité d’annuler leur abonnement. Cet exemple vous explique comment ajouter une option d’annulation sur la page des paramètres du compte. Dans cet exemple, l’ID de l’abonnement est collecté sur votre front-end, mais votre application peut obtenir cette information depuis votre base de données pour votre utilisateur connecté. ![Exemple d'interface d'annulation 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 ```swift func cancelSubscription() async { var request = URLRequest(url: URL(string: "http://localhost:4242/cancel-subscription")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscription.id]) let (subscriptionResponse, _) = try! await URLSession.shared.data(for: request) // Update the state to show the subscription has been cancelled } ``` Sur votre back-end, définissez l’endpoint que votre application appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = Stripe::Subscription.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` Votre back-end reçoit un événement `customer.subscription.deleted`. Après l’annulation de l’abonnement, mettez à jour votre base de données pour supprimer l’ID 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 afin qu’ils écoutent les événements de modification d’abonnement, tels que les passages à un autre abonnement et les annulations. En savoir plus sur les [webhooks d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md). Vous pouvez afficher les événements dans le [Dashboard](https://dashboard.stripe.com/test/events) ou à l’aide de la [CLI Stripe](https://docs.stripe.com/webhooks.md#test-webhook). Pour en savoir plus, consultez la page [Tester votre intégration Billing](https://docs.stripe.com/billing/testing.md). ## Optional: Permettre à vos clients de modifier leur plan [Client et serveur] Pour permettre à vos clients de modifier leur abonnement, collectez l’ID de tarif de l’option vers laquelle ils souhaitent migrer. Envoyez ensuite ce nouvel ID de tarif depuis votre application vers un endpoint du back-end. Dans cet exemple, l’ID de l’abonnement est également transmis, mais vous pouvez le récupérer depuis votre base de données pour votre utilisateur connecté. ```swift func updateSubscription(priceId: String, subscriptionId: String) async -> SubscriptionsResponse { var request = URLRequest(url: URL(string: "http://localhost:4242/update-subscription")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "priceId": priceId]) let (responseData, _) = try! await URLSession.shared.data(for: request) // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData) return subscriptionsResponse } ``` Sur votre back-end, définissez l’endpoint que votre front-end appellera et transmettez les ID de l’abonnement et du nouveau tarif. L’abonnement est maintenant Premium et coûte 15 USD par mois au lieu des 5 USD par mois de l’abonnement de base. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) updated_subscription = Stripe::Subscription.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: 'price_H1NlVtpo6ubk0m' } ] ) 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] Lorsque votre client modifie son abonnement, un réajustement du montant dû, ou [calcul au prorata](https://docs.stripe.com/billing/subscriptions/prorations.md), est souvent effectué. Vous pouvez utiliser l’[endpoint permettant la création de l’aperçu de la facture](https://docs.stripe.com/api/invoices/create_preview.md) afin d’afficher le montant ajusté à vos clients. Depuis l’application, transmettez les détails de l’aperçu de la facture à un endpoint du back-end. ```swift func createPreviewInvoice(customerId: String, subscriptionId: String, newPriceId: String) async -> InvoiceResponse { var request = URLRequest(url: URL(string: "http://localhost:4242/create-preview-invoice")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "customerId": customerId, "newPriceId": newPriceId]) let (responseData, _) = try! await URLSession.shared.data(for: request) // Invoice is a Decodable struct conforming to the expected response from your backend let invoiceResponse = try! JSONDecoder().decode(InvoiceResponse.self, from: responseData) return invoiceResponse } ``` Sur votre back-end, définissez l’endpoint que votre front-end appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: ENV[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 de votre client peut aider ce dernier à savoir quelle carte 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. ```swift func retrieveCustomerPaymentMethod(paymentMethodId: String) async -> PaymentMethodResponse { var request = URLRequest(url: URL(string: "http://localhost:4242/retrieve-customer-payment-method")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try! JSONEncoder().encode(["paymentMethodId": paymentMethodId]) let (responseData, _) = try! await URLSession.shared.data(for: request) // PaymentMethodResponse is a Decodable struct conforming to the expected response from your backend let paymentMethodResponse = try! JSONDecoder().decode(PaymentMethodResponse.self, from: responseData) return paymentMethodResponse } ``` Sur votre back-end, définissez l’endpoint que votre application appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = Stripe::PaymentMethod.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 votre collection ou votre tableau `users`. Vous pouvez également, si vous le souhaitez, enregistrer les valeurs `exp_month`, `exp_year`, `fingerprint` et `billing_details`. Ceci limitera le nombre d’appels à Stripe, vous garantissant de meilleures performances et évitant de potentielles 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). #### Android Apprenez à vendre des *abonnements* à tarif fixe. Vous apprendrez à utiliser le composant [Element Mobile Payment](https://docs.stripe.com/payments/accept-a-payment.md) pour créer un formulaire de paiement personnalisé que vous intégrerez à votre application. ![Page d'abonnement à tarif fixe avec Stripe Checkout](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png) > Si vous vendez des produits ou des services numériques dont l’utilisation a lieu dans votre application (par exemple, des abonnements, des devises de jeu, des niveaux de jeu, l’accès à du contenu premium ou le déverrouillage d’une version complète), vous devez utiliser les API d’achats intégrés d’Apple. Cette règle comporte quelques exceptions : par exemple, les services personnels sur mesure et les [applications accessibles dans des régions spécifiques](https://support.stripe.com/questions/changes-to-mobile-app-store-rules) ne sont pas concernés. Pour en savoir plus, consultez les [directives de vérification de l’App Store](https://developer.apple.com/app-store/review/guidelines/#payments). ## Créer votre abonnement Ce guide vous explique comment : - Modéliser votre offre en créant un catalogue de produits. - Créer un processus d’enregistrement pour ajouter des clients. - Créer des abonnements et collecter les informations de paiement de vos clients. - Tester et surveiller l’état des paiements et des abonnements. - Permettre aux clients de modifier leur plan ou d’annuler l’abonnement. - Découvrez comment utiliser [mode de facturation flexible](https://docs.stripe.com/facturation/Subscriptions/mode-facturation.md) pour accéder à un comportement de facturation amélioré et à des fonctionnalités supplémentaires. ## Comment modéliser un abonnement sur Stripe Les [abonnements](https://docs.stripe.com/api/subscriptions.md) simplifient votre facturation en créant automatiquement 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 objet *Produit* (Products represent what your business sells—whether that's a good or a service) pour modéliser ce qui est vendu, ainsi qu’un objet *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) pour déterminer l’intervalle et le montant à facturer. Vous avez également besoin d’un objet [Customer](https://docs.stripe.com/api/customers.md) pour enregistrer les *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilisés dans le cadre des paiements récurrents. Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions) ### Définitions des objets API | Ressource | Définition | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client qui achète un abonnement. Utilisez l’objet Customer associé à un abonnement pour effectuer et suivre ses paiements récurrents et 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 qu’un client utilise pour payer vos produits. Vous pouvez par exemple enregistrer une carte bancaire dans un objet Customer et l’utiliser pour les paiements récurrents de ce client. Généralement utilisés 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 Le [SDK Stripe Android](https://github.com/stripe/stripe-android) est disponible en open source et [fait l’objet d’une documentation complète](https://stripe.dev/stripe-android/). Pour installer le SDK, ajoutez `stripe-android` au bloc `dependencies` de votre fichier [app/build.gradle](https://developer.android.com/studio/build/dependencies) : #### Kotlin ```kotlin plugins { id("com.android.application") } android { ... } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.0.2") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.0.2") } ``` > Pour obtenir de plus amples informations sur la version la plus récente du SDK et ses versions antérieures, consultez la page des [versions](https://github.com/stripe/stripe-android/releases) sur GitHub. Pour savoir quand une nouvelle version est disponible, [surveillez les versions du référentiel](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository). Configurez le SDK avec votre [clé publique](https://dashboard.stripe.com/apikeys) Stripe de façon à ce qu’il puisse envoyer des requêtes à l’API Stripe, par exemple à la sous-classe `Application` : #### Kotlin ```kotlin import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext, "<>" ) } } ``` > Utilisez vos [clés de test](https://docs.stripe.com/keys.md#obtain-api-keys) lors de vos activités de test et de développement et vos clés du [mode production](https://docs.stripe.com/keys.md#test-live-modes) pour la publication de votre application. 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 [Interface de ligne de commande Stripe 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 objet *client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pour chaque abonnement. Sur le front-end de votre application, collectez toutes les informations nécessaires sur vos utilisateurs et transmettez-les à votre back-end. > #### Comparer les références Customers v1 et Accounts v2 > > Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Utilisez une bibliothèque réseau pour envoyer des requêtes réseau à votre back-end. Ce document utilise [okhttp](https://square.github.io/okhttp/), mais vous pouvez utiliser n’importe quelle bibliothèque adaptée à votre projet. ```groovy dependencies { ... implementation "com.squareup.okhttp3:okhttp:4.12.0" } ``` Si vous avez besoin de recueillir une adresse, le composant Address Element vous permet de recueillir l’adresse de livraison ou de facturation de vos clients. Pour plus d’informations sur ce composant, consultez la page consacrée à [Address Element](https://docs.stripe.com/elements/address-element.md). ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import org.json.JSONObject @Composable fun RegisterView() { var email by remember { mutableStateOf("") } Column { OutlinedTextField(value = email, label = { Text(text = "Email") }, onValueChange = { email = it }) Button(onClick = { val body = JSONObject().put("email", email).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/create-customer").post(body).build() CoroutineScope(Dispatchers.IO).launch { OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { println(JSONObject(response.body!!.string()).get("customer")) } } } }) { Text(text = "Submit") } } } ``` Sur le serveur, créez l’objet Customer Stripe. ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d email={{CUSTOMER_EMAIL}} \ -d name={{CUSTOMER_NAME}} \ -d "shipping[address][city]"=Brothers \ -d "shipping[address][country]"=US \ -d "shipping[address][line1]"="27 Fredrick Ave" \ -d "shipping[address][postal_code]"=97712 \ -d "shipping[address][state]"=CA \ -d "shipping[name]"={{CUSTOMER_NAME}} \ -d "address[city]"=Brothers \ -d "address[country]"=US \ -d "address[line1]"="27 Fredrick Ave" \ -d "address[postal_code]"=97712 \ -d "address[state]"=CA ``` ## Créer l'abonnement [Client et serveur] > Si vous souhaitez afficher le Payment Element sans créer d’abonnement au préalable, consultez [Collecter les informations de paiement avant de créer un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription). Laissez votre nouveau client choisir une offre, puis créez l’abonnement. Dans ce guide, le client a le choix entre l’option de base et l’option Premium. Dans votre application, transmettez l’ID du tarif sélectionné et l’ID du dossier client à votre back-end. ```kotlin import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import org.json.JSONObject fun createSubscription(priceId: String, customerId: String): SubscriptionResponse? { val body = JSONObject() .put("priceId", priceId) .put("customerId", customerId).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/create-subscription").post(body).build() OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { // SubscriptionsResponse is data class conforming to the expected response from your backend. // It should include the client_secret, as discussed below. return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java) } } return null } ``` Sur votre back-end, créez l’abonnement à l’état `incomplete` à l’aide de `payment_behavior=default_incomplete`. Renvoyez ensuite le `client_secret` du premier [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md) de l’abonnement vers le front-end pour finaliser le paiement en développant le [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) sur la dernière facture de l’abonnement. Pour activer [comportement d’abonnement amélioré](https://docs.stripe.com/billing/Subscriptions/billing-mode.md), définissez `billing_mode[type]` sur `flexible`. Vous devez utiliser Stripe API version [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` afin d’enregistrer un moyen de paiement comme moyen de paiement par défaut pour l’abonnement lorsque le paiement aboutit. L’enregistrement d’un moyen de paiement par défaut augmente le taux de réussite des paiements futurs. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/create-subscription' do content_type 'application/json' data = JSON.parse(request.body.read) customer_id = cookies[:customer] price_id = data['priceId'] # Create the subscription. Note we're expanding the Subscription's # latest invoice and that invoice's confirmation_secret # so we can pass it to the front end to confirm the payment subscription = Stripe::Subscription.create( customer: customer_id, items: [{ price: price_id, }], payment_behavior: 'default_incomplete', payment_settings: {save_default_payment_method: 'on_subscription'}, billing_mode: {type: 'flexible'}, expand: ['latest_invoice.confirmation_secret'] ) { subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.confirmation_secret.client_secret }.to_json end ``` > Si vous utilisez un *tarif multidevise* (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 quelle devise utiliser. (Si vous omettez le paramètre `currency`, l’abonnement utilise la devise par défaut associée au tarif.) L’abonnement est maintenant `inactive` et en attente de paiement. L’exemple de réponse ci-dessous met en évidence les champs minimaux à sauvegarder, mais vous pouvez sauvegarder tout ce à quoi votre application accède fréquemment. ```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": "cus_CMqDWO2xODTZqt", "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": "cus_CMqDWO2xODTZqt", "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 } ``` ### Mettez à jour l’endpoint de votre serveur Ajoutez la création d’une clé éphémère à l’endpoint d’abonnement et renvoyez-la dans la réponse : #### Ruby ```ruby ephemeral_key = Stripe::EphemeralKey.create( {customer: customer_id}, {stripe_version: '2025-06-30.basil'} ) { subscriptionId: subscription.id, clientSecret: subscription.latest_invoice.confirmation_secret.client_secret, ephemeralKey: ephemeral_key.secret, customerId: customer_id, }.to_json ``` ### Mettez à jour votre modèle de réponse ```kotlin data class SubscriptionsResponse( val subscriptionId: String, val clientSecret: String, val ephemeralKey: String, val customerId: String ) ``` ### Transmettez la configuration client à PaymentSheet Ajoutez ce qui suit lors de la configuration de PaymentSheet : ```kotlin PaymentSheet.Configuration( primaryButtonLabel = "Subscribe for $15/month", merchantDisplayName = "My merchant name", customer = PaymentSheet.CustomerConfiguration( id = customerId, ephemeralKeySecret = ephemeralKey ) ) ``` ## Collecter les informations de paiement [Client] Utilisez la [Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) pour recueillir les informations de paiement et activer l’abonnement. Vous pouvez personnaliser les Elements pour correspondre à l’identité visuelle de votre application. La Payment Sheet collecte en toute sécurité tous les détails nécessaires au paiement pour un large éventail de moyens de paiement. Découvrez les [moyens de paiement pris en charge par](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) pour la Payment Sheet et les Abonnements. ### Ajouter le composant Payment Element à votre application > Cette étape présente une façon de démarrer, mais vous pouvez utiliser n’importe quelle [intégration de paiements in-app](https://docs.stripe.com/payments/mobile.md). Initialiser et présenter le composant Mobile Payment Element à l’aide de la classe PaymentSheet. ```kotlin import androidx.compose.material3.Button import androidx.compose.material3.Text import androidx.compose.runtime.Composable import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheetResult import com.stripe.android.paymentsheet.rememberPaymentSheet @Composable fun SubscribeView(clientSecret: String) { val paymentSheet = rememberPaymentSheet(::onPaymentSheetResult) Button(onClick = { paymentSheet.presentWithPaymentIntent( clientSecret, PaymentSheet.Configuration( primaryButtonLabel = "Subscribe for $15/month", merchantDisplayName = "My merchant name", // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. allowsDelayedPaymentMethods = true ) ) }) { Text(text = "Subscribe") } } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { when (paymentSheetResult) { is PaymentSheetResult.Canceled -> { print("Canceled") } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") } is PaymentSheetResult.Completed -> { // Display for example, an order confirmation screen print("Completed") } } } ``` Le composant Mobile Payment Element affiche un formulaire qui permet à votre client de sélectionner un moyen de paiement. Le formulaire collecte automatiquement toutes les informations de paiement requises pour le moyen de paiement sélectionné. Si vous définissez `allowsDelayedPaymentMethods` sur true, les moyens de paiement à [notification différée](https://docs.stripe.com/payments/payment-methods.md#payment-notification), comme les comptes bancaires étasuniens, seront acceptés. Pour ces moyens de paiement, l’état final du paiement n’est pas connu une fois le processus du `PaymentSheet` achevé, et le paiement peut plus tard aboutir comme échouer. Si vous prenez en charge ces types de moyens de paiement, informez votre client que sa commande est confirmée et ne la traitez (en lui expédiant son produit, par exemple) qu’une fois le paiement reçu. Vous pouvez personnaliser le Payment Element afin qu’il corresponde au design de votre application en utilisant la propriété [`appearance`](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) de votre objet `PaymentSheet.Configuration`. ### Confirmer le paiement Le composant Mobile Payment Element crée un PaymentMethod et le premier PaymentIntent de l’abonnement incomplet est confirmé, ce qui déclenche le processus de paiement. Si une *authentication forte du client* (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 requise pour le paiement, le composant Payment Element gère le processus d’authentification avant de confirmer le PaymentIntent. ## Écouter les webhooks [Serveur] Afin de compléter votre intégration, vous devez traiter les *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) envoyés par Stripe. Les webhooks sont des événements qui se déclenchent lorsqu’un état change dans Stripe, par exemple lorsque des abonnements créent de nouvelles factures. Dans votre application, configurez un gestionnaire HTTP de sorte qu’il accepte 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. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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 does not 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 l’interface de ligne de commande de Stripe pour [observer les webhooks et les transférer vers votre application](https://docs.stripe.com/webhooks.md#test-webhook). Exécutez 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 le mode production, définissez une URL d’endpoint de webhook dans le Dashboard, ou utilisez [l’API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md). Les étapes restantes de ce guide vont vous amener à écouter quelques événements. Pour plus d’informations sur les webhooks spécifiques aux abonnements, consultez notre documentation consacrée aux [événements Subscription](https://docs.stripe.com/billing/subscriptions/webhooks.md#events). ## 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 fournissez l’accès à votre service. Le fait de vérifier le produit plutôt que le tarif vous assure une plus grande souplesse si vous devez modifier la tarification ou la fréquence de facturation. 1. Enregistrez les`product.id`, `subscription.id` et `subscription.status` dans votre base de données avec le `customer.id` que vous avez déjà enregistré. Utilisez cet enregistrement pour déterminer quelles 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 de retard de paiement. 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] Il est courant de laisser aux clients la possibilité d’annuler leur abonnement. Cet exemple vous explique comment ajouter une option d’annulation sur la page des paramètres du compte. Dans cet exemple, l’ID de l’abonnement est collecté sur votre front-end, mais votre application peut obtenir cette information depuis votre base de données pour votre utilisateur connecté. ![Exemple d'interface d'annulation 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 ```kotlin fun cancelSubscription(subscriptionId: String): SubscriptionResponse? { val body = JSONObject().put("subscriptionId", subscriptionId).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/cancel-subscription").post(body).build() OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java) } } return null } ``` Sur votre back-end, définissez l’endpoint que votre application appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/cancel-subscription' do content_type 'application/json' data = JSON.parse request.body.read deleted_subscription = Stripe::Subscription.cancel(data['subscriptionId']) deleted_subscription.to_json end ``` Votre back-end reçoit un événement `customer.subscription.deleted`. Après l’annulation de l’abonnement, mettez à jour votre base de données pour supprimer l’ID 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 afin qu’ils écoutent les événements de modification d’abonnement, tels que les passages à un autre abonnement et les annulations. En savoir plus sur les [webhooks d’abonnement](https://docs.stripe.com/billing/subscriptions/webhooks.md). Vous pouvez afficher les événements dans le [Dashboard](https://dashboard.stripe.com/test/events) ou à l’aide de la [CLI Stripe](https://docs.stripe.com/webhooks.md#test-webhook). Pour en savoir plus, consultez la page [Tester votre intégration Billing](https://docs.stripe.com/billing/testing.md). ## Optional: Permettre à vos clients de modifier leur plan [Client et serveur] Pour permettre à vos clients de modifier leur abonnement, collectez l’ID de tarif de l’option vers laquelle ils souhaitent migrer. Envoyez ensuite ce nouvel ID de tarif depuis votre application vers un endpoint du back-end. Dans cet exemple, l’ID de l’abonnement est également transmis, mais vous pouvez le récupérer depuis votre base de données pour votre utilisateur connecté. ```kotlin fun updateSubscription(subscriptionId: String, priceId: String): SubscriptionResponse? { val body = JSONObject() .put("priceId", priceId) .put("subscriptionId", subscriptionId).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/update-subscription").post(body).build() OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { // It should include the client_secret, as discussed below. return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java) } } return null } ``` Sur votre back-end, définissez l’endpoint que votre front-end appellera et transmettez les ID de l’abonnement et du nouveau tarif. L’abonnement est maintenant Premium et coûte 15 USD par mois au lieu des 5 USD par mois de l’abonnement de base. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/update-subscription' do content_type 'application/json' data = JSON.parse request.body.read subscription = Stripe::Subscription.retrieve(data['subscriptionId']) updated_subscription = Stripe::Subscription.update( data['subscriptionId'], cancel_at_period_end: false, items: [ { id: subscription.items.data[0].id, price: 'price_H1NlVtpo6ubk0m' } ] ) 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] Lorsque votre client modifie son abonnement, un réajustement du montant dû, ou [calcul au prorata](https://docs.stripe.com/billing/subscriptions/prorations.md), est souvent effectué. Vous pouvez utiliser l’[endpoint permettant la création de l’aperçu de la facture](https://docs.stripe.com/api/invoices/create_preview.md) afin d’afficher le montant ajusté à vos clients. Depuis l’application, transmettez les détails de l’aperçu de la facture à un endpoint du back-end. ```kotlin fun createPreviewInvoice( subscriptionId: String, priceId: String, newPriceId: String ): InvoiceResponse? { val body = JSONObject() .put("priceId", priceId) .put("subscriptionId", subscriptionId) .put("newPriceId", newPriceId).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/create-preview-invoice").post(body).build() OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { // InvoiceResponse is a data class conforming to the expected response from your backend return Gson().fromJson(response.body!!.string(), InvoiceResponse::class.java) } } return null } ``` Sur votre back-end, définissez l’endpoint que votre front-end appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' 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: data['customerId'], subscription: data['subscriptionId'], subscription_details: { items: [ { id: subscription.items.data[0].id, deleted: true }, { price: ENV[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 de votre client peut aider ce dernier à savoir quelle carte 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. ```kotlin fun retrieveCustomerPaymentMethod(paymentMethodId: String): PaymentMethodResponse? { val body = JSONObject() .put("paymentMethodId", paymentMethodId).toString() .toRequestBody("application/json".toMediaType()) val request = Request.Builder().url("http://10.0.2.2:4567/retrieve-customer-payment-method").post(body) .build() OkHttpClient().newCall(request).execute().use { response -> if (response.isSuccessful) { // PaymentMethodResponse is a data class conforming to the expected response from your backend return Gson().fromJson(response.body!!.string(), PaymentMethodResponse::class.java) } } return null } ``` Sur votre back-end, définissez l’endpoint que votre application appellera. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' post '/retrieve-customer-payment-method' do content_type 'application/json' data = JSON.parse request.body.read payment_method = Stripe::PaymentMethod.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 votre collection ou votre tableau `users`. Vous pouvez également, si vous le souhaitez, enregistrer les valeurs `exp_month`, `exp_year`, `fingerprint` et `billing_details`. Ceci limitera le nombre d’appels à Stripe, vous garantissant de meilleures performances et évitant de potentielles 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). #### React Native Apprenez à vendre des *abonnements* à tarif fixe. Vous apprendrez à utiliser le composant [Element Mobile Payment](https://docs.stripe.com/payments/accept-a-payment.md) pour créer un formulaire de paiement personnalisé que vous intégrerez à votre application. ![Page d'abonnement à tarif fixe avec Stripe Checkout](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png) > Si vous vendez des produits ou des services numériques dont l’utilisation a lieu dans votre application (par exemple, des abonnements, des devises de jeu, des niveaux de jeu, l’accès à du contenu premium ou le déverrouillage d’une version complète), vous devez utiliser les API d’achats intégrés d’Apple. Cette règle comporte quelques exceptions : par exemple, les services personnels sur mesure et les [applications accessibles dans des régions spécifiques](https://support.stripe.com/questions/changes-to-mobile-app-store-rules) ne sont pas concernés. Pour en savoir plus, consultez les [directives de vérification de l’App Store](https://developer.apple.com/app-store/review/guidelines/#payments). ## Créer votre abonnement Ce guide vous explique comment : - Modéliser votre offre en créant un catalogue de produits. - Créer un processus d’enregistrement pour ajouter des clients. - Créer des abonnements et collecter les informations de paiement de vos clients. - Tester et surveiller l’état des paiements et des abonnements. - Permettre aux clients de modifier leur plan ou d’annuler l’abonnement. - Découvrez comment utiliser [mode de facturation flexible](https://docs.stripe.com/facturation/Subscriptions/mode-facturation.md) pour accéder à un comportement de facturation amélioré et à des fonctionnalités supplémentaires. ## Comment modéliser un abonnement sur Stripe Les [abonnements](https://docs.stripe.com/api/subscriptions.md) simplifient votre facturation en créant automatiquement 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 objet *Produit* (Products represent what your business sells—whether that's a good or a service) pour modéliser ce qui est vendu, ainsi qu’un objet *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) pour déterminer l’intervalle et le montant à facturer. Vous avez également besoin d’un objet [Customer](https://docs.stripe.com/api/customers.md) pour enregistrer les *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilisés dans le cadre des paiements récurrents. Un diagramme illustrant des objets de facturation courants et leurs relations (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions) ### Définitions des objets API | Ressource | Définition | | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Customer](https://docs.stripe.com/api/customers.md) | Représente un client qui achète un abonnement. Utilisez l’objet Customer associé à un abonnement pour effectuer et suivre ses paiements récurrents et 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 qu’un client utilise pour payer vos produits. Vous pouvez par exemple enregistrer une carte bancaire dans un objet Customer et l’utiliser pour les paiements récurrents de ce client. Généralement utilisés 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 Le [SDK React Native](https://github.com/stripe/stripe-react-native) est disponible en open source et fait l’objet d’une documentation complète. En interne, il utilise des SDK [Android](https://github.com/stripe/stripe-android) et [iOS natifs](https://github.com/stripe/stripe-ios). Pour installer le SDK React Native de Stripe, exécutez l’une des commandes suivantes dans le répertoire de votre projet (selon le gestionnaire de paquets que vous utilisez) : #### yarn ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` Ensuite, installez les autres dépendances nécessaires : - Pour iOS, accédez au directeur **ios** et exécutez `pod install` pour vous assurer que vous installez également les dépendances natives requises. - Pour Android, il n’y a plus de dépendances à installer. > Nous vous recommandons de suivre le [guide officiel de TypeScript](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) pour ajouter la prise en charge de TypeScript. ### Initialisation de Stripe Pour initialiser Stripe dans votre application React Native, wrappez votre écran de paiement avec le composant `StripeProvider` ou utilisez la méthode d’initialisation `initStripe`. Seule la [clé publiable](https://docs.stripe.com/keys.md#obtain-api-keys) de l’API dans `publishableKey` est nécessaire. L’exemple suivant montre comment initialiser Stripe à l’aide du composant `StripeProvider`. ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > Utilisez vos [clés de test](https://docs.stripe.com/keys.md#obtain-api-keys) d’API lors de vos activités de test et de développement, et vos clés du [mode production](https://docs.stripe.com/keys.md#test-live-modes) pour la publication de votre application. 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 [Interface de ligne de commande Stripe 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 objet *client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pour chaque abonnement. Sur le front-end de votre application, collectez toutes les informations nécessaires sur vos utilisateurs et transmettez-les à votre back-end. > #### Comparer les références Customers v1 et Accounts v2 > > Si votre plateforme Connect utilise des [comptes configurés par le client](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer), consultez notre [guide](https://docs.stripe.com/connect/use-accounts-as-customers.md) pour remplacer dans votre code les références `Customer` et événements par les références équivalentes de l’API Comptes v2. Si vous avez besoin de recueillir une adresse, le composant Address Element vous permet de recueillir l’adresse de livraison ou de facturation de vos clients. Pour plus d’informations sur ce composant, consultez la page consacrée à [Address Element](https://docs.stripe.com/elements/address-element.md). ```javascript import React from 'react'; import {View, TextInput, StyleSheet, Button, Platform} from 'react-native'; function RegisterView() { const [email, setEmail] = React.useState(''); const createCustomer = async () => { const apiEndpoint = Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567'; const response = await fetch(`${apiEndpoint}/create-customer`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: email, }), }); if (response.status === 200) { const customer = await response.json(); console.log(customer); } }; return (