csob / paymentgateway

English documentation of the ČSOB Payment Gateway that offers an API for credit card payments, Apple Pay, Google Pay, mallpay and ČSOB Payment Button.
https://platbakartou.csob.cz/platebni-brana
GNU General Public License v3.0
121 stars 68 forks source link

Chybná odpověď z platební brány #501

Closed MarcelKocir closed 4 years ago

MarcelKocir commented 4 years ago

Dobrý den, zákazník nám hlásí problémy s placením na platební bráně, kdy platba je řádně zaúčtována, nicméně webové rozhraní naší aplikace odpověď z brány nemůže zpracovát, zalogovaná odvoď z brány je krom resultCode prázdná: BranaResult: {"payId":null,"dttm":null,"resultCode":0,"resultMessage":null,"paymentStatus":null,"authCode":null,"merchantData":null,"signature":null,"extensions":null}

Tím pádem se ztrácí celý kontext transakce, uživateli jsme nuceni zobrazit informaci o nestandardní odpovědi z platební brány, což se mu samozřejmě nelíbí, zvlášť když platba reálně proběhla.

Jeden příklad: MerchantId: M1MIPS7884 PayId: 9cce6c6f38fe0FE

K uvedenému dochází nepravidelně.

Mspisar commented 4 years ago

Dobrý den, požadavek jsme zaevidovali a předali k řešení. O dalším postupu budete informován. s pozdravem Spisar

mrazekl commented 4 years ago

Dobrý den,

příkladová transakce je z půlky května, bylo by možné uvést dřívější výskyt(pokud evidujete), ideálně během června?

MarcelKocir commented 4 years ago

Dobrý den, poslední případ eviduji momentálně 2020-05-16 14:13:19, což Vám asi moc nepomůže. Takže je to evidentně poměrně né příliš častý případ, za poslední rok eviduji pouze 4 případy, nicméně i toto musím vyřešit. Log budu pravidelně sledovat a jakmile se objeví nový případ, okamžitě jej zde přidám.

mrazekl commented 4 years ago

Dobrý den, určitě se tak můžeme domluvit. Jakmile k tomu znova dojde, "odchytíme" odpověď z platební brány a můžeme ji porovnat s tím, co bylo u vás na serveru přijato.

MarcelKocir commented 4 years ago

Dobrý den, včera se nám objevil nový případ: MerchantId: M1MIPS7884 PayId: 1f63e759887aaFG

Prosím o prověření.

mrazekl commented 4 years ago

Dobrý den, vše vztahující se k této transakci jsme dohledali pouze o několik dnů dříve a to 22.07. Z platební brány bylo přesměrováno zpět do eshopu s následujícími hodnotami(záměrně vyhvězdičkovaná první část URI): Payload: {"redirect":{"url":"https://********.zfpakademie.cz/zfpnahlasovani/ZakladniSeminar/GatewayReturnAction","method":"POST","vars":{"payId":"1f63e759887aaFG","dttm":"20200722220347","resultCode":"0","resultMessage":"OK","paymentStatus":"7","signature":"BN5WVBra7wJUF1tEXxckRSkmVoPI2UMU8OP39KhesC5Vkz3GDgkxxhIYWLBQWCXYOp8g0pkHvyWn/2tLkquDhq3UPUsyZrDw+Z//lHSWVhM1mPMM7i2//Z2aSXsTT2YS3r0PkB92WCrzPBAuWaZXep9DsXswnPa9qklAk4pnA095sz9XKPK6cEZvv4r5/KtUHdm2FZJUhbVw6B8TpBe7roJDLTwKGzyq1fwc6+/cTFIQiUEX5lacPDv6oYA7T9bHgbd97nBTfYxjrIlDD0A/orcK4OGC0uEOfmphTHD+CaucSGklMDTtCan4NSdkrpn2Y44KOhlU0NF1sGHMUIWa4Q==","authCode":"998787","merchantData":"MTMyNzIzNnw2MDB8MDAwMDAwMzQ0MXw2MDAyNTk="},"timeout":2500},"poll":false,"html":"<p class=\"main-msg\">Dokončujeme platbu</p><p class=\"msg return-link-text\">Vyčkejte, prosím, na&nbsp;přesměrování k obchodníkovi.</p>","text":null,"status":"processed","advert":null}

Z našeho pohledu to tedy vypadá na standartní odpověď.

MarcelKocir commented 4 years ago

Bohužel k nám doputují data takto: {"payId":null,"dttm":null,"resultCode":0,"resultMessage":null,"paymentStatus":null,"authCode":null,"merchantData":null,"signature":null,"extensions":null}

Co jsem vypozoroval a může být jistým vodítkem, je to, že úspěšné platby jsou volány POSTem, kdežto tyto chybné jsou vždy volány přes GET.

Během mé dovolené se vyrojily další 4 případy, merchid je totožné, payid nemám k dispozici (vzhledem k návratové hodnotě NULL nemám ani jak zalogovat, vždy musím analyticky dohledat konkrétní platbu a vyzjistit od zákazníka), ale mám alespoň časy z logu: 2020-07-28 19:45:41 2020-07-28 21:41:00 2020-07-29 17:38:54 2020-07-31 11:53:58

mrazekl commented 4 years ago

jsem z toho trochu zmatený, "volány POSTem" máte na mysli založení transakce payment/init, nebo typ metody při přesměrování zpět do eshopu po dokončení? Jelikož payment/init(vyjma LegacyAPI) musí být pomocí POST A přesměrování máte nastaveno rovněž pomocí POST Je ale zvláštní, že ve vámi udaných časech vždy jako by chybělo jedno číslo objednávky, jako by se na platební bránu vůbec neodeslala, což by mohlo mít spojitost, například: objednávka/datum 0000003524 28.07.20 21:40:30,852000000 0000003522 28.07.20 19:42:40,258000000 0000003520 28.07.20 18:00:08,832000000 0000003518 28.07.20 17:08:20,073000000 0000003517 28.07.20 17:01:30,859000000 0000003516 28.07.20 16:58:09,445000000 0000003515 28.07.20 16:52:55,109000000 0000003514 28.07.20 16:37:40,368000000 0000003513 28.07.20 16:01:12,466000000

Objednávky se inkrementují o jednu, chybí však čísla končící 19, 21 a 23. Zda se nehoníme za těmito případy, které spojujete s následnou transakcí, která je v pořádku.

MarcelKocir commented 4 years ago

Mám na mysli zpětné volání z brány do eshopu. V kódu mám podmínku na Request.HttpMethod a v uvedených chybových případech je identifikován GET, kdy v objektu BranaResult jsou zmiňovaná prázdná data. Pokud přijde request POSTem, je vše v pořádku.

Co se týče dat pak by mělo jít o platbu s číslem objednávky 0000003522. Dle logu je patrné, že init proběhl cca v 19:42:40, odpověď pak cca po třech minutách v 19:45:41 (což by mohlo odpovídat času strávenému vyplněním údajů k platbě).

mrazekl commented 4 years ago

V tom případě je to zvláštní, jelikož ve všech případech byla hodnota parametru returnMethod nastavena na POST, a dle našich logů tak bylo i přesměrováno. Napadá mě situace, kdy zákazník nepočká na přesměrování zpět do eshopu, a v tomto případě neobdržíte požadované informace. Máte možnost si to nasimulovat v integračním prostředí? Pro tyto případy můžete pro zjištění stavu transakce zaslat payment/status, viz: https://github.com/csob/paymentgateway/wiki/Z%C3%A1kladn%C3%AD-metody#metoda-paymentstatus-

MarcelKocir commented 4 years ago

Situaci, kdy uživatel nepočká na přesměrování do eshopu a uzavře křížkem, jsem již v minulosti prověřoval. Výsledek byl takový, že nedošlo vůbec ke zpětnému volání, což potvrzuje, to co píšete, nicméně log na našem webu, o kterém se zmiňuji, probíhá právě při zpětném volání (pouze s prázdnými daty), takže tento scénář je vyloučen.

V integračním prostředí se mi to nepodařilo nasimulovat, na produkci k tomu dochází také náhodně a sporadicky.

Musel jsem přistoupit k řešení prověření přes payment/status, nicméně formou periodockého jobu, protože fakticky neznám konkrétní paymentid, na kterém to selhalo při návratu (informace tam chybí), takže alespoň takto to budeme mít ošetřeno. Nicméně doufal jsem, že se nám podaří příčinu najít, aby k uvedenému vůbec nedocházelo.

mrazekl commented 4 years ago

A to je právě to,jelikož z hlediska platební brány se jedná vždy o totožnou odpověď, s jejímž zpracováním máte sem tam problém při zpracování, aniž bychom odhalili společnou vlastnost. Jakmile je opověď odeslána z našeho systému, nemáme k dispozici žádné další informace. Zkusím se poradit s vývojářem aplikace, zda by ho nenapadala možná příčina.

MarcelKocir commented 4 years ago

Momentálně se nám uvedenou chybu podařilo nasimulovat na integračním prostředí a to opakovaně.

https://github.com/csob/paymentgateway/wiki/Testovac%C3%AD-karty Přišli jsme na to, že pokud se použije karta VISA 4125010001000208, platba projde bez problému. Pokud se použije karta Mastercard 5168440001000202, vrátí se vždy odpoveď s popsanými null hodnotami a to GETem.

MarcelKocir commented 4 years ago

Aktuálně už nám neprochází platbou na integračním prostředí ani zmiňovaná VISA karta.

Rád bych věděl, zda logujete requesty na platební bránu (inicializaci), zda to posíláme správně. Ale předpokládám, že ano, jinak by se pravděpodobně stránka platební brány vůbec neoteřela.

mrazekl commented 4 years ago

Ano, máme zaznamy i z testovacího prostředí. Poslední inicializační request evidujeme ve 13:36:16 který byl úspěšný. Poté už vidíme jen payment/status. Pokud by nebyl správně složený payment/init či payment/process, nebyla by platební brána vůbec zobrazena. Kdy jste zkoušeli naposled?

Podnět z vašeho předchozího příspěvku analyzujeme.

MarcelKocir commented 4 years ago

Zde je seznam PayId ze včerejška, kdy platba je fyzicky v pořádku (dle PaymetStatus zaplaceno), ale návrat z brány byl s prázdným objektem (což bylo včera vždy) na testu: 808fce69bac6bFH be4710d128f4bFH c784a81bcbf30FH 435b849b22580FH 40eb106676342FH 99b9f21b50665FH 4235d0b482c53FH

mrazekl commented 4 years ago

můžete si to debugovat třeba na úrovni prohlížeče? Když jsem vyzkoušel platbu VISA kartou, při kterých se vám vrací prázdná data, a nastavil returnUrl na váš test, je vidět že se data odesílájí: obrazek

MarcelKocir commented 4 years ago

Provedli jsme 2 pokusy o platby.

  1. Mastercard - platba ok
  2. Visa - selhání Obrázky přikládám: MicrosoftTeams-image MicrosoftTeams-image (1)
mrazekl commented 4 years ago

To je zvláštní, protože nezávisle na použité kartě, platební brána provádí redirect naprosto stejným způsobem. Nám se ani jednou nepodařilo nasimulovat, že by byla pro redirect použita metoda GET př inastavení POST. Můžete se přepnout z network do konzole, a zaslat screen kam je směřováno ihned po informaci, že bylo úspěšně uhrazeno?

MarcelKocir commented 4 years ago

MicrosoftTeams-image (2)

mrazekl commented 4 years ago

Zde je vidět že redirect nejde na přímo, ale routuje se to přes nějakou adresu https://devex2013..... namísto https://neptun/zfpnahlasovaniActualBuild/ZakladniSeminar/GatewayReturnAction
a odtud pak na https://neptun/zfpnahlasovaniActualBuild/ZakladniSeminar/GatewayReturn

Z toho mi plyne, že se bude jednat o serverové nastavení vaší části, možná nějaký firewall apod.

MarcelKocir commented 4 years ago

Toto by nemělo mí vliv, jde pouze o vnitřní přesměrování, protože web je schován za ADFS a pokud by volání ADFS server nepustil, do controlleru našeho webu by to dále vůbec nepustil (nebo přesměroval na login page).

Nicméně - udělali jsme pokus, že jsme nastavili jako returnMethod=GET a vše pak projde, protože return přijde GETem a objekt se správně namapuje a zdá se to funkční. Tedy namísto očekávání POSTu a logování, že to přišlo GETem bychom to otočili, budeme očekávat GET a pokud by to přišlo POSTem a data by byla prázdná, provedl by se log o chybě.