Příjem plateb pomocí PayPal tlačítka
Na několika mých přednáškách jsem v poslední době ukazoval velmi jednoduchý způsob, jak přijímat platby. Protože PayPal nabízí celou řadu platebních nástrojů, záludné je především najít v dokumentaci to správné místo. V tomto článku popíšu celý princip fungování a připojím odkazy potřebné k implementaci.
Platební proces
Celý platební proces se dá rozložit na následující kroky:
- klient klikne na vygenerované platební tlačítko
- zobrazí se okno, ve kterém provede klient úhradu
- paypal platbu zpracuje a v případě úspěchu vytvoří webhook
Platící klient může zaplatit buď přímo z PayPal účtu nebo z libovolné kreditní karty. Za provedenou transakci si PayPal ponechá provizi. Finanční prostředky na PayPal účtu můžete průběžně používat k platbám nebo si je lze nechat vyplácet automaticky na učet.
Implementační workflow
Z pohledu implementace je potřeba vložit někam JavaScript s platebním tlačítkem a připravit si API endpoint, který bude přijímat webhooky z PayPalu. K tomu všemu je nutné založit si účel na PayPal a v něm aplikaci.
1. Založení účtu
Založit účet na PayPal a registrovat se do PayPal Developer (dále PPD) lze zdarma. Já mám účet u PayPal od nepaměti, takže nevím do detailu co vše se musí aktuálně zadávat, ale předpokládám, že kromě e-mailu jen vybrané osobní údaje. PayPal Developer by se měl zpřístupnit automaticky k danému účtu.
2. Vytvoření aplikace
Dále je potřeba vytvořit v PayPal Developer novou aplikaci (REST API app). Ihned po zadání názvu se aplikace vytvoří a obsahuje credentials. Pro naše účely budeme zatím potřebovat jen veřejný Client ID. Pro danou aplikaci lze nastavit i omezení oprávnění. Později se na stránku aplikace ještě vrátíme přidat webhook. Doporučuji si tuto stránku dát do záložek.
3. Platební tlačítko
Teď už nám nebrání vložit na místo platby platební tlačítko. Je to jen kus JS kódu, který nastavuje vzhled tlačítka a cenu. JS kód vypadá následovně:
<div id="paypal-button-container"></div>
<script src="https://www.paypal.com/sdk/js?client-id=XXXXX¤cy=CZK" data-sdk-integration-source="button-factory"></script>
<script>
function initPayPalButton() {
paypal.Buttons({
style: {
shape: 'rect',
color: 'blue',
layout: 'vertical',
label: 'paypal',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [
{"description":"Název produktu", "custom_id":"id_pro_parovani", "amount":{"currency_code":"CZK","value":999}}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(orderData) {
actions.redirect('/platba-provedena');
});
},
onError: function(err) {
console.log(err);
}
}).render('#paypal-button-container');
}
initPayPalButton();
</script>
Domnívám se, že pro implementaci může být užitečná tato část dokumentace, kde jsou uvedeny parametry skriptu. Důležité je nicméně jen nastavit měnu a právě zde použít Client ID aplikace vytvořené v předchozím kroku. Po úspěšné úhradě se provede redirect na uvedenou stránku.
Událost actions.order.create obsahuje pole zakoupených položek. Kompletní podoba objektu je popsána v této části dokumentace (request body schema u události Create order).
4. Příprava API pro příjem webhooků
Teď už mohou uživatelé klikat na tlačítko a platit. Ještě se potřebujeme o platbě dozvědět. Proto je potřeba vytvořit si někde na webu HTTP endpoint, který bude přijímat notifikace z PayPalu. Nejjednodušší řešení je použít službu Make. V rámci ní pak vytvořit nový scénář a jako inicializační krok si vybrat modul PayPal a událost Nová notifikace. Výhodou Make je, že nemusíte nic programovat a vše si lze naklikat v UI. Vypadá to zhruba takto:
Make má tisíce integrací, takže s notifikací lze dále pracovat dle libosti.
Jiné zcela tradiční řešení je naprogramovat si API endpoint ručně. Je ale nutné znát JSON strukturu, kterou PayPal posílá. Vše je sepsané naštěstí v dokumentaci včetně ukázkového payloadu. Když to ořežu na nejdůležitější fragmenty, vypadá to přibližně takto:
{
"id": "WH-XXXXXXXXXXXX-XXXXXXXXXXXXXXX",
"create_time": "2023-08-31T12:00:45.614Z",
"resource_type": "checkout-order",
"event_type": "CHECKOUT.ORDER.APPROVED",
"resource": {
"purchase_units": [{
"reference_id": "default",
"amount": {
"currency_code": "CZK",
"value": "390.00"
},
"payee": {
"email_address": "mail@prodavajici.cz"
},
"payments": {
"captures": [{
"id": "XXXXXXXXXXXX",
"status": "COMPLETED",
"amount": {
"currency_code": "CZK",
"value": "390.00"
}
}]
}
}],
"id": "XXXXXXXXXXX",
"payment_source": {
"paypal": {
"email_address": "mail@kupujici.cz",
"name": {
"given_name": "Jmeno",
"surname": "Kupujiciho"
},
"address": {
"country_code": "CZ"
}
}
}
}
}
Tak či onak je potřeba mít nakonec URL, která je schopná skrze metodu POST přijímat právě podobný kus JSON struktury.
5. Nastavení Webhooku
Teď už stačí přejít zpět do detailu aplikace na PayPalu a scrollovat úplně dolu. Zde je možné vytvořit nový webhook přes tlačítko Add Webhook.
Hned první políčko je URL, na kterou bude PayPal posílat notifikace. Měla by to být URL z předchozího kroku.
U webhooku si lze také vybrat události, které bude obsluhovat. Zásadní je sekce Checkout, kde se nachází mj. i ideální stav Checkout order approved / completed. V příchozím JSONu je vlastnost event_type, kde je uveden název události.
Při příjmu webhooku už si stačí spárovat uživatele dle e-mailu a částky. V dokumentaci jsem viděl i možnost přidat item_id, ale už to nedokážu zpětně dohledat.
Závěr, zkušenosti a doporučení
Výše popsané řešení už používám na webu restapi.cz, miroslavholec.cz a textomet.cz. Vždy mi vše fungovalo spolehlivě. Notifikace z PayPalu se občas trochu zpozdí, ale nakonec dorazí. Pro účely ladění je možné si účet z Live přepnout do Sandboxu (ale je nutné změnit i URL skriptů). Závěrem bych ještě upozornil, že Make neumí u příchozího JSON parsovat všechny vlastnosti. Je ale možné místo PayPal/Nová notifikace použit jednoduše tradiční Webhook a nechat si celý JSON zparsovat.