Ú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.

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ázev | Povinné | Datový typ | Maximální délka | Hodnota |
|---|---|---|---|---|
| random_nonce | ✓ | String | 64 | Jedinečný textový řetězec pro každou kontrolu |
| customer | ✓ | Customer | Podrobné informace o zákazníkovi | |
| order | ✓ | Order | Aktuální objednávka zákazníka | |
| previous_orders | ✓ | Order[] | 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_idk 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_idk 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žijtereason_paramsareason_id. Některé důvody mají vreason_paramsparametrlimit.reason_idje kladné číslo nebo0
- Zákazníkovi se zobrazí zamítnutý
{
"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_id | Stručný popis | Zpráva | reason_params |
|---|---|---|---|
| 0 | Výchozí | Je nám líto, musíme vás požádat o použití jiné platební metody. | {} |
| 1 | Neplatná adresa | Ač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. | {} |
| 2 | Neuhrazené faktury | Váš nákup je pro Twisto trochu moc velký. Rádi vám tuto platbu povolíme poté, co uhradíte předchozí nákupy. | {} |
| 3 | Nad limit | Váš 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č"} |
| 4 | Roční limit | Dosá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. | {} |
| 5 | Neplatné jméno | Do fakturační adresy prosím zadejte jméno a příjmení. | {} |
| 6 | Bez účtu | V tuto chvíli umožňujeme nákup jen zákazníkům s účtem Twisto. Informace o registraci najdete na www.twisto.cz | {} |
| 7 | Vyžadováno ověření SMS | Zavřeli jste okno s dialogem pro ověření SMS. Z bezpečnostních důvodů vyžadujeme ověření SMS. | {} |
| 100 | Nad limitem účtu | Váš 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č"} |
| 101 | Neuhrazené faktury | Váš 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ů. | {} |
| 102 | Vyž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).