Customer credit check

In case of a positive customer credit check with status “Accept”, the process for the customer is finished and a "Thank you for your purchase" message can be shown. If the payment is with status “Rejected” an alternative payment method should be proposed. The Twisto credit check is real-time and runs completely on Twisto’s server side.

The evaluation process is powered by the Twisto.js - JS library, that should be added to the purchase process and a back-end e-shop library designed to prepare data (payload) for the JS library. If you are using different programming language, it is also possible to prepare the data manually according to the specification.

Check Image

For detailed evaluation, it is necessary to provide full customer data, including previous transaction history.

At the time of clicking on "Confirm order" the credit check is started by calling the method in the JS Library Twisto.check(data, success, error). This process may take several seconds. The result of the credit check is then forwarded to the callback success, in both cases, even if the request was rejected.

In case of an error that may be caused by technical problems, error callback is called. We recommend showing an error to inform the customer and offer an alternative payment method. An order with error status cannot be shipped because it is not stored in the Twisto system. This means that the e-shop will not receive payment for it.

Implementation

The following example includes a full-featured code that performs customer credit check. The jQuery library is used to simplify code writing.

Customer data and previous orders are prepared on the server side and then passed to the Javascript library (as payload) for the Twisto.check() call. You can use the back-end library to prepare your payload or manually prepare the data according to the specifications. Then JS library will send prepared payload to the server.

When selecting the Twisto payment method and clicking on the order confirmation, the customer’s check is performed instead of submitting the form. This is done by replacing the normal action of submitting the form by clicking on the confirmation (submit) for the Twisto.check call. The "Confirm order" button should be changed to loader during the check process to indicate the ongoing credit check. Because this process may take several seconds, we recommend that this information is presented to the customer in a similar way.

When a payment is approved, a transaction ID is inserted into the hidden form field. Please save this ID to server, you will need it to create and update the order through our API.

A unique string for the random_nonce should be generated for each request. In case of Twisto.check will be called multiple times with the same random_nonce, the same result will always be returned. This way, you can avoid problems with sending same form repeatedly by customer. Twisto libraries generate random*nonce automatically, but if you’re manually creating the payload, please ensure that this string will always be unique. For example, you can use uuid4.

Note: Payload can’t be generated on the client side because it is encrypted and signed with a secret key that can not be disclosed.

Note: You can choose from two encryption options. You can change the encryption method in the eshop settings a detailed description can be found in the Reference Guide (data encryption).

Warning: If you perform the evaluation within WebView in a mobile application, you need to store and maintain cookies for further evaluation on the same device.

<?php define('TWISTO_PUBLIC_KEY', ''); // You can find your public key in administration define('TWISTO_SECRET_KEY', ''); // You can find your secret key in administration $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, // type 'Coca Cola 1 litr', // name 530, // product_id (Product ID has to be unique per order) 6, // quantity 156, // price_vat (total price of all items of order item) 15, // vat '5449000017888', // ean_code (product barcode) null, // isbn_code null, // issn_code 3808 // heureka_category (ID of Heureka.cz category) ), new Twisto\Item( Twisto\Item::TYPE_DEFAULT, // type 'Agatha Christie: The Secret Adversary', // name 942, // product_id 1, // quantity 285.31, // price_vat 15, // vat null, // ean_code '9781609421052', // isbn_code null, // issn_code 1469 // heureka_category ), new Twisto\Item( Twisto\Item::TYPE_SHIPMENT, // type 'Doprava DPD', // name 'shipment', // product_id 1, // quantity 119, // price_vat 21 // vat ), /* * Payment item (Twisto) is also required to be listed among order items * * You can lower the price of payment in order items below at your own expense. */ new Twisto\Item( Twisto\Item::TYPE_PAYMENT, // type 'Twisto – Zboží inhed, platím za 14 dní', // name 'payment', // product_id 1, // quantity 0, // price_vat 21 // vat ), new Twisto\Item( Twisto\Item::TYPE_ROUND, // type 'Zaokrouhlení', // name 'round', // product_id 1, // quantity -0.31, // price_vat 0 // vat ), ); // Instance of class NewOrder will contain all information about order $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 // items ); $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 ) ); // create data to be sent to Twisto server via 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(); // Twisto payment method was selected if($('input[name=payment_method]:checked').val() == 'twisto') { if($('#terms-checkbox').is(':not(:checked)')) { DemoCheckout.$terms_notice.show(); } else { DemoCheckout.reset(); // show button with an animation signaling order evaluation 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') { // payment accepted DemoCheckout.order_complete(); // save transaction id to hidden form field $('#twisto-transaction-id').val(response.transaction_id); } else { // payment declined DemoCheckout.reset(); DemoCheckout.error(response.reason); } }, function() { // an error occurred due to invalid request or connection failure 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> ?>

Data format

API requires valid phone numbers in international format, e.g. "+420732629228". In case of missing the country-specific prefix it will be automatically added (field country in billing address). For new orders, customer’s phone number is mandatory, and if the phone is not filled, the order will be declined. Phone number validation in the shopping cart is on a particular e-shop implementation, we recommend using the libphonenumber, library, which is also used by the Twisto API.

Warning: An incorrect phone number in the order will cause an API error and the order will not be created.

In the field for previous orders should be all customer orders that have already been paid, are not canceled and were not made with Twisto. If the customer is not registered, please search previous orders by email.

Request

NameRequiredData typeMaximum lengthValue
random_nonceString64Text string unique for each check
customerCustomerDetailed information about the customer
orderOrderCurrent customer order
previous_ordersOrder[]All already paid orders except for orders via Twisto

It’s possible to set callback using Twisto.js which will be called after the scoring process successfully started, i.e. at the moment when the data has been already sent to the server and the library waits for scoring result.

This can be set up using processingStarted option, see reference manual.

Response

The result of the credit check has two possible states. The response always has transaction ID (transaction_id) and status, if rejected - (reason). The answer is forwarded to the success callback.

  • accepted = approval
    • The order is successfully completed. "Thank you for your payment" message is shown to the customer.
    • When the purchase is completed, use transaction_id to create an invoice.
  • accepted-verification-required = verification required
    • Order is approved, but needs additional verification. The customer would have to enter verification code before finishing the order.
    • When the purchase is completed, use transaction_id to create an invoice.
    • Before invoice create user verification via API is required.
    • This response is only for eshops with enabled verification api.
  • rejected = rejection
    • The rejected reason will be shown to the customer.
    • If the rejection is final, allow customer to choose another payment method and display rejected reason.
    • If you have multilingual e-shop or you are not able to use reason, use reason_params and reason_id . Some reasons has in reason_params parametr limit. reason_id is positive number or 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č." }

Rejection reason

reason_idShort descriptionMessagereason_params
0DefaultWe’re sorry, but we have to ask you to use another payment method.{}
1Invalid addressAs much as we tried, we couldn’t find this address. However, when you enter it in the same format that is on your identity card, it should go through.{}
2Unpaid invoicesYour purchase is a little bit too big for Twisto. We’ll be happy to allow you this payment after you settle your previous purchases.{}
3Over limitYour 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č.{"limit": "1,000 Kč"}
4Over annual limitYou've reached maximum annual limit for Twisto Pay purchases.We will be happy to allow you to make a further purchase if you register a Twisto account. We have sent you more information by e-mail.{}
5Invalid namePlease enter your first name and surname in your billing address.{}
6No accountAt this time, we only allow the purchase of customers who have a Twisto account. You can find information on how to register a Twisto account at www.twisto.cz{}
7Sms verification requiredYou have closed the window with SMS verification dialog. For security reasons, we require SMS verification.{}
100Account over limitYour purchase exceeds the current limit of your Twisto account. We will be happy to allow you this payment if your purchase is within 1,000 Kč.{"limit": "1,000 Kč"}
101Unpaid invoicesYour purchase exceeds the current limit of your Twisto account. We’ll be happy to allow you this payment after you settle your previous purchases.{}
102Account login requiredYou have closed the window with Twisto account login dialog. For security reasons, we require a login before continuing.{}

Customer verification

In some cases additional identity verification is required. It’s either SMS code or login to customer account. In these cases modal is displayed to customer right on eshop page. Our JS library is responsible for displaying this modal. Our library can detect that third party cookies are disabled in the browser and allow the customer to display verification form in a new window instead of modal. To test this use email test@twisto.cz, in other word set email field of Customer object to this value. Modal is displayed and any password is accepted.

For payment gateway there is verification API. It’s not intended for eshops so It’s not needed in this case.

Testing

If you’d like to test rejection of the order (property status will be set to rejected in the response), please use testing email address karel.zlodej@example.cz. Object Customer should have the property email set to this value. The scoring will always accept all other email addresses in the testing API (property status will be set to accepted).