Hello,
J’ai investigué aussi, et je crois que c’est un peu plus complexe que ça.
Une stratégie est de reprendre le payementok.php de la v21, mais il a été corrigé car il y avait un bug « aléatoire » qui entrainait une erreur de temps en temps.
Bref, sur la nouvelle version, la séquence dans newpayment.php v22 avec STRIPE_USE_NEW_CHECKOUT :
$_SESSION['TRANSACTIONID'] = $sessionstripe->id; // = "cs_xxx..." (session Checkout)
Puis en JavaScript, le code appelle :
stripe.confirmPayment({ elements, confirmParams: { return_url: '<?php echo $urlok; ?>', ... } })
C’est là, je crois que se situe le bug:
stripe.confirmPayment() est l’API de Stripe Elements / PaymentIntent, PAS de Stripe Checkout. Quand Stripe redirige vers return_url après confirmPayment, il ajoute en query string :
?payment_intent=pi_xxxxx&payment_intent_client_secret=xxx&redirect_status=succeeded
MAIS il n’ajoute PAS session_id=cs_xxxxx.
Comme $_SESSION['TRANSACTIONID'] est déjà rempli avec cs_xxx (l’ID de la session Checkout), le second if n’est jamais exécuté, et $TRANSACTIONID reste à cs_xxx.
Ensuite, dans la vérification Stripe :
if (preg_match('/^pi_/', $TRANSACTIONID)) {
$paymentIntent = \Stripe\PaymentIntent::retrieve(...);
} else {
// Tente de retrouver une "charge" avec cs_xxx, ce qui échoue
}
Avec cs_xxx, le code tente de récupérer ça comme une « charge » (ch_xxx) et là, ça plante et on a le message d’erreur : « Stripe payment verification failed: TRANSACTIONID is not set or session key does not match. »
Pour info : En v21, ça fonctionnait, car la logique sauvegardait pi_xxx (payment_intent) au lieu de cs_xxx (session) dans $_SESSION['TRANSACTIONID'], la priorité était donc inversée : GETPOST('payment_intent') était lu avant la session, mais cela pouvait déclenché des erreurs innatendues.
Le truc, c’est que je suis pas sûr du pourquoi et du comment éviter le bug aléatoire de la v21 (et que je ne suis pas sûr de mon diagnostic non plus)