About EU new barcode requirements and barcode types

Hi, I’m hoping to get some clarification from Shopify about this:

A merchant just shared with us an email they received from Shopify on October 16, explaining an EU requirement where some products may need a Standardized Product Identifier (S-PID) or an Non-Standardized Manufacturer Product Identifier (NS-PID).

From what I understood, if the merchant has “official” GS1-issued barcodes, those can serve as the S-PID.

However, if the merchant does not require to have an S-PID, they can enter other kinds of “arbitrary” codes into the barcode field, and mark the type as “NS-PID”.

Here’s the problem: the vast majority (maybe all) of our clients have barcodes with type “Custom”. As you know, barcodes did not have type until very recently, so I presume Shopify just set all barcodes to type “Custom” when it launched the type feature, as a starting point.

If merchants are forced to flip the type from “Custom” to “NS-PID”, that is a lot of work for which there’s no bulk edit functionality in the Admin. Could Shopify just use barcodes of type “Custom” as a fallback instead of requiring the merchant to flip the type to “NS-PID”?

Hey @flavio-b, I dug into this for you and found no flip is needed. “Custom” just means no type was declared, and the October 16 email says the NS-PID can alternatively be the merchant’s own product code or SKU. When no NS-PID barcode is set, Shopify falls back to the standardized identifier, so the existing Custom values already count. Setting the NS-PID type only matters when a variant has several barcodes and the merchant wants to pick which one is used.

The per-variant work that does matter is the S-PID side. Each variant needs a GTIN, EAN, UPC, or ISBN barcode, or the “Has no standardized identifier” declaration in the Shipping card (More details > EU customs declaration, which can be set for several selected variants of a product at once). Placeholder values like “None” don’t record that declaration, so worth steering merchants away from those.

For bulk work, barcode types can be set through productVariantsBulkUpdate with BarcodeInput.type on the stable 2026-10 version, and merchants can edit barcode values through the bulk editor or a CSV import. The “no standardized identifier” declaration isn’t in a stable version yet. Sending compliance: [{key: Y081, value: "true"}] to productVariantsBulkUpdate on the unstable version works today, including from a third-party app, though unstable can change without notice.

Thank you. I get what you’re saying.

The confusing thing is that it seems like the checkbox “Has no standardized identifier” and a barcode of type NS-PID have a lot of overlap.

For example, many merchants already have a SKU in the Barcode field, or some other custom product code, or a random number. These codes would have type Custom right now.

So, you’re saying they would need to check the “Has no standardized identifier” box, but isn’t that effectively the same as setting a barcode type to NS-PID?

Ok, but that sounds like NS-PID is less a barcode type, and more like a pointer to which barcode to pick among several. Second, I was able to create two barcodes with type NS-PID just now. It’s not clear which one would be used.

I think the current implementation and terminology will create some confusion. You’ll likely start to see cases where both the checkbox is checked, and one ore more barcodes with type NS-PID are being used, in the coming months.

Edit: A couple more things I find odd about the design:

  1. “Custom” is pretty much the definition of “Not Standardized”, so not sure why a NS-PID type was introduced.
  2. There’s the NS-PID type, but no S-PID type. I get the impression that NS-PID really wants to be a pointer to a custom barcode, the same way S-PID is a pointer to an official barcode (EAN, UPC etc).

Thanks for the thoughtful reply @flavio-b ! On the wording overlap, the checkbox declares that a variant has no standardized identifier, meaning no S-PID in the form of a GTIN, EAN, UPC or ISBN barcode. The NS-PID is a separate identifier the EU also expects. When it’s missing, Shopify fills one in automatically, falling back to your other barcodes, your SKU, or the variant ID. So a variant whose only barcode is a Custom-typed SKU already has an NS-PID, but it still has no S-PID, which is exactly what the checkbox covers. Typing that SKU as NS-PID doesn’t record the declaration.

When a variant has multiple NS-PID barcodes, which one gets reported to customs isn’t documented, and since the ProductVariantBarcode object only exposes type and value, there’s no way to flag one as the one to use. I’d keep a single NS-PID barcode per variant so there’s no ambiguity about what gets reported.

On the naming, there’s no S-PID type because a standardized identifier is already one of the existing BarcodeType values, and the checkbox covers variants that have none of those. Thanks for flagging the design side of this. I’ve shared the Custom versus NS-PID overlap, the missing S-PID type, and the multiple-NS-PID behavior with the products team internally, and I’ll follow up here once they’ve confirmed how the mechanics are meant to work.

Following up as promised @flavio-b, I heard back from the products team on the mechanics.

With multiple NS-PID barcodes, one per variant is all that’s needed. When a variant has several, there’s no deterministic rule for which one gets used, so I’d remove the extras rather than rely on any particular order.

I also need to refine part of my last reply based on the product team’s explanation. A Custom-typed barcode that holds a valid GTIN (correct format and check digit) is already used as the S-PID. Merchants shouldn’t tick “Has no standardized identifier” for those variants, because the checkbox declares that no standardized identifier exists. The safer move is to change those barcodes’ type to GTIN, UPC, EAN or ISBN rather than rely on Shopify inferring it, and the productVariantsBulkUpdate route I mentioned earlier works for that. The checkbox is only for variants whose barcodes are SKUs, internal codes, or other values that aren’t valid GTINs.

The declaration itself is meant to reach customs paperwork and carriers, including Managed Markets orders - that part isn’t live just yet, but keep an eye out.

Got it! Thank you very much for the clarification.