Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/kind-zebras-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"shopify-buy": patch
---

Update checkout.webUrl to use the same domain for checkout as shopify-buy v2
38 changes: 31 additions & 7 deletions DEPLOYING.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
# Deploying JS Buy SDK

1. Merge your branch into main
2. Run `npm version [patch|minor|major]` which will do the following:
* write new version to package.json
* create a commit with a commit message matching the version number
* create a new tag matching the version number
3. Push the new commit and tags to main with `git push && git push --tags`
4. Deploy built scripts to s3 via [shipit](https://shipit.shopify.io/shopify/js-buy-sdk/production)
### 1. Make your desired changes


### 2. Then run

```
npx changeset add
```

### 3. Commit your changes (manually) using git.

**Do NOT bump the version manually in `package.json`.**

### 4. Push your changes
```
git push
```

### 5. Create a PR and merge it into `main`

This will automatically:
- Bump the version in `package.json`
- Create the tag in GitHub for the new version
- Publish the new version to npm

### 6. Deploy via [Shipit](https://shipit.shopify.io/shopify/js-buy-sdk/production)

Merging the PR will automatically publish the new version to npm, but the Shipit deploy is necessary to publish the new version to Shopify's CDN.

Press "Deploy" next to your changes once CI has passed, read and tick off the checkbox once you have read and verified the instructions, and create the deploy. Monitor it and verify it succeeds.


# Updating Documentation

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ npm install shopify-buy@3
**With Yarn:**

```bash
yarn install shopify-buy@3
yarn add shopify-buy@3
```

**CDN:**
Expand Down
18 changes: 17 additions & 1 deletion src/cart-payload-mapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,22 @@ export function mapCartPayload(cart) {
subtotalPrice = calculateSubtotalPrice(totalPrice, totalDutyAmount, totalTaxAmount);
}

let webUrl = cart.checkoutUrl;

if (webUrl) {
try {
const url = new URL(webUrl);

if (!url.searchParams.has('_fd') || url.searchParams.get('_fd') !== '0') {
url.searchParams.set('_fd', '0');
webUrl = url.toString();
}
} catch (error) {
// If URL parsing fails, return the original URL unchanged
// rather than risk breaking the checkout flow
}
}

const checkoutPayload = Object.assign({
appliedGiftCards,
buyerIdentity,
Expand All @@ -98,7 +114,7 @@ export function mapCartPayload(cart) {
totalTax: totalTaxAmount || getDefaultMoneyObject(currencyCode, totalAmount),
totalTaxV2: totalTaxAmount || getDefaultMoneyObject(currencyCode, totalAmount),
updatedAt: cart.updatedAt,
webUrl: cart.checkoutUrl
webUrl
}, UNSUPPORTED_FIELDS);

normalizeCartMoneyFieldDecimalPlaces(checkoutPayload);
Expand Down
52 changes: 51 additions & 1 deletion test/cart-payload-mapper-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,13 +471,63 @@ suite('cart-payload-mapper-test', () => {
});

suite('webUrl', () => {
test('it returns checkout URL', () => {
test('it returns checkout URL, with _fd=0 appended if not present', () => {
const cart = {
checkoutUrl: 'https://shop.com/checkout'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, `${cart.checkoutUrl}?_fd=0`);
});

test('it gracefully handles invalid URLs by returning them unchanged', () => {
const cart = {
checkoutUrl: 'invalid'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, cart.checkoutUrl);
});

test('it does not duplicate the query param _fd=0 if it is already present', () => {
const cart = {
checkoutUrl: 'https://shop.com/checkout?_fd=0'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, cart.checkoutUrl);
});

test('it updates the value of _fd to 0 if it is present but with a different value', () => {
Copy link
Contributor

@juanpprieto juanpprieto Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, I'd add two more tests for completeness:

  1. the url has already other params in it (without _fd)
  2. the url has already other params including _fd

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added! Lines 514-530 in this file

const cart = {
checkoutUrl: 'https://shop.com/checkout?_fd=1'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, 'https://shop.com/checkout?_fd=0');
});

test('it adds _fd=0 while preserving other query params', () => {
const cart = {
checkoutUrl: 'https://shop.com/checkout?foo=bar&baz=qux'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, 'https://shop.com/checkout?foo=bar&baz=qux&_fd=0');
});

test('it returns the original URL unchanged if it contains a _fd=0 query param along with other query params', () => {
const cart = {
checkoutUrl: 'https://shop.com/checkout?foo=bar&_fd=0&baz=qux'
};

const result = mapCartPayload(cart);

assert.strictEqual(result.webUrl, cart.checkoutUrl);
});
});
Expand Down
10 changes: 10 additions & 0 deletions test/client-checkout-integration-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,16 @@ suite('client-checkout-integration-test', () => {
});
});
});

test('it appends _fd=0 to the checkout URL if it is not present', () => {
return client.checkout.create({}).then((checkout) => {
return client.checkout.fetch(checkout.id).then((updatedCheckout) => {
const checkoutUrl = new URL(updatedCheckout.webUrl);

assert.strictEqual(checkoutUrl.searchParams.get('_fd'), '0');
});
});
});
});

suite('payload fields verification', () => {
Expand Down