HOW TO SEND ORDERS TO PROFITMETRICS SERVER-SIDE WITH SERVER-SIDE TRACKING DATA
The V2 order upload method allows you to send order data to ProfitMetrics from your server. Because the request originates from your server rather than the customer's browser, the customer's IP address and user agent must be captured client-side and explicitly forwarded as URL parameters, along with any browser cookies needed for analytics attribution.
NOTE: This methodology should only be used in situations where you do not wish to add any additional ProfitMetrics tracking script to the website, you store all the relevant tracking parameters server-side and can send this data to us with the order information
Send orders to ProfitMetrics serverside
Send orders to the following endpoint as a URL encoded GET request.
https://my.profitmetrics.io/l.php
Add the following parameters
| Parameter | Description | Notes |
|---|---|---|
| v | Version | Required - Must be set to "2" |
| pid | Website Public ID | Required |
| o | Orderspec, JSON object containing order data | Required - Must be URL-encoded |
| cip | Client IP address. The customer's IP address, captured from the browser request to your server. Must not be the server's own IP. | Required |
| cua | Client User Agent. The customer's browser user agent string, captured from the browser request to your server. | Required |
| gacid | Google Analytics Client ID. From the _ga cookie. |
Recommended - Statistics consent required |
| gacid_source | Source of the GA Client ID. Set to "gacookie" when reading from the _ga cookie. |
Recommended - Statistics consent required |
| ga4_sessionid | GA4 session ID(s). Extracted from _ga_* cookies. Format: MEASUREMENTID:sessionid, comma-separated if multiple. |
Recommended - Statistics consent required |
| ga4_sessioncount | GA4 session count(s). Extracted from _ga_* cookies. Format: MEASUREMENTID:count, comma-separated if multiple. |
Recommended - Statistics consent required |
| t | Trackspec / visit source. URL-encoded JSON from the pmVisitSource cookie (if present). |
Recommended - Statistics consent required |
| gclid | Google Click ID. From the _gcl_aw cookie (extract the value after the last dot), or from the gclid URL parameter on the landing page. |
Recommended - Marketing consent required |
| gbraid | Google gbraid. From the _gcl_gb cookie (extract the value after the last dot), or from the gbraid URL parameter on the landing page. |
Optional - Marketing consent required |
| wbraid | Google wbraid. From the _gcl_gw cookie (extract the value after the last dot), or from the wbraid URL parameter on the landing page. |
Optional - Marketing consent required |
| fbp | Facebook browser pixel ID. From _fbp cookie. |
Recommended - Marketing consent required |
| fbc | Facebook Click ID. From _fbc cookie, or constructed from the fbclid URL parameter in the format: fb.1.{timestamp_ms}.{fbclid_value} |
Recommended - Marketing consent required |
| cc_marketing | Marketing consent status. "true" or "false". | Required |
| cc_statistics | Statistics consent status. "true" or "false". | Required |
Consent handling: If the customer has not granted statistics consent, do not collect or send gacid, gacid_source, ga4_sessionid, ga4_sessioncount, or trackspec (t). If the customer has not granted marketing consent, do not collect or send gclid, gbraid, wbraid, fbp, or fbc. Always send cc_marketing and cc_statistics themselves, set to "false" when consent is not granted.
Build the Orderspec JSON object.
While some fields are REQUIRED and others are RECOMMENDED, we strongly recommend filling out as many as possible. Any missing fields will directly limit functionalities within ProfitMetrics.
Any fields that are not filled, should be omitted from the orderspec object, or set to null. They can not be empty or undefined.
NOTE: These fieldnames should be copy/pasted - they are case sensitive and specific!
| Field name | Type | Description | Notes |
|---|---|---|---|
| id | String | Unique order id | Required |
| ts | Number | Unix timestamp (UTC), second resolution | Required |
| orderEmail | String | Customer email | Required *1 |
| orderEmailMD5 | String | Customer email, md5 hashed. It is vital that the email must be trimmed and lowercased BEFORE hashing. | Required *3 |
| orderEmailSHA256 | String | Customer email, sha256 hashed. It is vital that the email must be trimmed and lowercased BEFORE hashing. | Required *3 |
| orderEmailSHA256GA | String | Customer email, sha256 hashed. It must be lowercased and trimmed, and the part before '@' must be stripped of any dots(.) if the domain part is googlemail.com or gmail.com. Example: " John.Mcafee@gmail.com" would be preprocessed to "johnmcafee@gmail.com", and then hashed | Required *3 |
| customerPhone | String | Customer phone number. There must be no letters or whitespaces, and it must include the countrycode number, area codes, and actual phone number. For example: "16505551212" for a north american phone number, or "4542504250" for a danish phone number | Recommended |
| customerPhoneMD5 | String | md5 hashed version of customerPhone | Recommended *2 |
| customerPhoneSHA256 | String | sha256 hashed version of customerPhone | Recommended *2 |
| customerFirstname | String | Customer first name | Recommended *5 |
| customerLastname | String | Customer last name | Recommended *5 |
| shippingMethod | String | Shipping method name | Required |
| shippingCountry | String | Should be in ISO 3166-1 alpha-2 format | Recommended |
| shippingState | String | Destination State (please use full state name or standard US State code) | Recommended |
| shippingZipcode | String | Destination zipcode | Recommended |
| shippingWeight | Number | Weight in grams | Recommended |
| paymentMethod | String | Payment method name | Required |
| currency | String | Format is 3 letter ISO 4217. Examples: "DKK", "EUR" | Recommended |
| voucherCode | String | gift/voucher code used | Optional |
| priceShippingExVat | Number | The charged price for shipping, excl VAT | Recommended |
| priceTotalExVat | Number | Total charged/paid price, excluding VAT | Required |
| priceTotalInclVat | Number | Total charged/paid price, including VAT | Required |
| products | Array | Array of objects | Required |
| overrides | Object | Contains overrides on the order level. See Override table below. | NEW - Optional |
Order overrides
Order overrides allows you to manually override shipping cost, payment cost, extra cost like Packaging and handling as well as the actual gross profit.
Any fields that are not filled, should be omitted from the orderspec object. They can not be empty or undefined.
| Field name | Type | Description | Notes |
|---|---|---|---|
| shippingCostExVat | Number | Used to send / overwrite Shipping cost. IMPORTANT: Value must be excluding VAT / Tax. | NEW - Optional |
| paymentCostExVat | Number | Used to send / overwrite Payment cost. (IMPORTANT: Value must be excluding VAT / Tax) | NEW - Optional |
| extraCostExVat | Number | Used to send / overwrite Packaging and handling cost or any extra expense to be deducted. IMPORTANT: Value must be excluding VAT / Tax. | NEW - Optional |
| grossProfitExVat | Number | Used to send / overwrite the Gross Profit. IMPORTANT: Value must be excluding VAT / Tax. | NEW - Optional |
*1: The orderEmail is required, either in plaintext or hash. If plaintext is supplied, hashes do not need to be submitted. If plaintext is left out, then both md5 and sha256 hash of the email must be submitted
*2 Its optional to provide the customer phone number, but if it is provided, either simply the customerPhone field should be provided, or both customerPhoneMD5 and customerPhoneSHA256
*3 This should not be supplied if plaintext orderEmail is supplied. In case it is not, we strongly recommend supplying this, or some features will be much less precise (Google Ads enhanced conversions)
*4 While it is possible to operate without this data, it severely limits functionality, so we very strongly recommend to send these fields unless it is absolutely not possible.
*5 When sending customer first and last name, we recommend also ensuring you send shippingCountry & shippingZipcode. To be sent to Google for Enhanced Conversions these four fields must all be present.
Products array objects contains the following fields:
| Field name | Type | Description | Remarks |
|---|---|---|---|
| sku | String | IMPORTANT: The product "sku" DOES NOT necessarily refer to the actual SKU but needs to match the product "id" in the product feed containing product cost. This can either be the internal product variant id of your e-commerce platform, the EAN or the actual SKU. Check with your product feed to determine the correct value. It must not be an empty string. | Required |
| qty | Number | Quantity | Required |
| priceExVat | Number | Unit price excluding VAT | Required |
| overrides | Object | Contains overrides on the product level. See Override table below. | NEW - Optional |
Product overrides
Product overrides allows you to manually override Cost Price, Title, Brand, Category, Google Product Category ID and Google Product Category EN.
Any fields that are not filled, should be omitted from the orderspec object. They can not be empty or undefined.
| Field name | Type | Description | Remarks |
|---|---|---|---|
| unitCostPriceExVat | Number | Used to send / overwrite product cost. IMPORTANT: Value must be excluding VAT / Tax. | NEW - Optional |
| title | String | Used to send / overwrite product title. | NEW - Optional |
| brand | String | Used to send / overwrite product brand. | NEW - Optional |
| categories | Array | Used to send the product category | NEW - Optional |
| googleProductCategoryId | String | Used to send the Google Product Category ID | NEW - Optional |
| googleProductCategoryEN | String | Used to send the Google Product Category EN | NEW - Optional |
Example json orderspec WITHOUT OVERRIDES:
{
"id": "12430345",
"ts": 1616595095,
"orderEmail": "test@profitmetrics.io",
"customerPhone": "4542504250",
"shippingMethod": "UPS Nextday",
"shippingCountry": "DK",
"shippingZipcode": "7400",
"shippingWeight": 2500,
"paymentMethod": "Stripe",
"currency": "DKK",
"voucherCode": "FREESHIPPING",
"priceShippingExVat": 0,
"priceTotalExVat": 100,
"priceTotalInclVat": 125,
"products": [
{
"sku": "123431-12",
"qty": 1,
"priceExVat": 50
},
{
"sku": "123431-13",
"qty": 1,
"priceExVat": 50
}
]
}
Example json orderspec WITH OVERRIDES:
{
"id": "12430345",
"ts": 1616595095,
"orderEmail": "test@profitmetrics.io",
"customerPhone": "4542504250",
"shippingMethod": "UPS Nextday",
"shippingCountry": "DK",
"shippingZipcode": "7400",
"shippingWeight": 2500,
"paymentMethod": "Stripe",
"currency": "DKK",
"voucherCode": "FREESHIPPING",
"priceShippingExVat": 0,
"priceTotalExVat": 100,
"priceTotalInclVat": 125,
"overrides":{
"shippingCostExVat": 29,
"paymentCostExVat": 1.8,
"extraCostExVat": 5,
"grossProfitExVat": 30
},
"products": [
{
"sku": "123431-12",
"qty": 1,
"priceExVat": 50,
"overrides":{
"unitCostPriceExVat": 4,
"title": "Product Title",
"brand": "Brand name",
"categories": ["Category 1", "Category 2"],
"googleProductCategoryId": 1,
"googleProductCategoryEN": "Animals & Pet Supplies"
}
},
{
"sku": "123431-13",
"qty": 1,
"priceExVat": 50,
"overrides":{
"unitCostPriceExVat": 4,
"title": "Product Title",
"brand": "Brand name",
"categories": ["Category 1", "Category 2"],
"googleProductCategoryId": 200,
"googleProductCategoryEN": "Apparel & Accessories > Jewelry > Rings"
}
}
]
}
Final GET request should look like this, but be URL encoded:
https://my.profitmetrics.io/l.php?v=2&pid=XXXXXXXXXXXXXXXX&cip=203.0.113.42&cua=Mozilla/5.0...&o={"id":"XXXX","ts":1679476010,"orderEmail":"example@example.com","customerPhone":"4542504250","shippingMethod":"SHIPPING","shippingCountry":"DK","shippingZipcode":"0000","shippingWeight":2500,"paymentMethod":"PAYMENTMETHOD","currency":"EUR","priceShippingExVat":0,"priceTotalExVat":100.00,"priceTotalInclVat":125.00,"products":[{"sku":"PRODUCT-ID","qty":1,"priceExVat":100.00},{"sku":"PRODUCT-ID","qty":1,"priceExVat":0}]}&gacid=GA1.1.1234567890.1709312400&gacid_source=gacookie&ga4_sessionid=ABC123:1709312400&ga4_sessioncount=ABC123:3&t={"source":"google","medium":"cpc"}&gclid=EAIaIQobChMI...&fbp=fb.1.1709312400.1234567890&fbc=fb.1.1709312400.AbCdEfGhIjKl&cc_marketing=true&cc_statistics=true
How to capture browser signals
Since requests originate from your server, all browser-side signals must be captured on the client and passed to your server before making the order upload call.
Client IP & User Agent
Your server must capture the customer's IP address and user agent string from the original HTTP request (typically the checkout or order confirmation page request). If you are behind a load balancer or proxy, read the IP from the X-Forwarded-For header or equivalent. Do not send your server's own IP address.
Google Analytics Client ID (gacid)
The Google Analytics Client ID is used for attribution. Read it from the _ga cookie and set gacid_source=gacookie.
GA4 Session Data (ga4_sessionid / ga4_sessioncount)
GA4 session information is stored in cookies named _ga_<MEASUREMENT_ID>. For each such cookie found, extract the session ID and session count.
The cookie value starts with GS2.1. - split the value by . and take the third segment. That segment uses $ as a delimiter. The first part is the session ID (strip a leading "s" if present) and the second part is the session count (strip a leading "o" if present).
Combine multiple measurement IDs as comma-separated values in the format MEASUREMENTID:value. For example: ABC123:1709312400,XYZ789:1709312400
Facebook Pixel Cookies (fbp / fbc)
- _fbp cookie - Read directly and send as the
fbpparameter. - _fbc cookie - Read directly and send as the
fbcparameter. - Fallback from URL: If the _fbc cookie is not available but the landing page URL contains an
fbclidquery parameter, construct the fbc value as:fb.1.{current_timestamp_ms}.{fbclid}
Visit Source / Trackspec (t)
Read the pmVisitSource cookie, URL-decode and parse the JSON value, then re-encode it as a URL-encoded JSON string and pass it as the t parameter.
Google Click IDs
- gclid - From the
_gcl_awcookie (extract the value after the last dot), or from thegclidURL parameter on the landing page - gbraid - From the
_gcl_gbcookie (extract the value after the last dot), or from thegbraidURL parameter on the landing page - wbraid - From the
_gcl_gwcookie (extract the value after the last dot), or from thewbraidURL parameter on the landing page
The _gcl_* cookies are set by the Google Tag or Conversion Linker tag. The cookie values use the format GCL.{timestamp}.{value} — extract the last segment after the final dot. If these cookies are not present, fall back to reading the corresponding URL parameter from the landing page URL.