How to send BigCommerce orders to ProfitMetrics using Make.com
This article describes how to set up server-side order syncing from BigCommerce to ProfitMetrics using a Make.com scenario
How the scenario works
The Make.com scenario contains four modules that run in sequence:
| Step | What it does |
|---|---|
| 1 — Order Status Updated | BigCommerce webhook trigger fires on any order status change |
| 2 — Fetch Full Order | Filtered to the target status only. Calls the BigCommerce V2 Orders API with include=consignments.line_items to get the full order and product data |
| 3 — Transform (JavaScript) | Maps BigCommerce order fields into a ProfitMetrics order payload |
| 4 — Send to ProfitMetrics | HTTP GET request to https://my.profitmetrics.io/l.php with the encoded order JSON |
A filter between Module 1 and Module 2 checks the new order status ID. By default, the blueprint filters on status 10 (Completed). Change this value to match your store's workflow — see Filter Logic below.
Prerequisites
Gather the following before you start:
| Item | Where to find it |
|---|---|
| ProfitMetrics Public ID | ProfitMetrics → Settings → Website → Public ID |
| BigCommerce API credentials | BigCommerce admin → Settings → API → API Accounts (needs Orders read scope) |
| Make.com account | make.com — the free plan is sufficient for low order volumes |
| Blueprint file | The blueprint.json file included at the bottom of this guide |
Step 1 — Import the blueprint
- In Make.com, go to Scenarios → Create a new scenario.
- Click the ⋯ menu (bottom of the editor) → Import Blueprint.
- Upload the
blueprint.jsonfile (see below). - All four modules appear on the canvas. Connections will show errors until configured in Step 2.
Step 2 — Configure connections
Each BigCommerce module needs a connection to your store.
Module 1 — BigCommerce Webhook
Click Module 1 (Order Status Updated) and create or select a BigCommerce webhook connection for your target store. Make.com registers the webhook in BigCommerce automatically.
Module 2 — BigCommerce API
Click Module 2 (Universal API Call) and create or select a BigCommerce API connection. This connection needs read access to Orders.
Step 3 — Set your ProfitMetrics Public ID
Click Module 3 (JavaScript Code) and locate the Input variables section. Change the PUBLIC_ID value from YOUR_PROFITMETRICS_PUBLIC_ID to your actual ProfitMetrics Public ID.
Find your Public ID in the ProfitMetrics dashboard under Settings → Website.
Step 4 — Activate the scenario
- Click Run once to test with a live order status change, or toggle the scenario ON.
- Set the scheduling to Immediately — the scenario is webhook-driven, so no polling interval is needed.
Filter logic
The filter between Module 1 and Module 2 checks new_status_id against a single value. The blueprint defaults to 10.
Common BigCommerce status IDs:
| Status ID | Status name |
|---|---|
2 |
Shipped |
5 |
Cancelled |
9 |
Awaiting Fulfillment |
10 |
Completed |
11 |
Awaiting Shipment |
To change the trigger status, click the filter (the dotted line between Module 1 and Module 2), then update the value to the status ID that matches your workflow. For most stores, 10 (Completed) or 9 (Awaiting Fulfillment) are the right choices.
Field mapping reference
The JavaScript module (Module 3) maps BigCommerce order data into the ProfitMetrics order payload. ProfitMetrics hashes any PII (email, name, phone) server-side.
Core order fields
| ProfitMetrics field | BigCommerce source |
|---|---|
id |
order.id (cast to string) |
ts |
order.date_created (converted to Unix timestamp) |
orderEmail |
billing_address.email |
currency |
order.currency_code |
priceTotalExVat |
order.total_ex_tax |
priceTotalInclVat |
order.total_inc_tax |
Shipping & customer fields
| ProfitMetrics field | BigCommerce source |
|---|---|
priceShippingExVat |
Consignment cost_ex_tax (fallback: order.shipping_cost_ex_tax) |
shippingCountry |
Consignment country_iso2 (fallback: billing address) |
shippingZipcode |
Consignment zip (fallback: billing address) |
shippingMethod |
Consignment shipping_method |
shippingWeight |
Sum of weight × quantity across all line items |
paymentMethod |
order.payment_method |
customerFirstname |
billing_address.first_name |
customerLastname |
billing_address.last_name |
customerPhone |
billing_address.phone (leading + stripped) |
Product line items
| ProfitMetrics field | BigCommerce source |
|---|---|
products[].sku |
line_item.sku (falls back to product_id as string) |
products[].qty |
line_item.quantity |
products[].priceExVat |
line_item.price_ex_tax |
ProfitMetrics API call
Module 4 sends a GET request to:
https://my.profitmetrics.io/l.php?v=3uh&pid={PUBLIC_ID}&o={URL-encoded JSON}
| Parameter | Description |
|---|---|
v |
API version — always 3uh |
pid |
Your ProfitMetrics Public ID |
o |
JSON-stringified order payload |
Important notes
SKU matching: The sku field in the ProfitMetrics payload must match the product identifier used in your ProfitMetrics product feed. This could be the BigCommerce SKU, product ID, or variant ID. Check your feed and update the JavaScript in Module 3 if needed.
Consignment data: The scenario reads shipping details from BigCommerce consignments (via the include=consignments.line_items query parameter). If an order has no consignment data, the code falls back to the billing address for country and zip code.
Empty fields: The JavaScript code omits fields that have no value rather than sending empty strings. This is the expected behaviour for the ProfitMetrics API.
Testing the integration
- Place a test order in your BigCommerce store and move it to the status matching your filter (default: Completed).
- In Make.com, open the scenario and check the execution log. Each module should show a green checkmark.
- In ProfitMetrics, go to Orders and verify the test order appears with the correct totals, products, and shipping data.
Troubleshooting
| Issue | What to check |
|---|---|
| No orders syncing | Verify the webhook is active in Module 1 and the filter status ID matches your workflow. Check the Make.com execution log for skipped runs. |
| Missing products | Confirm include=consignments.line_items is present in the Module 2 query parameters. Without it, the API response does not include line item data. |
401 on BC API call |
Reconnect the BigCommerce API credentials in Module 2. Ensure the API account has Orders read scope. |
400 from ProfitMetrics |
Open Module 3 and verify PUBLIC_ID is set correctly. Check the output JSON structure in the execution log. |
| Missing shipping data | Some orders may not have consignment data. The code falls back to the billing address — verify the billing address has country and zip fields populated. |
| Wrong SKU in ProfitMetrics | The code uses line_item.sku by default, falling back to product_id. If your product feed uses a different identifier, update the mapping in Module 3. |
If you run into issues not covered here, contact support@profitmetrics.io.
Make.com blueprint
Copy the JSON below into a file called blueprint.json. Then import it into Make.com via ⋯ → Import Blueprint.
{
"name": "ProfitMetrics - BigCommerce Order Sync",
"flow": [
{
"id": 9,
"module": "bigcommerce:orderStatusUpdated",
"version": 1,
"parameters": {
"__IMTHOOK__": 2430707
},
"mapper": {},
"metadata": {
"designer": {
"x": 0,
"y": 0
},
"restore": {
"parameters": {
"__IMTHOOK__": {
"data": {
"editable": "false"
},
"label": "My Order Status Updated"
}
}
},
"parameters": [
{
"name": "__IMTHOOK__",
"type": "hook:bigcommerce8",
"label": "Webhook",
"required": true
}
]
}
},
{
"id": 3,
"module": "bigcommerce:universal",
"version": 1,
"parameters": {
"__IMTCONN__": 4473107
},
"filter": {
"name": "",
"conditions": [
[
{
"a": "",
"b": "9",
"o": "text:equal"
}
]
]
},
"mapper": {
"qs": [
{
"key": "include",
"value": "consignments.line_items"
},
{
"key": "consignment_structure",
"value": "object"
}
],
"url": "/v2/orders/",
"method": "GET",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
},
"metadata": {
"designer": {
"x": 300,
"y": 0
},
"restore": {
"expect": {
"qs": {
"mode": "chose",
"items": [
null,
null
]
},
"method": {
"mode": "chose",
"label": "GET"
},
"headers": {
"mode": "chose",
"items": [
null
]
}
},
"parameters": {
"__IMTCONN__": {
"data": {
"scoped": "true",
"connection": "bigcommerce2"
},
"label": "My BigCommerce Connection"
}
}
},
"parameters": [
{
"name": "__IMTCONN__",
"type": "account:bigcommerce,bigcommerce2",
"label": "Connection",
"required": true
}
],
"expect": [
{
"name": "hidden",
"type": "hidden"
},
{
"name": "url",
"type": "text",
"label": "URL",
"required": true
},
{
"name": "method",
"type": "select",
"label": "Method",
"required": true,
"validate": {
"enum": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
]
}
},
{
"name": "headers",
"spec": [
{
"name": "key",
"type": "text",
"label": "Key"
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "array",
"label": "Headers"
},
{
"name": "qs",
"spec": [
{
"name": "key",
"type": "text",
"label": "Key"
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "array",
"label": "Query String"
},
{
"name": "body",
"type": "any",
"label": "Body"
}
]
}
},
{
"id": 4,
"module": "code:ExecuteCode",
"version": 0,
"parameters": {},
"mapper": {
"input": [
{
"name": "bcOrderRaw",
"value": ""
},
{
"name": "PUBLIC_ID",
"value": "YOUR_PROFITMETRICS_PUBLIC_ID"
}
],
"language": "javascript",
"inputFormat": "editor",
"dependencies": [],
"codeEditorJavascript": "// Minimal ProfitMetrics payload (no catalog/product API call, single pid)\n// Inputs expected:\n// - input.bcOrderRaw -> BigCommerce /v2/orders/{id}?include=consignments.line_items&consignment_structure=object (response body)\n// - input.PUBLIC_ID -> ProfitMetrics pid (single store)\n\nconst order = typeof input.bcOrderRaw === \"string\"\n ? JSON.parse(input.bcOrderRaw)\n : input.bcOrderRaw;\n\nif (!order) throw new Error(\"No order found in input.bcOrderRaw\");\n\nconst pid = input.PUBLIC_ID;\nif (!pid) throw new Error(\"Missing input.PUBLIC_ID\");\n\n// Consignments structure with consignment_structure=object:\n// order.consignments.shipping is an array\nconst shipments = Array.isArray(order.consignments?.shipping) ? order.consignments.shipping : [];\n\n// line_items across all shipments\nconst lineItems = shipments.flatMap(s => Array.isArray(s?.line_items) ? s.line_items : []);\n\nconst products = lineItems\n .filter(li => li?.sku)\n .map(li => ({\n sku: String(li.sku),\n qty: Number(li.quantity ?? 0),\n priceExVat: Number(li.price_ex_tax ?? li.base_price ?? 0),\n }));\n\nconst firstShip = shipments[0] || null;\n\n// timestamp from order date\nconst createdMs = Date.parse(order.date_created);\nconst ts = Math.floor((Number.isFinite(createdMs) ? createdMs : Date.now()) / 1000);\n\nconst pmOrder = {\n id: String(order.id),\n ts,\n orderEmail: order.billing_address?.email || \"\",\n currency: order.currency_code || \"EUR\",\n priceTotalExVat: Number(order.total_ex_tax ?? 0),\n priceTotalInclVat: Number(order.total_inc_tax ?? 0),\n products,\n shippingCountry: firstShip?.country_iso2 || order.billing_address?.country_iso2 || \"\",\n shippingZipcode: firstShip?.zip || order.billing_address?.zip || \"\",\n priceShippingExVat: Number(firstShip?.cost_ex_tax ?? order.shipping_cost_ex_tax ?? 0),\n shippingMethod: firstShip?.shipping_method || \"\",\n shippingWeight: lineItems.reduce((sum, li) => sum + (Number(li.weight ?? 0) * Number(li.quantity ?? 1)), 0),\n paymentMethod: order.payment_method || \"\",\n // Customer PII - PM hashes server-side\n customerFirstname: order.billing_address?.first_name || \"\",\n customerLastname: order.billing_address?.last_name || \"\",\n customerPhone: (order.billing_address?.phone || \"\").replace(/^\\+/, \"\"),\n};\n\n// Return exactly what HTTP needs\nreturn {\n pid,\n v: \"3uh\", // optional convenience; map it or hardcode in HTTP module\n o: JSON.stringify(pmOrder),\n};\n"
},
"metadata": {
"designer": {
"x": 600,
"y": 0
},
"restore": {
"expect": {
"input": {
"items": [
null,
null
]
},
"language": {
"mode": "chose",
"label": "JavaScript"
},
"inputFormat": {
"label": "Code editor"
}
}
},
"expect": [
{
"name": "language",
"type": "select",
"label": "Language",
"required": true,
"validate": {
"enum": [
"javascript",
"python"
]
}
},
{
"name": "input",
"spec": {
"name": "value",
"spec": [
{
"name": "name",
"type": "text",
"label": "Name",
"required": true,
"validate": {
"max": 32,
"min": 1,
"pattern": "^[a-zA-Z0-9_]{1,32}$"
}
},
{
"name": "value",
"type": "any",
"label": "Value"
}
],
"type": "collection",
"label": "Variable"
},
"type": "array",
"label": "Input"
},
{
"name": "dependencies",
"spec": {
"name": "value",
"type": "text",
"label": "Dependency",
"required": true,
"validate": {
"max": 214,
"min": 1,
"pattern": "^[A-Za-z0-9_@\\./<>\\=\\!~\\^+\\-]{1,214}$"
}
},
"type": "array",
"label": "Additional dependencies (Enterprise plans only)"
},
{
"name": "inputFormat",
"type": "select",
"label": "Input format",
"required": true,
"validate": {
"enum": [
"editor",
"string"
]
}
},
{
"name": "codeEditorJavascript",
"type": "editor",
"label": "Code",
"required": true
}
]
}
},
{
"id": 5,
"module": "http:MakeRequest",
"version": 4,
"parameters": {
"tlsType": "",
"proxyKeychain": "",
"authenticationType": "noAuth"
},
"mapper": {
"url": "https://my.profitmetrics.io/l.php",
"method": "get",
"shareCookies": false,
"parseResponse": true,
"allowRedirects": true,
"queryParameters": [
{
"name": "v",
"value": ""
},
{
"name": "pid",
"value": ""
},
{
"name": "o",
"value": ""
}
],
"stopOnHttpError": true,
"requestCompressedContent": true
},
"metadata": {
"designer": {
"x": 900,
"y": 0
},
"restore": {
"expect": {
"method": {
"mode": "chose",
"label": "GET"
},
"headers": {
"mode": "chose"
},
"contentType": {
"label": "Empty"
},
"shareCookies": {
"mode": "chose"
},
"parseResponse": {
"mode": "chose"
},
"allowRedirects": {
"mode": "chose"
},
"paginationType": {
"label": "Empty"
},
"queryParameters": {
"mode": "chose",
"items": [
null,
null,
null
]
},
"stopOnHttpError": {
"mode": "chose"
},
"requestCompressedContent": {
"mode": "chose"
}
},
"parameters": {
"tlsType": {
"label": "Empty"
},
"proxyKeychain": {
"label": "Choose a key"
},
"authenticationType": {
"label": "No authenticationUse when no credentials are required for the request."
}
}
},
"parameters": [
{
"name": "authenticationType",
"type": "select",
"label": "Authentication type",
"required": true,
"validate": {
"enum": [
"noAuth",
"apiKey",
"basicAuth",
"oAuth"
]
}
},
{
"name": "tlsType",
"type": "select",
"label": "Transport layer security (TLS)",
"validate": {
"enum": [
"mTls",
"tls"
]
}
},
{
"name": "proxyKeychain",
"type": "keychain:proxy",
"label": "Proxy"
}
],
"expect": [
{
"name": "url",
"type": "url",
"label": "URL",
"required": true
},
{
"name": "method",
"type": "select",
"label": "Method",
"required": true,
"validate": {
"enum": [
"get",
"head",
"post",
"put",
"patch",
"delete",
"options"
]
}
},
{
"name": "headers",
"spec": {
"name": "value",
"spec": [
{
"name": "name",
"type": "text",
"label": "Name",
"required": true,
"validate": {
"pattern": "^[-!#$%&'*+.^_`|~0-9A-Za-z]+$"
}
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "collection",
"label": "Header"
},
"type": "array",
"label": "Headers"
},
{
"name": "queryParameters",
"spec": {
"name": "value",
"spec": [
{
"name": "name",
"type": "text",
"label": "Name",
"required": true
},
{
"name": "value",
"type": "text",
"label": "Value"
}
],
"type": "collection",
"label": "Parameter"
},
"type": "array",
"label": "Query parameters"
},
{
"name": "contentType",
"type": "select",
"label": "Body content type",
"validate": {
"enum": [
"json",
"multipart",
"urlEncoded",
"custom"
]
}
},
{
"name": "parseResponse",
"type": "boolean",
"label": "Parse response",
"required": true
},
{
"name": "stopOnHttpError",
"type": "boolean",
"label": "Return error if HTTP request fails",
"required": true
},
{
"name": "timeout",
"type": "uinteger",
"label": "Timeout",
"validate": {
"max": 300,
"min": 1
}
},
{
"name": "allowRedirects",
"type": "boolean",
"label": "Allow redirects",
"required": true
},
{
"name": "shareCookies",
"type": "boolean",
"label": "Share cookies with other HTTP modules",
"required": true
},
{
"name": "requestCompressedContent",
"type": "boolean",
"label": "Request compressed content",
"required": true
},
{
"name": "paginationType",
"type": "select",
"label": "Pagination type",
"validate": {
"enum": [
"offsetBased",
"pageBased",
"urlBased",
"tokenBased"
]
}
}
],
"interface": [
{
"name": "data",
"type": "any",
"label": "Data"
},
{
"name": "statusCode",
"type": "number",
"label": "Status Code"
},
{
"name": "headers",
"spec": [
{
"name": "content-length",
"type": "text",
"label": "Content-Length"
},
{
"name": "content-encoding",
"type": "text",
"label": "Content-Encoding"
},
{
"name": "content-type",
"type": "text",
"label": "Content-Type"
},
{
"name": "server",
"type": "text",
"label": "Server"
},
{
"name": "cache-control",
"type": "text",
"label": "Cache-Control"
},
{
"name": "set-cookie",
"spec": {
"type": "text"
},
"type": "array",
"label": "Set-Cookie"
}
],
"type": "collection",
"label": "Headers"
}
]
}
}
],
"metadata": {
"instant": true,
"version": 1,
"scenario": {
"roundtrips": 1,
"maxErrors": 3,
"autoCommit": true,
"autoCommitTriggerLast": true,
"sequential": false,
"slots": null,
"confidential": false,
"dataloss": false,
"dlq": false,
"freshVariables": false
},
"designer": {
"orphans": []
},
"zone": "eu1.make.com",
"notes": []
}
}