Jak těžké je integrovat platební bránu GoPay bez předchozích zkušeností s bránami? Na jeden z mých e-shopů jsem se rozhodl nasadit platební bránu. Jde o e-shop s personalizovanými produkty, takže neexistuje žádné hotové řešení. Musím to naprogramovat od nuly.

 

S GoPay se komunikuje přes REST API. Dokumentace je přehledná, ale nikde jsem nenašel žádnou ukázku implementace, takže se zde pokusím sám nějakou ukázku připravit, protože nemá smysl zkoušet integrovat bránu přímo do e-shopu, dokud nemáte vyzkoušenou komunikaci, tzn. např. zíkání tokenu, založení platby, odesílání či rušení platby, zjištění stavu atd.

Pokud jsem to pochopil správně, s bránou se pracuje následujícím způsobem:

  1. Získání tokenu pomocí ClientID a ClientSecret
    payment-create (pouze pro založení platby)
    nebo
    payment-all (pro všechny další operace)
  2. Založení platby
    Předání parametrů z e-shopu do brány, tzn. token v hlavičce, cena, měna platby, povolené platební metody, předvybraná platební metoda, položky objednávky, jazyk platební brány, adresy pro notifikace a adresy pro návrat na prodejní místo (více viz standardní platby https://doc.gopay.cz/#zalozeni-platby )
    Výsledkem volání je JSON objekt, kde nejdůležitější je parametr id, který se musí uložit do objednávky pro návrat z brány a identifikaci s notifikacemi z brány.
    Druhým důležitým parametrem je gw_url, které se použije v dalším kroku (pro vyvolání brány).
  3. Vyvolání platební brány
    inline nebo přesměrováním
  4. Návrat z brány
    přesměrování na return_url, které bylo jedním z param. v kroku 2 (při založení platby)
    Za return_url je platební bránou připojen GET parametr ?id=<id_platby>.
  5. Ověření platby
    provést dotaz na stav platby a zákazníkovi zobrazit informaci o aktuálním stavu
  6. Refundace platby
    platbu lze za určitý poplatek nechat poslat zákazníkovi nazpět

V API dokumentaci jsou v pravém sloupci ukázky kódu. Hned na začátku je návod na instalaci PHP SDK. Pomocí Compos(t)eru jsem naházel potřebné soubory do složky vendor

 

2. ZALOŽENÍ PLATBY

Krok číslo 1. jsem přeskočil, protože se autorizace (oauth2) řeší interně s využitím PHP SDK. Znamená to, že se o token nemusíme vůbec starat. Můžeme se soustředit rovnou na krok spočívající v založení platby, odeslání informací o platbě na bránu a získání idgw_url, které použijeme pro vyvolání brány ve třetím kroku.

Z dokumentace jsem zkopíroval následující kód, změnil přihlašovací údaje na ty, které mi byly zaslány z GoPay a začal jsem testovat. Zkusím nejprve získat gw_url …

Brána nejprve hlásila chybné přihlašovací údaje. Popletl jsem ClientSecret za SecureKey. Po opravě sice brána začala komunikovat, ale gw_url jsem nezískal. Místo toho přišla chybová hláška, se kterou si zatím nevím rady:

oops, API returned 400: Unrecognized field "0" (class cz.gopay.web.api.model.payment.RCreateBasePayment), not marked as ignorable

Brána se snaží nejspíš sdělit, že předávané pole z příkazu GoPay\payments() má hned první položku nerozpoznatelnou. Pole posílané na bránu má při výpisu pomocí print_r tento tvar:

Nakonec jsem se rozhodl zkontaktovat technickou podporu. Reakce byla v postatě okamžitá. Pan Šimánek ihned objevil, že jsem tam dal jedny hranaté závorky navíc. Vzniklo to zřejmě divokým kopírováním. (V ukázce výše již nejsou, aby si nikdo stejnou chybu nezopakoval.)

Po zrušení duplicitních hranatých závorek přišla první odezva z brány:

default_payment_instrument … toto bude zřejmě způsob platby zvolený zákazníkem, např. BANK_ACCOUNT

allowed_payment_instruments … typicky:

["PAYMENT_CARD","BANK_ACCOUNT"]

default_swift … hádám, že jde o swift kód banky, kterou si uživatel vybral pro platbu

allowed_swifts … seznam bank, ze kterých je možné dodatečně převybrat přímo na bráně?

Seznam swift kódů dole na stránce https://doc.gopay.cz/#payment-instrument .

 

3. VYVOLÁNÍ PLATEBNÍ BRÁNY

Jestliže již máte idgw_url, můžete vyvolat bránu a vyzkoušet platbu.
Oba identifikátory získáte jednoduše z JSON response příkazem

 

Po úspěšné odezvě zobrazíme formulář, kde do parametru action vložíme gw_url

Formulář pro odeslání objednávky, resp. vyvolání platební brány má ještě skryté pole s názvem signature, které předává bráně šifrovaný podpis platby:

Podpis platby lze sestavit následovně:

targetGoId+|+pa­ymentSessionId+|+se­cureKey

V popisu integrace je trochu zavádějící informace, která se týká předchozí verze brány, což je v dokumentaci jenom naznačeno – v názvu stránky: „Implementace nového vzhledu platební brány pro stávající zákazníky“. Nikde není explicitně uvedeno, že se signature týká výhradně SOAP verzí, které už nejsou podporovány (nyní komunikace probíhá pouze přes REST API). Podpis signature tedy neprogramujeme!

 

4. NÁVRAT Z BRÁNY

Po úspěšném provedení platby dojde bránou k přesměrování na odkaz return_url uvedený při založení platby. Důležité je zpracovat k odkazu přidaný parametr ?id=3151179967, tzn. spárovat s objednávkou.

5. OVĚŘENÍ PLATBY

Data týkající se uskutečněné platby získáme například takto:

V příkazu výše předávám id platby rovnou po přesměrování. $response zobrazím například příkazem echo $response;

Správně se však musí vytáhnout id z databáze ze spárované objednávky v bodě 4., protože dotaz na stav platby se provádí také při přesměrování na notifikační stránku notification_url , což může nastat nezávisle na pozadí, bez účasti uživatele a děje se tak po každé transakci, byť se zpožděním. Notifikační dotaz vrací rovněž ?id=<id platby>. Podle id platby je nutné dohledat objednávku, ke které platba náleží, provést dotaz na stav platby, porovnat ho se stavem v databázi a případně provést update stavu v databázi.
V případě plateb kartou se notifikace provádí z toho důvodu, že uživatel může nechtěně zavřít okno těsně po úspěšném provedení transakce, takže nedojde kvůli tomu k přesměrování do e-shopu. Obchod by se nedozvěděl o platbě. Proto musí dojít ještě k dodatečnému zaslání zprávy (k notifikaci) o proběhlé platbě. GoPay zkouší posílat notifikaci celkem 20x, než to vzdá. Uspokojivou odpovědí je pouze status 200.
Jediný rozdíl oproti zpracování výsledku platby těsně po dokončení interakce s bránou spočívá v tom, že v prvním případě zobrazujeme uživateli nějaké informace, v případě druhém (když jde jen o notifikaci) nic nezobrazujeme, protože není komu. Nestačí tedy pouze zapsat stav do objednávky, ale je potřeba také poslat standardní potvrzovací e-mail zákazníkovi, který se posílá když dojde ke standardnímu přesměrování na eshop.
Po zpracování notifikačního dotazu jsem do skriptu pro jistotu dal ještě příkazy:

 

Stav platby je v parametru state.

Stav platby tedy získáme v dalším kroku takto:

Přehled jednotlivých stavů:

CREATED
Platba vytvořena
PAID Platba uhrazena
CANCELED Platba zamítnuta
PAYMENT_METHOD_CHOSEN Platební metoda potvrzena
TIMEOUTED Platbě vypršela životnost
AUTHORIZED Platba předautorizována
REFUNDED Platba vrácena
PARTIALLY_REFUNDED Platba částečně vrácena

Dále existují ještě podstavy Substate plateb s číselnými kódy stavů (viz API manuál).

Jednotlivé stavy je dobré ošetřit.

 

Ještě pro zajímavost uvedu, jak lze získávat data z JSON (bez SDK):

 

 

6. REFUNDACE PLATBY

Je-li potřeba provést storno platby, lze tak učinit příkazem

kde první parametr je id  a druhý parametr částka k vrácení. Druhý parametr není povinný, takže při jeho vynechání by mělo dojít k refundaci celé částky.

 

7. TESTOVÁNÍ PLATEB

Pro testování jsou k dispozici fiktivní čísla karet na stránce Provádění plateb v testovacím prostředí.

 

8. PŘECHOD NA OSTRÝ PROVOZ

Jakmile dojde k podepsání smlouvy, identifikaci a technické oddělení ověří funkčnost integrace (podívají se do hlášek v sandboxu), zašlou ostré provozní údaje (část na mail, zbytek na mobil). Následuje zkušební platba v ostrém režimu, kterou ohlásíte na technické oddělení. Prostě něco objednáte (platbu můžete po vyvolání brány zrušit). Oni to zkontrolují, potvrdí a vy zapnete zobrazování možnosti platby přes bránu i uživatelům. Dokud není potvrzena první platba, nezobrazujte uživatelům možnost platby přes bránu! Řeším to pomocí cookie.
A to je vše.
Hlavně nezapomeňte prohodit i url skript ostré brány, tzn. namísto https://gw.sandbox.gopay.com/gp-gw/js/embed.js  tam nakopírujte https://gate.gopay.cz/gp-gw/js/embed.js .