Tickets - Login

How Bolt Interacts

Now that we’ve covered the general components of Bolt in Part One of our Developer’s Guide, let’s dive into some specifics about how Bolt is communicating with your e-commerce platform. This article is a high-level framework tackling information found in our Bolt API Reference and Merchant API Reference.

Bolt API (Inbound Requests)

Orders

Bolt requires an inbound request, initiated on your storefront when a shopper selects the checkout button, to generate a Bolt Order Token.

This token is used to reference the shopper’s cart while they populate shipping information, card details, discounts, and add/remove items. These order updates are passed back and forth between Bolt and your store’s Merchant API until the shopperfinalizes checkout. Without the order token, the order’s information would get lost.

How the Order Token is Used

The following scenario relies on the Bolt Order Token to identify the order details upon each event initiated by the shopper.

Checkout Event Request (Requires Order Token)
Shopper inputs shipping information. The first delivery method is auto-selected; they choose a different, faster method. Triggers a request to the Merchant API for shipping information
Shopper inputs a discount code. Triggers a request to the Merchant API to validate discount code.
Shopper replaces the discount code for a better discount. Triggers a request to the Merchant API to validate discount code (again).
The shopper proceeds towards the final checkout steps. Triggers a request to the Merchant API for the order’s total tax amount.

Transactions

The transaction begins to process after the order is submitted. You can make inbound requests to update the transaction based on events from your backend—this includes ingesting a Transaction Webhook sent by Bolt and replying with a follow-up Request.

Example:

A shopper orders multiple items. Your order management system discovers that one of the items is out of stock. You can use Bolt’s Transactions API to submit a partial refund so that you can confidently capture the rest of the order.

Pre-Authorization Workflow

Bolt recommends setting up a Pre-Authorization workflow. If you are using a Pre-Authorization flow, there are a few more actions that you can take, such as voiding a transaction before it is authorized. Pre-Authorization also enables Bolt to act as your fraud analyst.

Merchant API (Outbound Requests)

As discussed in relation to Bolt Order Tokens, the Merchant API is used to update a shopper’s cart details during checkout. Your business must implement a Merchant API on your platform that can handle these requests. The objects discussed in this section can be found as part of the Data object’s array in a JSON request.

Discounts

You should make discount code details accessible through a unique endpoint in your Merchant API. Whenever a shopper inputs a discount code, it is validated by sending a POST request that creates a discount-application event. The response looks like this:

{
  "event": "discounts.code.apply",
  "status": "success",
  "data": {
    "discount_code": "WELCOME10",
    "discount_description": "$10 off for first-time customers.",
    "discount_type": "fixed_amount",
    "discount_amount": 1000
  }
}

Whether or not the discount code is applied depends on 1) whether the code exists in your database and 2) if the cart’s contents have matched your requirements (for example, an order over $100). You can provide specific details for code failures like this:

{
  "event": "discounts.code.apply",
  "status": "failure",
  "error": {
    "code": 2319,
    "message": "Order total must be more than $100 to apply this discount."
  }
}

You can validate whether a discount code qualifies for use by using the order details sent in the POST request. Namely, the total_amount and items are a great starting point.

{
  "event": "discounts.code.apply",
  "data": {
    "discount_code": "URAWIZARD",
    "cart": {
      "order_reference": "2319",
      "total_amount": {
        "amount": 60000,
        "currency": "USD",
        "currency_symbol": "$"
      },
      "tax_amount": { },
      "items": [
        {
          "name": "Magic Wand",
          "reference": "WIZ1000",
          "total_amount": {
            "amount": 500000,
            "currency": "USD",
            "currency_symbol": "$"
          },
          "unit_price": {
            "amount": 500000,
            "currency": "USD",
            "currency_symbol": "$"
          },
          "quantity": 1,
          "image_url": "https://images.example.com/unicorn-core-wand.jpg",
          "size": "L",
          "color": "brown",
          "type": "physical"
        }
      ],
      "shipments": []
    },
    "customer_name": "Johnathan Doewell",
    "customer_email": "JDoewell@example.com",
    "customer_phone": 14151231234
  }
}

Shipping

You should make shipping and pickup options accessible through a unique endpoint in your Merchant API. This endpoint is called during the Delivery step in a shopper’s checkout experience and may be called multiple times.

Shipping and pickup options are separate objects with an array of options that are determined by your database. They look like this:

{
   "shipping_options":[
      {
         "service":"Fedex two days",
         "cost": 5000,
         "reference": "2"
      }
   ],
   "pickup_options":[
      {
         "store_name": "Macy's SF",
         "pickup_window_open": 1578904185,
         "pickup_window_close": 1578904185,
         "pickup_address": {
           "street_address1": "170 O'Farrell St",
           "street_address2": "",
           "locality": "San Francisco",
           "region": "California",
           "postal_code": "94102",
           "country": "United States",
           "country_code": "US"
         },
         "distance": 1,
         "distance_unit": "mile",
         "cost":0,
         "reference": "1"
      }
    ]
}

Your database would need to check the order’s shipping destination to validate which pickup options are within an acceptable radius to the shopper. That information is passed through the shipping_address object in the initial request and looks like this:

"shipping_address": {
"street_address1": "123 Baker Street",
"locality": "San Francisco",
"region": "California",
"postal_code": "94550",
"country_code": "US",
"name": "Johnathan Doewell",
"first_name": "Johnathan",
"last_name": "Doewell"

Tax

You should make tax calculations accessible through a unique endpoint in your Merchant API. This endpoint is called during the Payment step in a shopper’s checkout experience. The response should be a tax_result object which returns an amount of tax for the cart’s subtotal.

"tax_result": {
"subtotal_amount": 500
},

Create Order

After everything else has been completed, Bolt sends a pre-authorization POST request to your Merchant API. This confirms the final version of the order and whether or not it can be successfully placed. The response should provide a success message, order number, and a URL that redirects the shopper to an order confirmation page.

{
  "event": "order.create",
  "status": "success",
  "data": {
    "display_id": "O-100104040",
    "order_received_url": "https://***.com/confirmation/O-100104040"
  }
}

Webhooks

Bolt uses webhooks to listen for events that change either the status of your shopper’s transaction or changes to their saved credit card information. These changes are then forwarded to your backoffice. You can use this information to update your official records or perform additional operations.

If the response to a webhook request is not HTTP 200 OK or the response body is not a valid JSON, Bolt retries with exponential back-off.

Transaction Webhooks

Common use cases for Transaction Webhooks include:

  • Notifying your store when a transaction has been approved or rejected by Bolt.
  • Sending your store the transaction_id, which is necessary for back-office operations.
  • Sending your store more information about a transaction, such as credit card details.

Transaction Hook Types

  • Pending: A transaction occurred and is pending review; the status is pending.
  • Failed Payment: A credit card authorization failed; the status is failed.
  • Rejected Reversible: A transaction was rejected, but the decision can be overridden; the status is: _rejected_reversible. _
  • Rejected Irreversible: A transaction was rejected, and the decision cannot be overridden; the status is _rejected_irreversible. _
  • Credit: A credit/refund was issued; The status is _refunded. _
  • Void: A void has occurred; The status is canceled.

Manual Capture Only

  • Auth: An authorization was issued; The status is authorized.
  • Capture: A capture occurred; the status is _completed. _
  • Payment: A sale occurred; the status is _completed. _

Dropped Transactions

Order generation performed via the front-end instead of a pre-authorization endpoint has the potential to be dropped during checkout if the internet connection is disrupted (via outage, browser crash, etc).

Dropped orders are prevented by ensuring the Pending Transaction Webhook is capable of listening for cart order_references that have no status, picking those up, and submitting them as orders.

{
	"type": "pending",
	"object": "transaction",
	"data": {
		"id": "TS5gDwDjucZd4",
		"type": "cc_payment",
		"reference": "N7Y3-NFKC-VFRF",
		"date": 1485997169003,
		"status": " ",
		"from_user": {},
		"from_credit_card": {},
		"amount": {},
		"order": {
			"cart": {
				"order_reference": "4200",
				"display_id": "O-100104040",
				"metadata": {
				}
			}
		},
		"authorization": {
			"status": "",
			"reason": "none"
		},
		"captures": [],
		"refund_transactions": [],
		"source_transaction": {},
		"checkboxes": []
	}
}

Credit Card Webhooks (BETA)

Common use cases for Credit Card Webhooks include:

  • Updating the primary card associated with the shopper’s account.
  • Removing a credit card associated with the shopper’s account.
  • Adding additional credit cards to the shopper’s account.

Verification

Requests made by Bolt to your ecommerce Merchant API are signed to ensure the authenticity of our requests. Verify these signatures to ensure that it’s always Bolt calling your endpoint.

Bolt signs each payload and includes the HMAC signature in the request header, X-Bolt-Hmac-Sha256. Bolt generates the signature by hashing the payload using the SHA-256 hashing algorithm. A signing secret is used as the salt in the hashing. The resulting value is then Base64 encoded to transmit as plain text.

Signing Secret

Your signing secret is located in the Bolt Merchant Dashboard. Navigate to Developers > API > Keys > Signing Secret.

You can test the verification of your signing secret using the following javascript:

$hmac_header = $_SERVER['X-Bolt-Hmac-Sha256'];

function verify_webhook($payload, $hmac_header) {
  $computed_hmac = base64_encode(hash_hmac('sha256', $payload, BOLT_SIGNING_SECRET, true));
  return ($computed_hmac == $hmac_header);
}

Summary

Bolt interacts with your platform through a combination of outbound requests to several separate endpoints (Merchant API, Webhook Endpoint) that you must build. Your platform can also submit requests through Bolt’s API to generate order tokens, fetch statements, and execute transaction events. All outbound requests require HMAC signature verification via the Signing Secret found in your Merchant Dashboard.

Related Articles