Skip to main content

Step 2: Checking out

In Step 1: Identifying The Buyer, you implemented company search, and API calls to create a User and Organisation for the customer.

Now it's time to implement the checkout:

  • Step 2a: First, get the payment terms from Hokodo's API. You will pass order data to Hokodo to check credit eligibility.
  • Step 2b: Then, display the checkout to the customer using our frontend SDK. This includes showing the Payment Offers to the customer.

Once this step is complete, the customer will be able to buy goods in your store using Hokodo.

Step 2a: Get payment terms from Hokodo

In this step, your integration will:

  1. Create an Order: Send details about the customer's basket to the Hokodo API.
  2. Request a Payment Offer: Ask the API for the payment terms Hokodo will offer for that Order.
Full working example

For working examples of the Order and Payment Offer HTTP requests, see the Postman collection.

Create an Order

API Reference: Create order

An Order represents the customer's basket of goods. Hokodo needs this information when deciding which payment terms to offer.

Request

From your store's server side, make an HTTP POST request to /v1/payment/orders.

The main information in the POST /v1/payment/orders request is:

  • The customer's Hokodo User ID.
  • The customer's delivery and invoice addresses.
  • A unique_id field.
Order Identifiers

The unique_id must be an identifier or reference that both your operational team and Buyers will recognise to identify an order. It is crucial to have a shared language when referring to the order between all parties.

It is common that your primary order identifer is only generated after the completion of the checkout. That is why we allow you to modify the order.unique_ID with a PATCH request at any time. Other fields of the order are not modifiable after checkout.

  • Total order monetary amount, and tax amount.
    • This is in minor units: number of cents (EUR) or pence (GBP).
  • Some details about the line items of the order.
    • This is used at the fulfillment stage and it also helps Hokodo with fraud detection.
    • Please ensure categories are supplied. This is required for our fraud detection.
  • Historical data about the customer to enhance our risk decisioning (see In Depth).
Integration test

Integration test 1.2 checks that each Order item has a category.

Integration test

Integration test 1.5 checks that our API receives your unique_ids correctly.

Integration test

Integration test 2.2 checks that the total_amount and tax_amount of the order is consistent with the sum of the line items.

This consistency is explained in more detail below.

Here's a shortened version of the request showing the main fields:

POST /v1/payment/orders HTTP 1.1
Content-Type: application/json
Authorization: Token <your-api-key>

{
"unique_id": "your-unique-order-id",
"customer": {
"type": "registered", # use "sole-trader" for sole traders
"organisation": "org-asrE7fKEuNor5CaVQD4Ah5", # The customer's Organisation ID from Step 1b
"user": "user-WFOMowqyUjpv8JeihXn5Xh", # The customer's User ID from Step 1b
"delivery_address": {
...
},
"invoice_address": {
...
}
},
"status": "draft",
"currency": "GBP",
"total_amount": 300000,
"tax_amount": 60000,
"order_date": "2022-04-29", # The date the order was placed *on your platform*
"items": [
...
]
}

Expand the blue box to see the full request details, and see the API Reference for descriptions of each field.

Full Request Details - Order Creation

POST /v1/payment/orders HTTP 1.1
Content-Type: application/json
Authorization: Token <your-api-key>

{
"unique_id": "your-unique-order-id",
"customer": {
"type": "registered", # use "sole-trader" for sole traders
"organisation": "org-asrE7fKEuNor5CaVQD4Ah5", # The customer's Organisation ID from Step 1b
"user": "user-WFOMowqyUjpv8JeihXn5Xh", # The customer's User ID from Step 1b
"delivery_address": {
"name": "John Smith",
"address_line1": "1 Station Street",
"address_line2": "Flat B",
"city": "London",
"postcode": "SE11 6NQ",
"country": "GB"
},
"invoice_address": {
"name": "Bob Accounting",
"address_line1": "1 Main Street",
"address_line2": "65th floor",
"city": "London",
"postcode": "SE11 6NQ",
"country": "GB"
}
},
"status": "draft",
"currency": "GBP",
"total_amount": 300000,
"tax_amount": 60000,
"order_date": "2022-04-29", # The date the order was placed *on your platform*
"items": [
{
"item_id": "your-unique-item-id-0001",
"type": "product",
"description": "Super ergonomic chair",
"metadata":
{
"color": "black",
"name": "Karmus",
"variant": "M"
},
"reference": "your-reference-number",
"category": "Furniture > Chairs",
"supplier_id": "your-supplier-id",
"quantity": "10.000",
"unit_price": 10000,
"total_amount": 100000,
"tax_amount": 20000,
"fulfilled_quantity": 0,
"fulfillment_info": null,
"cancelled_quantity": 0,
"cancelled_info": null,
"returned_quantity": 0,
"returned_info": null
},
{
"item_id": "your-unique-item-id-0002",
"type": "product",
"description": "Super ergonomic table",
"metadata":
{
"color": "black",
"name": "Karmus",
"variant": "M"
},
"reference": "your-reference-number",
"category": "Furniture > Tables",
"supplier_id": "your-supplier-id",
"quantity": "10.000",
"unit_price": 20000,
"total_amount": 200000,
"tax_amount": 40000,
"fulfilled_quantity": 0,
"fulfillment_info": null,
"cancelled_quantity": 0,
"cancelled_info": null,
"returned_quantity": 0,
"returned_info": null
}
],
"metadata": {
"customer_id": "your-customer-id (optional)",
"checkout_id": "your-checkout-id (optional)",
"channel": "search engine",
"checkouts_count": "21",
"checkouts_value": "12030",
"any-other-meta-data-you-want-to-store": "your-other-data"
}
}

Make sure the amounts add up

Each entry in items contains the unit_price, quantity, total_amount and tax_amount. Be careful to make sure these are correct, as they are validated by the API and they need to add up.

  • The total_amount of each item must equal unit_price * quantity
  • The total_amount of the order must equal the sum of the unit_price * quantity of each item.

See the In-Depth Knowledge section on Orders and Items for a detailed explanation of how to submit consistent Order Items.

  // Example of an entry in the "items" list in the POST /v1/payment/orders request
"items": [
{
"item_id": "your-unique-item-id-0001",
"type": "product",
"description": "Super ergonomic chair",
"metadata":
{
"color": "black",
"name": "Karmus",
"variant": "M"
},
"reference": "your-reference-number",
"category": "Furniture > Chairs",
"supplier_id": "your-supplier-id",
"quantity": "10.000",
"unit_price": 10000,
"total_amount": 100000,
"tax_amount": 20000,
"fulfilled_quantity": 0,
"fulfillment_info": null,
"cancelled_quantity": 0,
"cancelled_info": null,
"returned_quantity": 0,
"returned_info": null
},
...
]

Response

You will receive an HTTP 201 response if the request succeeded. The body will contain the information you sent in the request, plus a few extra optional fields we're not using in this example.

Keep the order ID

The response contains the "id" of the order, such as order-xxxx. You should keep track of this Order ID, you will need it later to inform us when it's time for us to pay you ('fulfilling' the order).

A common approach is to store this ID in your database table that stores your own internal order information (in a column named something like hokodo_id).

There is a status field, which starts out as "unpaid". There are fields for paid_date and invoice_date, which start out null.

Here's a shortened version of the response showing the main fields:

201 Created
Content-Type: application/json

{
"id": "order-YrG5y79iuxTTEpkzPbaqcX",
"unique_id": "your-unique-order-id",
"customer": {
"organisation": "org-asrE7fKEuNor5CaVQD4Ah5", # The customer's Organisation ID from Step 1b
"user": "user-WFOMowqyUjpv8JeihXn5Xh", # The customer's User ID from Step 1b
"delivery_address": {
...
},
"invoice_address": {
...
},
"billing_address": null
},
"status": "draft",
"currency": "GBP",
"total_amount": 300000,
"tax_amount": 60000,
"order_date": "2022-04-29", # The date the order was placed *on your platform*
"invoice_date": null,
"paid_date": null,
"status": "unpaid",
"pay_method": "unknown",
"items": [
...
]
}

Expand the blue box to see the full response details, and see the API Reference for descriptions of each field.

Full Response Details - Order Creation

201 Created
Content-Type: application/json

{
"id": "order-YrG5y79iuxTTEpkzPbaqcX",
"unique_id": "your-unique-order-id",
"url": "https://api-sandbox.hokodo.co/v1/payment/orders/order-YrG5y79iuxTTEpkzPbaqcX",
"currency": "EUR",
"total_amount": 300000,
"tax_amount": 60000,
"status": "unpaid",
"customer": {
"organisation": "org-asrE7fKEuNor5CaVQD4Ah5",
"user": "user-WFOMowqyUjpv8JeihXn5Xh",
"delivery_address": {
"name": "John Smith",
"address_line1": "1 Station Street",
"address_line2": "Flat B",
"city": "London",
"postcode": "SE11 6NQ",
"country": "GB"
},
"invoice_address": {
"name": "Bob Accounting",
"address_line1": "1 Main Street",
"address_line2": "65th floor",
"city": "London",
"postcode": "SE11 6NQ",
"country": "GB"
}
"billing_address": null
},
"po_number": "",
"created": "2022-04-29T22:16:60.512656Z",
"pay_method": "directdebit",
"order_date": "2022-04-29",
"invoice_date": null,
"paid_date": null,
"items": [
{
"item_id": "your-unique-item-id-0001",
"type": "product",
"description": "Super ergonomic chair",
"metadata": {
"name": "Karmus",
"color": "black",
"variant": "M"
},
"reference": "702.611.50",
"category": "Furniture > Chairs",
"supplier_id": "7363",
"supplier_name": "",
"quantity": "10.000",
"unit_price": 1084,
"total_amount": 10840,
"tax_amount": 2170,
"tax_rate": "20.00"
},
{
"item_id": "your-unique-item-id-0002",
"type": "product",
"description": "This is free!",
"metadata": null,
"reference": "",
"category": "",
"supplier_id": "",
"supplier_name": "",
"quantity": "1.000",
"unit_price": 0,
"total_amount": 0,
"tax_amount": 0,
"tax_rate": "25.00"
},
{
"item_id": "your-unique-item-id-0003",
"type": "shipping",
"description": "Delivery fee",
"metadata": null,
"reference": "",
"category": "",
"supplier_id": "",
"supplier_name": "",
"quantity": "1.000",
"unit_price": 1000,
"total_amount": 1000,
"tax_amount": 200,
"tax_rate": "25.00"
}
],
"metadata": {
"customer_id": "your-customer-id (optional)",
"checkout_id": "your-checkout-id (optional)",
"channel": "search engine",
"checkouts_count": "21",
"checkouts_value": "12030",
"any-other-meta-data-you-want-to-store": "your-other-data"
},
"payment_offer": "offer-cqfxJVUwXBrkyZHRQaknJS",
"deferred_payment": "defpay-7PiKMX2gEpJmasb8Du65zn"
}

Request a Payment Offer

API Reference: Request a New Offer

A Payment Offer lists the payment terms that the customer is eligible for. Making this request causes the Hokodo backend to evaluate the customer's eligibility based on criteria such as credit limit.

Billing Accounts vs Payment Plan Selection

Read Determining Payment Terms to consider whether you want your Buyers to use Billing Accounts to predetermine terms before the checkout, or offer a variety of terms with each order. If a Buyer is set a Billing Account, they will only be offered a plan that corresponds to the Billing Account.

Request

From your store's server side, make an HTTP POST request to /v1/payment/offers.

The request body should contain:

  • The order ID (returned from POST /v1/payment/orders in the previous step)
  • The locale of the customer. This is the language and region (RFC 1766), for example "en-gb" or "fr-fr". The locale is used to determine which language to use for emails sent to the user relating to this order.
  • A urls object
    • You can supply a notification URL, this is a webhook that will inform you of the payment status.
    • Leave its success, failure and cancel fields as empty strings: these are required by the schema but are now superceded by the Checkout Element's events, which we will cover later in Checkout confirmation events.
POST /v1/payment/offers HTTP 1.1
Content-Type: application/json
Authorization: Token <your-api-key>

{
"order": "order-YrG5y79iuxTTEpkzPbaqcX",
"locale": "en-gb",
"urls": {
"success": "",
"failure": "",
"cancel": "",
"notification": "https://backend.your-site.com/payment/notifications",
},
"metadata": {
"any-key": "Any additional data you want to store against the offer (optional)"
}
}
Integration test

Integration test 1.3 checks that your back-office system does not allow shipping unless the Deferred Payment has been accepted.

It is common to use the webhook received by the "notification" URL to track the status of the Deferred Payment in your back-office.

Response

Hokodo's backend assesses the buyer's eligiblity for each of your payment plans. The response body contains a list of payment plans. Each payment plan in the list has a status field showing whether the buyer is eligible.

Design Decision

You can choose to send the customer an email at this point, detailing the payment terms they have been offered.

See Your Design Decisions for details.

Here's a shortened version of the response showing the main fields:

201 Created
Content-Type: application/json

{
"url": "https://api.hokodo.co/v1/payment/offers/offr-vyR4AFXGJWZz8XDgXoWVtZ",
"id": "offr-vyR4AFXGJWZz8XDgXoWVtZ",
"order": "order-YrG5y79iuxTTEpkzPbaqcX",
"offered_payment_plans": [
{
"name": "Pay in 3x",
"scheduled_payments": [
{...},
{...},
{...}
],
...
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-G4d57Dkmrgbh2HHbhhv89n&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-tq28UahiUe49cDb4knmf4U",
"status": "offered",
"rejection_reason": null
},
{
"name": "Pay in 30 days",
"scheduled_payments": [
{...}
],
...
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-EWjykhvDNWydKUfeJQyoM4&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-28L6wQ66UCguEiGFqwfHjM",
"status": "offered",
"rejection_reason": null
}
}
],
...
}

There's a lot of useful information in the response body so it's worth getting to grips with the details. Expand the blue box below to see a full example, and see the API Reference for descriptions of each field.

Full Response Details - Payment Offer Creation

201 Created
Content-Type: application/json

{
"url": "https://api.hokodo.co/v1/payment/offers/offr-vyR4AFXGJWZz8XDgXoWVtZ",
"id": "offr-vyR4AFXGJWZz8XDgXoWVtZ",
"order": "order-YrG5y79iuxTTEpkzPbaqcX",
"offered_payment_plans": [
{
"id": "ppln-G4d57Dkmrgbh2HHbhhv89n",
"name": "Pay in 3x",
"template": "pptemp-tq28UahiUe49cDb4knmf4U",
"currency": "GBP",
"scheduled_payments": [
{
"date": "2022-05-09",
"amount": 102000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
},
{
"date": "2022-06-08",
"amount": 99000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
},
{
"date": "2022-07-08",
"amount": 99000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
}
],
"payment_terms_relative_to": "order_creation",
"merchant_fee": {
"currency": "GBP",
"amount": 9000
},
"customer_fee": {
"currency": "GBP",
"amount": 0
},
"valid_until": "2027-05-08T14:52:30.698Z",
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-G4d57Dkmrgbh2HHbhhv89n&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-tq28UahiUe49cDb4knmf4U",
"status": "declined",
"rejection_reason": {
"code": "buyer-country",
"detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
"params": {
"debtor_country": "Japan",
}
}
},
{
"id": "ppln-EWjykhvDNWydKUfeJQyoM4",
"name": "Pay in 30 days",
"template": "pptemp-28L6wQ66UCguEiGFqwfHjM",
"currency": "GBP",
"scheduled_payments": [
{
"date": "2022-06-08",
"amount": 300000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
}
],
"payment_terms_relative_to": "order_creation",
"merchant_fee": {
"currency": "GBP",
"amount": 9000
},
"customer_fee": {
"currency": "GBP",
"amount": 0
},
"valid_until": "2027-05-08T14:52:30.902Z",
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-EWjykhvDNWydKUfeJQyoM4&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-28L6wQ66UCguEiGFqwfHjM",
"status": "declined",
"rejection_reason": {
"code": "buyer-country",
"detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
"params": {
"debtor_country": "Japan",
}
}
}
],
"legals": {
"type": "a",
"terms_url": "https://static.hokodo.co/payments/a_v1.0/a_v1.0_gb.pdf"
},
"urls": {
"success": "",
"failure": "",
"cancel": "",
"notification": "",
"merchant_terms": ""
},
"locale": "en-gb",
"metadata": {
"any-key": "Any additional data you want to store against the offer (optional)"
}
}

Offered vs. declined Payment Plans

Some Payment Plans might be offered and others declined.

Let's imagine you're offering 30-day and 60-day payment terms. Some of your customers may be eligible for 30-day terms, but not 60. In this case, the response will contain "status": "offered" for the 30-day Payment Plan, and "status": "declined" for the 60-day plan.

If the Payment Plan is offered, the payment_plan contains:

"status": "offered",
"rejection_reason": null

and status will update to "status": "accepted" once the customer has completed the checkout for a particular Payment Plan.

If the Payment Plan is declined, the payment_plan contains:

"status": "declined",
"rejection_reason": { # Example rejection reason
"code": "buyer-country",
"detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
"params": {
"debtor_country": "Japan",
}
}
Top-up Hokodo's credit Limit with Merchant Limits

If Hokodo's credit limit has been fully consumed by previous orders, you can apply a Merchant Limit for extra orders. All or part of these orders will be Unprotected Credit. The unprotected value is not protected against non-payment by the Buyer, although our collections team will still attempt to recover the value from the buyer. See In Depth Knowledge.

Step 2b: Display the Checkout Element

Full working example

For a working code example of the Checkout element in use, see this CodePen snippet.

The Checkout Element is the final step in completing the purchase. The workflow contained within the Checkout Element is built-in. The parts you need to implement are:

  1. Displaying the Checkout Element
  2. Handling checkout events to configure what happens when the checkout is complete, or if the checkout fails to load.

Here's an example of what the Checkout Element looks like:

The Checkout's built-in workflow

The workflow within the checkout is built-in and requires no additional development from you. We'll describe it here so that you're familiar with what the Checkout Element does.

  1. The customer selects their payment plan:
A part of the Hokodo Checkout Element, showing a radio button list of payment plans. One is selected.
  1. The customer then enters their payment information. Either they use a payment method saved from a previous checkout:
A part of the Hokodo Checkout Element, showing a radio list of payment options: Direct Debit, Invoice Payment, Debit/Credit Card.

or they enter a new payment method:

A part of the Hokodo Checkout Element, showing a radio list of payment options: Direct Debit, Invoice Payment, Debit/Credit Card.
  1. The customer then clicks Confirm to finalise the purchase:
A part of the Hokodo Checkout Element, showing a Ts and Cs checkbox, and a Confirm button.

Once this is complete, a Deferred Payment is created in the Hokodo backend, representing the customer's commitment to pay for the goods.

Displaying the Checkout Element

Now we'll get the Checkout Element displayed on your page.

First, initialise the Hokodo SDK on the page that you wish to display the Checkout Element. For a refresher of how to do this, see Initialising the SDK.

If you've followed the SDK initialisation guide successfully, you will have a variable in scope called elements. You can instantiate the Checkout Element like so:

// Create Checkout element
const checkout = elements.create("checkout", data);

The data parameter is an object containing the data you got from the API in Step 2a.

KeyValue
paymentOfferThis is the object returned from the /payment/offers endpoint (see API Reference).
paymentPlanId (optional)The ID [string] of the payment plan you wish to select for the buyer,
e.g. "ppln-EWjykhvDNWydKUfeJQyoM4". If used, the list of available payment plans will be replaced by a single pre-selected plan.

Note: This is a useful option if you have the ability to select a payment plan within your application. You can use the update method to inform the Checkout Element when the user selects a different plan.

In your implementation, you should store the paymentOffer object as a variable when you make the POST /v1/payment/offers request.

Expand the blue box below to see a full example:

Detailed Checkout Creation Example

In your implementation, you should store the paymentOffer object as a variable when you make the POST /v1/payment/offers call. For the sake of this example, we have replaced it with a literal.

const checkout = elements.create("checkout", {
paymentPlanId: "ppln-EWjykhvDNWydKUfeJQyoM4",
paymentOffer: {
"url": "https://api.hokodo.co/v1/payment/offers/offr-vyR4AFXGJWZz8XDgXoWVtZ",
"id": "offr-vyR4AFXGJWZz8XDgXoWVtZ",
"order": "order-YrG5y79iuxTTEpkzPbaqcX",
"offered_payment_plans": [
{
"id": "ppln-G4d57Dkmrgbh2HHbhhv89n",
"name": "Pay in 3x",
"template": "pptemp-tq28UahiUe49cDb4knmf4U",
"currency": "GBP",
"scheduled_payments": [
{
"date": "2022-05-09",
"amount": 102000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
},
{
"date": "2022-06-08",
"amount": 99000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
},
{
"date": "2022-07-08",
"amount": 99000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
}
],
"merchant_fee": {
"currency": "GBP",
"amount": 9000
},
"customer_fee": {
"currency": "GBP",
"amount": 0
},
"valid_until": "2027-05-08T14:52:30.698Z",
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-G4d57Dkmrgbh2HHbhhv89n&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-tq28UahiUe49cDb4knmf4U",
"status": "declined",
"rejection_reason": {
"code": "buyer-country",
"detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
"params": {
"debtor_country": "Japan",
}
}
},
{
"id": "ppln-EWjykhvDNWydKUfeJQyoM4",
"name": "Pay in 30 days",
"template": "pptemp-28L6wQ66UCguEiGFqwfHjM",
"currency": "GBP",
"scheduled_payments": [
{
"date": "2022-06-08",
"amount": 300000,
"allowed_payment_methods": [
{
"type": "direct_debit"
},
{
"type": "invoice"
},
{
"type": "card"
}
]
}
],
"merchant_fee": {
"currency": "GBP",
"amount": 9000
},
"customer_fee": {
"currency": "GBP",
"amount": 0
},
"valid_until": "2027-05-08T14:52:30.902Z",
"payment_url": "https://pay.hokodo.co/?order=order-YrG5y79iuxTTEpkzPbaqcX&plan=ppln-EWjykhvDNWydKUfeJQyoM4&key=AnPbAFHxtmt6cAvMvATbPqxhfCGGqc3-kA84RWIb1vg&template=pptemp-28L6wQ66UCguEiGFqwfHjM",
"status": "declined",
"rejection_reason": {
"code": "buyer-country",
"detail": "We're currently unable to provide payment plans to Buyers domiciled in {debtor_country}.",
"params": {
"debtor_country": "Japan",
}
}
}
],
"legals": {
"type": "a",
"terms_url": "https://static.hokodo.co/payments/a_v1.0/a_v1.0_gb.pdf"
},
"urls": {
"success": "",
"failure": "",
"cancel": "",
"notification": "",
"merchant_terms": ""
},
"locale": "en-gb",
}
});

Now you can mount the Checkout Element on the page:

// In your HTML
<div id="hokodoCheckout"></div>;

// In your JS
checkout.mount("#hokodoCheckout");

That's it! Now when you load that page you should see the Hokodo Checkout Element.

Hide the Hokodo Checkout if payment terms were declined

If the user has been declined payment terms in the previous step, you can avoid showing the Checkout Element at all.

Simply iterate over the array of payment plans returned by the Payment Offer request and check if all the status fields are "declined". If true, skip the Checkout Element create/mount process.

Handling checkout events

Finally, we will configure what happens when the user clicks the Confirm button, and a placeholder in case the Checkout Element fails to load.

The Checkout Element provides several on() events that allow for communication between the Hokodo Checkout Element and your application. You should bind these events before mounting the element, to ensure events are called correctly.

You bind each event using the event name, and a handler function:

// General form of binding a checkout event
checkout.on(event, handler);

Required event handlers

It is a required part of the integration that you bind these events:

  • "success", triggered when the user clicks the Confirm button and the checkout is successful.
  • "failure", triggered if the Checkout Element fails to load.

For example, on "success" you might decide to load a page summarising the order:

// Example checkout event: on success, load an order summary page
checkout.on("success", function () {
location.replace(`http://www.merchant.com/checkout/success?order=${orderId}`);
});

On "failure" to load the Checkout Element, you might want to remove the Checkout Element and show a message:

// Example of showing a 'declined' message if the user is given payment terms
checkout.on("failure", function () {
// Destroy the Checkout Element JS object
if (checkout) {
checkout.destroy();
}
// Remove the Checkout Element from the DOM
const view = document.getElementById("hokodoCheckout");
if (view) {
view.remove();
}
// Show the 'failure' message - assuming you have a #failureMessage element in the DOM
const failureMessage = document.getElementById("#failureMessage");
if (failureMessage) {
failureMessage.classList.remove("hide"); // Assuming .hide has been keeping the message hidden
}
});

See the Frontend SDK page for a full list of events provided by the Checkout Element.

More event handling examples

There are some more event handling examples in the CodePen snippet.

Once you've got the "success" and "failure" event handlers working, you've completed the checkout step of the integration.

Next up

At this point, your customer is able to complete the full flow of making a purchase using Hokodo.

In Step 3, we'll cover what happens after the purchase is complete.