@porulle/adapter-shopify 0.70.2 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/adapter-shopify",
3
- "version": "0.70.2",
3
+ "version": "0.72.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "zod": "^4.1.11",
19
- "@porulle/core": "0.70.2"
19
+ "@porulle/core": "0.72.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^24.5.2",
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createHmac, timingSafeEqual } from "node:crypto";
2
- import { CHANNEL_CANCEL_REFUSED, defineChannelConnector, Err, Ok } from "@porulle/core";
2
+ import { CHANNEL_CANCEL_REFUSED, CHANNEL_OUT_OF_STOCK, defineChannelConnector, Err, Ok } from "@porulle/core";
3
3
  import type {
4
4
  ChannelCancelReason,
5
5
  ChannelConnector,
@@ -56,7 +56,7 @@ export const STORE_PROFILE_QUERY = `query PorulleStoreProfile {
56
56
  }`;
57
57
 
58
58
  export const ORDER_CREATE_MUTATION = `mutation PorulleOrderCreate($order: OrderCreateOrderInput!, $options: OrderCreateOptionsInput) {
59
- orderCreate(order: $order, options: $options) { order { legacyResourceId } userErrors { field message } }
59
+ orderCreate(order: $order, options: $options) { order { legacyResourceId } userErrors { code field message } }
60
60
  }`;
61
61
 
62
62
  /**
@@ -86,7 +86,7 @@ const storeProfileSchema = z.object({
86
86
  const orderCreateSchema = z.object({
87
87
  orderCreate: z.object({
88
88
  order: z.object({ legacyResourceId: z.string() }).nullable(),
89
- userErrors: z.array(z.object({ field: z.array(z.string()).nullable(), message: z.string() })),
89
+ userErrors: z.array(z.object({ code: z.string().nullish(), field: z.array(z.string()).nullable(), message: z.string() })),
90
90
  }),
91
91
  });
92
92
  const orderCancelSchema = z.object({
@@ -279,12 +279,17 @@ export function shopifyConnector(options: ShopifyConnectorOptions): ChannelConne
279
279
  })),
280
280
  // The delivery the shopper paid this seller, so the order total matches the payment below.
281
281
  ...(slice.shipping ? { shippingLines: [{ title: slice.shipping.title, priceSet: money(slice.shipping.amount, slice.currency) }] } : {}),
282
+ // The shopper's discount as a fixed amount off the items, so the store's total is what was paid.
283
+ ...(slice.discount ? { discountCode: { itemFixedDiscountCode: { code: slice.discount.code, amountSet: money(slice.discount.amount, slice.currency) } } } : {}),
282
284
  transactions: [{ kind: "SALE", status: "SUCCESS", gateway: SOURCE_NAME, amountSet: money(slice.grandTotal, slice.currency) }],
283
285
  },
284
286
  options: { inventoryBehaviour: "DECREMENT_OBEYING_POLICY", sendReceipt: false, sendFulfillmentReceipt: false },
285
287
  }, orderCreateSchema);
286
288
  if (!created.ok) return created;
287
289
  const { order, userErrors } = created.value.orderCreate;
290
+ if (userErrors.some((error) => error.code === "INVENTORY_CLAIM_FAILED")) {
291
+ return Err({ code: CHANNEL_OUT_OF_STOCK, message: `The store does not have the stock: ${userErrors.map((error) => error.message).join("; ")}.`, retriable: false });
292
+ }
288
293
  if (userErrors.length > 0 || !order) {
289
294
  return Err({ code: "SHOPIFY_ORDER_REJECTED", message: `Shopify refused the order: ${userErrors.map((error) => error.message).join("; ") || "no order returned"}.`, retriable: false });
290
295
  }