@easypayment/medusa-paypal 0.4.5 → 0.4.7

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.
@@ -183,7 +183,7 @@ function AdditionalSettingsTab() {
183
183
  )
184
184
  ] }) });
185
185
  }
186
- function PayPalGooglePayPage() {
186
+ function PayPalApplePayPage() {
187
187
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
188
188
  }
189
189
  async function adminFetch$1(path, opts = {}) {
@@ -325,9 +325,6 @@ function AdvancedCardPaymentsTab() {
325
325
  )
326
326
  ] }) });
327
327
  }
328
- function PayPalApplePayPage() {
329
- return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
330
- }
331
328
  const config = adminSdk.defineRouteConfig({
332
329
  label: "PayPal Connection",
333
330
  hide: true
@@ -929,6 +926,9 @@ function PayPalConnectionPage() {
929
926
  ` })
930
927
  ] });
931
928
  }
929
+ function PayPalGooglePayPage() {
930
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
931
+ }
932
932
  function PayPalPayLaterMessagingPage() {
933
933
  return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
934
934
  }
@@ -1217,21 +1217,21 @@ const routeModule = {
1217
1217
  path: "/settings/paypal/additional-settings"
1218
1218
  },
1219
1219
  {
1220
- Component: PayPalGooglePayPage,
1221
- path: "/settings/paypal/google-pay"
1220
+ Component: PayPalApplePayPage,
1221
+ path: "/settings/paypal/apple-pay"
1222
1222
  },
1223
1223
  {
1224
1224
  Component: AdvancedCardPaymentsTab,
1225
1225
  path: "/settings/paypal/advanced-card-payments"
1226
1226
  },
1227
- {
1228
- Component: PayPalApplePayPage,
1229
- path: "/settings/paypal/apple-pay"
1230
- },
1231
1227
  {
1232
1228
  Component: PayPalConnectionPage,
1233
1229
  path: "/settings/paypal/connection"
1234
1230
  },
1231
+ {
1232
+ Component: PayPalGooglePayPage,
1233
+ path: "/settings/paypal/google-pay"
1234
+ },
1235
1235
  {
1236
1236
  Component: PayPalPayLaterMessagingPage,
1237
1237
  path: "/settings/paypal/pay-later-messaging"
@@ -182,7 +182,7 @@ function AdditionalSettingsTab() {
182
182
  )
183
183
  ] }) });
184
184
  }
185
- function PayPalGooglePayPage() {
185
+ function PayPalApplePayPage() {
186
186
  return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
187
187
  }
188
188
  async function adminFetch$1(path, opts = {}) {
@@ -324,9 +324,6 @@ function AdvancedCardPaymentsTab() {
324
324
  )
325
325
  ] }) });
326
326
  }
327
- function PayPalApplePayPage() {
328
- return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
329
- }
330
327
  const config = defineRouteConfig({
331
328
  label: "PayPal Connection",
332
329
  hide: true
@@ -928,6 +925,9 @@ function PayPalConnectionPage() {
928
925
  ` })
929
926
  ] });
930
927
  }
928
+ function PayPalGooglePayPage() {
929
+ return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
930
+ }
931
931
  function PayPalPayLaterMessagingPage() {
932
932
  return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
933
933
  }
@@ -1216,21 +1216,21 @@ const routeModule = {
1216
1216
  path: "/settings/paypal/additional-settings"
1217
1217
  },
1218
1218
  {
1219
- Component: PayPalGooglePayPage,
1220
- path: "/settings/paypal/google-pay"
1219
+ Component: PayPalApplePayPage,
1220
+ path: "/settings/paypal/apple-pay"
1221
1221
  },
1222
1222
  {
1223
1223
  Component: AdvancedCardPaymentsTab,
1224
1224
  path: "/settings/paypal/advanced-card-payments"
1225
1225
  },
1226
- {
1227
- Component: PayPalApplePayPage,
1228
- path: "/settings/paypal/apple-pay"
1229
- },
1230
1226
  {
1231
1227
  Component: PayPalConnectionPage,
1232
1228
  path: "/settings/paypal/connection"
1233
1229
  },
1230
+ {
1231
+ Component: PayPalGooglePayPage,
1232
+ path: "/settings/paypal/google-pay"
1233
+ },
1234
1234
  {
1235
1235
  Component: PayPalPayLaterMessagingPage,
1236
1236
  path: "/settings/paypal/pay-later-messaging"
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/create-order/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAuG7E,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,2BA6VjE"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/create-order/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAsN7E,wBAAsB,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,2BA0VjE"}
@@ -79,6 +79,95 @@ function resolveCancelUrl(req) {
79
79
  }
80
80
  return `${configured.replace(/\/$/, "")}/cart`;
81
81
  }
82
+ // ---------------------------------------------------------------------------
83
+ // buildPayPalLineItems
84
+ //
85
+ // This function mirrors the WooCommerce PayPal plugin reconciliation logic:
86
+ //
87
+ // 1. Convert each item's line_subtotal from MINOR units (cents) to MAJOR
88
+ // units (euros/dollars) using the currency exponent factor.
89
+ // e.g. 1000 cents ÷ 100 = €10.00
90
+ //
91
+ // 2. Compute unit_amount = line_subtotal_major / quantity (pre-discount
92
+ // price per unit, rounded to currency decimal places).
93
+ //
94
+ // 3. Sum all (unit_amount × quantity) — this is "roundedItemSum".
95
+ //
96
+ // 4. Compare roundedItemSum with subtotalMajor (cart.subtotal in major
97
+ // units, already correct from Medusa). If there is any rounding
98
+ // discrepancy (e.g. ±0.01), insert a single "Line Item Amount Offset"
99
+ // item worth exactly `diff` to absorb it.
100
+ // After this: sum(items) === subtotalMajor exactly.
101
+ //
102
+ // 5. breakdown.item_total is ALWAYS set to subtotalMajor — never modified.
103
+ // The offset item ensures the items array sums to match it.
104
+ //
105
+ // 6. If the final breakdownSum (item_total + shipping + tax - discount)
106
+ // does not match cart.total, absorb the gap via shipping_discount
107
+ // (if gap < 0) or by adding to tax_total (if gap > 0).
108
+ // This guarantees the PayPal order total always matches cart.total exactly.
109
+ // ---------------------------------------------------------------------------
110
+ function buildPayPalLineItems(lineItems, subtotalMajor, currency, exponent, sendItemDetails) {
111
+ if (!sendItemDetails || lineItems.length === 0) {
112
+ return { items: [], adjustedItemTotal: subtotalMajor };
113
+ }
114
+ // factor = 100 for EUR/USD, 1 for JPY, 1000 for KWD, etc.
115
+ const factor = Math.pow(10, exponent);
116
+ // Step 1 & 2: Build raw items with proper unit amounts
117
+ const rawItems = lineItems
118
+ .map((item) => {
119
+ const quantity = Number(item?.quantity || 0);
120
+ if (!quantity || Number.isNaN(quantity))
121
+ return null;
122
+ // item.subtotal is in MINOR units (cents) — must divide by factor
123
+ const lineSubtotalMinor = Number(item?.subtotal ?? Number(item?.unit_price || 0) * quantity);
124
+ const lineSubtotalMajor = lineSubtotalMinor / factor;
125
+ // unit price per item, rounded to currency decimal places
126
+ const unitAmount = parseFloat((lineSubtotalMajor / quantity).toFixed(exponent));
127
+ if (Number.isNaN(unitAmount))
128
+ return null;
129
+ return {
130
+ quantity,
131
+ unitAmount,
132
+ paypalItem: {
133
+ name: String(item?.title || "Item").slice(0, 127),
134
+ quantity: String(quantity),
135
+ unit_amount: {
136
+ currency_code: currency,
137
+ value: unitAmount.toFixed(exponent),
138
+ },
139
+ },
140
+ };
141
+ })
142
+ .filter(Boolean);
143
+ if (rawItems.length === 0) {
144
+ return { items: [], adjustedItemTotal: subtotalMajor };
145
+ }
146
+ // Step 3: Sum of (unit_amount × quantity) after rounding
147
+ const roundedItemSum = rawItems.reduce((sum, item) => sum + item.unitAmount * item.quantity, 0);
148
+ const roundedItemSumFixed = parseFloat(roundedItemSum.toFixed(exponent));
149
+ // Step 4: Calculate rounding difference
150
+ // diff = how much to add as an offset item so that:
151
+ // roundedItemSumFixed + diff === subtotalMajor
152
+ const diff = parseFloat((subtotalMajor - roundedItemSumFixed).toFixed(exponent));
153
+ const finalItems = rawItems.map((item) => item.paypalItem);
154
+ if (Math.abs(diff) > 0.000001) {
155
+ // Insert a tiny offset item to absorb the rounding gap.
156
+ // After this: sum(finalItems unit_amount × quantity) === subtotalMajor exactly.
157
+ finalItems.push({
158
+ name: "Line Item Amount Offset",
159
+ quantity: "1",
160
+ unit_amount: {
161
+ currency_code: currency,
162
+ value: diff.toFixed(exponent),
163
+ },
164
+ });
165
+ // NOTE: adjustedItemTotal stays as subtotalMajor — do NOT add diff here.
166
+ // The offset item brings the items sum UP to subtotalMajor.
167
+ // Adding diff to adjustedItemTotal would cause a double-count.
168
+ }
169
+ return { items: finalItems, adjustedItemTotal: subtotalMajor };
170
+ }
82
171
  async function POST(req, res) {
83
172
  const paypal = req.scope.resolve("paypal_onboarding");
84
173
  let debugId = null;
@@ -93,9 +182,12 @@ async function POST(req, res) {
93
182
  if (existingOrderId) {
94
183
  return res.json({ id: existingOrderId });
95
184
  }
96
- /**
97
- * Medusa v2 cart retrieval via Query Graph
98
- */
185
+ // -------------------------------------------------------------------------
186
+ // Fetch cart via Query Graph
187
+ // All monetary fields returned by Medusa are in MAJOR units (e.g. euros)
188
+ // EXCEPT item-level fields (item.unit_price, item.subtotal, item.total)
189
+ // which are in MINOR units (cents). This is the root cause of the bug.
190
+ // -------------------------------------------------------------------------
99
191
  const query = req.scope.resolve("query");
100
192
  const { data } = await query.graph({
101
193
  entity: "cart",
@@ -134,9 +226,9 @@ async function POST(req, res) {
134
226
  ? advancedCardSettings.threeDS
135
227
  : "when_required";
136
228
  const threeDsMethod = isCardPayment
137
- ? (threeDsRaw === "always"
229
+ ? threeDsRaw === "always"
138
230
  ? "SCA_ALWAYS"
139
- : "SCA_WHEN_REQUIRED")
231
+ : "SCA_WHEN_REQUIRED"
140
232
  : null;
141
233
  const configuredCurrency = typeof apiDetails.currency_code === "string"
142
234
  ? (0, currencies_1.normalizeCurrencyCode)(apiDetails.currency_code)
@@ -147,7 +239,16 @@ async function POST(req, res) {
147
239
  paypalCurrencyOverride: configuredCurrency,
148
240
  });
149
241
  const exponent = (0, amounts_1.getCurrencyExponent)(currency);
242
+ // -------------------------------------------------------------------------
243
+ // Cart-level totals — these are already in MAJOR units (euros/dollars)
244
+ // e.g. cart.total = 20 means €20.00
245
+ // -------------------------------------------------------------------------
150
246
  const totalMajor = Number(cart.total || 0);
247
+ const subtotalMajor = Number(cart.subtotal || 0);
248
+ const shippingMajor = Number(cart.shipping_total || 0);
249
+ const taxMajor = Number(cart.tax_total || 0);
250
+ const discountMajor = Number(cart.discount_total || 0);
251
+ const giftCardMajor = Number(cart.gift_card_total || 0);
151
252
  const value = totalMajor.toFixed(exponent);
152
253
  const paymentActionRaw = typeof additionalSettings.paymentAction === "string"
153
254
  ? additionalSettings.paymentAction
@@ -177,12 +278,12 @@ async function POST(req, res) {
177
278
  ? additionalSettings.invoicePrefix
178
279
  : "";
179
280
  const invoiceId = `${invoicePrefix}${cart.id}`.trim() || cart.id;
180
- const returnUrl = (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
281
+ const returnUrl = typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
181
282
  ? `${apiDetails.storefront_url.replace(/\/$/, "")}/checkout`
182
- : resolveReturnUrl(req));
183
- const cancelUrl = (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
283
+ : resolveReturnUrl(req);
284
+ const cancelUrl = typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
184
285
  ? `${apiDetails.storefront_url.replace(/\/$/, "")}/cart`
185
- : resolveCancelUrl(req));
286
+ : resolveCancelUrl(req);
186
287
  const applicationContext = {
187
288
  ...(brandName ? { brand_name: brandName } : {}),
188
289
  ...(landingPage ? { landing_page: landingPage } : {}),
@@ -190,52 +291,16 @@ async function POST(req, res) {
190
291
  ...(returnUrl ? { return_url: returnUrl } : {}),
191
292
  ...(cancelUrl ? { cancel_url: cancelUrl } : {}),
192
293
  };
193
- const subtotalMajor = Number(cart.subtotal || 0);
194
- const shippingMajor = Number(cart.shipping_total || 0);
195
- const taxMajor = Number(cart.tax_total || 0);
196
- const discountMajor = Number(cart.discount_total || 0);
197
- const giftCardMajor = Number(cart.gift_card_total || 0);
294
+ // -------------------------------------------------------------------------
295
+ // Build line items with correct minor→major conversion and reconciliation.
296
+ // See buildPayPalLineItems() above for full explanation.
297
+ // -------------------------------------------------------------------------
198
298
  const lineItems = Array.isArray(cart.items) ? cart.items : [];
199
- const purchaseItemsRaw = sendItemDetails
200
- ? lineItems
201
- .map((item) => {
202
- const quantity = Number(item?.quantity || 0);
203
- const lineSubtotal = Number(item?.subtotal ?? (Number(item?.unit_price || 0) * quantity));
204
- const unitAmount = quantity > 0 ? parseFloat((lineSubtotal / quantity).toFixed(exponent)) : 0;
205
- if (!quantity || Number.isNaN(quantity) || Number.isNaN(unitAmount)) {
206
- return null;
207
- }
208
- return {
209
- quantity,
210
- unitAmount,
211
- paypalItem: {
212
- name: String(item?.title || "Item").slice(0, 127),
213
- quantity: String(Math.max(1, quantity)),
214
- unit_amount: {
215
- currency_code: currency,
216
- value: unitAmount.toFixed(exponent),
217
- },
218
- },
219
- };
220
- })
221
- .filter(Boolean)
222
- : [];
223
- const roundedItemSum = purchaseItemsRaw.reduce((sum, item) => sum + item.unitAmount * item.quantity, 0);
224
- const roundedItemSumFixed = parseFloat(roundedItemSum.toFixed(exponent));
225
- const diff = parseFloat((subtotalMajor - roundedItemSumFixed).toFixed(exponent));
226
- const finalPurchaseItems = purchaseItemsRaw.map((item) => item.paypalItem);
227
- let adjustedItemTotal = subtotalMajor;
228
- if (Math.abs(diff) > 0.000001 && sendItemDetails && finalPurchaseItems.length > 0) {
229
- finalPurchaseItems.push({
230
- name: "Line Item Amount Offset",
231
- quantity: "1",
232
- unit_amount: {
233
- currency_code: currency,
234
- value: diff.toFixed(exponent),
235
- },
236
- });
237
- adjustedItemTotal = parseFloat((subtotalMajor + diff).toFixed(exponent));
238
- }
299
+ const { items: finalPurchaseItems, adjustedItemTotal } = buildPayPalLineItems(lineItems, subtotalMajor, currency, exponent, sendItemDetails);
300
+ // -------------------------------------------------------------------------
301
+ // Build the breakdown object.
302
+ // PayPal rule: item_total + shipping + tax_total - discount - shipping_discount === value
303
+ // -------------------------------------------------------------------------
239
304
  const breakdown = {};
240
305
  if (adjustedItemTotal > 0) {
241
306
  breakdown.item_total = {
@@ -255,6 +320,8 @@ async function POST(req, res) {
255
320
  value: taxMajor.toFixed(exponent),
256
321
  };
257
322
  }
323
+ // Discounts and gift cards — only include if we are also sending items,
324
+ // otherwise PayPal rejects breakdown with discount but no items.
258
325
  const discountValue = discountMajor + giftCardMajor;
259
326
  if (discountValue > 0 && finalPurchaseItems.length > 0) {
260
327
  breakdown.discount = {
@@ -262,16 +329,25 @@ async function POST(req, res) {
262
329
  value: discountValue.toFixed(exponent),
263
330
  };
264
331
  }
332
+ // -------------------------------------------------------------------------
333
+ // Final reconciliation: ensure breakdown sums exactly to cart total.
334
+ // If there is a gap (can happen due to rounding across multiple fields),
335
+ // absorb it via shipping_discount (if we over-counted) or tax_total
336
+ // (if we under-counted). This is exactly what WooCommerce does.
337
+ // -------------------------------------------------------------------------
265
338
  const breakdownSum = parseFloat((adjustedItemTotal + shippingMajor + taxMajor - discountValue).toFixed(exponent));
266
339
  if (Math.abs(breakdownSum - totalMajor) > 0.000001) {
267
340
  const gap = parseFloat((totalMajor - breakdownSum).toFixed(exponent));
268
341
  if (gap > 0) {
342
+ // We under-counted — add the gap to tax_total
343
+ const existingTax = Number(breakdown.tax_total?.value || 0);
269
344
  breakdown.tax_total = {
270
345
  currency_code: currency,
271
- value: parseFloat(((Number(breakdown.tax_total?.value || 0) + gap).toFixed(exponent))).toFixed(exponent),
346
+ value: parseFloat((existingTax + gap).toFixed(exponent)).toFixed(exponent),
272
347
  };
273
348
  }
274
349
  else {
350
+ // We over-counted — add shipping_discount to bring total down
275
351
  breakdown.shipping_discount = {
276
352
  currency_code: currency,
277
353
  value: Math.abs(gap).toFixed(exponent),
@@ -284,6 +360,13 @@ async function POST(req, res) {
284
360
  client_secret: creds.client_secret,
285
361
  });
286
362
  const requestId = resolveIdempotencyKey(req, "create-order", `pp-create-${cart.id}`);
363
+ // Log what we are sending to PayPal for debugging
364
+ console.info("[PayPal] create-order payload", {
365
+ cart_id: cart.id,
366
+ value,
367
+ breakdown,
368
+ item_count: finalPurchaseItems.length,
369
+ });
287
370
  const ppResp = await fetch(`${base}/v2/checkout/orders`, {
288
371
  method: "POST",
289
372
  headers: {
@@ -332,7 +415,7 @@ async function POST(req, res) {
332
415
  }
333
416
  const order = JSON.parse(ppText);
334
417
  await attachPayPalOrderToSession(req, cart.id, order.id);
335
- console.info("[PayPal] create-order", {
418
+ console.info("[PayPal] create-order success", {
336
419
  cart_id: cart.id,
337
420
  order_id: order.id,
338
421
  request_id: requestId,
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/create-order/route.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../src/api/store/paypal/create-order/route.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easypayment/medusa-paypal",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "Industry-standard PayPal integration for Medusa v2",
5
5
  "license": "MIT",
6
6
  "main": "./.medusa/server/src/index.js",
@@ -1,6 +1,6 @@
1
1
  import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
2
2
  import { randomUUID } from "crypto"
3
- import { getCurrencyExponent } from "../../../../modules/paypal/utils/amounts"
3
+ import { getCurrencyExponent, formatAmountForPayPal } from "../../../../modules/paypal/utils/amounts"
4
4
  import {
5
5
  assertPayPalCurrencySupported,
6
6
  normalizeCurrencyCode,
@@ -101,6 +101,117 @@ function resolveCancelUrl(req: MedusaRequest) {
101
101
  return `${configured.replace(/\/$/, "")}/cart`
102
102
  }
103
103
 
104
+ // ---------------------------------------------------------------------------
105
+ // buildPayPalLineItems
106
+ //
107
+ // This function mirrors the WooCommerce PayPal plugin reconciliation logic:
108
+ //
109
+ // 1. Convert each item's line_subtotal from MINOR units (cents) to MAJOR
110
+ // units (euros/dollars) using the currency exponent factor.
111
+ // e.g. 1000 cents ÷ 100 = €10.00
112
+ //
113
+ // 2. Compute unit_amount = line_subtotal_major / quantity (pre-discount
114
+ // price per unit, rounded to currency decimal places).
115
+ //
116
+ // 3. Sum all (unit_amount × quantity) — this is "roundedItemSum".
117
+ //
118
+ // 4. Compare roundedItemSum with subtotalMajor (cart.subtotal in major
119
+ // units, already correct from Medusa). If there is any rounding
120
+ // discrepancy (e.g. ±0.01), insert a single "Line Item Amount Offset"
121
+ // item worth exactly `diff` to absorb it.
122
+ // After this: sum(items) === subtotalMajor exactly.
123
+ //
124
+ // 5. breakdown.item_total is ALWAYS set to subtotalMajor — never modified.
125
+ // The offset item ensures the items array sums to match it.
126
+ //
127
+ // 6. If the final breakdownSum (item_total + shipping + tax - discount)
128
+ // does not match cart.total, absorb the gap via shipping_discount
129
+ // (if gap < 0) or by adding to tax_total (if gap > 0).
130
+ // This guarantees the PayPal order total always matches cart.total exactly.
131
+ // ---------------------------------------------------------------------------
132
+ function buildPayPalLineItems(
133
+ lineItems: any[],
134
+ subtotalMajor: number,
135
+ currency: string,
136
+ exponent: number,
137
+ sendItemDetails: boolean
138
+ ): { items: any[]; adjustedItemTotal: number } {
139
+ if (!sendItemDetails || lineItems.length === 0) {
140
+ return { items: [], adjustedItemTotal: subtotalMajor }
141
+ }
142
+
143
+ // factor = 100 for EUR/USD, 1 for JPY, 1000 for KWD, etc.
144
+ const factor = Math.pow(10, exponent)
145
+
146
+ // Step 1 & 2: Build raw items with proper unit amounts
147
+ const rawItems = lineItems
148
+ .map((item: any) => {
149
+ const quantity = Number(item?.quantity || 0)
150
+ if (!quantity || Number.isNaN(quantity)) return null
151
+
152
+ // item.subtotal is in MINOR units (cents) — must divide by factor
153
+ const lineSubtotalMinor = Number(
154
+ item?.subtotal ?? Number(item?.unit_price || 0) * quantity
155
+ )
156
+ const lineSubtotalMajor = lineSubtotalMinor / factor
157
+
158
+ // unit price per item, rounded to currency decimal places
159
+ const unitAmount = parseFloat((lineSubtotalMajor / quantity).toFixed(exponent))
160
+
161
+ if (Number.isNaN(unitAmount)) return null
162
+
163
+ return {
164
+ quantity,
165
+ unitAmount,
166
+ paypalItem: {
167
+ name: String(item?.title || "Item").slice(0, 127),
168
+ quantity: String(quantity),
169
+ unit_amount: {
170
+ currency_code: currency,
171
+ value: unitAmount.toFixed(exponent),
172
+ },
173
+ },
174
+ }
175
+ })
176
+ .filter(Boolean) as Array<{ quantity: number; unitAmount: number; paypalItem: any }>
177
+
178
+ if (rawItems.length === 0) {
179
+ return { items: [], adjustedItemTotal: subtotalMajor }
180
+ }
181
+
182
+ // Step 3: Sum of (unit_amount × quantity) after rounding
183
+ const roundedItemSum = rawItems.reduce(
184
+ (sum, item) => sum + item.unitAmount * item.quantity,
185
+ 0
186
+ )
187
+ const roundedItemSumFixed = parseFloat(roundedItemSum.toFixed(exponent))
188
+
189
+ // Step 4: Calculate rounding difference
190
+ // diff = how much to add as an offset item so that:
191
+ // roundedItemSumFixed + diff === subtotalMajor
192
+ const diff = parseFloat((subtotalMajor - roundedItemSumFixed).toFixed(exponent))
193
+
194
+ const finalItems = rawItems.map((item) => item.paypalItem)
195
+
196
+ if (Math.abs(diff) > 0.000001) {
197
+ // Insert a tiny offset item to absorb the rounding gap.
198
+ // After this: sum(finalItems unit_amount × quantity) === subtotalMajor exactly.
199
+ finalItems.push({
200
+ name: "Line Item Amount Offset",
201
+ quantity: "1",
202
+ unit_amount: {
203
+ currency_code: currency,
204
+ value: diff.toFixed(exponent),
205
+ },
206
+ })
207
+ // NOTE: adjustedItemTotal stays as subtotalMajor — do NOT add diff here.
208
+ // The offset item brings the items sum UP to subtotalMajor.
209
+ // Adding diff to adjustedItemTotal would cause a double-count.
210
+ }
211
+
212
+ return { items: finalItems, adjustedItemTotal: subtotalMajor }
213
+ }
214
+
104
215
  export async function POST(req: MedusaRequest, res: MedusaResponse) {
105
216
  const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
106
217
  let debugId: string | null = null
@@ -119,9 +230,12 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
119
230
  return res.json({ id: existingOrderId })
120
231
  }
121
232
 
122
- /**
123
- * Medusa v2 cart retrieval via Query Graph
124
- */
233
+ // -------------------------------------------------------------------------
234
+ // Fetch cart via Query Graph
235
+ // All monetary fields returned by Medusa are in MAJOR units (e.g. euros)
236
+ // EXCEPT item-level fields (item.unit_price, item.subtotal, item.total)
237
+ // which are in MINOR units (cents). This is the root cause of the bug.
238
+ // -------------------------------------------------------------------------
125
239
  const query = req.scope.resolve("query")
126
240
 
127
241
  const { data } = await query.graph({
@@ -175,10 +289,11 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
175
289
  : "when_required"
176
290
 
177
291
  const threeDsMethod: string | null = isCardPayment
178
- ? (threeDsRaw === "always"
179
- ? "SCA_ALWAYS"
180
- : "SCA_WHEN_REQUIRED")
292
+ ? threeDsRaw === "always"
293
+ ? "SCA_ALWAYS"
294
+ : "SCA_WHEN_REQUIRED"
181
295
  : null
296
+
182
297
  const configuredCurrency =
183
298
  typeof apiDetails.currency_code === "string"
184
299
  ? normalizeCurrencyCode(apiDetails.currency_code)
@@ -193,7 +308,18 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
193
308
  })
194
309
 
195
310
  const exponent = getCurrencyExponent(currency)
311
+
312
+ // -------------------------------------------------------------------------
313
+ // Cart-level totals — these are already in MAJOR units (euros/dollars)
314
+ // e.g. cart.total = 20 means €20.00
315
+ // -------------------------------------------------------------------------
196
316
  const totalMajor = Number(cart.total || 0)
317
+ const subtotalMajor = Number(cart.subtotal || 0)
318
+ const shippingMajor = Number(cart.shipping_total || 0)
319
+ const taxMajor = Number(cart.tax_total || 0)
320
+ const discountMajor = Number(cart.discount_total || 0)
321
+ const giftCardMajor = Number(cart.gift_card_total || 0)
322
+
197
323
  const value = totalMajor.toFixed(exponent)
198
324
 
199
325
  const paymentActionRaw =
@@ -201,6 +327,7 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
201
327
  ? additionalSettings.paymentAction
202
328
  : "capture"
203
329
  const paymentAction = paymentActionRaw === "authorize" ? "AUTHORIZE" : "CAPTURE"
330
+
204
331
  const brandName =
205
332
  typeof additionalSettings.brandName === "string"
206
333
  ? additionalSettings.brandName
@@ -231,14 +358,15 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
231
358
  ? additionalSettings.invoicePrefix
232
359
  : ""
233
360
  const invoiceId = `${invoicePrefix}${cart.id}`.trim() || cart.id
361
+
234
362
  const returnUrl =
235
- (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
363
+ typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
236
364
  ? `${apiDetails.storefront_url.replace(/\/$/, "")}/checkout`
237
- : resolveReturnUrl(req))
365
+ : resolveReturnUrl(req)
238
366
  const cancelUrl =
239
- (typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
367
+ typeof apiDetails.storefront_url === "string" && apiDetails.storefront_url.trim()
240
368
  ? `${apiDetails.storefront_url.replace(/\/$/, "")}/cart`
241
- : resolveCancelUrl(req))
369
+ : resolveCancelUrl(req)
242
370
 
243
371
  const applicationContext: Record<string, any> = {
244
372
  ...(brandName ? { brand_name: brandName } : {}),
@@ -248,63 +376,26 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
248
376
  ...(cancelUrl ? { cancel_url: cancelUrl } : {}),
249
377
  }
250
378
 
251
- const subtotalMajor = Number(cart.subtotal || 0)
252
- const shippingMajor = Number(cart.shipping_total || 0)
253
- const taxMajor = Number(cart.tax_total || 0)
254
- const discountMajor = Number(cart.discount_total || 0)
255
- const giftCardMajor = Number(cart.gift_card_total || 0)
379
+ // -------------------------------------------------------------------------
380
+ // Build line items with correct minor→major conversion and reconciliation.
381
+ // See buildPayPalLineItems() above for full explanation.
382
+ // -------------------------------------------------------------------------
256
383
  const lineItems = Array.isArray((cart as any).items) ? (cart as any).items : []
257
- const purchaseItemsRaw = sendItemDetails
258
- ? lineItems
259
- .map((item: any) => {
260
- const quantity = Number(item?.quantity || 0)
261
- const lineSubtotal = Number(item?.subtotal ?? (Number(item?.unit_price || 0) * quantity))
262
- const unitAmount =
263
- quantity > 0 ? parseFloat((lineSubtotal / quantity).toFixed(exponent)) : 0
264
-
265
- if (!quantity || Number.isNaN(quantity) || Number.isNaN(unitAmount)) {
266
- return null
267
- }
268
384
 
269
- return {
270
- quantity,
271
- unitAmount,
272
- paypalItem: {
273
- name: String(item?.title || "Item").slice(0, 127),
274
- quantity: String(Math.max(1, quantity)),
275
- unit_amount: {
276
- currency_code: currency,
277
- value: unitAmount.toFixed(exponent),
278
- },
279
- },
280
- }
281
- })
282
- .filter(Boolean)
283
- : []
284
-
285
- const roundedItemSum = purchaseItemsRaw.reduce(
286
- (sum: number, item: any) => sum + item.unitAmount * item.quantity,
287
- 0
385
+ const { items: finalPurchaseItems, adjustedItemTotal } = buildPayPalLineItems(
386
+ lineItems,
387
+ subtotalMajor,
388
+ currency,
389
+ exponent,
390
+ sendItemDetails
288
391
  )
289
- const roundedItemSumFixed = parseFloat(roundedItemSum.toFixed(exponent))
290
- const diff = parseFloat((subtotalMajor - roundedItemSumFixed).toFixed(exponent))
291
-
292
- const finalPurchaseItems = purchaseItemsRaw.map((item: any) => item.paypalItem)
293
- let adjustedItemTotal = subtotalMajor
294
-
295
- if (Math.abs(diff) > 0.000001 && sendItemDetails && finalPurchaseItems.length > 0) {
296
- finalPurchaseItems.push({
297
- name: "Line Item Amount Offset",
298
- quantity: "1",
299
- unit_amount: {
300
- currency_code: currency,
301
- value: diff.toFixed(exponent),
302
- },
303
- })
304
- adjustedItemTotal = parseFloat((subtotalMajor + diff).toFixed(exponent))
305
- }
306
392
 
393
+ // -------------------------------------------------------------------------
394
+ // Build the breakdown object.
395
+ // PayPal rule: item_total + shipping + tax_total - discount - shipping_discount === value
396
+ // -------------------------------------------------------------------------
307
397
  const breakdown: Record<string, any> = {}
398
+
308
399
  if (adjustedItemTotal > 0) {
309
400
  breakdown.item_total = {
310
401
  currency_code: currency,
@@ -324,6 +415,8 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
324
415
  }
325
416
  }
326
417
 
418
+ // Discounts and gift cards — only include if we are also sending items,
419
+ // otherwise PayPal rejects breakdown with discount but no items.
327
420
  const discountValue = discountMajor + giftCardMajor
328
421
  if (discountValue > 0 && finalPurchaseItems.length > 0) {
329
422
  breakdown.discount = {
@@ -332,6 +425,12 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
332
425
  }
333
426
  }
334
427
 
428
+ // -------------------------------------------------------------------------
429
+ // Final reconciliation: ensure breakdown sums exactly to cart total.
430
+ // If there is a gap (can happen due to rounding across multiple fields),
431
+ // absorb it via shipping_discount (if we over-counted) or tax_total
432
+ // (if we under-counted). This is exactly what WooCommerce does.
433
+ // -------------------------------------------------------------------------
335
434
  const breakdownSum = parseFloat(
336
435
  (adjustedItemTotal + shippingMajor + taxMajor - discountValue).toFixed(exponent)
337
436
  )
@@ -340,13 +439,14 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
340
439
  const gap = parseFloat((totalMajor - breakdownSum).toFixed(exponent))
341
440
 
342
441
  if (gap > 0) {
442
+ // We under-counted — add the gap to tax_total
443
+ const existingTax = Number(breakdown.tax_total?.value || 0)
343
444
  breakdown.tax_total = {
344
445
  currency_code: currency,
345
- value: parseFloat(
346
- ((Number(breakdown.tax_total?.value || 0) + gap).toFixed(exponent))
347
- ).toFixed(exponent),
446
+ value: parseFloat((existingTax + gap).toFixed(exponent)).toFixed(exponent),
348
447
  }
349
448
  } else {
449
+ // We over-counted — add shipping_discount to bring total down
350
450
  breakdown.shipping_discount = {
351
451
  currency_code: currency,
352
452
  value: Math.abs(gap).toFixed(exponent),
@@ -362,6 +462,14 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
362
462
 
363
463
  const requestId = resolveIdempotencyKey(req, "create-order", `pp-create-${cart.id}`)
364
464
 
465
+ // Log what we are sending to PayPal for debugging
466
+ console.info("[PayPal] create-order payload", {
467
+ cart_id: cart.id,
468
+ value,
469
+ breakdown,
470
+ item_count: finalPurchaseItems.length,
471
+ })
472
+
365
473
  const ppResp = await fetch(`${base}/v2/checkout/orders`, {
366
474
  method: "POST",
367
475
  headers: {
@@ -418,7 +526,7 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
418
526
 
419
527
  await attachPayPalOrderToSession(req, cart.id, order.id)
420
528
 
421
- console.info("[PayPal] create-order", {
529
+ console.info("[PayPal] create-order success", {
422
530
  cart_id: cart.id,
423
531
  order_id: order.id,
424
532
  request_id: requestId,
@@ -450,4 +558,4 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
450
558
  : 500
451
559
  return res.status(status).json({ message })
452
560
  }
453
- }
561
+ }