An SKU contains an ampersand. An adapter inserts it into a query string by concatenating text, and the receiving parser treats part of the identifier as another parameter. The request now asks something different from what the caller supplied.
For a Shopify 3PL integration, preserve the difference between an identifier and the syntax transporting it. The example below assumes a documented read operation that accepts repeated sku parameters. It uses URLSearchParams to serialize each identifier as a value.
The append() method adds a name/value pair and supports repeated names. toString() produces the encoded query component without its leading question mark. Pass the original identifier to the serializer; do not pre-encode it first.
Test the values recovered by the receiver
These checks compare parsed values with the exact original strings. They also demonstrate how concatenation can accidentally create an extra parameter. All operations are local; no request is sent.
const assert = require('node:assert/strict'); function skuQuery(skus) { if (!Array.isArray(skus) || skus.length === 0) { throw new Error('Nonempty SKU array required'); } const params = new URLSearchParams(); for (const sku of skus) { if (typeof sku !== 'string' || !sku || sku.trim() !== sku) { throw new Error('Invalid SKU identifier'); } params.append('sku', sku); } return params.toString(); } const skus = ['0012', 'A&admin=true', 'BLUE+L', 'a/b', 'name with space', 'A#B', 'A=B', 'C%2FD']; const original = [...skus]; const encoded = skuQuery(skus); const parsed = new URLSearchParams(encoded); assert.deepEqual(parsed.getAll('sku'), skus); assert.equal(parsed.has('admin'), false); assert.deepEqual([...new Set(parsed.keys())], ['sku']); assert.deepEqual(skus, original); const unsafe = new URLSearchParams('sku=' + skus[1]); assert.equal(unsafe.get('sku'), 'A'); assert.equal(unsafe.get('admin'), 'true'); for (const invalid of [null, [], [''], [' padded'], [12], new Array(1)]) { assert.throws(() => skuQuery(invalid)); } console.log('SKU query round-trip checks passed'); Save this as sku-query.cjs and run node sku-query.cjs with Node.js 24. The checks cover leading zeros, ampersands, plus signs, slashes, spaces, fragments, equals signs and literal percent sequences. Recovered values remain unchanged, and the intended serialization does not create an admin parameter.
Match the documented downstream contract
An adapter for drop shipping may query supplier identifiers, while a shopify fulfillment workflow may use another item reference. Confirm which identifier the operation expects before constructing the request. Encoding faithfully preserves a string; it does not establish that the string identifies the correct product.
For China fulfillment, verify whether the downstream interface accepts repeated names, one identifier per request or another representation. A China 3PL adapter must implement that documented shape deliberately. Do not assume that a receiver will interpret an array, a comma-separated string and repeated keys in the same way.
In a hypothetical technical brief titled “International Fulfillment for Folligen,” specify the permitted identifier characters and query representation before adopting this example. The brief's title provides context, not an endpoint contract.
I work with YX Fulfillment, whose warehouse workflow includes SKU and inventory management. This executable example supports an integration review and makes no claim about a deployed YX endpoint. Production work still needs account authorization, request-size limits and verification of the returned inventory. The characters used here are test inputs, not a declaration of any provider's accepted SKU format.
Workstations at YX Fulfillment.
