# Accepter un paiement Bancontact Découvrez comment accepter les paiements effectués à l'aide de Bancontact, un moyen de paiement très répandu en Belgique. # API Direct Bancontact est un moyen de paiement [à usage unique](https://docs.stripe.com/payments/payment-methods.md#usage) qui nécessite une [authentification](https://docs.stripe.com/payments/payment-methods.md#customer-actions) de son paiement par le client. Pour effectuer un paiement avec Bancontact, votre *client* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) quitte votre application, authentifie son paiement, puis revient sur votre application. Vous recevez alors une [notification immédiate](https://docs.stripe.com/payments/payment-methods.md#payment-notification) vous indiquant si le paiement a abouti ou s’il a échoué. > Votre utilisation de Bancontact doit se conformer aux [Conditions d’utilisation du service Bancontact](https://stripe.com/bancontact/legal). ## Configurer Stripe [Côté serveur] Pour commencer, vous devez créer un compte Stripe. [Inscrivez-vous maintenant](https://dashboard.stripe.com/register). Utilisez nos bibliothèques officielles pour accéder à l’API Stripe depuis votre application : #### 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éer un PaymentIntent [Côté serveur] Un [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) est un objet qui représente votre intention d’encaisser le paiement d’un client et qui suit le cycle de vie du processus de paiement étape par étape. Créez un `PaymentIntent` sur votre serveur et spécifiez le montant à collecter ainsi que la devise `eur` (Bancontact ne prend pas en charge d’autres devises). Si vous disposez d’une intégration [Payment Intents](https://docs.stripe.com/payments/payment-intents.md) existante, les moyens de paiement admissibles s’affichent automatiquement en fonction de la devise et des autres paramètres que vous fournissez. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=eur \ -d "automatic_payment_methods[enabled]=true" ``` Par défaut, la langue de la page d’autorisation de Bancontact est l’anglais (`en`). Vous pouvez la remplacer par la langue préférée de votre client en réglant la propriété `preferred_language` sur `fr`, `nl` ou `de`. ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=eur \ -d "automatic_payment_methods[enabled]=true" \ -d "payment_method_options[bancontact][preferred_language]=fr" ``` ### Récupérer la clé secrète du client Le PaymentIntent contient une *clé secrète* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) à utiliser côté client pour finaliser le processus de paiement en toute sécurité. Vous pouvez adopter différentes approches pour transmettre cette clé secrète côté client. #### Application monopage Récupérez la clé secrète du client à partir d’un endpoint sur votre serveur, à l’aide de la fonction `fetch` du navigateur. Cette approche est recommandée si votre côté client est une application d’une seule page, en particulier si elle repose sur un framework front-end moderne tel que React. Créez l’endpoint de serveur qui gère la clé secrète du client : #### Ruby ```ruby get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` Récupérez ensuite la clé secrète du client à l’aide JavaScript côté client : ```javascript (async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })(); ``` #### Rendu côté serveur Transmettez la clé secrète à votre client depuis votre serveur. Cette approche fonctionne mieux si votre application génère du contenu statique sur le serveur avant de l’envoyer sur le navigateur. Ajoutez le [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) à votre formulaire de paiement. Dans votre code côté serveur, récupérez la clé secrète du client à partir du PaymentIntent : #### Ruby ```erb
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` ## Collecter les informations du moyen de paiement [Côté client] #### HTML + JS Créez un formulaire de paiement côté client pour collecter les informations de facturation du client : | Champ | Valeur | | ------ | ------------------------ | | `name` | Nom et prénom du client. | ```html
``` #### React #### npm Installez [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) et le [chargeur Stripe.js](https://www.npmjs.com/package/@stripe/stripe-js) à partir du registre public npm. ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` #### umd Nous fournissons également une version UMD pour les sites qui n’utilisent pas npm ni de modules. Incluez le script Stripe.js, qui exporte une fonction `Stripe` globale, ainsi que la version UMD de React Stripe.js, qui exporte un objet `ReactStripe` global. Chargez toujours le script Stripe.js directement à partir de **js.stripe.com** pour maintenir votre conformité PCI. Vous ne devez pas inclure le script dans un lot ni en héberger de copie. ```html ``` > La [démo de CodeSandbox](https://codesandbox.io/s/react-stripe-official-q1loc?fontsize=14&hidenavigation=1&theme=dark) vous permet de tester React Stripe.js sans créer de projet. ### Ajoutez Stripe.js et Elements à votre page Pour utiliser les composants Element, enveloppez votre composant de page de paiement dans un [fournisseur Elements](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider). Appelez `loadStripe` avec votre clé publiable et transmettez l’élément `Promise` renvoyé au fournisseur `Elements`. ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component's render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); function App() { return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` ## Soumettre le paiement à Stripe [Côté client] Créez un paiement côté client à l’aide de la [clé secrète du client](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) du `PaymentIntent`. La clé secrète du client est différente de vos clés d’API, qui servent à authentifier les requêtes adressées à l’API Stripe. Elle doit être manipulée avec précaution, car elle permet de finaliser le paiement. Ne la consignez pas dans les logs, ne l’intégrez pas dans des URL et ne l’exposez à personne d’autre que le client. #### HTML + JS Lorsqu’un client clique pour payer avec Bancontact, utilisez Stripe.js pour soumettre le paiement à Stripe. [Stripe.js](https://docs.stripe.com/payments/elements.md) est la bibliothèque JavaScript de base pour créer les tunnels de paiement : elle gère automatiquement les opérations complexes telles que la redirection décrite ci-dessous, et facilite l’extension de votre intégration à d’autres moyens de paiement. Incluez le script Stripe.js sur votre page de paiement en l’ajoutant à la section `head` de votre fichier HTML. ```html Checkout ``` Créez une instance de Stripe.js avec le code JavaScript suivant sur votre page de paiement. ```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('<>'); ``` Appelez [stripe.confirmBancontactPayment](https://docs.stripe.com/js/payment_intents/confirm_bancontact_payment) pour rediriger votre client vers le site Web ou l’application de Bancontact afin d’effectuer le paiement. Ajoutez une URL `return_url` pour rediriger votre client une fois le paiement effectué. Vous devez également fournir le nom complet du client dans `billing_details`. ```javascript var stripe = Stripe('<>'); // Redirects away from the client const {error} = await stripe.confirmBancontactPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { name: "Jenny Rosen" } }, return_url: 'https://example.com/checkout/complete', } ); if (error) { // Inform the customer that there was an error. } ``` #### React Utilisez [stripe.confirmBancontactPayment](https://docs.stripe.com/js/payment_intents/confirm_bancontact_payment) pour exécuter la redirection vers la banque et effectuer le paiement. Ajoutez une [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) à cette fonction pour indiquer à Stripe vers quelle page rediriger l’utilisateur une fois le paiement effectué sur le site Web ou l’application mobile de sa banque. Pour appeler `stripe.confirmBancontactPayment` depuis votre composant de formulaire de paiement, utilisez les hooks [useStripe](https://docs.stripe.com/sdks/stripejs-react.md#usestripe-hook) et [useElements](https://docs.stripe.com/sdks/stripejs-react.md#useelements-hook). Si vous préférez les composants de classe traditionnels aux hooks, vous pouvez utiliser un [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer). #### Hooks ```jsx import React from 'react'; import {useStripe, useElements} from '@stripe/react-stripe-js'; export default function CheckoutForm() { const stripe = useStripe(); const elements = useElements(); const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe || !elements) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } // For brevity, this example is using uncontrolled components for // the accountholder's name. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const {error} = await stripe.confirmBancontactPayment('{CLIENT_SECRET}', { payment_method: { billing_details: { name: accountholderName.value, }, }, return_url: 'https://example.com/checkout/complete', }); if (error) { // Show error to your customer. console.log(error.message); } // Otherwise the customer will be redirected away from your // page to complete the payment with their bank. }; return (
); } ``` #### Composants de classe ```jsx import React from 'react'; import {ElementsConsumer} from '@stripe/react-stripe-js'; class CheckoutForm extends React.Component { handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const {stripe, elements} = this.props if (!stripe || !elements) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } // For brevity, this example is using uncontrolled components for // the accountholder's name. In a real world app you will // probably want to use controlled components. // https://reactjs.org/docs/uncontrolled-components.html // https://reactjs.org/docs/forms.html#controlled-components const accountholderName = event.target['accountholder-name']; const {error} = await stripe.confirmBancontactPayment('{CLIENT_SECRET}', { payment_method: { billing_details: { name: accountholderName.value, }, }, return_url: 'https://example.com/checkout/complete', }); if (error) { // Show error to your customer. console.log(error.message); } // Otherwise the customer will be redirected away from your // page to complete the payment with their bank. }; render() { const {stripe} = this.props; return (
); } } export default function InjectedCheckoutForm() { return ( {({stripe, elements}) => ( )} ); } ``` ### Effectuer la redirection Les paramètres de requête d’URL suivants sont fournis lorsque Stripe redirige le client vers l’URL `return_url`. | Paramètre | Description | | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent` | L’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`. | Vous pouvez également ajouter vos propres paramètres de requête lorsque vous fournissez `return_url`. Ceux-ci resteront activés pendant toute la durée du processus de redirection. Le paramètre `return_url` doit correspondre à une page de votre site web sur laquelle l’état du paiement est fourni. Vous devez vérifier l’état du `PaymentIntent` lors de l’affichage de la page de retour. Vous pouvez le faire en utilisant la fonction `retrievePaymentIntent` de Stripe.js et en transmettant `payment_intent_client_secret`. ```javascript (async () => { const url = new URL(window.location); const clientSecret = url.searchParams.get('payment_intent_client_secret'); const {paymentIntent, error} = await stripe.retrievePaymentIntent(clientSecret); if (error) { // Handle error } else if (paymentIntent && paymentIntent.status === 'succeeded') { // Handle successful payment } })(); ``` ### Détails du compte bancaire Vous pouvez consulter les informations concernant le compte bancaire qu’utilise le client pour effectuer le paiement sur le montant facturé dans la propriété [payment_method_details](https://docs.stripe.com/api/charges/object.md#charge_object-payment_method_details-bancontact). #### Json ```json { "charges": { "data": [ {"payment_method_details": { "bancontact": { "bank_code": "VAPE", "bank_name": "VAN DE PUT & CO", "bics": "VAPEBE22", "iban_last4": "7061", "preferred_language": "en", "verified_name": "Jenny Rosen" }, "type": "bancontact" }, "id": "src_16xhynE8WzK49JbAs9M21jaR", "object": "source", "amount": 1099, "client_secret": "src_client_secret_UfwvW2WHpZ0s3QEn9g5x7waU", "created": 1445277809, "currency": "eur", "flow": "redirect", "livemode": true, "statement_descriptor": null, "status": "pending", "type": "bancontact", "usage": "single_use" } ], "object": "list", "has_more": false, "url": "/v1/charges?payment_intent=pi_1G1sgdKi6xqXeNtkldRRE6HT" }, "payment_method_options": { "bancontact": { "preferred_language": "en" } }, "payment_method_types": [ "bancontact" ], "id": "pi_1G1sgdKi6xqXeNtkldRRE6HT", "object": "payment_intent", "amount": 1099, "client_secret": "pi_1G1sgdKi6xqXeNtkldRRE6HT_secret_h9B56ObhTN72fQiBAuzcVPb2E", "confirmation_method": "automatic", "created": 1579259303, "currency": "eur", "livemode": true, "next_action": null } ``` ## Optional: Gérer les événements post-paiement Stripe envoie un événement [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) à l’issue du paiement. Utilisez le Dashboard, un *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) personnalisé ou une solution partenaire pour recevoir ces événements et exécuter des actions, comme envoyer une confirmation de commande par e-mail à votre client, enregistrer la vente dans une base de données ou lancer un workflow de livraison. Plutôt que d’attendre un rappel de votre client, écoutez ces événements. En effet, côté client, l’acheteur pourrait fermer la fenêtre de son navigateur ou quitter l’application avant l’exécution du rappel. Des personnes malveillantes peuvent en profiter pour manipuler la réponse. Si vous configurez votre intégration de manière à écouter les événements asynchrones, cela vous permettra également d’accepter de nouveaux moyens de paiement plus facilement à l’avenir. Apprenez-en davantage sur les [différences entre les différents moyens de paiement pris en charge](https://stripe.com/payments/payment-methods-guide). - **Gérer les événements manuellement dans le Dashboard** Utilisez le Dashboard pour [consulter vos paiements](https://dashboard.stripe.com/payments), envoyer des reçus par e-mail, gérer les virements ou relancer les paiements échoués. - **Créer un webhook personnalisé** [Créez un gestionnaire de webhooks personnalisé](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) pour écouter les événements et concevoir des flux de paiement asynchrones sur mesure. Testez et déboguez votre intégration de webhooks en local avec la Stripe CLI. - **Intégrer une application prédéfinie** Gérez les événements commerciaux courants, tels que l’[automatisation](https://stripe.partners/?f_category=automation) ou le [marketing et les ventes](https://stripe.partners/?f_category=marketing-and-sales), en intégrant une application partenaire. ## Optional: Gérer la redirection de Bancontact manuellement Nous recommandons d’utiliser Stripe.js pour gérer les Bancontact redirections et paiements côté client avec `confirmBancontactPayment`. L’utilisation de Stripe.js permet d’ajouter d’autres moyens de paiement à votre intégration. Cependant, vous pouvez aussi rediriger vos clients manuellement sur votre serveur en procédant comme suit : 1. Créez et *confirmez* (Confirming an intent indicates that the customer intends to use the current or provided payment method. Upon confirmation, the intent attempts to initiate the portions of the flow that have real-world side effects) un PaymentIntent de type `bancontact`. Vous devez fournir la propriété `payment_method_data.billing_details.name`, à recueillir auprès de votre client. Spécifiez `payment_method_data` pour créer un PaymentMethod et l’utiliser immédiatement avec ce PaymentIntent. Vous devez également fournir l’URL vers laquelle votre client est redirigé après avoir terminé son paiement dans le champ `return_url`. Vous pouvez éventuellement ajouter vos propres paramètres de requête dans cette URL. Ces paramètres seront inclus dans l’URL finale une fois le flux de redirection terminé. #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') payment_intent = client.v1.payment_intents.create({ confirm: true, amount: 1099, currency: 'eur', payment_method_types: ['bancontact'], payment_method_data: { type: 'bancontact', billing_details: { name: 'Jenny Rosen', }, }, return_url: 'https://example.com/checkout/complete', }) ``` 1. Vérifiez que le `PaymentIntent` a l’état `requires_action` et que le type de `next_action` est `redirect_to_url`. #### Json ```json {"status": "requires_action", "next_action": { "type": "redirect_to_url", "redirect_to_url": { "url": "https://hooks.stripe.com/...", "return_url": "https://example.com/checkout/complete" } }, "id": "pi_1G1sgdKi6xqXeNtkldRRE6HT", "object": "payment_intent", ... } ``` 1. Redirigez le client vers l’URL fournie dans la propriété `next_action.redirect_to_url.url`. Cet exemple de code fourni ici n’a qu’une valeur illustrative : la méthode de redirection peut différer sur votre framework Web. #### Ruby ```ruby if payment_intent.status == 'requires_action' && payment_intent.next_action.type == 'redirect_to_url' url = payment_intent.next_action.redirect_to_url.url redirect(url) end ``` Le client est redirigé vers l’URL `return_url` une fois qu’il a effectué le paiement. Les paramètres de la requête d’URL `payment_intent` et `payment_intent_client_secret` sont inclus avec tous vos propres paramètres. Stripe recommande de configurer un [endpoint de webhook](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks) pour configurer l’état d’un paiement par voie programmatique.