> ## 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 Consumer Guarantee

Part of the [EU Consumer Guarantee (Notice & GARAN) - Platform Setup Guides](/eu-consumer-guarantee-platform-setup-guides).

<Note>
  **Plan for a developer.** Unlike platforms with a plugin setting for this, SFCC resolves the GARAN URL through a Global-e integration hook. Someone with access to your SFCC cartridge code needs to implement one small handler. The rest is configuration.
</Note>

## One-time setup

**1. Decide where the URL lives on your products**

Create or choose a product custom attribute to hold the GARAN image URL — for example `garanImageUrl` (string). There is no fixed attribute name: your hook handler decides where to read from, so any attribute id works. You can also compute the URL instead of storing it.

**2. Implement the Global-e hook**

In your project cartridge, register the hook in `hooks.json`:

```json theme={null}
{
  "name": "globale.product.getGaranImageUrl",
  "script": "./cartridge/scripts/hooks/getGaranImageUrl.js"
}
```

Then add `cartridge/scripts/hooks/getGaranImageUrl.js`:

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

exports.getGaranImageUrl = function (product) {
    // Return the full HTTPS URL of this product's GARAN PNG, or null.
    return (product && product.custom.garanImageUrl) || null;
};
```

<Warning>
  Two details that fail silently if missed:

  * The export must be named exactly `getGaranImageUrl`. A different name returns null with no error anywhere.
  * Guard against a null product (`product && ...`). The handler is called for every cart line, including product-option lines that have no product of their own. Without the guard you get an error entry in the Global-e log for each one.
</Warning>

No handler ships with the Global-e cartridges — if you do not add one, `GaranImageURL` is always empty.

**3. Enable the SendCart path**

The SendCart mapping is held in Global-e's platform settings, not in Business Manager. Ask your Customer Success Manager to add a `GaranImageURL` product mapping for your account.

Once added, it reaches your instance on the next run of the scheduled `GlobaleSettings` job (daily, 02:00 UTC). Run that job manually if you want it sooner.

For reference, the mapping Global-e adds looks like this:

```json theme={null}
{
  "targetPath": "GaranImageURL",
  "getterFunc": "return require('*/cartridge/scripts/helpers/globaleHooksHelper').invokeCustomHookWithFallback('globale.product.getGaranImageUrl', function () { return null; }, source.productLineItem.product);"
}
```

**4. Enable the Catalog path**

This one you configure yourself, in Business Manager: **Merchant Tools → Site Preferences → Custom Preferences → Global-e**, preference `geCatalogFeedConfig`. Add a column to `file.columns`:

```json theme={null}
{
  "type": "hook",
  "header": "GaranImageURL",
  "hookName": "globale.product.getGaranImageUrl",
  "fallback": { "type": "static", "attr": "" }
}
```

Nothing is added to your feed automatically — the column appears only after you add it. `header` and `hookName` are both required; without them the catalog feed job fails validation.

## Per product

Populate the attribute on each product that qualifies, with the full HTTPS URL of that item's GARAN PNG. Leave it empty where there is no producer durability guarantee.

| Product | Attribute value |
| - | - |
| Alpine Insulated Jacket | `https://cdn.example.com/garan/JKT-4471.png` |
| Cotton Crew Tee | (empty — no guarantee) |

## When the value syncs

**SendCart** reads the attribute at checkout, on every cart, so changes take effect immediately.

**Catalog** picks the value up on the next scheduled run of the `GlobaleCatalogFeed` job — it is a batch export, not a live sync. If your feed is configured with `processOnlyModifiedProducts`, editing the attribute marks the product modified and it is included in the next run.

## Prerequisites

| Requirement | Value |
| - | - |
| Minimum cartridge version | `int_globale` 24.7.0 or later (adds the hook catalog column type) |
| Hook handler | `globale.product.getGaranImageUrl` implemented in your project cartridge — mandatory, nothing ships by default |
| SendCart mapping | Added on the Global-e side by your CSM, then synced by the `GlobaleSettings` job |
| Catalog column | Added by you to the `geCatalogFeedConfig` site preference |
| Feature enablement | Confirm with your Customer Success Manager that GARAN attachment is enabled for your account |

## Delivery paths

The value reaches Global-e on two paths, and one hook serves both:

* **SendCart / GetCart at checkout** — `SendCartData.Products[].GaranImageURL`
* **GlobaleCatalogFeed** — a scheduled job that writes a CSV and uploads it to Global-e over SFTP

SFCC does not use Browsing/SaveProductsList. If other Global-e documentation refers to that call for the catalog path, the SFCC equivalent is the CSV feed described here.

You do not need both. Use whichever matches how you already send product data to Global-e.

## Platform notes

<Warning>
  The GARAN URL must be reachable from your hook handler. Putting it only in the Global-e MetaData attributes bag will not populate `GaranImageURL`.
</Warning>

Do not reuse the product image field. `ImageURL` is the storefront photo and `GaranImageURL` is the guarantee label — Global-e keeps them as separate fields.

**Variants.** The hook receives a `dw.catalog.Product` for each product exported or added to the cart, which for most catalogs means variants. If every variant shares one label, read from the master in your handler:

```javascript theme={null}
exports.getGaranImageUrl = function (product) {
    if (!product) { return null; }
    if (product.custom.garanImageUrl) { return product.custom.garanImageUrl; }
    var master = product.variant && product.masterProduct;
    return (master && master.custom.garanImageUrl) || null;
};
```

Product options and gift certificates do not carry a GARAN label. Option lines send `GaranImageURL` as null; gift-certificate lines omit it entirely.

**Older cartridges.** If your cartridge predates Global-e's SendCart attribute-mapping support and you are not upgrading, the SendCart value can instead be set directly in `getProduct()` in your cartridge, calling the same hook. Ask your CSM or SFCC integration contact for the snippet.

## Payload reference

For technical readers. The field name is `GaranImageURL` on both paths.

**Cart — `SendCartData.Products[]`**

```json theme={null}
{
  "Products": [
    {
      "ProductCode": "JKT-4471-BLK-M",
      "CartItemId": "1057",
      "Name": "Alpine Insulated Jacket",
      "OrderedQuantity": 1,
      "ImageURL": "https://cdn.example.com/products/jkt-4471-blk.jpg",
      "GaranImageURL": "https://cdn.example.com/garan/JKT-4471.png"
    },
    {
      "ProductCode": "TEE-1102-WHT-L",
      "CartItemId": "1058",
      "Name": "Cotton Crew Tee",
      "OrderedQuantity": 1,
      "ImageURL": "https://cdn.example.com/products/tee-1102-wht.jpg",
      "GaranImageURL": null
    }
  ]
}
```

The t-shirt has no guarantee — `GaranImageURL` is null and no attachment is generated for it.

**Catalog — CSV over SFTP.** Column order follows your `file.columns` configuration:

```csv theme={null}
ProductCode,Name,ImageURL,GaranImageURL
JKT-4471-BLK-M,Alpine Insulated Jacket,https://cdn.example.com/products/jkt-4471-blk.jpg,https://cdn.example.com/garan/JKT-4471.png
TEE-1102-WHT-L,Cotton Crew Tee,https://cdn.example.com/products/tee-1102-wht.jpg,
```

Products with no GARAN URL produce an empty cell, not a missing column.

## Verify

| Check | Done |
| - | - |
| Hook handler registered and its export named exactly `getGaranImageUrl` | ☐ |
| `GaranImageURL` appears in the cart payload for a product with a populated attribute | ☐ |
| A product with an empty attribute sends `GaranImageURL` as null | ☐ |
| Catalog feed job completes and the CSV contains a `GaranImageURL` column | ☐ |
| The CSV cell is populated for a qualifying product and empty for a non-qualifying one | ☐ |
| No UTIL\_HOOK errors in the Global-e log after a checkout containing a product with options | ☐ |
| GARAN URL returns a valid PNG (not JPG/SVG/PDF at the source URL) | ☐ |

<Note>
  Activation modes and the general preparation steps — opting in, identifying qualifying products, and creating and hosting the GARAN PNG — are covered on the [EU Consumer Guarantee Information (Notice & GARAN)](/eu-consumer-guarantee-notice-and-garan) overview page.
</Note>

## FAQ

<AccordionGroup>
  <Accordion title="Do I have to change cartridge code?">
    Yes, one handler. There is no site preference or Business Manager setting that maps an attribute directly, because the handler is what lets you read from any attribute or compute the URL.
  </Accordion>

  <Accordion title="Can I skip the hook and just set a mapping?">
    No. The mapping calls the hook; without a handler it returns null.
  </Accordion>

  <Accordion title="Why is my GaranImageURL always empty?">
    Most often the handler export is misnamed — it must be `getGaranImageUrl`, matching the last segment of the hook id. Also check that the handler is registered in a cartridge that is actually on your site's cartridge path.
  </Accordion>

  <Accordion title="Do variants each need their own URL?">
    Only if they differ. See Platform notes for a handler that falls back to the master product.
  </Accordion>

  <Accordion title="Can I reuse the product image attribute?">
    No. `ImageURL` is the storefront photo. GARAN must come from its own attribute or logic.
  </Accordion>

  <Accordion title="Does the catalog feed change for products without a guarantee?">
    No. The column is present for every row; rows without a URL simply have an empty cell.
  </Accordion>
</AccordionGroup>
