@easypayment/medusa-paypal 0.4.1 → 0.4.3
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/.medusa/server/src/admin/index.js +54 -135
- package/.medusa/server/src/admin/index.mjs +54 -135
- package/.medusa/server/src/api/admin/paypal/environment/route.js +1 -1
- package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.js +0 -4
- package/.medusa/server/src/api/store/paypal/config/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/create-order/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/create-order/route.js +32 -6
- package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js +14 -0
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js.map +1 -0
- package/.medusa/server/src/modules/paypal/service.d.ts +2 -4
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/service.js +8 -46
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/README.md +130 -102
- package/package.json +1 -1
- package/src/admin/routes/settings/paypal/additional-settings/page.tsx +0 -2
- package/src/admin/routes/settings/paypal/connection/page.tsx +25 -21
- package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +3 -126
- package/src/api/admin/paypal/environment/route.ts +1 -1
- package/src/api/admin/paypal/onboarding-status/route.ts +1 -1
- package/src/api/store/paypal/config/route.ts +0 -4
- package/src/api/store/paypal/create-order/route.ts +34 -7
- package/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.ts +11 -0
- package/src/modules/paypal/service.ts +9 -51
|
@@ -136,6 +136,12 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
|
136
136
|
"gift_card_total",
|
|
137
137
|
"currency_code",
|
|
138
138
|
"region.currency_code",
|
|
139
|
+
"items.title",
|
|
140
|
+
"items.quantity",
|
|
141
|
+
"items.unit_price",
|
|
142
|
+
"items.subtotal",
|
|
143
|
+
"items.tax_total",
|
|
144
|
+
"items.total",
|
|
139
145
|
],
|
|
140
146
|
filters: { id: cartId },
|
|
141
147
|
})
|
|
@@ -211,14 +217,15 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
|
211
217
|
: landingPageRaw === "no_preference"
|
|
212
218
|
? "NO_PREFERENCE"
|
|
213
219
|
: undefined
|
|
214
|
-
const skipReview =
|
|
215
|
-
typeof additionalSettings.skipOrderReviewPage === "boolean"
|
|
216
|
-
? additionalSettings.skipOrderReviewPage
|
|
217
|
-
: undefined
|
|
218
220
|
const requireInstantPayment =
|
|
219
221
|
typeof additionalSettings.requireInstantPayment === "boolean"
|
|
220
222
|
? additionalSettings.requireInstantPayment
|
|
221
223
|
: undefined
|
|
224
|
+
const sendItemDetails = additionalSettings.sendItemDetails !== false
|
|
225
|
+
const statementName =
|
|
226
|
+
typeof additionalSettings.creditCardStatementName === "string"
|
|
227
|
+
? additionalSettings.creditCardStatementName.trim()
|
|
228
|
+
: ""
|
|
222
229
|
const invoicePrefix =
|
|
223
230
|
typeof additionalSettings.invoicePrefix === "string"
|
|
224
231
|
? additionalSettings.invoicePrefix
|
|
@@ -236,9 +243,6 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
|
236
243
|
const applicationContext: Record<string, any> = {
|
|
237
244
|
...(brandName ? { brand_name: brandName } : {}),
|
|
238
245
|
...(landingPage ? { landing_page: landingPage } : {}),
|
|
239
|
-
...(typeof skipReview === "boolean"
|
|
240
|
-
? { user_action: skipReview ? "PAY_NOW" : "CONTINUE" }
|
|
241
|
-
: {}),
|
|
242
246
|
...(requireInstantPayment ? { payment_method_preference: "IMMEDIATE_PAYMENT_REQUIRED" } : {}),
|
|
243
247
|
...(returnUrl ? { return_url: returnUrl } : {}),
|
|
244
248
|
...(cancelUrl ? { cancel_url: cancelUrl } : {}),
|
|
@@ -280,6 +284,27 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
|
280
284
|
}
|
|
281
285
|
}
|
|
282
286
|
|
|
287
|
+
const lineItems = Array.isArray((cart as any).items) ? (cart as any).items : []
|
|
288
|
+
const purchaseItems = sendItemDetails
|
|
289
|
+
? lineItems
|
|
290
|
+
.map((item: any) => {
|
|
291
|
+
const quantity = Number(item?.quantity || 0)
|
|
292
|
+
const unitMinor = Number(item?.unit_price || 0)
|
|
293
|
+
if (!quantity || Number.isNaN(quantity) || Number.isNaN(unitMinor)) {
|
|
294
|
+
return null
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
name: String(item?.title || "Item").slice(0, 127),
|
|
298
|
+
quantity: String(Math.max(1, quantity)),
|
|
299
|
+
unit_amount: {
|
|
300
|
+
currency_code: currency,
|
|
301
|
+
value: formatAmountForPayPal(unitMinor, currency),
|
|
302
|
+
},
|
|
303
|
+
}
|
|
304
|
+
})
|
|
305
|
+
.filter(Boolean)
|
|
306
|
+
: []
|
|
307
|
+
|
|
283
308
|
const { accessToken, base } = await getPayPalAccessToken({
|
|
284
309
|
environment: creds.environment,
|
|
285
310
|
client_id: creds.client_id,
|
|
@@ -301,11 +326,13 @@ export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
|
301
326
|
{
|
|
302
327
|
reference_id: cart.id,
|
|
303
328
|
invoice_id: invoiceId,
|
|
329
|
+
...(statementName ? { soft_descriptor: statementName.slice(0, 22) } : {}),
|
|
304
330
|
amount: {
|
|
305
331
|
currency_code: currency,
|
|
306
332
|
value,
|
|
307
333
|
...(Object.keys(breakdown).length > 0 ? { breakdown } : {}),
|
|
308
334
|
},
|
|
335
|
+
...(purchaseItems.length > 0 ? { items: purchaseItems } : {}),
|
|
309
336
|
},
|
|
310
337
|
],
|
|
311
338
|
...(threeDsMethod
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations"
|
|
2
|
+
|
|
3
|
+
export class Migration20270101090000 extends Migration {
|
|
4
|
+
override async up(): Promise<void> {
|
|
5
|
+
this.addSql(`alter table if exists "paypal_connection" alter column "environment" set default 'live';`)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
override async down(): Promise<void> {
|
|
9
|
+
this.addSql(`alter table if exists "paypal_connection" alter column "environment" set default 'sandbox';`)
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -159,7 +159,7 @@ class PayPalModuleService extends MedusaService({
|
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* We keep a single row in DB and store the currently selected environment there.
|
|
162
|
-
* If no row exists yet, default to
|
|
162
|
+
* If no row exists yet, default to live (production).
|
|
163
163
|
*/
|
|
164
164
|
private async getCurrentRow(): Promise<any | null> {
|
|
165
165
|
const rows = await this.listPayPalConnections({})
|
|
@@ -169,32 +169,25 @@ class PayPalModuleService extends MedusaService({
|
|
|
169
169
|
private async getCurrentEnvironment(): Promise<Environment> {
|
|
170
170
|
try {
|
|
171
171
|
const row = await this.getCurrentRow()
|
|
172
|
-
const env = (row?.environment as Environment) || "
|
|
173
|
-
return env === "
|
|
172
|
+
const env = (row?.environment as Environment) || "live"
|
|
173
|
+
return env === "sandbox" ? "sandbox" : "live"
|
|
174
174
|
} catch {
|
|
175
|
-
return "
|
|
175
|
+
return "live"
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
private getEnvCreds(
|
|
180
180
|
row: any,
|
|
181
181
|
env: Environment
|
|
182
|
-
): { clientId?: string; clientSecret?: string
|
|
182
|
+
): { clientId?: string; clientSecret?: string } {
|
|
183
183
|
const meta = (row?.metadata || {}) as any
|
|
184
184
|
const creds = meta?.credentials?.[env] || {}
|
|
185
185
|
return {
|
|
186
186
|
clientId: creds.client_id || creds.clientId || undefined,
|
|
187
187
|
clientSecret: creds.client_secret || creds.clientSecret || undefined,
|
|
188
|
-
merchantId: creds.merchant_id || creds.merchantId || undefined,
|
|
189
188
|
}
|
|
190
189
|
}
|
|
191
190
|
|
|
192
|
-
private getMerchantId(row: any, env: Environment) {
|
|
193
|
-
const meta = (row?.metadata || {}) as any
|
|
194
|
-
const creds = this.getEnvCreds(row, env)
|
|
195
|
-
return creds.merchantId || meta?.merchant_id || meta?.merchantId || undefined
|
|
196
|
-
}
|
|
197
|
-
|
|
198
191
|
private async fetchMerchantIntegrationDetails(env: Environment, merchantId: string) {
|
|
199
192
|
const partnerMerchantId = await this.getPartnerMerchantId(env)
|
|
200
193
|
if (!partnerMerchantId) {
|
|
@@ -256,9 +249,9 @@ class PayPalModuleService extends MedusaService({
|
|
|
256
249
|
*/
|
|
257
250
|
|
|
258
251
|
async setEnvironment(env: Environment) {
|
|
259
|
-
const nextEnv: Environment = env === "
|
|
252
|
+
const nextEnv: Environment = env === "sandbox" ? "sandbox" : "live"
|
|
260
253
|
const row = await this.getCurrentRow()
|
|
261
|
-
const previousEnv = (row?.environment as Environment) || "
|
|
254
|
+
const previousEnv = (row?.environment as Environment) || "live"
|
|
262
255
|
|
|
263
256
|
if (!row) {
|
|
264
257
|
// Create a row with no credentials yet for either environment
|
|
@@ -586,8 +579,6 @@ class PayPalModuleService extends MedusaService({
|
|
|
586
579
|
|
|
587
580
|
const clientId = String(credJson.client_id || "")
|
|
588
581
|
const clientSecret = String(credJson.client_secret || "")
|
|
589
|
-
const payerId = String(credJson.payer_id || "")
|
|
590
|
-
|
|
591
582
|
if (!clientId || !clientSecret) {
|
|
592
583
|
throw new Error(
|
|
593
584
|
`PayPal credentials response missing client_id/client_secret. Keys: ${Object.keys(credJson || {}).join(", ")}`
|
|
@@ -597,19 +588,6 @@ class PayPalModuleService extends MedusaService({
|
|
|
597
588
|
// 4) Save seller credentials (marks status = connected)
|
|
598
589
|
await this.saveSellerCredentials({ clientId, clientSecret })
|
|
599
590
|
|
|
600
|
-
// 5) Store payer_id as merchant_id in metadata (optional)
|
|
601
|
-
if (payerId) {
|
|
602
|
-
const row = await this.getCurrentRow()
|
|
603
|
-
if (row) {
|
|
604
|
-
const meta = (row.metadata || {}) as any
|
|
605
|
-
const creds = { ...(meta.credentials || {}) }
|
|
606
|
-
creds[env] = { ...(creds[env] || {}), merchant_id: payerId }
|
|
607
|
-
await this.updatePayPalConnections({
|
|
608
|
-
id: row.id,
|
|
609
|
-
metadata: { ...meta, credentials: creds, merchant_id: payerId },
|
|
610
|
-
})
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
591
|
}
|
|
614
592
|
|
|
615
593
|
|
|
@@ -844,7 +822,7 @@ class PayPalModuleService extends MedusaService({
|
|
|
844
822
|
|
|
845
823
|
const updated = await this.getCurrentRow()
|
|
846
824
|
if (updated) {
|
|
847
|
-
await this.syncRowFieldsFromMetadata(updated, (updated.environment as Environment) || "
|
|
825
|
+
await this.syncRowFieldsFromMetadata(updated, (updated.environment as Environment) || "live")
|
|
848
826
|
}
|
|
849
827
|
|
|
850
828
|
await this.recordAuditEvent("credentials_rotated", {
|
|
@@ -864,26 +842,7 @@ class PayPalModuleService extends MedusaService({
|
|
|
864
842
|
|
|
865
843
|
const c = this.getEnvCreds(row, env)
|
|
866
844
|
const hasCreds = !!(c.clientId && c.clientSecret)
|
|
867
|
-
const
|
|
868
|
-
let sellerEmail: string | null = null
|
|
869
|
-
|
|
870
|
-
if (hasCreds && merchantId) {
|
|
871
|
-
try {
|
|
872
|
-
const merchantInfo = await this.fetchMerchantIntegrationDetails(env, merchantId)
|
|
873
|
-
sellerEmail = String(
|
|
874
|
-
merchantInfo?.primary_email ||
|
|
875
|
-
merchantInfo?.merchant_email ||
|
|
876
|
-
merchantInfo?.email ||
|
|
877
|
-
merchantInfo?.primaryEmail ||
|
|
878
|
-
""
|
|
879
|
-
)
|
|
880
|
-
if (!sellerEmail) {
|
|
881
|
-
sellerEmail = null
|
|
882
|
-
}
|
|
883
|
-
} catch (error) {
|
|
884
|
-
console.warn("[paypal_onboarding] failed to fetch merchant integration details", error)
|
|
885
|
-
}
|
|
886
|
-
}
|
|
845
|
+
const sellerEmail: string | null = null
|
|
887
846
|
|
|
888
847
|
return {
|
|
889
848
|
environment: env,
|
|
@@ -1091,7 +1050,6 @@ class PayPalModuleService extends MedusaService({
|
|
|
1091
1050
|
environment: env,
|
|
1092
1051
|
client_id: c.clientId,
|
|
1093
1052
|
client_secret: clientSecret,
|
|
1094
|
-
merchant_id: c.merchantId,
|
|
1095
1053
|
}
|
|
1096
1054
|
}
|
|
1097
1055
|
|