Úvěrová kontrola zákazníka

Při pozitivní úvěrové kontrole zákazníka se stavem „Accept“ je proces pro zákazníka dokončen a lze zobrazit zprávu „Děkujeme za nákup“. Pokud má platba stav „Rejected“, měla by se nabídnout alternativní platební metoda. Úvěrová kontrola Twisto probíhá v reálném čase a kompletně na straně serveru Twisto.

Vyhodnocení zajišťuje JS knihovna Twisto.js, kterou je potřeba vložit do nákupního procesu, a knihovna na backendu e-shopu pro přípravu dat (payload) pro JS knihovnu. Pokud používáte jiný programovací jazyk, lze data připravit i ručně podle specifikace.

Obrázek kontroly

Pro podrobné vyhodnocení je nutné dodat úplná data o zákazníkovi včetně historie předchozích transakcí.

V okamžiku kliknutí na „Potvrdit objednávku“ se úvěrová kontrola spustí voláním metody v JS knihovně Twisto.check(data, success, error). Proces může trvat několik sekund. Výsledek kontroly se předá do callbacku success v obou případech, i když byl požadavek zamítnut.

Při chybě, kterou mohou způsobit technické problémy, se zavolá error callback. Doporučujeme zobrazit chybu zákazníkovi a nabídnout alternativní platební metodu. Objednávku ve stavu chyby nelze expedovat, protože není uložena v systému Twisto. E-shop za ni tedy neobdrží platbu.

Implementace

Následující příklad obsahuje plně funkční kód, který provede úvěrovou kontrolu zákazníka. Ke zjednodušení zápisu se používá knihovna jQuery.

Data zákazníka a předchozí objednávky se připraví na serveru a předají se JavaScriptové knihovně (jako payload) pro volání Twisto.check(). Payload lze připravit knihovnou na backendu nebo ručně podle specifikace. Poté JS knihovna připravený payload odešle na server.

Při výběru platby Twisto a kliknutí na potvrzení objednávky se místo odeslání formuláře provede kontrola zákazníka nahrazením běžné akce odeslání formuláře po kliknutí na potvrzení (submit) voláním Twisto.check. Tlačítko „Potvrdit objednávku“ by během kontroly mělo přejít do stavu načítání, aby bylo zřejmé, že kontrola probíhá. Vzhledem k délce procesu doporučujeme tuto informaci zákazníkovi zobrazit podobným způsobem.

Po schválení platby se ID transakce vloží do skrytého pole formuláře. Uložte si ho na serveru, budete ho potřebovat k vytvoření a aktualizaci objednávky přes naše API.

Pro každý požadavek je potřeba vygenerovat jedinečný řetězec random_nonce. Pokud se Twisto.check zavolá vícekrát se stejným random_nonce, vždy se vrátí stejný výsledek. Tím lze předejít problémům s opakovaným odesláním stejného formuláře zákazníkem. Knihovny Twisto random_nonce generují automaticky, ale pokud payload sestavujete ručně, zajistěte, aby byl tento řetězec vždy jedinečný. Například můžete použít uuid4.

Poznámka: Payload nelze generovat na straně klienta, protože je šifrovaný a podepsaný tajným klíčem, který nesmí být zveřejněn.

Poznámka: Lze zvolit ze dvou možností šifrování. Metodu šifrování můžete změnit v nastavení e-shopu; podrobný popis je v referenční příručce (šifrování dat).

Upozornění: Pokud vyhodnocení probíhá ve WebView v mobilní aplikaci, je potřeba ukládat a udržovat cookies pro další vyhodnocení na stejném zařízení.

<?php define('TWISTO_PUBLIC_KEY', ''); // veřejný klíč najdete v administraci define('TWISTO_SECRET_KEY', ''); // tajný klíč najdete v administraci $reject_test_order = false; require 'vendor/autoload.php'; date_default_timezone_set('Europe/Prague'); $twisto = new Twisto\Twisto(); $twisto->setPublicKey(TWISTO_PUBLIC_KEY); $twisto->setSecretKey(TWISTO_SECRET_KEY); $customer = new Twisto\Customer('novak@example.cz', 'Jan Novák', '1146217671', '01615165', 'CZ01615165'); if($reject_test_order) $customer->email = 'karel.zlodej@example.cz'; $order_items = array( new Twisto\Item( Twisto\Item::TYPE_DEFAULT, // typ 'Coca Cola 1 litr', // název 530, // product_id (v rámci objednávky musí být jedinečné) 6, // množství 156, // price_vat (celková cena všech kusů dané položky) 15, // DPH '5449000017888', // ean_code (čárový kód) null, // isbn_code null, // issn_code 3808 // heureka_category (ID kategorie Heureka.cz) ), new Twisto\Item( Twisto\Item::TYPE_DEFAULT, // typ 'Agatha Christie: The Secret Adversary', // název 942, // product_id 1, // množství 285.31, // price_vat 15, // DPH null, // ean_code '9781609421052', // isbn_code null, // issn_code 1469 // heureka_category ), new Twisto\Item( Twisto\Item::TYPE_SHIPMENT, // typ 'Doprava DPD', // název 'shipment', // product_id 1, // množství 119, // price_vat 21 // DPH ), /* * Položka platby (Twisto) musí být uvedena mezi položkami objednávky * * Cenu platby v položkách níže můžete snížit na vlastní náklady. */ new Twisto\Item( Twisto\Item::TYPE_PAYMENT, // typ 'Twisto – Zboží inhed, platím za 14 dní', // název 'payment', // product_id 1, // množství 0, // price_vat 21 // DPH ), new Twisto\Item( Twisto\Item::TYPE_ROUND, // typ 'Zaokrouhlení', // název 'round', // product_id 1, // množství -0.31, // price_vat 0 // DPH ), ); // instance třídy NewOrder obsahuje veškeré informace o objednávce $order = new Twisto\Order( new DateTime(), // date_created new Twisto\Address('Jan Novák', 'Milady Horákové 116/109', 'Praha 6', '16000', 'CZ', '+420603604605'), // billing_address new Twisto\Address('Jan Novák, Twisto payments a.s.', 'Sokolovská 47/73', 'Praha 8', '18600', 'CZ', '+420603604605'), // delivery_address 560, // total_price_vat $order_items // položky ); $previous_orders = array( new Twisto\Order( new DateTime("2012-07-08 11:14:15.638276"), $order->billing_address, $order->delivery_address, $order->total_price_vat, $order_items ) ); // příprava dat k odeslání na server Twisto přes JavaScript $payload = $twisto->getCheckPayload($customer, $order, $previous_orders); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" href="https://static.twistopay.com/base/css/doc-examples.css"> <script type="text/javascript"> var _twisto_config = { public_key: '<?php echo TWISTO_PUBLIC_KEY; ?>', script: 'https://api.twisto.cz/v2/lib/twisto.js' }; (function(e,g,a){function h(a){return function(){b._.push([a,arguments])}}var f=["check"],b=e||{},c=document.createElement(a);a=document.getElementsByTagName(a)[0];b._=[];for(var d=0;d<f.length;d++)b[f[d]]=h(f[d]);this[g]=b;c.type="text/javascript";c.async=!0;c.src=e.script;a.parentNode.insertBefore(c,a);delete e.script}).call(window,_twisto_config,"Twisto","script"); </script> <script type="text/javascript"> $(function() { DemoCheckout = { $terms_notice: $('#terms-notice'), $checkout_form: $('#checkout-form'), $form_submit_button: $('.btn-submit'), $btn_check: $('.btn-check'), $error_alert: $('#error-alert'), init: function () { DemoCheckout.$checkout_form.on('submit', function(e) { e.preventDefault(); // zvolena platba Twisto if($('input[name=payment_method]:checked').val() == 'twisto') { if($('#terms-checkbox').is(':not(:checked)')) { DemoCheckout.$terms_notice.show(); } else { DemoCheckout.reset(); // tlačítko s animací signalizující vyhodnocení objednávky DemoCheckout.$form_submit_button.hide(); DemoCheckout.$btn_check.css('display', 'inline-block'); DemoCheckout.twisto_check('<?php echo $payload; ?>'); } } }); }, twisto_check: function (payload) { Twisto.check(payload, function(response) { if (response.status == 'accepted') { // platba schválena DemoCheckout.order_complete(); // uložení ID transakce do skrytého pole formuláře $('#twisto-transaction-id').val(response.transaction_id); } else { // platba zamítnuta DemoCheckout.reset(); DemoCheckout.error(response.reason); } }, function() { // chyba kvůli neplatnému požadavku nebo selhání spojení DemoCheckout.reset(); DemoCheckout.error(); }); }, reset: function () { DemoCheckout.$terms_notice.hide(); DemoCheckout.$form_submit_button.show(); DemoCheckout.$btn_check.hide(); DemoCheckout.$error_alert.hide(); }, error: function (reason) { if(typeof(reason) == 'undefined') reason = 'Došlo k chybě při odesílání objednávky na platební bránu Twisto. Zkuste to prosím znovu, případně si vyberte jinou platební metodu.'; DemoCheckout.$error_alert.html(reason); DemoCheckout.$error_alert.show(); }, order_complete: function() { DemoCheckout.reset(); $('.panel-body.form').hide(); $('.panel-body.thank-you').show(); } }; DemoCheckout.init(); }); </script> </head> <body> <div class="container" role="main"> <div class="panel panel-default"> <div class="panel-body form"> <form action="" method="post" id="checkout-form"> <input type="hidden" name="twisto-transaction-id" id="twisto-transaction-id" value=""> <div class="alert alert-danger" id="error-alert"></div> <div class="radio"> <label> <input type="radio" name="payment_method" value="twisto" checked> <span>Zboží ihned, platím za 14 dní</span> </label> <div id="terms-notice"> <small>Pro použití platební metody Twisto je potřeba souhlasit s podmínkami služby.</small> </div> <div class="twisto-terms"> <label> <input type="checkbox" id="terms-checkbox"> Souhlasím s <a href="https://www.twisto.cz/podminky/">všeobecnými obchodními podmínkami</a> služby Twisto.cz (platba první objednávky do 14 dní od doručení zboží) a se zpracováním osobních údajů pro účely této služby. Podmínkou služby je věk 18+ a převzetí zboží zákazníkem. </label> </div> </div> <div class="radio"> <label> <input type="radio" name="payment_method" value="cash"> <span>Dobírka</span> </label> </div> <div class="radio"> <label> <input type="radio" name="payment_method" value="online_card"> <span>Platební kartou online</span> </label> </div> <div id="twisto-checkout"></div> <input type="hidden" name="transaction_id"> <div class="submit"> <input type="submit" class="btn btn-success btn-submit" value="Dokončit objednávku"> <a class="btn btn-success btn-check disabled">Probíhá vyhodnocení objednávky <img src="https://upx.cz/9ii0u5ydmfi7u1zx3mxr9xqp628ra2eoljoyqrhy"></a> </div> </form> </div> <div class="panel-body thank-you"> <h3>Děkujeme za Vaši objednávku!</h3> <p>Po obdržení zboží budete mít 14 dní na zaplacení bankovním převodem, kartou online nebo hotově společnosti Twisto.cz.</p> </div> </div> </div> </body> </html> ?>

Formát dat

API vyžaduje platná telefonní čísla v mezinárodním formátu, např. „+420732629228“. Pokud chybí předvolba země, doplní se automaticky (pole country ve fakturační adrese). U nových objednávek je telefon zákazníka povinný; pokud chybí, bude objednávka zamítnuta. Validaci telefonu v košíku řeší konkrétní implementace e-shopu; doporučujeme knihovnu libphonenumber, kterou používá také Twisto API.

Upozornění: Nesprávné telefonní číslo v objednávce způsobí chybu API a objednávka nevznikne.

Do pole předchozích objednávek patří všechny objednávky zákazníka, které už byly uhrazeny, nejsou stornované a neproběhly přes Twisto. Pokud zákazník není registrovaný, vyhledejte předchozí objednávky podle e-mailu.

Požadavek

NázevPovinnéDatový typMaximální délkaHodnota
random_nonceString64Jedinečný textový řetězec pro každou kontrolu
customerCustomerPodrobné informace o zákazníkovi
orderOrderAktuální objednávka zákazníka
previous_ordersOrder[]Všechny již uhrazené objednávky kromě plateb přes Twisto

V Twisto.js lze nastavit callback, který se zavolá po úspěšném zahájení scóringu, tj. v okamžiku, kdy jsou data odeslána na server a knihovna čeká na výsledek.

Nastaví se pomocí volby processingStarted, viz referenční příručka.

Odpověď

Výsledek úvěrové kontroly má dva možné stavy. Odpověď vždy obsahuje ID transakce (transaction_id) a status, při zamítnutí také (reason). Odpověď se předává do success callbacku.

  • accepted = schválení
    • Objednávka je úspěšně dokončena. Zákazníkovi se zobrazí zpráva „Děkujeme za platbu“.
    • Po dokončení nákupu použijte transaction_id k vytvoření faktury.
  • accepted-verification-required = vyžadováno ověření
    • Objednávka je schválena, ale vyžaduje dodatečné ověření. Zákazník by před dokončením musel zadat ověřovací kód.
    • Po dokončení nákupu použijte transaction_id k vytvoření faktury.
    • Před vytvořením faktury je potřeba ověření uživatele přes API.
    • Tato odpověď platí jen pro e-shopy s zapnutým verification API.
  • rejected = zamítnutí
    • Zákazníkovi se zobrazí zamítnutý reason.
    • Pokud je zamítnutí konečné, umožněte zákazníkovi zvolit jinou platební metodu a zobrazte důvod zamítnutí.
    • Pokud máte vícejazyčný e-shop nebo nemůžete použít reason, použijte reason_params a reason_id. Některé důvody mají v reason_params parametr limit. reason_id je kladné číslo nebo 0
{ "status": "accepted", "transaction_id": "hisnmy6enxhq07rx69hniwwd" }
{ "status": "accepted-verification-required", "transaction_id": "hisnmy6enxhq07rx69hniwwd" }
{ "status": "rejected", "transaction_id": "hisnmy6enxhq07rx69hniwwd", "reason_id": 2, "reason_params": {}, "reason": "The payment was not approved as we were unable to process the format of your address. Please try entering the address again as it is written in your personal ID or the Land Register." }
{ "status": "rejected", "transaction_id": "hisnmy6enxhq07rx69hniwwd", "reason_id": 0, "reason_params": {}, "reason": "Sorry, unfortunately this order was not accepted by the Twisto payment gateway verification process. Please use an alternative payment method." }
{ "status": "rejected", "transaction_id": "hisnmy6enxhq07rx69hniwwd", "reason_id": 3, "reason_params": { "limit": "1,000 Kč" }, "reason": "Your purchase is too big for Twisto. We’ll be happy to serve you if the total price of the order will be lower than 1,000 Kč." }

Důvod zamítnutí

reason_idStručný popisZprávareason_params
0VýchozíJe nám líto, musíme vás požádat o použití jiné platební metody.{}
1Neplatná adresaAčkoli jsme se snažili, tuto adresu se nám nepodařilo najít. Když ji zadáte ve stejném formátu jako na občance, mělo by to projít.{}
2Neuhrazené fakturyVáš nákup je pro Twisto trochu moc velký. Rádi vám tuto platbu povolíme poté, co uhradíte předchozí nákupy.{}
3Nad limitVáš nákup je pro Twisto příliš velký. Rádi vám vyhovíme, pokud bude celková cena objednávky nižší než 1 000 Kč.{"limit": "1,000 Kč"}
4Roční limitDosáhli jste maximálního ročního limitu pro nákupy Twisto Pay. Rádi vám umožníme další nákup po registraci účtu Twisto. Více informací jsme vám zaslali e-mailem.{}
5Neplatné jménoDo fakturační adresy prosím zadejte jméno a příjmení.{}
6Bez účtuV tuto chvíli umožňujeme nákup jen zákazníkům s účtem Twisto. Informace o registraci najdete na www.twisto.cz{}
7Vyžadováno ověření SMSZavřeli jste okno s dialogem pro ověření SMS. Z bezpečnostních důvodů vyžadujeme ověření SMS.{}
100Nad limitem účtuVáš nákup překračuje aktuální limit vašeho účtu Twisto. Rádi vám tuto platbu povolíme, pokud bude nákup do 1 000 Kč.{"limit": "1,000 Kč"}
101Neuhrazené fakturyVáš nákup překračuje aktuální limit vašeho účtu Twisto. Rádi vám tuto platbu povolíme po uhrazení předchozích nákupů.{}
102Vyžadováno přihlášeníZavřeli jste okno s dialogem pro přihlášení k účtu Twisto. Z bezpečnostních důvodů vyžadujeme přihlášení před pokračováním.{}

Ověření zákazníka

V některých případech je potřeba dodatečné ověření identity – buď kód SMS, nebo přihlášení k zákaznickému účtu. Zákazníkovi se pak přímo na stránce e-shopu zobrazí modální okno. Za jeho zobrazení odpovídá naše JS knihovna. Knihovna dokáže zjistit, že jsou v prohlížeči zakázané cookies třetích stran, a umožní ověřovací formulář v novém okně místo modálu. K testu použijte e-mail test@twisto.cz, jinými slovy nastavte v objektu Customer pole email na tuto hodnotu. Zobrazí se modální okno a jakékoliv heslo bude přijato.

Pro platební bránu existuje ověřovací API. Není určeno pro e-shopy, v tomto případě ho nepotřebujete.

Testování

Chcete-li testovat zamítnutí objednávky (vlastnost status bude v odpovědi rejected), použijte testovací e-mail karel.zlodej@example.cz. Objekt Customer by měl mít vlastnost email nastavenou na tuto hodnotu. Scóring v testovacím API vždy přijme všechny ostatní e-mailové adresy (vlastnost status bude accepted).