# Récupérer des paniers abandonnés Comment récupérer des pages Checkout abandonnées et augmenter vos revenus. # Page hébergée > This is a Page hébergée for when payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/checkout/abandoned-carts?payment-ui=stripe-hosted. Dans le e-commerce, un [abandon de panier](https://docs.stripe.com/payments/checkout/compliant-promotional-emails.md) désigne le fait pour un client de quitter votre tunnel de paiement avant d’avoir finalisé son achat. Pour inciter vos clients à finaliser leur commande sur Checkout, créez un flux de relance par e-mail. Les e-mails d’abandon de panier tombent dans la catégorie plus générale des *e-mails promotionnels*, qui comprend les e-mails visant à informer les clients des nouveaux produits et à partager avec eux des bons de réduction et des ristournes. Les clients doivent accepter de recevoir des e-mails promotionnels pour que vous puissiez les contacter. Checkout vous aide : 1. Demander le consentement des clients pour leur envoyer des e-mails promotionnels. 1. Recevoir des notifications lorsque des clients quittent Checkout pour pouvoir leur envoyer des e-mails concernant l’abandon de leur panier. ## Demander le consentement relatif au contenu promotionnel Configurez Checkout pour [recueillir le consentement de vos clients à recevoir votre contenu promotionnel](https://docs.stripe.com/payments/checkout/promotional-emails-consent.md). Si vous collectez l’adresse e-mail du client ainsi que ce consentement avant de le rediriger vers Checkout, vous n’avez pas besoin d’utiliser `consent_collection[promotions]`. > #### Utiliser l’API Accounts v2 pour représenter les clients > > L’API Accounts v2 est disponible en version générale pour les utilisateurs Connect, et en version bêta publique pour les autres utilisateurs Stripe. Tous les utilisateurs Stripe peuvent activer Accounts v2 [dans leur Dashboard](https://dashboard.stripe.com/settings/connect/platform-setup). Cependant, lorsqu’ils effectuent des appels à l’API Accounts v2, les utilisateurs de la version bêta doivent [indiquer une version bêta](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning). > > Dans la plupart des cas d’usage, nous vous recommandons de [modéliser vos clients en tant qu’objets Account configurés par le client](https://docs.stripe.com/connect/use-accounts-as-customers.md), plutôt que d’utiliser des objets [Customer](https://docs.stripe.com/api/customers.md). #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "consent_collection[promotions]=auto" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "customer={{CUSTOMER_ID}}" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "consent_collection[promotions]=auto" ``` ## Configurer la récupération Une session Checkout est abandonnée lorsqu’elle atteint son horodatage [expires_at](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-expires_at) et que le client n’a pas finalisé son paiement. Dans ce cas, la session n’est plus accessible et Stripe déclenche le `checkout.session.expired` *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests), que vous pouvez écouter de manière à tenter de ramener ensuite le client dans une nouvelle session de paiement pour qu’il finalise son achat. Pour utiliser cette fonctionnalité, activez `after_expiration.recovery` lorsque vous créez la session. #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "customer={{CUSTOMER_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` ## Recevoir des notifications d'abandon Écoutez le webhook `checkout.session.expired` pour recevoir des notifications lorsqu’un client quitte Checkout et que la session expire. Lorsque la session expire et que la récupération est activée, la charge utile du webhook contient [after_expiration](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-after_expiration-recovery), qui comprend une URL `after_expiration.recovery.url` que vous pouvez intégrer dans les e-mails d’abandon de panier. Lorsque le client ouvre cette URL, **cela crée une nouvelle session Checkout qui sera une copie de la session initiale ayant expiré**. Le client utilise cette session copiée pour finaliser l’achat. > Pour des raisons de sécurité, l’URL de récupération d’une session a une durée de validité de 30 jours, indiquée par l’horodatage `after_expiration.recovery.expires_at`. ```json { "id": "evt_123456789", "object": "event", "type": "checkout.session.expired", // ...other webhook attributes "data": { "object": { "id": "cs_12356789", "object": "checkout.session", // ...other Checkout Session attributes"consent_collection": { "promotions": "auto", }, "consent": { "promotions": "opt_in" }, "after_expiration": { "recovery": { "enabled": true, "url": "https://buy.stripe.com/r/live_asAb1724", "allow_promotion_code": true, "expires_at": 1622908282, } } } } } ``` ## Envoyer des e-mails de relance Pour envoyer des e-mails de récupération de panier, créez un gestionnaire de webhooks pour les sessions expirées et envoyez un e-mail qui intègre l’URL de récupération de la session. Un client peut abandonner plusieurs sessions Checkout, chacune déclenchant son propre événement `checkout.session.expired`. Veillez donc à prendre note des e-mails de récupération envoyés aux clients pour éviter l’envoi de courriers indésirables. #### Node.js ```javascript // Find your endpoint's secret in your Dashboard's webhook settings const endpointSecret = 'whsec_...'; // Using Express const app = require('express')(); // Use body-parser to retrieve the raw body as a buffer const bodyParser = require('body-parser');const sendRecoveryEmail = (email, recoveryUrl) => { // TODO: fill me in console.log("Sending recovery email", email, recoveryUrl); } app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => { const payload = request.body; const sig = request.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(payload, sig, endpointSecret); } catch (err) { return response.status(400).send(`Webhook Error: ${err.message}`); }// Handle the checkout.session.expired event if (event.type === 'checkout.session.expired') { const session = event.data.object; // When a Checkout Session expires, the customer's email isn't returned in // the webhook payload unless they give consent for promotional content const email = session.customer_details?.email const recoveryUrl = session.after_expiration?.recovery?.url // Do nothing if the Checkout Session has no email or recovery URL if (!email || !recoveryUrl) { return response.status(200).end(); } // Check if the customer has consented to promotional emails and // avoid spamming people who abandon Checkout multiple times if ( session.consent?.promotions === 'opt_in' && !hasSentRecoveryEmailToCustomer(email) ) { sendRecoveryEmail(email, recoveryUrl) } } response.status(200).end(); }); ``` ## Optional: Modifier l'expiration de la session Par défaut, les sessions Checkout expirent 24 heures après leur création, mais vous pouvez réduire cette durée en paramétrant `expires_at` pour recevoir des notifications plus tôt en cas d’abandon. La valeur minimale autorisée pour `expires_at` est de 30 minutes à compter de la création de la session. #### Accounts v2 #### cURL ```bash curl https://api.stripe.com/v1/checkout/sessions \ -u <>: \ -d customer_account='{{CUSTOMER_ACCOUNT_ID}}' \ -d "line_items[0][price]"='{{PRICE_ID}}' \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \-d expires_at="{{NOW_PLUS_TWO_HOURS}}" ``` #### Customers v1 #### cURL ```bash curl https://api.stripe.com/v1/checkout/sessions \ -u <>: \ -d customer='{{CUSTOMER_ID}}' \ -d "line_items[0][price]"='{{PRICE_ID}}' \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d success_url="https://example.com/success" \-d expires_at="{{NOW_PLUS_TWO_HOURS}}" ``` ## Optional: Suivre le taux de conversion Lorsqu’un client ouvre l’URL de récupération d’une session Checkout ayant expiré, cela crée une nouvelle session Checkout qui est une copie de la session abandonnée. Pour déterminer si un e-mail de relance a abouti à une conversion, vérifiez l’attribut [recovered_from](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-recovered_from) dans le webhook `checkout.session.completed` de la nouvelle session Checkout. Cet attribut fait référence à la session d’origine ayant expiré. #### Node.js ```javascript // Find your endpoint's secret in your Dashboard's webhook settings const endpointSecret = 'whsec_...'; // Using Express const app = require('express')(); // Use body-parser to retrieve the raw body as a buffer const bodyParser = require('body-parser');const logRecoveredCart = (sessionId, recoveredFromSessionId) => { // TODO: fill me in console.log("Recording recovered session", sessionId, recoveredFromSessionId); } app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => { const payload = request.body; const sig = request.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(payload, sig, endpointSecret); } catch (err) { return response.status(400).send(`Webhook Error: ${err.message}`); }// Handle the checkout.session.completed event if (event.type === 'checkout.session.completed') { const session = event.data.object; const recoveryFromSessionId = session.recovered_from if (recoveryFromSessionId) { // Log relationship between successfully completed session and abandoned session logRecoveredCart(session.id, recoveryFromSessionId) } // Handle order fulfillment } response.status(200).end(); }); ``` ## Optional: Offrir des codes promotionnels dans les e-mails de relance Offrir des [ristournes](https://docs.stripe.com/payments/checkout/discounts.md) aux clients qui abandonnent leurs paniers peut les inciter à finaliser leur commande. Vous pouvez configurer l’affichage d’une option pour les codes promotionnels dans la session Checkout créée par l’URL de récupération en spécifiant le paramètre `after_expiration.recovery.allow_promotion_code`. #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/success" \ -d "customer={{CUSTOMER_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` # Page intégrée > This is a Page intégrée for when payment-ui is embedded-form. View the full page at https://docs.stripe.com/payments/checkout/abandoned-carts?payment-ui=embedded-form. Dans le e-commerce, un [abandon de panier](https://docs.stripe.com/payments/checkout/compliant-promotional-emails.md) désigne le fait pour un client de quitter votre tunnel de paiement avant d’avoir finalisé son achat. Pour inciter vos clients à finaliser leur commande sur Checkout, créez un flux de relance par e-mail. Les e-mails d’abandon de panier tombent dans la catégorie plus générale des *e-mails promotionnels*, qui comprend les e-mails visant à informer les clients des nouveaux produits et à partager avec eux des bons de réduction et des ristournes. Les clients doivent accepter de recevoir des e-mails promotionnels pour que vous puissiez les contacter. Checkout vous aide : 1. Demander le consentement des clients pour leur envoyer des e-mails promotionnels. 1. Recevoir des notifications lorsque des clients quittent Checkout pour pouvoir leur envoyer des e-mails concernant l’abandon de leur panier. ## Demander le consentement relatif au contenu promotionnel Configurez Checkout pour [recueillir le consentement de vos clients à recevoir votre contenu promotionnel](https://docs.stripe.com/payments/checkout/promotional-emails-consent.md). Si vous collectez l’adresse e-mail du client ainsi que ce consentement avant qu’il ne voie le formulaire intégré, vous n’avez pas besoin d’utiliser `consent_collection[promotions]`. > #### Utiliser l’API Accounts v2 pour représenter les clients > > L’API Accounts v2 est disponible en version générale pour les utilisateurs Connect, et en version bêta publique pour les autres utilisateurs Stripe. Tous les utilisateurs Stripe peuvent activer Accounts v2 [dans leur Dashboard](https://dashboard.stripe.com/settings/connect/platform-setup). Cependant, lorsqu’ils effectuent des appels à l’API Accounts v2, les utilisateurs de la version bêta doivent [indiquer une version bêta](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning). > > Dans la plupart des cas d’usage, nous vous recommandons de [modéliser vos clients en tant qu’objets Account configurés par le client](https://docs.stripe.com/connect/use-accounts-as-customers.md), plutôt que d’utiliser des objets [Customer](https://docs.stripe.com/api/customers.md). #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "consent_collection[promotions]=auto" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "customer={{CUSTOMER_ID}}" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/return" \ -d "consent_collection[promotions]=auto" ``` ## Configurer la récupération Une session Checkout est abandonnée lorsqu’elle atteint son horodatage [expires_at](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-expires_at) et que le client n’a pas finalisé son paiement. Dans ce cas, la session n’est plus accessible et Stripe déclenche le `checkout.session.expired` *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests), que vous pouvez écouter de manière à tenter de ramener ensuite le client dans une nouvelle session de paiement pour qu’il finalise son achat. Pour utiliser cette fonctionnalité, activez `after_expiration.recovery` lorsque vous créez la session. #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" \ -d "customer={{CUSTOMER_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` ## Recevoir des notifications d'abandon Écoutez le webhook `checkout.session.expired` pour recevoir des notifications lorsqu’un client quitte Checkout et que la session expire. Lorsque la session expire et que la récupération est activée, la charge utile du webhook contient [after_expiration](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-after_expiration-recovery), qui comprend une URL `after_expiration.recovery.url` que vous pouvez intégrer dans les e-mails d’abandon de panier. Lorsque le client ouvre cette URL, **cela crée une nouvelle session Checkout qui sera une copie de la session initiale ayant expiré**. Le client utilise cette session copiée pour finaliser l’achat. > Pour des raisons de sécurité, l’URL de récupération d’une session a une durée de validité de 30 jours, indiquée par l’horodatage `after_expiration.recovery.expires_at`. ```json { "id": "evt_123456789", "object": "event", "type": "checkout.session.expired", // ...other webhook attributes "data": { "object": { "id": "cs_12356789", "object": "checkout.session", // ...other Checkout Session attributes"consent_collection": { "promotions": "auto", }, "consent": { "promotions": "opt_in" }, "after_expiration": { "recovery": { "enabled": true, "url": "https://buy.stripe.com/r/live_asAb1724", "allow_promotion_code": true, "expires_at": 1622908282, } } } } } ``` ## Envoyer des e-mails de relance Pour envoyer des e-mails de récupération de panier, créez un gestionnaire de webhooks pour les sessions expirées et envoyez un e-mail qui intègre l’URL de récupération de la session. Un client peut abandonner plusieurs sessions Checkout, chacune déclenchant son propre événement `checkout.session.expired`. Veillez donc à prendre note des e-mails de récupération envoyés aux clients pour éviter l’envoi de courriers indésirables. #### Node.js ```javascript // Find your endpoint's secret in your Dashboard's webhook settings const endpointSecret = 'whsec_...'; // Using Express const app = require('express')(); // Use body-parser to retrieve the raw body as a buffer const bodyParser = require('body-parser');const sendRecoveryEmail = (email, recoveryUrl) => { // TODO: fill me in console.log("Sending recovery email", email, recoveryUrl); } app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => { const payload = request.body; const sig = request.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(payload, sig, endpointSecret); } catch (err) { return response.status(400).send(`Webhook Error: ${err.message}`); }// Handle the checkout.session.expired event if (event.type === 'checkout.session.expired') { const session = event.data.object; // When a Checkout Session expires, the customer's email isn't returned in // the webhook payload unless they give consent for promotional content const email = session.customer_details?.email const recoveryUrl = session.after_expiration?.recovery?.url // Do nothing if the Checkout Session has no email or recovery URL if (!email || !recoveryUrl) { return response.status(200).end(); } // Check if the customer has consented to promotional emails and // avoid spamming people who abandon Checkout multiple times if ( session.consent?.promotions === 'opt_in' && !hasSentRecoveryEmailToCustomer(email) ) { sendRecoveryEmail(email, recoveryUrl) } } response.status(200).end(); }); ``` ## Optional: Modifier l'expiration de la session Par défaut, les sessions Checkout expirent 24 heures après leur création, mais vous pouvez réduire cette durée en paramétrant `expires_at` pour recevoir des notifications plus tôt en cas d’abandon. La valeur minimale autorisée pour `expires_at` est de 30 minutes à compter de la création de la session. #### cURL ```bash curl https://api.stripe.com/v1/checkout/sessions \ -u <>: \ -d customer='{{CUSTOMER_ID}}' \ -d "line_items[0][price]"='{{PRICE_ID}}' \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d ui_mode=embedded_page \ -d return_url="https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" \-d expires_at="{{NOW_PLUS_TWO_HOURS}}" ``` ## Optional: Suivre le taux de conversion Lorsqu’un client ouvre l’URL de récupération d’une session Checkout ayant expiré, cela crée une nouvelle session Checkout qui est une copie de la session abandonnée. Pour déterminer si un e-mail de relance a abouti à une conversion, vérifiez l’attribut [recovered_from](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-recovered_from) dans le webhook `checkout.session.completed` de la nouvelle session Checkout. Cet attribut fait référence à la session d’origine ayant expiré. #### Node.js ```javascript // Find your endpoint's secret in your Dashboard's webhook settings const endpointSecret = 'whsec_...'; // Using Express const app = require('express')(); // Use body-parser to retrieve the raw body as a buffer const bodyParser = require('body-parser');const logRecoveredCart = (sessionId, recoveredFromSessionId) => { // TODO: fill me in console.log("Recording recovered session", sessionId, recoveredFromSessionId); } app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => { const payload = request.body; const sig = request.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(payload, sig, endpointSecret); } catch (err) { return response.status(400).send(`Webhook Error: ${err.message}`); }// Handle the checkout.session.completed event if (event.type === 'checkout.session.completed') { const session = event.data.object; const recoveryFromSessionId = session.recovered_from if (recoveryFromSessionId) { // Log relationship between successfully completed session and abandoned session logRecoveredCart(session.id, recoveryFromSessionId) } // Handle order fulfillment } response.status(200).end(); }); ``` ## Optional: Offrir des codes promotionnels dans les e-mails de relance Offrir des [ristournes](https://docs.stripe.com/payments/checkout/discounts.md) aux clients qui abandonnent leurs paniers peut les inciter à finaliser leur commande. Vous pouvez configurer l’affichage d’une option pour les codes promotionnels dans la session Checkout créée par l’URL de récupération en spécifiant le paramètre `after_expiration.recovery.allow_promotion_code`. #### Accounts v2 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}" \ -d "customer={{CUSTOMER_ID}}" \ -d "consent_collection[promotions]=auto" \ -d "after_expiration[recovery][enabled]=true" \ -d "after_expiration[recovery][allow_promotion_codes]=true" ```