# Configurer et gérer des autorisations en temps réel Comment configurer et déployer un webhook pour répondre à des autorisations Issuing. # Outil pour la création de endpoints d’autorisation en temps réel Comment configurer et déployer un webhook pour répondre à des autorisations Issuing en temps réel. 1. Build the server ~~~ npm install ~~~ 2. Run the server ~~~ npm start ~~~ 1. Run the server ~~~ go run server.go ~~~ 1. Build the server ~~~ pip3 install -r requirements.txt ~~~ 2. Run the server ~~~ export FLASK_APP=server.py python3 -m flask run --port=4242 ~~~ 1. Build the server ~~~ bundle install ~~~ 2. Run the server ~~~ ruby server.rb -o 0.0.0.0 ~~~ 1. Build the server ~~~ composer install ~~~ 2. Run the server ~~~ php -S 127.0.0.1:4242 --docroot=public ~~~ 1. Build the server ~~~ dotnet restore ~~~ 2. Run the server ~~~ dotnet run ~~~ 1. Build the server ~~~ mvn package ~~~ 2. Run the server ~~~ java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ~~~ ~~~ stripe listen --forward-to localhost:4242/webhook.php ~~~ ~~~ stripe listen --forward-to localhost:4242/webhook ~~~ ### Installer la bibliothèque Node de Stripe Installez le package et importez-le dans votre code. Si vous partez de zéro et qu’il vous faut un fichier package.json, vous pouvez également télécharger les fichiers du projet à l’aide du lien de téléchargement dans l’éditeur de code. #### npm Installez la bibliothèque : ```bash npm install --save stripe ``` #### GitHub Vous pouvez sinon télécharger le code source de la bibliothèque Node de Stripe directement [depuis GitHub](https://github.com/stripe/stripe-node). ### Installer la bibliothèque Ruby de Stripe Installez le gem Ruby de Stripe et exigez-le dans votre code. Si vous partez de zéro et avez besoin d’un Gemfile, téléchargez les fichiers du projet à l’aide du lien dans l’éditeur de code. #### Terminal Installez le gem : ```bash gem install stripe ``` #### Bundler Ajoutez cette ligne à votre Gemfile : ```bash gem 'stripe' ``` #### GitHub Vous pouvez sinon télécharger le code source du gem Ruby de Stripe directement [depuis GitHub](https://github.com/stripe/stripe-ruby). ### Installer la bibliothèque Java Ajoutez la dépendance à votre build et importez la bibliothèque. Ou bien, si vous partez de zéro et avez besoin d’un exemple de fichier pom.xml (pour Maven), téléchargez les fichiers du projet à l’aide du lien de téléchargement dans l’éditeur de code. #### Maven Ajoutez la dépendance suivante à votre POM et remplacez {VERSION} par le numéro de version que vous souhaitez utiliser. ```bash \ncom.stripe\nstripe-java\n{VERSION}\n ``` #### Gradle Ajoutez la dépendance à votre fichier build.gradle et remplacez {VERSION} par le numéro de version que vous souhaitez utiliser. ```bash implementation "com.stripe:stripe-java:{VERSION}" ``` #### GitHub Téléchargez le fichier JAR directement [depuis GitHub](https://github.com/stripe/stripe-java/releases/latest). ### Installer le package Python de Stripe Installez le package Stripe et importez-le dans votre code. Si vous partez de zéro et qu’il vous faut un fichier requirements.txt, téléchargez les fichiers du projet à l’aide du lien de téléchargement dans l’éditeur de code. #### pip Installez le package via pip : ```bash pip3 install stripe ``` #### GitHub Téléchargez le code source de la bibliothèque stripe-python directement [depuis GitHub](https://github.com/stripe/stripe-python). ### Installer la bibliothèque PHP Installez la bibliothèque avec composer et initialisez-la avec votre clé API secrète. Si vous partez de zéro et que vous avez besoin d’un fichier composer.json, vous pouvez également télécharger les fichiers à l’aide du lien de téléchargement dans l’éditeur de code. #### Composer Installez la bibliothèque : ```bash composer require stripe/stripe-php ``` #### GitHub Vous pouvez sinon télécharger le code source de la bibliothèque php de Stripe directement [depuis GitHub](https://github.com/stripe/stripe-php). ### Configurer votre serveur Ajoutez la dépendance à votre build et importez la bibliothèque. Si vous partez de zéro et avez besoin d’un fichier go.mod, téléchargez les fichiers du projet à l’aide du lien de téléchargement dans l’éditeur de code. #### Go Veillez à initialiser avec des modules Go : ```bash go get -u github.com/stripe/stripe-go/v85 ``` #### GitHub Vous pouvez sinon télécharger le code source de la bibliothèque Go de Stripe directement [depuis GitHub](https://github.com/stripe/stripe-go). ### Installer la bibliothèque Stripe.net Installez le package avec .NET ou NuGet. Si vous partez de zéro, vous pouvez également télécharger les fichiers qui contiennent un fichier .csproj configuré. #### .NET Installez la bibliothèque : ```bash dotnet add package Stripe.net ``` #### NuGet Installez la bibliothèque : ```bash Install-Package Stripe.net ``` #### GitHub Vous pouvez sinon télécharger le code source de la bibliothèque .NET de Stripe directement [depuis GitHub](https://github.com/stripe/stripe-dotnet). ### Installer les bibliothèques Stripe Installez les packages et importez-les dans votre code. Si vous partez de zéro et qu’il vous faut un fichier `package.json`, vous pouvez également télécharger les fichiers du projet à l’aide du lien de téléchargement dans l’éditeur de code. Installez les bibliothèques : ```bash npm install --save stripe @stripe/stripe-js next ``` ### Configurer votre endpoint Votre webhook synchrone vous permet d’approuver ou de refuser les demandes d’autorisation en temps réel. Vous pouvez configurer votre endpoint de [webhook](https://docs.stripe.com/webhooks.md) dans vos [paramètres Issuing](https://dashboard.stripe.com/account/issuing). À chaque tentative de paiement, Stripe crée un événement `issuing_authorization.request` et l’envoie à l’endpoint configuré pour obtenir votre approbation. ### Lire les données de l’événement Stripe envoie les données de l’événement dans le corps de la requête. Chaque événement est structuré comme un [objet Event](https://docs.stripe.com/api/events.md) avec un `type`, un `id` et une ressource Stripe associée, intégrée sous les `data`. ### Gérer l’événement Dès que vous avez récupéré l’objet Event, vérifiez son [type](https://docs.stripe.com/api/events/types.md) et appliquez un filtre sur `issuing_authorization.request`. Il s’agit de l’événement webhook que Stripe envoie lors d’un paiement par carte. C’est ici que vous devez rédiger votre logique métier pour approuver ou refuser l’autorisation. Par exemple, vous pouvez faire en sorte de rejeter toutes les autorisations dont la valeur `amount` dépasse un certain montant. ### Répondre à la requête Le webhook `issuing_authorization.request` fonctionne de manière synchrone, ce qui vous permet d’approuver ou de refuser des demandes d’autorisation en temps réel. Vous pouvez inclure votre décision d’approbation dans le corps de la réponse de la requête de webhook. Pour ce faire, vous devez également indiquer `application/json` pour l’en-tête `Content-Type`. Pour en savoir plus, consultez la section relative aux [réponses directes aux demandes d’autorisation](https://docs.stripe.com/issuing/controls/real-time-authorizations.md#authorization-handling). Si Stripe ne reçoit pas votre réponse ou votre requête approuvant ou refusant l’autorisation sous 2 secondes, l’`Authorization` est automatiquement approuvée ou refusée en fonction de vos paramètres d’expiration. ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook`. ```bash ruby server.rb ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook`. ```bash npm start ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook.php`. ```bash php -S 127.0.0.1:4242 ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook`. ```bash python3 -m flask run --port=4242 ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook`. ```bash go run server.go ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à `http://localhost:4242/webhook`. ```bash dotnet run ``` ### Exécuter le serveur Développez, puis exécutez votre serveur pour tester l’endpoint à http://localhost:4242/webhook. ```bash java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ``` ### Télécharger l’interface de ligne de commande Utilisez l’interface de ligne de commande Stripe pour tester votre webhook localement. [Téléchargez l’interface de ligne de commande](https://github.com/stripe/stripe-cli) et connectez-vous avec votre compte Stripe. Vous pouvez également utiliser un service comme ngrok pour rendre votre endpoint local publiquement accessible. ```bash stripe login ``` ### Transférer les événements à votre endpoint Configurez le [transfert d’événements](https://docs.stripe.com/webhooks.md#test-webhook) à l’aide de la CLI pour envoyer tous les événements Stripe en mode test à votre endpoint de webhook local. ```bash stripe listen --forward-to localhost:4242/webhook ``` ### Transférer les événements à votre endpoint Configurez le [transfert d’événements](https://docs.stripe.com/webhooks.md#test-webhook) à l’aide de la CLI pour envoyer tous les événements Stripe en mode test à votre endpoint de webhook local. ```bash stripe listen --forward-to localhost:4242/webhook.php ``` ### Simuler une autorisation Utilisez la CLI pour simuler la demande d’autorisation en envoyant une requête POST à votre endpoint de webhook à l’aide d’un objet Event Stripe fictif. ```bash stripe trigger issuing_authorization.request ``` ## Félicitations ! Vous disposez d’un endpoint de webhook de base en mesure d’accepter les demandes d’autorisation de la part de Stripe. ### Sécuriser votre webhook Vérifiez la source des requêtes de webhook afin de contrer les possibles envois malveillants de fausses charges utiles ou de requêtes SQL à même de modifier vos systèmes back-end. Sécurisez votre webhook avec une signature client pour confirmer que Stripe a bien généré une requête de webhook et que celle-ci ne provient pas d’un serveur se faisant passer pour Stripe. ### Ajouter la clé secrète de l’endpoint Chaque endpoint de webhook possède une clé secrète de signature unique. Vous pouvez la trouver dans le Dashboard ou, si vous testez cet endpoint de webhook en local avec la CLI Stripe, en exécutant la commande `stripe listen`. ### Vérifier l’événement Utilisez la bibliothèque Stripe pour vérifier et assembler l’événement avec Stripe. Il vous faut la clé secrète de l’endpoint, l’en-tête de la requête et son contenu brut pour vérifier correctement l’événement. Vous pouvez également [vérifier manuellement](https://docs.stripe.com/webhooks.md#verify-manually) la signature sans avoir à utiliser la bibliothèque Stripe. ### Lire la signature de la requête Chaque requête provenant de Stripe contient un en-tête avec `Stripe-Signature`. Conservez une référence à cette valeur d’en-tête pour usage ultérieur. ### Vérifier la requête Utilisez la bibliothèque Stripe pour vérifier que la requête provient bien de Stripe. Transmettez le contenu brut de la requête, l’en-tête avec la `Stripe-Signature` et la clé secrète de l’endpoint pour développer un objet [Event](https://docs.stripe.com/api/events/object.md). ### Gérer les erreurs La vérification permet de détecter et d’identifier des erreurs comme les webhooks mal configurés ou les requêtes mal formées provenant de services non-Stripe. Les erreurs courantes comprennent l’utilisation d’une mauvaise clé secrète d’endpoint, la transmission d’une représentation (par exemple, JSON) analysée du contenu de la requête ou la lecture d’un mauvais en-tête de requête. ### Tester l’endpoint Testez votre endpoint sécurisé à l’aide de l’interface de ligne de commande Stripe, qui envoie l’en-tête de signature approprié dans chaque événement de test. Vous pouvez également utiliser la vue webhooks du [Dashboard](https://dashboard.stripe.com/webhooks) pour envoyer des événements ponctuels. require 'stripe' \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. \# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') \# Replace this endpoint secret with your endpoint's unique secret # If you're testing with the CLI, find the secret by running 'stripe listen' # If you're using an endpoint defined with the API or Dashboard, look in your webhook settings # at https://dashboard.stripe.com/webhooks endpoint_secret = 'whsec_...'; post '/webhook' do payload = request.body.read event = nil begin event = Stripe::Event.construct_from( JSON.parse(payload, symbolize_names: true) ) rescue JSON::ParserError => e \# Invalid payload puts "⚠️ Webhook error while parsing basic request. #{e.message}" status 400 return end \# Check if webhook signing is configured. if endpoint_secret # Retrieve the event by verifying the signature using the raw body and secret. signature = request.env['HTTP_STRIPE_SIGNATURE']; begin event = Stripe::Webhook.construct_event( payload, signature, endpoint_secret ) rescue Stripe::SignatureVerificationError => e puts "⚠️ Webhook signature verification failed. #{e.message}" status 400 end end \# Handle the event if event['type'] == 'issuing_authorization.request' auth = event['data']['object'] approved = auth.amount <= 10_00 status 200 headers 'Stripe-Version' => '2022-08-01', 'Content-Type' => 'application/json' data = { 'approved' => approved } body data.to_json return // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require('stripe')('<>'); // Replace this endpoint secret with your endpoint's unique secret // If you're testing with the CLI, find the secret by running 'stripe listen' // If you're using an endpoint defined with the API or Dashboard, look in your webhook settings // at https://dashboard.stripe.com/webhooks const endpointSecret = 'whsec_...'; const express = require('express'); const app = express(); app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => { const express = require('express'); const app = express(); app.post('/webhook', express.json({type: 'application/json'}), (request, response) => { let event = request.body; const event = request.body; // Only verify the event if you have an endpoint secret defined. // Otherwise use the basic event deserialized with JSON.parse if (endpointSecret) { // Get the signature sent by Stripe const signature = request.headers['stripe-signature']; try { event = stripe.webhooks.constructEvent( request.body, signature, endpointSecret ); } catch (err) { console.log(`⚠️ Webhook signature verification failed.`, err.message); return response.sendStatus(400); } } if (event.type === 'issuing_authorization.request') { const auth = event.data.object; const approved = auth.pending_request.amount <= 1000; response.writeHead(200, {"Stripe-Version": "2022-08-01", "Content-Type": "application/json"}); const body = JSON.stringify({"approved": approved}); response.end(body); return; } app.listen(4242, () => console.log('Running on port 4242')); { "name": "stripe-sample", "version": "1.0.0", "description": "A sample Stripe implementation", "main": "server.js", "scripts": { "start": "node server.js" }, "author": "stripe-samples", "license": "ISC", "dependencies": { "express": "^4.17.1", "stripe": "^21.0.1" } } { "name": "stripe-sample", "version": "0.1.0", "dependencies": { "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.3.0", "express": "^4.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^3.4.0", "stripe": "21.0.1" }, "devDependencies": { "concurrently": "4.1.2" }, "homepage": "http://localhost:3000/checkout", "proxy": "http://localhost:4242", "scripts": { "start-client": "react-scripts start", "start-server": "node server.js", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start": "concurrently \"yarn start-client\" \"yarn start-server\"" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } $stripe = new \Stripe\StripeClient($stripeSecretKey); // Replace this endpoint secret with your endpoint's unique secret // If you're testing with the CLI, find the secret by running 'stripe listen' // If you are using an endpoint defined with the API or Dashboard, look in your webhook settings // at https://dashboard.stripe.com/webhooks $endpoint_secret = 'whsec_...'; $payload = @file_get_contents('php://input'); $event = null; try { $event = \Stripe\Event::constructFrom( json_decode($payload, true) ); } catch(\UnexpectedValueException $e) { // Invalid payload echo '⚠️ Webhook error while parsing basic request.'; http_response_code(400); exit(); } if ($endpoint_secret) { // Only verify the event if there is an endpoint secret defined // Otherwise use the basic decoded event $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE']; try { $event = \Stripe\Webhook::constructEvent( $payload, $sig_header, $endpoint_secret ); } catch(\Stripe\Exception\SignatureVerificationException $e) { // Invalid signature echo '⚠️ Webhook error while validating signature.'; http_response_code(400); exit(); } } if ($event->type == 'issuing_authorization.request') { $auth = $event->data->object; $approved = $auth->amount < 1000; http_response_code(200); header('Stripe-Version: 2022-08-01', false); header('Content-Type: application/json', false); echo json_encode(['approved' => $approved]); exit(); // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. $stripeSecretKey = '<>'; import stripe \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. \# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = stripe.StripeClient('<>') \# Replace this endpoint secret with your endpoint's unique secret # If you're testing with the CLI, find the secret by running 'stripe listen' # If you're using an endpoint defined with the API or Dashboard, look in your webhook settings # at https://dashboard.stripe.com/webhooks endpoint_secret = 'whsec_...' app = Flask(__name__) @app.route('/webhook', methods=['POST']) try: event = json.loads(payload) except json.decoder.JSONDecodeError as e: print('⚠️ Webhook error while parsing basic request.' + str(e)) return jsonify(success=False) if endpoint_secret: \# Only verify the event if there is an endpoint secret defined # Otherwise use the basic event deserialized with json sig_header = request.headers.get('stripe-signature') try: event = client.construct_event( payload, sig_header, endpoint_secret ) except stripe.error.SignatureVerificationError as e: print('⚠️ Webhook signature verification failed.' + str(e)) return jsonify(success=False) if event["type"] == "issuing_authorization.request": auth = event["data"]["object"] approved = auth.amount <= 1000 return json.dumps({"approved": approved}), 200, {"Stripe-Version": "2022-08-01", "Content-Type": "application/json"} certifi==2026.1.4 chardet==5.2.0 click==8.3.1 Flask==3.1.2 idna==3.11 itsdangerous==2.2.0 Jinja2==3.1.6 MarkupSafe==3.0.3 requests==2.32.5 stripe==15.0.0 toml==0.10.2 Werkzeug==3.1.5 // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. services.AddSingleton(new StripeClient("<>")); [Route("webhook")] [ApiController] [Produces("application/json")] public class WebhookController : Controller const string endpointSecret = "whsec_..."; var stripeEvent = EventUtility.ParseEvent(json); var signatureHeader = Request.Headers["Stripe-Signature"]; stripeEvent = EventUtility.ConstructEvent(json, signatureHeader, endpointSecret); // If on SDK version < 46, use class Events instead of EventTypes if (stripeEvent.Type == EventTypes.IssuingAuthorizationRequest) { var authorization = stripeEvent.Data.Object as Authorization; bool approved = false; if (authorization.Amount < 1000) { approved = true; } var data = new { approved = approved }; Response.Headers.Add("Stripe-Version", "2022-08-01"); return Ok(data); catch (StripeException e) { Console.WriteLine("Error: {0}", e.Message); return BadRequest(); } "github.com/stripe/stripe-go/v85" "github.com/stripe/stripe-go/v85/webhook" // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. sc = stripe.NewClient("<>") http.HandleFunc("/webhook", handleWebhook) event := stripe.Event{} if err := json.Unmarshal(payload, &event); err != nil { fmt.Fprintf(os.Stderr, "⚠️ Webhook error while parsing basic request. %v\n", err.Error()) w.WriteHeader(http.StatusBadRequest) return } // Replace this endpoint secret with your endpoint's unique secret // If you're testing with the CLI, find the secret by running 'stripe listen' // If you're using an endpoint defined with the API or Dashboard, look in your webhook settings // at https://dashboard.stripe.com/webhooks endpointSecret := "whsec_..." signatureHeader := req.Header.Get("Stripe-Signature") event, err := sc.ConstructEvent(payload, signatureHeader, endpointSecret) if err != nil { fmt.Fprintf(os.Stderr, "⚠️ Webhook signature verification failed. %v\n", err) w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature return } if event.Type == "issuing_authorization.request" { var auth stripe.IssuingAuthorization err := json.Unmarshal(event.Data.Raw, &auth) if err != nil { fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err) w.WriteHeader(http.StatusBadRequest) return } approved := false if auth.Amount < 10000 { approved = true } w.Header().Set("Stripe-Version", "2022-08-01") w.Header().Set("Content-Type", "application/json") data := make(map[string]bool) data["approved"] = approved json.NewEncoder(w).Encode(data) return } require github.com/stripe/stripe-go/v85 v85.0.0 import com.stripe.exception.SignatureVerificationException; // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. StripeClient client = new StripeClient("<>"); // Replace this endpoint secret with your endpoint's unique secret // If you're testing with the CLI, find the secret by running 'stripe listen' // If you're using an endpoint defined with the API or Dashboard, look in your webhook settings // at https://dashboard.stripe.com/webhooks String endpointSecret = "whsec_..."; post("/webhook", (request, response) -> { String payload = request.body(); Event event = null; try { event = ApiResource.GSON.fromJson(payload, Event.class); } catch (JsonSyntaxException e) { // Invalid payload System.out.println("⚠️ Webhook error while parsing basic request."); response.status(400); return ""; } String sigHeader = request.headers("Stripe-Signature"); if (endpointSecret != null && sigHeader != null) { // Only verify the event if you have an endpoint secret defined. // Otherwise use the basic event deserialized with GSON. try { event = client.constructEvent( payload, sigHeader, endpointSecret); } catch (SignatureVerificationException e) { // Invalid signature System.out.println("⚠️ Webhook error while validating signature."); response.status(400); return ""; } } if ("issuing_authorization.request".equals(event.getType())) { if (!Objects.isNull(stripeObject)) { Authorization auth = (Authorization) stripeObject; boolean approved = false; if (auth.getAmount() < 1000) { approved = true; } response.status(200); response.header("Stripe-Version", "2022-08-01"); response.body(new Gson().toJson(Collections.singletonMap("approved", approved))); ## Prochaines étapes #### [Mise en production](https://docs.stripe.com/webhooks.md#register-webhook) Apprenez à déployer votre endpoint de webhook en mode production et à gérer des événements à grande échelle en n’envoyant que les événements dont vous avez besoin. #### [CLI Stripe](https://docs.stripe.com/stripe-cli.md) L’interface de ligne de commande Stripe comporte plusieurs commandes vous permettant de tester votre application Stripe au-delà des webhooks.