Přeskočit na hlavní obsah

Platební brána v aplikaci

Integrace platební brány do mobilní, či desktopové aplikace (dále již jen jako Aplikace) je velmi podobná jako integrace do webového rozhraní. I v tomto případě je využíván standardní API protokol. Jediným rozdílem je, že na webu je možné si zvolit buď redirect na platební bránu, nebo zobrazení brány v iframe, zatímco v aplikaci je potřeba platbu otevřít v komponentě určené pro zobrazení webové stránky, typicky WebView, nebo využít možnosti přesměrování pomocí Android Intent případně Apple URL Schemes a Universal Links.

WebView

Pro Android, .Net a Xamarin je dostupná komponenta WebView, zatímco Apple používá ve svém Swiftu WKWebView.

Informace

Rozhraní WebView by mělo být zobrazeno na co největší části obrazovky tak, aby měla platební brána dostatek prostoru pro zobrazení a maximalizovala uživatelský komfort.

Průběh zpracování platby

  1. Aplikace kontaktuje svůj Server a vytvoří objednávku.
  2. Server provede HTTP request na Comgate API (/create), čímž založí platbu. Comgate API vrátí odpověď obsahující informace o platbě.
  3. Server si informace získané z Comgate API uloží a předá je i Aplikaci (jak parsovat query string v PHP, JavaScriptu, Kotlinu, Javě a Swiftu).
  4. Aplikace vytvoří přes co největší část displeje WebView komponentu a v ní načte URL platební brány (parametr redirect).
  5. Plátci se načte platební brána ve WebView.
  6. Během toho, co se plátce pokouší zaplatit, je nutné spustit status watcher. Ten se snaží co nejrychleji synchronizovat stav platby ze Serveru do Aplikace. Dostupné metody:
    • Polling - krátké opakované requesty na server (cca každé 3 sekundy),
    • Long Polling - server drží requesty otevřené dokud nejsou data dostupná nebo nedojde k timeout. Pokud ještě není znám status, request se opakuje,
    • WebSocket - poskytuje full-duplex komunikační kanál, kdy je server schopen aplikaci v reálném čase poslat informaci o stavu platby.
  7. Plátce zaplatí objednávku.
  8. Poté, co plátce provede úhradu, je Server pomocí Push notifikace informován o novém stavu platby. Tuto informaci si uloží.
  9. Server si ověří stav platby, tím že se dotáže Comgate API (/status), zda je platba skutečně zaplacena.
    • Pokud ne, dotazuje se periodicky každé cca 3 sekundy znovu. Po 10 dotazech (cca 30 sekundách) je vhodné dotazování ukončit a na pozadí se dotázat Serveru na stav jednou za 30 minut.
      Věnujte zvýšenou pozornost

      V některých případech může zpracování platby trvat až do 12:00 následujícího pracovního dne.

    • V opakování dotazování lze pokračovat podle stavů plateb.
  10. Brána zobrazená ve WebView zjistí, že došlo k zaplacení:
  11. a těsně před přesměrováním zasílá post message, kterou je možné zachytit a na jejím základě WebView skrýt,
  12. případně dojde k přesměrování plátce na URL definovanou v propojení obchodu - na tuto URL by měla Aplikace reagovat a WebView skrýt.
  13. Aplikace kontaktuje svůj Server a ověří si stav platby.
  14. Aplikace zpřístupní zaplacenou službu.

Sekvenční diagram

Sekvenční diagram

Jak poznat okamžik, kdy je potřeba skrýt WebView

Jak již bylo nastíněno v bodu 10, existují v zásadě 2 způsoby, jak poznat, že je platba zaplacena a je třeba skrýt WebView:

  1. zachycení zaslané post message,
  2. přesměrování plátce na URL definovanou v propojení obchodu.

Post message

Před přesměrováním plátce pryč z brány je zasílána post message, která informuje o stavu platby. Tuto zprávu je možné zachytit a na jejím základě WebView skrýt.

Struktura post message:

{
"value":{
"id": "XXXX-XXXX-XXXX",
"status": "PAID", // PAID, CANCELLED, AUTHORIZED, PENDING
"refId": "hodnota-refId"
},
"scope": "comgate-to-eshop",
"action": "status"
}
Věnujte zvýšenou pozornost

Při přijetí message je potřeba ověřovat, že scope je "comgate-to-eshop" a action je "status". Ostatní post messages by měly být ignorovány.

Současně je potřeba věnovat zvýšenou pozornost ověření stavu platby. Stavy získané pomocí post messages nejsou důvěryhodné a je vždy potřeba si stav ověřit na API Comgate.

Přesměrování plátce

Plátce je také možné přesměrovat na nějakou URL vlastního serveru. V tomto případě je nutné zajistit automatické zjištění tohoto přesměrování v Aplikaci a skrytí WebView.

URL je možné nastavit v klientském portálu (nebo přes API při zakládání platby):

  • URL zaplacený (url_paid) - zaplacené platby (PAID, AUTHORIZED),
  • URL zrušený (url_cancelled) - zrušené a expirované platby (CANCELLED),
  • URL nevyřízený (url_pending) - stále probíhající platby (PENDING),
  • URL pro předání výsledku platby - je nutné nastavit pouze v klientském portálu v propojení obchodu.
Detekce změny URL ve WebView
Java kód
WebViewClient webViewClient = new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(url.equals("your link...")){
finish();
}
}
};
Zajímavé odkazy:
Zjednodušená implementace v Kotlinu
Kotlin kód
package com.comgate.webviewtest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.webkit.WebView
import java.net.URLDecoder
import java.nio.charset.StandardCharsets

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// TODO: Create a payment
// Request the mobile app server to create a payment using the Comgate API

// Server returns payment data
val cloudResponseFromComgate = "code=0&message=OK&transId=XXXX-XXXX-XXXX&redirect=https%3A%2F%2Fpay1.comgate.cz%2Finit%3Fid%3DXXXX-XXXX-XXXX";

// Parse the response
val paymentData = this.parseQuery(cloudResponseFromComgate)
val comgateMessage = paymentData["message"]
val paymentUrl = paymentData["redirect"]
val transId = paymentData["transId"]

if (comgateMessage == "OK" && paymentUrl?.isNotEmpty() == true && transId?.isNotEmpty() == true) {
val paymentView: WebView = findViewById(R.id.comgatePaymentFrame)
paymentView.visibility = View.VISIBLE

// The URL can change over time, so always use the URL returned by the Comgate API
paymentView.loadUrl(paymentUrl)

// Start the status watcher
runStatusWatcher(transId)
} else {
// TODO: Handle payment error
}
}

private fun runStatusWatcher(transId: String) {
// TODO: Implement a payment status watcher
// Options for implementation:
// - Polling: Send repeated requests every 3 seconds
// - Long polling: Keep the request open until new data is available
// - WebSockets: Establish a full-duplex communication channel
// - Other methods
}

/**
* Parses a query string into a Map (Key -> Value)
*/
private fun parseQuery(input: String): Map<String, String> {
return input.split("&")
.map { pair ->
pair.split("=").let {
URLDecoder.decode(it[0].trim(), StandardCharsets.UTF_8.toString()) to
URLDecoder.decode(it.getOrElse(1) { "" }.trim(), StandardCharsets.UTF_8.toString())
}
}
.toMap()
}
}

Android Intent

Comgate také umožňuje integraci návratů z platební brány pomocí Intent. Výhodou je, že nemusíte implementovat WebView a pro zobrazení platby se použije výchozí prohlížeč, který následně aplikaci vrátí focus.

Průběh zpracování platby

  1. Aplikace kontaktuje svůj Server a vytvoří objednávku.
  2. Server provede HTTP request na Comgate API (/create), čímž založí platbu. Comgate API vrátí odpověď obsahující informace o platbě.
  3. Server si informace získané z Comgate API uloží a předá je i Aplikaci (jak parsovat query string v PHP, JavaScriptu, Kotlinu, Javě a Swiftu).
  4. Aplikace otevře platbu ve výchozím prohlížeči plátce (použije URL na platební bránu z parametru "redirect"). Tím aplikace ztrácí focus.
  5. Plátci se načte platební brána ve výchozím prohlížeči.
  6. Plátce zaplatí objednávku.
  7. Poté, co plátce provede úhradu, je Server pomocí Push notifikace informován o novém stavu platby. Tuto informaci si uloží.
  8. Server si ověří stav platby, tím že se dotáže Comgate API (/status), zda je platba skutečně zaplacena.
    • Pokud ne, dotazuje se periodicky každé cca 3 sekundy znovu. Po 10 dotazech (cca 30 sekundách) je vhodné dotazování ukončit a na pozadí se dotázat Serveru na stav jednou za 30 minut.
      Věnujte zvýšenou pozornost

      V některých případech může zpracování platby trvat až do 12:00 následujícího pracovního dne.

    • V opakování dotazování lze pokračovat podle stavů plateb.
  9. Plátce je následně přesměrován zpět do Aplikace a ta získá "focus".
  10. Aplikace kontaktuje svůj Server a ověří si stav platby.
  11. Aplikace zpřístupní zaplacenou službu.

Sekvenční diagram

Sekvenční diagram

Nastavení návratových URI pro Intent

V současné chvíli je možné Android Intent použít pouze jako parametry při zakládání platby přes Comgate API (/create). Jedná se o parametry:

  • url_paid - URI pro přesměrování plátce po zaplacení platby,
  • url_cancelled - URI pro přesměrování plátce po zrušení platby,
  • url_pending - URI pro přesměrování plátce, pokud platba ještě není vyřízena.

Platební brána se následně bude snažit použít tento Intent ve výchozím prohlížeči a přesměrovat tak plátce zpět do vaší aplikace.

Věnujte zvýšenou pozornost

Android Intent není v současné chvíli možné nastavit v klientském portálu.

Android Intent formát

Lze používat prakticky libovolný formát Intentu. Velmi často se setkáme s obecným zápisem ve tvaru:

intent://host/path?transactionId=XXXX-XXXX-XXXX&status=PAID#Intent;package=com.example.package;end

Je možné se také setkat s více specifickými Intenty např.:

myapp://payment/success?transactionId=XXXX-XXXX-XXXX&status=PAID

Informace

V obou případech jsou Intenty úzce svázány s konkrétní aplikací. Jejich funkčnost je nutné implementovat v rámci samotné aplikace.

Apple na svých zažízeních poskytuje mechanismy, které umožňují aplikacím efektivně zpracovat přesměrování. Mezi tyto mechanismy patří URL Schemes a Universal Links.

URL Schemes

Vlastní URL schemata umožňují aplikacím registrovat jedinečné odkazy, pomocí kterých může platební brána přesměrovat uživatele zpět do aplikace.

myapp://payment/success?transactionId=XXXX-XXXX-XXXX&status=PAID

Universal Links jsou standardní HTTP/HTTPS odkazy, které umí automaticky otevřít aplikaci. Tento mechanismus je preferován kvůli lepší bezpečnosti a uživatelské přívětivosti.

https://example.com/payment/success?transactionId=XXXX-XXXX-XXXX&status=PAID

Při nastavování plateb přes Comgate API je možné definovat návratové URL, která určují, kam bude uživatel přesměrován v různých situacích:

  • url_paid: Přesměrování po úspěšné platbě (PAID, AUTHORIZED)
  • url_cancelled: Přesměrování po zrušené nebo expirované platbě (CANCELLED)
  • url_pending: Přesměrování pro probíhající platby (PENDING)
Věnujte zvýšenou pozornost

Návratové URL ve formátu Universal Links je možné definovat jak přes Comgate API, tak i v klientském portálu.
URL Schemes je v tuto chvíli možné nastavit pouze přes Comgate API.