@easypayment/medusa-paypal 0.4.6 → 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,6 +183,9 @@ function AdditionalSettingsTab() {
183
183
  )
184
184
  ] }) });
185
185
  }
186
+ function PayPalApplePayPage() {
187
+ return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
188
+ }
186
189
  async function adminFetch$1(path, opts = {}) {
187
190
  var _a;
188
191
  const { method = "GET", body, query } = opts;
@@ -322,12 +325,6 @@ function AdvancedCardPaymentsTab() {
322
325
  )
323
326
  ] }) });
324
327
  }
325
- function PayPalGooglePayPage() {
326
- return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "/settings/paypal/connection", replace: true });
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
  }
@@ -1216,22 +1216,22 @@ const routeModule = {
1216
1216
  Component: AdditionalSettingsTab,
1217
1217
  path: "/settings/paypal/additional-settings"
1218
1218
  },
1219
- {
1220
- Component: AdvancedCardPaymentsTab,
1221
- path: "/settings/paypal/advanced-card-payments"
1222
- },
1223
- {
1224
- Component: PayPalGooglePayPage,
1225
- path: "/settings/paypal/google-pay"
1226
- },
1227
1219
  {
1228
1220
  Component: PayPalApplePayPage,
1229
1221
  path: "/settings/paypal/apple-pay"
1230
1222
  },
1223
+ {
1224
+ Component: AdvancedCardPaymentsTab,
1225
+ path: "/settings/paypal/advanced-card-payments"
1226
+ },
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,6 +182,9 @@ function AdditionalSettingsTab() {
182
182
  )
183
183
  ] }) });
184
184
  }
185
+ function PayPalApplePayPage() {
186
+ return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
187
+ }
185
188
  async function adminFetch$1(path, opts = {}) {
186
189
  var _a;
187
190
  const { method = "GET", body, query } = opts;
@@ -321,12 +324,6 @@ function AdvancedCardPaymentsTab() {
321
324
  )
322
325
  ] }) });
323
326
  }
324
- function PayPalGooglePayPage() {
325
- return /* @__PURE__ */ jsx(Navigate, { to: "/settings/paypal/connection", replace: true });
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
  }
@@ -1215,22 +1215,22 @@ const routeModule = {
1215
1215
  Component: AdditionalSettingsTab,
1216
1216
  path: "/settings/paypal/additional-settings"
1217
1217
  },
1218
- {
1219
- Component: AdvancedCardPaymentsTab,
1220
- path: "/settings/paypal/advanced-card-payments"
1221
- },
1222
- {
1223
- Component: PayPalGooglePayPage,
1224
- path: "/settings/paypal/google-pay"
1225
- },
1226
1218
  {
1227
1219
  Component: PayPalApplePayPage,
1228
1220
  path: "/settings/paypal/apple-pay"
1229
1221
  },
1222
+ {
1223
+ Component: AdvancedCardPaymentsTab,
1224
+ path: "/settings/paypal/advanced-card-payments"
1225
+ },
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,2BA4VjE"}
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,51 +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
- }
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
+ // -------------------------------------------------------------------------
238
304
  const breakdown = {};
239
305
  if (adjustedItemTotal > 0) {
240
306
  breakdown.item_total = {
@@ -254,6 +320,8 @@ async function POST(req, res) {
254
320
  value: taxMajor.toFixed(exponent),
255
321
  };
256
322
  }
323
+ // Discounts and gift cards — only include if we are also sending items,
324
+ // otherwise PayPal rejects breakdown with discount but no items.
257
325
  const discountValue = discountMajor + giftCardMajor;
258
326
  if (discountValue > 0 && finalPurchaseItems.length > 0) {
259
327
  breakdown.discount = {
@@ -261,16 +329,25 @@ async function POST(req, res) {
261
329
  value: discountValue.toFixed(exponent),
262
330
  };
263
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
+ // -------------------------------------------------------------------------
264
338
  const breakdownSum = parseFloat((adjustedItemTotal + shippingMajor + taxMajor - discountValue).toFixed(exponent));
265
339
  if (Math.abs(breakdownSum - totalMajor) > 0.000001) {
266
340
  const gap = parseFloat((totalMajor - breakdownSum).toFixed(exponent));
267
341
  if (gap > 0) {
342
+ // We under-counted — add the gap to tax_total
343
+ const existingTax = Number(breakdown.tax_total?.value || 0);
268
344
  breakdown.tax_total = {
269
345
  currency_code: currency,
270
- value: parseFloat(((Number(breakdown.tax_total?.value || 0) + gap).toFixed(exponent))).toFixed(exponent),
346
+ value: parseFloat((existingTax + gap).toFixed(exponent)).toFixed(exponent),
271
347
  };
272
348
  }
273
349
  else {
350
+ // We over-counted — add shipping_discount to bring total down
274
351
  breakdown.shipping_discount = {
275
352
  currency_code: currency,
276
353
  value: Math.abs(gap).toFixed(exponent),
@@ -283,6 +360,13 @@ async function POST(req, res) {
283
360
  client_secret: creds.client_secret,
284
361
  });
285
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
+ });
286
370
  const ppResp = await fetch(`${base}/v2/checkout/orders`, {
287
371
  method: "POST",
288
372
  headers: {
@@ -331,7 +415,7 @@ async function POST(req, res) {
331
415
  }
332
416
  const order = JSON.parse(ppText);
333
417
  await attachPayPalOrderToSession(req, cart.id, order.id);
334
- console.info("[PayPal] create-order", {
418
+ console.info("[PayPal] create-order success", {
335
419
  cart_id: cart.id,
336
420
  order_id: order.id,
337
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.6",
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,62 +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
- }
305
392
 
393
+ // -------------------------------------------------------------------------
394
+ // Build the breakdown object.
395
+ // PayPal rule: item_total + shipping + tax_total - discount - shipping_discount === value
396
+ // -------------------------------------------------------------------------
306
397
  const breakdown: Record<string, any> = {}
398
+
307
399
  if (adjustedItemTotal > 0) {
308
400
  breakdown.item_total = {
309
401
  currency_code: currency,
@@ -323,6 +415,8 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
323
415
  }
324
416
  }
325
417
 
418
+ // Discounts and gift cards — only include if we are also sending items,
419
+ // otherwise PayPal rejects breakdown with discount but no items.
326
420
  const discountValue = discountMajor + giftCardMajor
327
421
  if (discountValue > 0 && finalPurchaseItems.length > 0) {
328
422
  breakdown.discount = {
@@ -331,6 +425,12 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
331
425
  }
332
426
  }
333
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
+ // -------------------------------------------------------------------------
334
434
  const breakdownSum = parseFloat(
335
435
  (adjustedItemTotal + shippingMajor + taxMajor - discountValue).toFixed(exponent)
336
436
  )
@@ -339,13 +439,14 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
339
439
  const gap = parseFloat((totalMajor - breakdownSum).toFixed(exponent))
340
440
 
341
441
  if (gap > 0) {
442
+ // We under-counted — add the gap to tax_total
443
+ const existingTax = Number(breakdown.tax_total?.value || 0)
342
444
  breakdown.tax_total = {
343
445
  currency_code: currency,
344
- value: parseFloat(
345
- ((Number(breakdown.tax_total?.value || 0) + gap).toFixed(exponent))
346
- ).toFixed(exponent),
446
+ value: parseFloat((existingTax + gap).toFixed(exponent)).toFixed(exponent),
347
447
  }
348
448
  } else {
449
+ // We over-counted — add shipping_discount to bring total down
349
450
  breakdown.shipping_discount = {
350
451
  currency_code: currency,
351
452
  value: Math.abs(gap).toFixed(exponent),
@@ -361,6 +462,14 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
361
462
 
362
463
  const requestId = resolveIdempotencyKey(req, "create-order", `pp-create-${cart.id}`)
363
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
+
364
473
  const ppResp = await fetch(`${base}/v2/checkout/orders`, {
365
474
  method: "POST",
366
475
  headers: {
@@ -417,7 +526,7 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
417
526
 
418
527
  await attachPayPalOrderToSession(req, cart.id, order.id)
419
528
 
420
- console.info("[PayPal] create-order", {
529
+ console.info("[PayPal] create-order success", {
421
530
  cart_id: cart.id,
422
531
  order_id: order.id,
423
532
  request_id: requestId,
@@ -449,4 +558,4 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
449
558
  : 500
450
559
  return res.status(status).json({ message })
451
560
  }
452
- }
561
+ }