Stripe et les webhooks

WRInaute passionné
Salut à tous,

J'essaie de mettre Sripe comme moyen de paiement sur l'un de mes sites, le module de paiement fonctionne correctement mais je voudrais maintenant utiliser leur webhook (une sorte d'url IPN : Instant Payment Notification) afin de mettre à jour une table MySql une fois que le paiement s'est bien déroulé mais j'ai du mal à comprendre comment installer ce webhook et à l'utiliser, quelqu'un utilise-t-il Stripe avec les webhooks ?

Je n'utilise pas de CMS pour mon site.

J'ai contacté leur support technique à plusieurs reprises mais ils répondent à chaque fois à côté de la plaque... ou alors c'est mon anglais qui est incompréhensible

Merci pour votre retour.
 
WRInaute passionné
Je les utilise, bien obligé si on veut faire une action une fois que le paiement a eu lieu (mise à jour de la base, envoi d'email...).

Côté admin Stripe, dans Webhooks, "Ajouter un point de terminaison" en indiquant votre URL qui sera appelée automatiquement lors du paiement, en choissant l'événement qui vous intéresse (sans doute "checkout.session.completed").

Coté site, créez l'URL en question, ils expliquent tout ici : https://stripe.com/docs/payments/checkout/fulfill-orders

Dans l'objet $session vous pouvez retrouver votre client_reference_id ($session->client_reference_id) pour savoir de quel client il s'agit.

Je remets l'exemple qui est dans leur page :

PHP:
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey(
'sk_test_w8PQpnGoEIv9H0thqdnlqkHm'
);

function print_log($val) {
  return file_put_contents('php://stderr', print_r($val, TRUE));
}

// You can find your endpoint's secret in your webhook settings
$endpoint_secret = 'whsec_...';

$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;

try {
  $event = \Stripe\Webhook::constructEvent(
   $payload, $sig_header, $endpoint_secret
  );
} catch(\UnexpectedValueException $e) {
  // Invalid payload
  http_response_code(400);
  exit();
} catch(\Stripe\Exception\SignatureVerificationException $e) {
  // Invalid signature
  http_response_code(400);
  exit();
}

function fulfill_order($session) {
  // TODO: fill me in
  print_log("Fulfilling order...");
  print_log($session);
}

// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
  $session = $event->data->object;

  // Fulfill the purchase...
  fulfill_order($session);
}

http_response_code(200);
 
WRInaute passionné
Merci pour ta réponse rick38.

J'ai ajouté un point de terminaison dans le Dashboard de Stripe.

J'ai installé Stripe CLI https://stripe.com/docs/stripe-cli mais je ne vois pas comment je l'utilise en local pour débuguer mon code ?

Comment dans ton code ci-dessus tu retrouves le client_reference_id puisque c'est le serveur de Stripe qui appelle l'url de la page qui contient le code ci-dessus ?

Comment tester le webhook en local ?
 
WRInaute passionné
En local tu peux pas, pour le webhook.
Par contre tu peux utiliser leur clé de test avec leur numéro de CB de test pour simuler un paiement, ou sinon tu te fais des paiements de 10 centimes...

Pour le client_reference_id, la page est appelée par Stripe mais avec des paramètres (POST), on reçoit tout ça en faisant $payload = @file_get_contents('php://input');

Plus loin dans le code tu vois $session = $event->data->object; là on récupère l'objet session, dans lequel il y a notamment client_reference_id.
 
WRInaute passionné
Sur cette page https://stripe.com/docs/payments/checkout/fulfill-orders ils indiquent qu'il faut entrer la commande :
Code:
stripe listen --forward-to localhost:4242/webhook
Il faut donc adapter "localhost:4242/webhook" à son propre environnement.

J'utilise le serveur wamp en local et mes variables php sont :
Code:
$_SERVER['SERVER_NAME']    localhost
$_SERVER['SERVER_ADDR']    127.0.0.1
$_SERVER['SERVER_PORT']    80
$_SERVER['REMOTE_ADDR']    127.0.0.1
$_SERVER['DOCUMENT_ROOT']    C:/wamp64/www
$_SERVER['REQUEST_SCHEME']    http

Mon site en local est accessible via l'url http://mon-site/ et mon fichier webhook.php est situé à http://mon-site/scripts/paiement/webhook.php

Par qu'elle url dois-je remplacer "localhost:4242/webhook" dans la commande stripe listen ?
 
WRInaute passionné
Plus loin dans le code tu vois $session = $event->data->object; là on récupère l'objet session, dans lequel il y a notamment client_reference_id.
Pour mettre le client_reference_id dans une variable on doit faire :
Code:
$client_reference_id = $session->client_reference_id;
C'est bien cela ?

Une autre question concernant la page (success_url) sur laquelle est renvoyée le client après un paiement réussi, comment peut-on récupérer le client_reference_id et les informations de paiement depuis cette page ?
 
WRInaute passionné
Je ne sais pas pour le local, je n'ai pas eu besoin de débugger en local, juste quelques error_log() ou file_put_contents() pour aller vérifier le contenu des objets la première fois.

Oui pour client_reference_id c'est comme ça.
Sur la page success_url le visiteur revient (ou reste) sur votre site, donc sa session est toujours active, donc cette page continue d'accéder à toutes les infos du visiteurs que vous avez en session, c'est à vous de mettre dans votre session PHP ce que vous voulez, ou alors d'ajouter à cette url des paramètres comme l'id client ou le produit acheté.
 
WRInaute passionné
Merci pour tes réponses, ça m'a beaucoup aidé, j'y vois plus clair ;)

Si le paiement est refusé par Stripe, sur quelle url de notre site est renvoyée le client ?
 
WRInaute passionné
J'imagine que c'est cancel_url
Ou plutôt qu'ils affichent que c'est refusé, sur leur page, avec ce lien pour retourner au site.
 
WRInaute passionné
Dans ce code ci-dessous https://stripe.com/docs/payments/checkout/fulfill-orders :
Code:
switch ($event->type) {
  case 'checkout.session.completed':
    $session = $event->data->object;

    // Save an order in your database, marked as 'awaiting payment'
    create_order($session);

    // Check if the order is paid (e.g., from a card payment)
    //
    // A delayed notification payment will have an `unpaid` status, as
    // you're still waiting for funds to be transferred from the customer's
    // account.
    if ($session->payment_status == 'paid') {
      // Fulfill the purchase
      fulfill_order($session);
    }

    break;

  case 'checkout.session.async_payment_succeeded':
    $session = $event->data->object;

    // Fulfill the purchase
    fulfill_order($session);

    break;

  case 'checkout.session.async_payment_failed':
    $session = $event->data->object;

    // Send an email to the customer asking them to retry their order
    email_customer_about_failed_payment($session);

    break;
}
Quelle est la différence entre if ($session->payment_status == 'paid') {....} qui est dans case 'checkout.session.completed' et case 'checkout.session.async_payment_succeeded' ? Dans les 2 cas on a bien la confirmation que la paiement a réussi, non ?
 
WRInaute passionné
Le checkout.session.async_payment_succeeded ne concerne pas les cartes bancaires, ça doit être pour les prélèvements ou virements bancaires.
 
Discussions similaires
Réponses
3
Affichages
3K
mathieukassovitz
M
Haut