To integrate the Billie checkout widget, the following steps are required:
- Add the Billie checkout widget bundle to your checkout page
- Provide config data (with the
session_idfrom the server-side integration) - Provide order details and call the mount method
- Handle the widget responses
This section provides a step-by-step guide of the setup process.
1. Include Billie Checkout Widget Bundle into your Checkout Page
On the checkout page, the following code snippet must be included:
<script>
var bcwSrc = 'https://static.paella-sandbox.billie.io/checkout/billie-checkout.js';
(function(w,d,s,o,f,js,fjs){
w['BillieCheckoutWidget']=o;w[o]=w[o]||function(){(w[o].q=w[o].q||[]).push(arguments)};
w.billieSrc=f;js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];js.id=o;
js.src=f;js.charset='utf-8';js.async=1;fjs.parentNode.insertBefore(js,fjs);bcw('init');
}(window,document,'script','bcw', bcwSrc));
</script>
The URL contained in bcwSrc specifies whether you are using the Sandbox or Production environment:
Sandbox: https://static.paella-sandbox.billie.io/checkout/billie-checkout.js
Production: https://static.billie.io/checkout/billie-checkout.js
The code snippet above injects our checkout script into the head of the webshop. This will download our widget bundle code and enable function calls to interact with the widget.
It is strongly recommended to add this code snippet as high as possible in the document head to ensure that the widget download completes as soon as possible, providing a smooth user experience.
2. Provide Config Data
During initialization of the widget, the session_id is required. This can be obtained by calling Checkout Session Create from your backend and exposing it to the frontend. The session_id will be unique per order.
<script>
const billie_config_data = {
'session_id': ':YOUR_SESSION_ID',
'merchant_name': ':YOUR_NAME'
}
</script>
The session_id is needed to approve the order and should be known before mounting the widget.
Ideally, if you are using server-side rendering, this piece of code should be inserted into the document head with prefilled values. Otherwise please ensure there is an XHR request as early as possible to your backend to retrieve the session_id.
For a guideline how to present Billie as payment method please refer to the Checkout Design Guide.
3. Provide Order Details and Call Mount Method
Once the user reviews their checkout basket and is ready to pay, they can click on the Pay with Billie button. When this happens, Billie expects the mount method to be called. The easiest integration option is to inline the function call directly on the button, for example:
<script>
function payWithBillie() {
// prepare / get all the data and assign it to billie_order_data, please refer to 3a section
BillieCheckoutWidget.mount({
billie_config_data: billie_config_data,
billie_order_data: billie_order_data,
})
.then(function success(ao) {
// code to execute when approved order
// console.log('Approved order', ao);
})
.catch(function failure(err) {
// code to execute when there is an error or when order is rejected
// console.log('Error occurred', err);
});
}
</script>
<button onclick="payWithBillie()"> Pay with Billie </button>
BillieCheckoutWidget is a JavaScript promise which can accept optional then and catch methods. They can be added if the webshop needs to perform an action based on the outcome of the order authorization.
The then block will receive as a parameter the object with the authorized order details.
The catch block will receive the error object with reasons why the order creation was rejected.
3.a Mount Method Parameters
BillieCheckoutWidget.mount expects three parameters:
billie_config_datais the object received in step two which includes thesession_idandmerchant_namebillie_order_datais a collection of order data from the userbillie_widget_options[optional] is an object which includespayment_method
3.b Order Data Object
The order data object must contain all information about an order, in the following format (required values are marked with a *):
amount[object]*gross[float]*> 0tax[float]*>= 0net[float]*> 0
duration[integer]*[7...120]delivery_address[object]*street[string]*<= 255 charactershouse_number[string]<= 255 charactersaddition[string]<= 255 characterscity[string]*<= 255 characterspostal_code[string]*country[string]*2 characters^[A-Za-z]{2}$
debtor_company[object]*name[string]*<= 255 charactersestablished_customer[boolean]address_street[string]*<= 255 charactersaddress_house_number[string]<= 255 charactersaddress_addition[string]<= 255 charactersaddress_city[string]*<= 255 charactersaddress_postal_code[string]*5 characters^[0-9]{5}$address_country[string]*2 characters^[A-Za-z]{2}$merchant_customer_id[string]255 characters^[A-Za-z]{2}$legal_form[string]5 characters
debtor_person[object]*salutation[string]1 character["m" / "f"]first_name[string]<= 255 characterslast_name[string]<= 255 charactersphone_number[string]>= 5 characters,<= 20 characters^(\+|\d|\()[ \-\/0-9()]{5,20}$email[string]*<= 255 charactersvalid email
line_items[array of objects]*external_id[string]<= 255 characterstitle[string]*<= 255 charactersdescription[string]<= 255 charactersquantity[integer]*>= 1category[string]<= 255 charactersbrand[string]<= 255 charactersgtin[string]<= 255 charactersmpn[string]<= 255 charactersamount[object]*gross[float]*> 0tax[float]*>= 0net[float]*> 0
Below you can find an example of orderData object in javascript:
const billie_order_data = {
"amount": { "net": 100, "gross": 100, "tax": 0 },
"comment": "string",
"duration": 30,
"delivery_address": {
"house_number": "string",
"street": "string",
"city": "string",
"postal_code": "10000",
"country": "DE",
"addition": "string"
},
"debtor_company": {
"name": "string",
"established_customer": false,
"address_house_number": "string",
"address_street": "string",
"address_city": "string",
"address_postal_code": "10000",
"address_country": "DE",
"address_addition": "string"
},
"debtor_person": {
"salutation": "m",
"first_name": "string",
"last_name": "string",
"phone_number": "030 31199251",
"email": "[email protected]"
},
"line_items": [
{
"external_id": "string",
"title": "string",
"description": "string",
"quantity": 1,
"category": "string",
"brand": "string",
"gtin": "string",
"mpn": "string",
"amount": { "net": 100, "gross": 100, "tax": 0 },
}
// , ...
]
};
4. Handle Widget Responses
When submitted, the checkout widget will evaluate if an order with the given data can be accepted.
- If an order cannot be accepted, the widget will return the state
declinedwith a specifieddecline_reason - If an order can be accepted immediately the widget will return the state
authorized. - It is also possible that some additional checks need to be conducted by Billie in order to accept the order. In this case the widget will return the state
pre_waiting.
In both authorized and pre_waiting states the checkout-session-confirm call must be used to confirm the order creation.
Response
After submitting the widget, following data will be returned to either then or catch block:
state[string]<= 255 characters
Enum:authorizeddeclinedpre_waitingdecline_reason[string]<= 255 characters
Enum:validation_errorrisk_policydebtor_not_identifieddebtor_addressrisk_scoring_faileddebtor_limit_exceededemail_verification_requiredunknown_errorvalidation_error_source[string]<= 255 charactersdebtor_company[object]name[string]<= 255 charactersaddress_street[string]<= 255 charactersaddress_house_number[string]<= 255 charactersaddress_city[string]<= 255 charactersaddress_postal_code[string]5 characters^[0-9]{5}$address_country[string]2 characters^[A-Za-z]{2}$
Special note
decline_reasonwill be set only whenstatevalue isdeclinedvalidation_error_sourcewill be set only whendecline_reasonvalue isvalidation_error. We will fill this property with information to help you find which fields are failing validation checks.
The following processes should be implemented based on the given decline_reason:
validation_error:- Validate the error message and correct the submitted values if possible for new Checkout Client
debtor_not_identified,debtor_address:- Show a message that Billie needs the registered business address and restart the check out.
email_verification_required:- Show a message that Billie requested an email verification from the provided address. Buyer should verify the address and try again.
debtor_limit_exceeded:- Show a message that the limit of the buyer with Billie is exceeded. The buyer can contact Billie for more information.
risk_policy,risk_scoring_failed,unknown_error:- Do nothing, redirect the buyer to the paywall to choose a different payment method.
