Skip to main content

Implement the Event-Action Loop

caution

Bold Commerce encourages developers to use integrations in order to extend Bold Checkout, instead of plugins. There are two types of integrations: private and public. For more information, refer to Extending Bold Checkout.

The most common way that Bold Checkout interacts with plugins is via the event-action loop.

A Checkout plugin listens for events (defined points of significance in the checkout experience), and the plugin can respond with actions. Bold Checkout executes the actions, which often result in changes to the order.

For more information about the event-action loop, refer to the conceptual Plugins page.

This how-to guide covers how to implement the event-action loop in your own plugin. It includes examples from the Checkout Example Plugin.

Prerequisites

  1. Complete the steps in Getting Started with Plugins.
  2. Complete the steps in Implement the Plugin Installation Flow.

Listen for events

For each event, Bold Checkout sends a POST request to your event dispatch URL (which you provided in the plugin intake form). This request contains the following components:

  • HTTP signature — which you must use to verify that the request came from Bold Checkout.
  • Request body — which contains information about the checkout session depending on the event type. This request body is always in the same format. Depending on at what point in the session the event was triggered, some values are unpopulated. For example, in an initialize_checkout event, the request body might not contain customer and shipping data.

For the full list of events, refer to the Plugin Events reference.

note

Bold sends only the events indicated in the plugin intake form. For a full list of the events that your plugin is registered for, or change which events you want to receive, reach out to [email protected].

The following snippet shows an example of an initialize_checkout event request body:

Click to expand
{
"cart": {
"total_weight": 0,
"item_count": 2,
"requires_shipping": null,
"bold_cart_id": 145,
"cart_token": "19ef770ca493359fb7cfb955e76e1da9",
"public_token": "b8e310398168cc8824182045cc8cabde750af025",
"attributes": [],
"line_items": [[]],
"subtotal": 2468
},
"cart_params": [],
"customer": {
"core_info": {
"first_name": "Bold",
"last_name": "McBoldstein",
"tags": "Bold",
"public_id": "1h6j893jsdfewwe",
"customer_id": 1234,
"email": "[email protected]",
"billing_type": "same",
"accepts_marketing": false
},
"shipping": {
"first_name": "Bold",
"last_name": "McBoldStein",
"company": "Bold Commerce LTD",
"address": "50 Fultz Blvd",
"address2": "Another line",
"city": "Winnipeg",
"country": "Canada",
"country_code": "CA",
"province": "Manitoba",
"province_code": "MB",
"postal_code": "R3Y 1L6",
"phone": "1 (800) 555-0100"
},
"billing": {
"first_name": "Bold",
"last_name": "McBoldStein",
"company": "Bold Commerce LTD",
"address": "50 Fultz Blvd",
"address2": "Another line",
"city": "Winnipeg",
"country": "Canada",
"country_code": "CA",
"province": "Manitoba",
"province_code": "MB",
"postal_code": "R3Y 1L6",
"phone": "1 (800) 555-0101"
},
"addresses": []
},
"order_id": 145,
"properties": {},
"idempotent_key": null,
"shipping_lines": [],
"tax_lines": [],
"discount_lines": [],
"order": {
"order_source": "cashier",
"order_source_name": "cashier",
"public_order_id": "lakjfoihiuh223u82989vhsinvd0s9f8",
"customer": {
"id": 23,
"public_customer_id": 22345345346,
"platform_customer_id": 23,
"core_info": [],
"shipping_address": [],
"billing_address": []
},
"currency": "SEK",
"exchange_rate": "1.000000000000",
"fees": [
{
"id": "gift-wrap-1",
"value": 150,
"lineText": "Gift wrapping",
"tag": "Fee",
"taxable": false
}
],
"order_total": 2468,
"resumable_url": "https://example.com/order/abc123",
"shipping": [
{
"id": "abc123",
"value": 5000,
"price": 5000,
"lineText": "Express Rate",
"name": "Express Rate",
"code:": "Express Rate",
"source": "",
"tag": "Shipping",
"delivery_date": "",
"delivery_range": "",
"delivery_days": ""
}
],
"note": "",
"note_attributes": [],
"tags": []
},
"language_iso": "fr",
"event": "initialize_checkout"
}

Verify the HTTP signature

Each request you receive from Bold is signed with an HTTP signature. This signature is a string that is encrypted through HMAC, encoded using your client secret as the key. Before you proceed to handle an event, you must verify that the call came from Bold and is secure.

The following code snippet shows an example of signature verification. Bold's example plugin does so in a middleware.js file:

const httpSignature = require("http-signature");

function verifyRequest(req, res, next) {
try {
const parsed = httpSignature.parseRequest(req);
const result = httpSignature.verifyHMAC(parsed, process.env.CLIENT_SECRET);

if (result === true) {
next();
} else {
res.status(401).end();
}
} catch (e) {
res.status(401).end();
}
}

module.exports = verifyRequest;

Handle requests based on event type

Now that you verified that the request came from Bold, you can proceed to handle the event appropriately. While there are various ways to do so, Bold's example checkout plugin uses a switch statement to determine how to handle the event. The plugin is registered for the initialize_checkout and order_submitted events and has different functions for handling each request, as shown in the following code snippet:

router.post("/", (req, res) => {
let actions;

switch (req.body.event) {
case "initialize_checkout":
actions = handleInitializeCheckout(req);
break;
case "order_submitted":
actions = handleOrderSubmitted(req);
break;
default:
actions = [];
}

res.send({
success: true,
actions: actions,
});
});

Respond to the event with an action

For every event sent to a plugin, Bold Checkout expects a response that contains a "success" value of true and a list of actions. If you do not want to perform any actions, return an empty array for the "actions" value.

For the full list of actions and their structures, refer to the Plugin Actions reference.

The following code snippet shows a response body sent to Bold Checkout for an add_line_item_by_platform_variant action:

{
"success": true,
"actions": [
{
"type": "add_line_item_by_platform_variant",
"data": {
"platform_variant_id": 9153875214378,
"line_item_key": "9153875214378:4853336925a8c06cc1edc0058577aa48",
"quantity": 1,
"properties": {
"gift_wrap": "yes"
},
"price": 1500,
"is_amendment": true
}
}
]
}
note

Bold Checkout assumes all actions sent by a plugin have been verified beforehand and found legitimate. It is the responsibility of the plugin to make sure an action is not fraudulent before sending the action to Checkout.

Next steps

After completion of these steps, your plugin has successfully implemented the event-action loop. If necessary for your use case, continue to extend the behavior of your plugin.