> ## Documentation Index
> Fetch the complete documentation index at: https://docs-pro.global-e.com/llms.txt
> Use this file to discover all available pages before exploring further.

# EU Product Identifiers

Part of the [EU Customs Reform - Product Identifiers (PID)](/eu-product-identifiers-pid).

On SFCC, the two identifiers are read from your product catalog at checkout and sent to Global-e on each cart line. For most merchants this is a configuration update, not a code change: if your Global-e integration already uses SendCart dynamic mapping, your CSM adds a mapping that reads your catalog attributes directly. Older cartridges that do not support dynamic mapping use a small project hook instead.

For what each identifier is, see [The three identifiers](/eu-product-identifiers-pid#the-three-identifiers) on the overview page.

## Check your cartridge version

EU Product Identifiers on SFCC depend on **SendCart dynamic attribute mappings**. That capability was added in Global-e cartridge **24.1.0**. Your next step depends on which `int_globale` version is running on the site.

### How to find the version

Use either method. Both read the same release string.

1. **From the active code version in Business Manager (recommended)**

   1. In **Business Manager**, go to **Administration → Site Development → Code Deployment**.
   2. Open the **active** code version.
   3. Open `int_globale/cartridge/templates/resources/globale.properties`.
   4. Read the `version` line. Example:

   ```
   version=24.6.0
   ```

   That value is the Global-e cartridge version deployed on the instance.

2. **From the cartridge properties file**

   In the same code version, open `int_globale/cartridge/int_globale.properties` and read the `#version` comment:

   ```
   #version 24.6.0
   ```

If you manage cartridges in source control rather than only on the instance, the same `version=` line lives in `cartridges/int_globale/cartridge/templates/resources/globale.properties` in the package you deployed.

If the version line or comment is **missing**, treat the cartridge as **earlier than 24.1.0** and follow the older-cartridge route below.

### What the version means for this guide

| Your `int_globale` version | What to do |
| - | - |
| **24.1.0 or later** | Use the **configuration path** below. Ask your CSM to add the SendCart mapping. No cartridge code change is required. |
| **Earlier than 24.1.0**, or **version missing** | Either **upgrade** to 24.1.0+ (preferred), or use the **hook path** for older cartridges. Do not enable the CSM mapping and the hook for the same keys. |

> **Note:** SendCart dynamic attribute mapping shipped in **24.1.0**. Versions **24.1.0 and above** support the configuration path.

## Prerequisites

| Requirement | Value |
| - | - |
| Minimum cartridge version for the mapping path | `int_globale` **24.1.0** or later |
| Product custom attributes | `geStandardCode` and `geMidIdentifier` (exact IDs) |
| SendCart mapping | Added on the Global-e side by your CSM, then synced by the **GlobaleSettings** job (mapping path only) |
| Feature enablement | Confirm with your Customer Success Manager that EU PID is enabled for your account |

## What you need to do

### 1. Store the values on your products

Create two product custom attributes to hold the identifiers, named exactly `geStandardCode` and `geMidIdentifier`. Populate them on each variation SKU independently, and leave a value unset when you have nothing to send for that line.

| Sent as | What it holds | When to leave it out |
| - | - | - |
| `standardcode` | The barcode for that line (GTIN, EAN or UPC) | When the item has no barcode. Global-e declares the "no barcode" code automatically. |
| `mididentifier` | The manufacturer's product code for that line | Never. This is required on every line. |

```
"Products": [
  {
    "ProductCode": "JKT-4471-BLK-M",
    "MetaData": {
      "Attributes": [
        { "AttributeKey": "standardcode",  "AttributeValue": "5901234123457" },
        { "AttributeKey": "mididentifier", "AttributeValue": "MFG-JKT-4471" }
      ]
    }
  }
]
```

### 2a. Cartridge 24.1.0 or later — ask your CSM to enable the SendCart mapping

The mapping lives in your Global-e platform settings (`sfccSendCartMappings`), not in Business Manager, so your CSM or integration contact adds it for your account.

When you ask your CSM, tell them:

* Your cartridge version (from the check above)
* Whether the values live on the **variation SKU**, the **master product**, or both

Once added, the mapping reaches your instance on the next run of the scheduled settings sync (**GlobaleSettings**, daily at 02:00 UTC). Run that job manually if you want it sooner. No cartridge code change is needed on supported cartridges.

### 2b. Cartridge earlier than 24.1.0, or version missing — upgrade, or use the project hook

Use this path when the version is **below 24.1.0**, or when you **cannot find a version** in `globale.properties` / `int_globale.properties`.

**Preferred:** upgrade `int_globale` (and the matching SFRA / SiteGenesis / headless extension cartridges) to **24.1.0 or later**, then follow step 2a.

**If you cannot upgrade yet**, supply the values through the `globale.getPLICustomMetadata` hook in your project cartridge. Register the hook in `hooks.json` and return the lowercase keys only when a value exists:

```json theme={null}
{
  "hooks": [
    {
      "name": "globale.getPLICustomMetadata",
      "script": "./cartridge/scripts/globale/hooks/getPLICustomMetadata.js"
    }
  ]
}
```

```js theme={null}
'use strict';

/**
 * Returns per-PLI metadata for the SendCart request.
 * @param {dw.order.ProductLineItem} productLineItem - Product line item
 * @returns {Object|null} - Key/value pairs added to Product.MetaData.Attributes
 */
exports.getPLICustomMetadata = function (productLineItem) {
    var apiProduct = productLineItem && productLineItem.product;
    if (!apiProduct) {
        return null;
    }

    var result = {};
    var standardCode = apiProduct.custom.geStandardCode;
    var midIdentifier = apiProduct.custom.geMidIdentifier;

    if (standardCode) {
        result.standardcode = String(standardCode);
    }
    if (midIdentifier) {
        result.mididentifier = String(midIdentifier);
    }

    return Object.keys(result).length ? result : null;
};
```

Do **not** use both the CSM SendCart mapping and this hook for `standardcode` / `mididentifier`, or you will get duplicate entries.

## Key points

**One pair of values per variant.** Each variation SKU sends its own `standardcode` and `mididentifier`, not just the master product.

**The values are sent under the exact keys** `standardcode` and `mididentifier` (lowercase).

**Omit, don't fake.** When you have no value, leave the key out entirely. Never send an empty string, `NA`, `0`, or `-`.

**Do not use the** `geMetadataCustomAttributes` **site preference for EU PID.** It only skips null values, not empty strings, so it can send blanks.

**Keep separate from US MID.** If you already send `midcode` / `midname` / `midaddress`, keep sending them and add these two alongside. Do not map EU PID onto the MID keys.

## Quick check before go-live

| Check | Done |
| - | - |
| Cartridge version confirmed (`globale.properties` → `version=`), or missing version treated as \< 24.1.0 | ☐ |
| Path chosen: mapping (24.1.0+) **or** hook (\< 24.1.0 / version missing), not both for the same keys | ☐ |
| Catalog attributes populated on each variation SKU that needs identifiers | ☐ |
| SendCart mapping added and synced (settings job has run) — mapping path only | ☐ |
| Hook registered and returning lowercase keys — hook path only | ☐ |
| `standardcode` appears on a line when the variant has a barcode | ☐ |
| `mididentifier` appears on every line that has a manufacturer code | ☐ |
| Lines with no barcode omit the key (no empty string or placeholder) | ☐ |
| Each variation SKU sends its own pair of values | ☐ |
| EU PID keys are separate from the US MID keys, with no duplicates | ☐ |
