Closed rastapopougros closed 3 years ago
Erreur enregistrée ici : https://github.com/nursit/bank/blob/master/presta/payzen/inc/payzen.php#L491 (où on est bien dans "traiter la réponse", donc quand on a bien reçu une réponse)
C'est visiblement un cas particulier pas prévu, ou un bug, ou un changement de signature sur les notifications
Normalement tu as un log de l'URL complète avec tous les arguments de la notifications dans un des logs, ça se passe ici https://github.com/nursit/bank/blob/master/action/bank_response.php#L62
Donc la procédure c'est :
Quand on rejoue l'URL, si le bug a été fixé, on revalide la transaction et on repasse dans toutes les étapes prévues
Je ne suis pas sûr d'avoir compris ce que tu appelles "récupérer l'URL" mais depuis l'interface de Payzen on peut "relancer la notification" de tel paiement, en clic droit. Quand je l'ai fait hier midi, dans le SPIP j'ai donc effectivement ce log (qui correspond à la même erreur reçu en mars quand ya eu la vraie commande donc) :
2021-06-22 13:33:09 194.50.38.6 (pid 11847) :Pub:ERREUR: call_response : transaction 16447 refusee ou annulee pour : 00 (pas de vads_payment_certifica
te)
vads_amount=5000
vads_auth_mode=MARK
vads_auth_number=
vads_auth_result=
vads_capture_delay=2
vads_card_brand=SDD
vads_card_number=
vads_payment_certificate=
vads_ctx_mode=PRODUCTION
vads_currency=978
vads_effective_amount=5000
vads_effective_currency=978
vads_site_id=123456789
vads_trans_date=20210323180522
vads_trans_id=687227
vads_trans_uuid=xxxxxxxxxxxxxxxxxxxxxxxxxxx086406
vads_validation_mode=0
vads_version=V2
vads_warranty_result=NO
vads_payment_src=EC
vads_order_id=16447
vads_cust_email=MACHINE@hotmail.fr
vads_cust_title=Mme
vads_cust_name=MACHINE
vads_cust_first_name=MA
vads_cust_last_name=CHINE
vads_contrib=SPIP 3.2.9 + Bankv3.6.2\(https://github.com/nursit/bank\)
vads_sequence_number=1
vads_acquirer_network=SEPA
vads_contract_used=FR76XXXXXXXXXXXXXXXX
vads_trans_status=CAPTURED
vads_expiry_month=3
vads_expiry_year=2024
vads_pays_ip=FR
vads_presentation_date=20210325180853
vads_effective_creation_date=20210323180600
vads_identifier=xxxxxxxxxxxxxxxxxxxxxxxxxffe5a4
vads_occurrence_type=RECURRENT_INITIAL
vads_subscription=20210323C9Wjry
vads_operation_type=DEBIT
vads_result=00
vads_extra_result=
vads_card_country=FR
vads_language=fr
vads_hash=HASHSUPERLONG
vads_url_check_src=BO
vads_sub_amount=5000
vads_sub_currency=978
vads_sub_desc=RRULE:FREQ=YEARLY\;
vads_sub_effect_date=20220323
vads_sub_init_amount_number=0
vads_threeds_enrolled=
vads_threeds_auth_type=
vads_threeds_eci=
vads_threeds_xid=
vads_threeds_cavvAlgorithm=
vads_threeds_status=
vads_threeds_sign_valid=
vads_threeds_error_code=4
vads_threeds_exit_status=4
vads_threeds_cavv=
signature=f1cf44eb5b4e82fd6742b077c73d5d92fff34948
"vads_payment_certificate" est effectivement vide donc. Par contre il y a bien un "vads_certificate", mais peut-être que dès lors que l'autre est vide, ça n'a pas pu enregistrer et passer dans tous les pipelines qu'il faut de quand ça se passe bien.
"Bankv3.6.2" ça commence à être une vieille version, ça serait bien de mettre à jour.
Récupérerer l'URL c'est faire tail tm/log/payzenauto.log
et récupérer l'URL qui est logée
...Pub:info: call_autoresponse : /bank.api/payzen-xxxx/autoresponse/?vads_amount=NNN&....
et ensuite faire un curl sur cette URL
Le problème vient de là:
https://github.com/nursit/bank/blob/master/presta/payzen/inc/payzen.php#L484
sur les SEPA comme on a pas de vads_payment_certificate
on utilise le vads_card_number
qui dans le cas de paiement par SEPA est censé contenir l'IBAN de l'acheteur cf https://payzen.io/fr-FR/form-payment/payment-method/sepa/analyser-le-resultat-d-un-paiement-sdd.html
Ici donc le vads_card_number est vide pour une raison inconnue, et donc le paiement semble invalide du point de vue du plugin (et le message d'erreur mériterait d'être plus clair dans ce cas particulier)
Je te propose de tester le patch
// si c'est un SEPA, on a pas encore la transaction et le numero d'autorisation car il y a un delai avant presentation
// (paiement dans le futur)
if ($is_sepa AND !$transaction){
- list($transaction, $authorisation_id) = explode("_", $response['vads_card_number']);
+ if (!empty($response['vads_card_number'])) {
+ list($transaction, $authorisation_id) = explode("_", $response['vads_card_number']);
+ }
+ elseif (!empty($response['vads_identifier']) and !empty($response['vads_trans_uuid'])) {
+ $transaction = $response['vads_trans_uuid'];
+ $authorisation_id = $response['vads_identifier'];
+ }
+ if (!$transaction or !$authorisation_id) {
+ $erreur = "SEPA sans reference de paiement (vads_card_number ou vads_identifier + vads_trans_uuid)";
+ }
Alors avec ton patch, en ayant mis le max log à 8, j'ai dans payzen.log :
call_response : id_transaction 16447, reglee
en ayant relancé la notif depuis le backoffice payzen.
Donc en théorie ça ne fait plus d'erreur !… mais par contre dans l'admin de SPIP ça n'a pas changé le statut de la transaction, qui est toujours marqué "echec[00]" avec le message d'erreur d'origine.
Est-ce que ça ne met en "réglé" que quand c'était en "commande" ? Ou bien ça sait mettre en "réglé" aussi même après des échecs ?
Ça semble pas possible selon le code : quand on a le log 'réglée' https://github.com/nursit/bank/blob/master/presta/payzen/inc/payzen.php#L630 on a fait le update sur la ligne avant, et le set est mis avec le statut=ok et le reglee=oui en même temps. https://github.com/nursit/bank/blob/master/presta/payzen/inc/payzen.php#L534
Donc je dirai qu'il faut regarder la ligne SQL pour voir ce qu'il y a dedans et dérouler le code pour voir dans quel scénario on a pu passer vu les données que tu as pour ton hit de paiement
(et la réponse courte est 'oui, une notif de paiement qui conclut un paiement réussi alors que la première fois on avait enregistré un echec, ça marche complètement' et c'est une feature que j'ai utilisé plein de fois - à chaque fois que je me suis retrouvé dans ce genre de cas, des données envoyées qui ne correspondent pas à ce qui est attendu, soit parce que la spec était pas claire, soit parce que j'ai surinterprété sur la base des données de test et de ce que j'ai vu en prod, mais qui ne couvrait pas tous les cas)
Non mea culpa c'était juste un problème de cache, pourtant j'avais bien rechargé (et dans l'admin c'est pas censé garder) mais donc ça a bien tout changé, et même avec la facture générée et tout. Nickel !
Donc le patch peut être ajouté, en master et en V4 stable à priori
Corrigé par 8b64710dfba21f87593fe68c366f2b5965ac8dba et 06bbbfaf6fc4412cf7ecddb132a14156d1ed985b
Merci !
Cas découvert cette semaine (avec Payzen en l'occurrence) : une personne a bien réussi son virement SEPA comme il faut, elle a été prélevée sur son compte, et il y a même un prélèvement récurrent annuel bien programmé à l'infini. Donc elle sera de nouveau prélevée dans un an comme il faut à priori.
Cependant, après quelques notifications en erreur (ça arrive, problème de connexion ou autre), une notification a bien fonctionnée, mais ne contenait pas le champ "vads_payement_certificate" attendu par Bank ! Du coup ça a changé la transaction pour "erreur", avec le détail "pas de vads_payement_certificate" (ce qui veut bien dire qu'il y a eu une notif captée, c'est pas juste resté en attente à l'infini). Il n'y avait pas non plus de vads_subscription qui rempli abo_uid.
Comment faire désormais ? L'abonnement interne à SPIP (du plugin Abonnements) n'a pas été généré en cascade du coup puisque la commande liée n'a pas été mise en "payée". Ça on peut le changer à la main dans l'interface, ok.
Sauf qu'il s'agit d'un virement récurrent : dans ce cas il y a un vads_subscription/abo_ui qui est gardé en mémoire pour que l'année prochaine, on puisse continuer de faire le lien avec la même commande. Qui n'a donc pas été rempli non plus là.
Bon je n'ai pas beaucoup d'espoir hein, j'explique tout ça à tout hasard, mais sûrement que la réponse sera : "c'est comme ça, dans le lot ya des notifs qui ne seront pas bonnes et c'est au logiciel de commerce de savoir se démerder ensuite" (mais justement on peut pas éditer les transactions à la main).