@easypayment/medusa-paypal 0.5.7 → 0.5.9
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 +14 -21
- package/.medusa/server/src/admin/index.mjs +14 -21
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.js +5 -1
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/service.d.ts +33 -0
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/service.js +229 -46
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/package.json +1 -1
- package/src/admin/routes/settings/paypal/connection/page.tsx +747 -754
- package/src/api/admin/paypal/save-credentials/route.ts +22 -14
- package/src/modules/paypal/service.ts +279 -48
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
|
|
2
|
-
import type PayPalModuleService from "../../../../modules/paypal/service"
|
|
3
|
-
|
|
4
|
-
export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
5
|
-
const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
|
|
6
|
-
const body = req.body as {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
1
|
+
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
|
|
2
|
+
import type PayPalModuleService from "../../../../modules/paypal/service"
|
|
3
|
+
|
|
4
|
+
export async function POST(req: MedusaRequest, res: MedusaResponse) {
|
|
5
|
+
const paypal = req.scope.resolve<PayPalModuleService>("paypal_onboarding")
|
|
6
|
+
const body = req.body as {
|
|
7
|
+
clientId?: string
|
|
8
|
+
clientSecret?: string
|
|
9
|
+
environment?: "sandbox" | "live"
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (!body?.clientId || !body?.clientSecret) {
|
|
13
|
+
return res.status(400).json({ message: "Missing clientId/clientSecret" })
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
await paypal.saveAndHydrateSellerCredentials({
|
|
17
|
+
clientId: body.clientId,
|
|
18
|
+
clientSecret: body.clientSecret,
|
|
19
|
+
environment: body.environment,
|
|
20
|
+
})
|
|
21
|
+
return res.json({ ok: true })
|
|
22
|
+
}
|
|
@@ -185,7 +185,13 @@ class PayPalModuleService extends MedusaService({
|
|
|
185
185
|
return {
|
|
186
186
|
clientId: creds.client_id || creds.clientId || undefined,
|
|
187
187
|
clientSecret: creds.client_secret || creds.clientSecret || undefined,
|
|
188
|
-
sellerMerchantId:
|
|
188
|
+
sellerMerchantId:
|
|
189
|
+
creds.seller_merchant_id ||
|
|
190
|
+
creds.sellerMerchantId ||
|
|
191
|
+
creds.payer_id ||
|
|
192
|
+
creds.merchant_id ||
|
|
193
|
+
creds.merchantId ||
|
|
194
|
+
undefined,
|
|
189
195
|
sellerEmail: creds.seller_email || creds.sellerEmail || undefined,
|
|
190
196
|
}
|
|
191
197
|
}
|
|
@@ -221,15 +227,23 @@ class PayPalModuleService extends MedusaService({
|
|
|
221
227
|
obj.email_address,
|
|
222
228
|
obj.account_email,
|
|
223
229
|
obj.contact_email,
|
|
230
|
+
obj.value,
|
|
231
|
+
obj.address,
|
|
224
232
|
]
|
|
225
233
|
queue.push(...prioritized)
|
|
226
234
|
|
|
227
235
|
for (const [k, v] of Object.entries(obj)) {
|
|
228
236
|
const key = String(k).toLowerCase()
|
|
229
|
-
if (key.includes("email")) {
|
|
237
|
+
if (key.includes("email") || key.includes("address")) {
|
|
230
238
|
queue.push(v)
|
|
231
239
|
}
|
|
232
240
|
}
|
|
241
|
+
|
|
242
|
+
// Fallback: traverse nested values so shapes like
|
|
243
|
+
// { email_address: { value: "seller@example.com" } }
|
|
244
|
+
// or { email: { address: "seller@example.com" } }
|
|
245
|
+
// are still detected.
|
|
246
|
+
queue.push(...Object.values(obj))
|
|
233
247
|
}
|
|
234
248
|
}
|
|
235
249
|
|
|
@@ -281,6 +295,155 @@ class PayPalModuleService extends MedusaService({
|
|
|
281
295
|
return json
|
|
282
296
|
}
|
|
283
297
|
|
|
298
|
+
private async getAppAccessTokenForCredentials(
|
|
299
|
+
env: Environment,
|
|
300
|
+
credentials: { clientId: string; clientSecret: string }
|
|
301
|
+
) {
|
|
302
|
+
const baseUrl = env === "live" ? "https://api-m.paypal.com" : "https://api-m.sandbox.paypal.com"
|
|
303
|
+
const basic = Buffer.from(`${credentials.clientId}:${credentials.clientSecret}`).toString("base64")
|
|
304
|
+
|
|
305
|
+
const body = new URLSearchParams()
|
|
306
|
+
body.set("grant_type", "client_credentials")
|
|
307
|
+
|
|
308
|
+
const res = await fetch(`${baseUrl}/v1/oauth2/token`, {
|
|
309
|
+
method: "POST",
|
|
310
|
+
headers: {
|
|
311
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
312
|
+
Authorization: `Basic ${basic}`,
|
|
313
|
+
},
|
|
314
|
+
body,
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
const text = await res.text().catch(() => "")
|
|
318
|
+
let json: any = {}
|
|
319
|
+
try {
|
|
320
|
+
json = text ? JSON.parse(text) : {}
|
|
321
|
+
} catch (e: any) {
|
|
322
|
+
console.warn("[PayPal] Failed to parse app token response JSON:", e?.message)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (!res.ok) {
|
|
326
|
+
throw new Error(`PayPal client_credentials failed (${res.status}): ${text || JSON.stringify(json)}`)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const accessToken = String(json.access_token || "")
|
|
330
|
+
if (!accessToken) {
|
|
331
|
+
throw new Error("PayPal client_credentials succeeded but access_token is missing.")
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return { accessToken, tokenPayload: json }
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private async fetchSellerProfileFromDirectCredentials(
|
|
338
|
+
env: Environment,
|
|
339
|
+
credentials?: { clientId: string; clientSecret: string }
|
|
340
|
+
): Promise<{ sellerMerchantId: string | null; sellerEmail: string | null }> {
|
|
341
|
+
const baseUrl = env === "live" ? "https://api-m.paypal.com" : "https://api-m.sandbox.paypal.com"
|
|
342
|
+
const partnerMerchantId = await this.getPartnerMerchantId(env)
|
|
343
|
+
let tokenPayload: Record<string, any> | null = null
|
|
344
|
+
|
|
345
|
+
let accessToken = ""
|
|
346
|
+
if (credentials) {
|
|
347
|
+
const tokenResp = await this.getAppAccessTokenForCredentials(env, {
|
|
348
|
+
clientId: credentials.clientId,
|
|
349
|
+
clientSecret: credentials.clientSecret,
|
|
350
|
+
})
|
|
351
|
+
accessToken = tokenResp.accessToken
|
|
352
|
+
tokenPayload = tokenResp.tokenPayload
|
|
353
|
+
} else {
|
|
354
|
+
accessToken = await this.getAppAccessToken()
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
let sellerEmail = this.extractSellerEmail(tokenPayload || undefined)
|
|
358
|
+
let sellerMerchantId = String(
|
|
359
|
+
tokenPayload?.merchant_id || tokenPayload?.payer_id || tokenPayload?.account_id || ""
|
|
360
|
+
).trim() || null
|
|
361
|
+
|
|
362
|
+
try {
|
|
363
|
+
const userInfoResp = await fetch(`${baseUrl}/v1/identity/oauth2/userinfo?schema=paypalv1`, {
|
|
364
|
+
method: "GET",
|
|
365
|
+
headers: {
|
|
366
|
+
Authorization: `Bearer ${accessToken}`,
|
|
367
|
+
"Content-Type": "application/json",
|
|
368
|
+
Accept: "application/json",
|
|
369
|
+
},
|
|
370
|
+
})
|
|
371
|
+
if (userInfoResp.ok) {
|
|
372
|
+
const userInfo = await userInfoResp.json().catch(() => ({}))
|
|
373
|
+
sellerEmail = sellerEmail || this.extractSellerEmail(userInfo)
|
|
374
|
+
sellerMerchantId =
|
|
375
|
+
sellerMerchantId ||
|
|
376
|
+
String(userInfo?.merchant_id || userInfo?.payer_id || userInfo?.user_id || userInfo?.sub || "").trim() ||
|
|
377
|
+
null
|
|
378
|
+
}
|
|
379
|
+
} catch (e: any) {
|
|
380
|
+
console.warn("[PayPal] userinfo lookup failed:", e?.message || e)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (partnerMerchantId) {
|
|
384
|
+
try {
|
|
385
|
+
const credsResp = await fetch(
|
|
386
|
+
`${baseUrl}/v1/customer/partners/${encodeURIComponent(
|
|
387
|
+
partnerMerchantId
|
|
388
|
+
)}/merchant-integrations/credentials/`,
|
|
389
|
+
{
|
|
390
|
+
method: "GET",
|
|
391
|
+
headers: {
|
|
392
|
+
Authorization: `Bearer ${accessToken}`,
|
|
393
|
+
"Content-Type": "application/json",
|
|
394
|
+
},
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
if (credsResp.ok) {
|
|
398
|
+
const credsJson = await credsResp.json().catch(() => ({}))
|
|
399
|
+
sellerEmail = sellerEmail || this.extractSellerEmail(credsJson)
|
|
400
|
+
sellerMerchantId = sellerMerchantId || String(credsJson?.merchant_id || "").trim() || null
|
|
401
|
+
}
|
|
402
|
+
} catch (e: any) {
|
|
403
|
+
console.warn("[PayPal] direct credential profile lookup failed:", e?.message || e)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const hydrated = await this.hydrateSellerMetadataFromCredentials(env, {
|
|
408
|
+
accessToken,
|
|
409
|
+
sellerMerchantId,
|
|
410
|
+
sellerEmail,
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
return {
|
|
414
|
+
sellerMerchantId: hydrated.sellerMerchantId,
|
|
415
|
+
sellerEmail: hydrated.sellerEmail,
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private async hydrateSellerMetadataFromCredentials(
|
|
420
|
+
env: Environment,
|
|
421
|
+
input: {
|
|
422
|
+
accessToken?: string
|
|
423
|
+
sellerMerchantId?: string | null
|
|
424
|
+
sellerEmail?: string | null
|
|
425
|
+
metadataCandidates?: any[]
|
|
426
|
+
}
|
|
427
|
+
): Promise<{ sellerMerchantId: string | null; sellerEmail: string | null }> {
|
|
428
|
+
let sellerMerchantId = (input.sellerMerchantId || "").trim() || null
|
|
429
|
+
let sellerEmail = (input.sellerEmail || "").trim() || null
|
|
430
|
+
|
|
431
|
+
if (!sellerEmail && input.metadataCandidates?.length) {
|
|
432
|
+
sellerEmail = this.extractSellerEmail(...input.metadataCandidates)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (sellerMerchantId && !sellerEmail) {
|
|
436
|
+
try {
|
|
437
|
+
const details = await this.fetchMerchantIntegrationDetails(env, sellerMerchantId, input.accessToken)
|
|
438
|
+
sellerEmail = this.extractSellerEmail(details)
|
|
439
|
+
} catch (e: any) {
|
|
440
|
+
console.warn("[PayPal] merchant integration lookup failed:", e?.message || e)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return { sellerMerchantId, sellerEmail }
|
|
445
|
+
}
|
|
446
|
+
|
|
284
447
|
private async syncRowFieldsFromMetadata(row: any, env: Environment) {
|
|
285
448
|
const c = this.getEnvCreds(row, env)
|
|
286
449
|
await this.updatePayPalConnections({
|
|
@@ -633,8 +796,8 @@ class PayPalModuleService extends MedusaService({
|
|
|
633
796
|
)
|
|
634
797
|
}
|
|
635
798
|
|
|
636
|
-
const clientId = String(credJson.client_id || "")
|
|
637
|
-
const clientSecret = String(credJson.client_secret || "")
|
|
799
|
+
const clientId = String(credJson.client_id || credJson.clientId || "")
|
|
800
|
+
const clientSecret = String(credJson.client_secret || credJson.clientSecret || "")
|
|
638
801
|
if (!clientId || !clientSecret) {
|
|
639
802
|
throw new Error(
|
|
640
803
|
`PayPal credentials response missing client_id/client_secret. Keys: ${Object.keys(credJson || {}).join(", ")}`
|
|
@@ -642,14 +805,17 @@ class PayPalModuleService extends MedusaService({
|
|
|
642
805
|
}
|
|
643
806
|
|
|
644
807
|
let sellerEmail = this.extractSellerEmail(credJson, tokenJson)
|
|
645
|
-
let sellerMerchantId =
|
|
808
|
+
let sellerMerchantId =
|
|
809
|
+
String(credJson.payer_id || credJson.merchant_id || tokenJson.payer_id || tokenJson.merchant_id || "").trim() ||
|
|
810
|
+
null
|
|
646
811
|
|
|
647
812
|
if (!sellerEmail) {
|
|
648
813
|
// Use all available merchant/payer ID candidates from the token and credential responses
|
|
649
814
|
const merchantCandidates = [
|
|
815
|
+
String(credJson.payer_id || "").trim(),
|
|
650
816
|
String(credJson.merchant_id || "").trim(),
|
|
651
|
-
String(tokenJson.merchant_id || "").trim(),
|
|
652
817
|
String(tokenJson.payer_id || "").trim(),
|
|
818
|
+
String(tokenJson.merchant_id || "").trim(),
|
|
653
819
|
].filter(Boolean).filter((v, i, arr) => arr.indexOf(v) === i)
|
|
654
820
|
|
|
655
821
|
for (const merchantId of merchantCandidates) {
|
|
@@ -675,44 +841,19 @@ class PayPalModuleService extends MedusaService({
|
|
|
675
841
|
sellerEmail,
|
|
676
842
|
})
|
|
677
843
|
|
|
678
|
-
// 5) Post-save email lookup via
|
|
679
|
-
//
|
|
680
|
-
//
|
|
681
|
-
|
|
682
|
-
if (!sellerEmail && input.sharedId) {
|
|
844
|
+
// 5) Post-save email lookup via merchant_id.
|
|
845
|
+
// Some partner accounts do not have permission to query by tracking_id,
|
|
846
|
+
// so we only rely on merchant integration detail lookup.
|
|
847
|
+
if (!sellerEmail && sellerMerchantId) {
|
|
683
848
|
try {
|
|
684
849
|
const appAccessToken = await this.getAppAccessToken()
|
|
685
|
-
const
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
{
|
|
689
|
-
method: "GET",
|
|
690
|
-
headers: {
|
|
691
|
-
"Content-Type": "application/json",
|
|
692
|
-
Authorization: `Bearer ${appAccessToken}`,
|
|
693
|
-
...(onboardingCfg.bn_code ? { "PayPal-Partner-Attribution-Id": onboardingCfg.bn_code } : {}),
|
|
694
|
-
},
|
|
695
|
-
}
|
|
696
|
-
)
|
|
697
|
-
if (trackingRes.ok) {
|
|
698
|
-
const trackingJson = await trackingRes.json().catch(() => ({}))
|
|
699
|
-
sellerEmail = this.extractSellerEmail(trackingJson)
|
|
700
|
-
const foundMerchantId = String(trackingJson.merchant_id || "").trim()
|
|
701
|
-
if (foundMerchantId) {
|
|
702
|
-
sellerMerchantId = sellerMerchantId || foundMerchantId
|
|
703
|
-
}
|
|
704
|
-
if (!sellerEmail && foundMerchantId) {
|
|
705
|
-
const details = await this.fetchMerchantIntegrationDetails(env, foundMerchantId, appAccessToken)
|
|
706
|
-
sellerEmail = this.extractSellerEmail(details)
|
|
707
|
-
}
|
|
708
|
-
if (sellerEmail || sellerMerchantId) {
|
|
709
|
-
await this.saveSellerCredentials({ clientId, clientSecret, sellerMerchantId, sellerEmail })
|
|
710
|
-
}
|
|
711
|
-
} else {
|
|
712
|
-
console.warn(`[PayPal] tracking_id lookup failed (${trackingRes.status})`)
|
|
850
|
+
const details = await this.fetchMerchantIntegrationDetails(env, sellerMerchantId, appAccessToken)
|
|
851
|
+
sellerEmail = this.extractSellerEmail(details)
|
|
852
|
+
if (sellerEmail) {
|
|
853
|
+
await this.saveSellerCredentials({ clientId, clientSecret, sellerMerchantId, sellerEmail })
|
|
713
854
|
}
|
|
714
855
|
} catch (e: any) {
|
|
715
|
-
console.warn("[PayPal] Post-save
|
|
856
|
+
console.warn("[PayPal] Post-save merchant_id email lookup failed:", e?.message || e)
|
|
716
857
|
}
|
|
717
858
|
}
|
|
718
859
|
|
|
@@ -724,16 +865,31 @@ class PayPalModuleService extends MedusaService({
|
|
|
724
865
|
clientSecret: string
|
|
725
866
|
sellerMerchantId?: string | null
|
|
726
867
|
sellerEmail?: string | null
|
|
868
|
+
environment?: Environment
|
|
727
869
|
}) {
|
|
728
870
|
const row = await this.getCurrentRow()
|
|
729
|
-
const
|
|
871
|
+
const currentEnv = await this.getCurrentEnvironment()
|
|
872
|
+
const env = (input.environment || currentEnv) as Environment
|
|
730
873
|
|
|
731
874
|
const encryptedSecret = this.maybeEncryptSecret(input.clientSecret)
|
|
875
|
+
const existingCreds = row ? this.getEnvCreds(row, env) : {}
|
|
876
|
+
const nextSellerMerchantId =
|
|
877
|
+
(input.sellerMerchantId || "").trim() || existingCreds.sellerMerchantId || row?.seller_merchant_id || null
|
|
878
|
+
const nextSellerEmail =
|
|
879
|
+
(input.sellerEmail || "").trim() || existingCreds.sellerEmail || row?.seller_email || null
|
|
880
|
+
|
|
732
881
|
const nextCreds = {
|
|
733
882
|
client_id: input.clientId,
|
|
883
|
+
clientId: input.clientId,
|
|
734
884
|
client_secret: encryptedSecret,
|
|
735
|
-
|
|
736
|
-
|
|
885
|
+
clientSecret: encryptedSecret,
|
|
886
|
+
merchantId: nextSellerMerchantId,
|
|
887
|
+
merchant_id: nextSellerMerchantId,
|
|
888
|
+
payer_id: nextSellerMerchantId,
|
|
889
|
+
seller_merchant_id: nextSellerMerchantId,
|
|
890
|
+
sellerMerchantId: nextSellerMerchantId,
|
|
891
|
+
seller_email: nextSellerEmail,
|
|
892
|
+
sellerEmail: nextSellerEmail,
|
|
737
893
|
}
|
|
738
894
|
|
|
739
895
|
if (!row) {
|
|
@@ -742,8 +898,8 @@ class PayPalModuleService extends MedusaService({
|
|
|
742
898
|
status: "connected",
|
|
743
899
|
seller_client_id: input.clientId,
|
|
744
900
|
seller_client_secret: encryptedSecret,
|
|
745
|
-
seller_merchant_id:
|
|
746
|
-
seller_email:
|
|
901
|
+
seller_merchant_id: nextSellerMerchantId,
|
|
902
|
+
seller_email: nextSellerEmail,
|
|
747
903
|
app_access_token: null,
|
|
748
904
|
app_access_token_expires_at: null,
|
|
749
905
|
metadata: {
|
|
@@ -773,8 +929,8 @@ class PayPalModuleService extends MedusaService({
|
|
|
773
929
|
status: "connected",
|
|
774
930
|
seller_client_id: input.clientId,
|
|
775
931
|
seller_client_secret: encryptedSecret,
|
|
776
|
-
seller_merchant_id:
|
|
777
|
-
seller_email:
|
|
932
|
+
seller_merchant_id: nextSellerMerchantId,
|
|
933
|
+
seller_email: nextSellerEmail,
|
|
778
934
|
app_access_token: null,
|
|
779
935
|
app_access_token_expires_at: null,
|
|
780
936
|
metadata: {
|
|
@@ -791,6 +947,46 @@ class PayPalModuleService extends MedusaService({
|
|
|
791
947
|
return updated
|
|
792
948
|
}
|
|
793
949
|
|
|
950
|
+
async saveAndHydrateSellerCredentials(input: {
|
|
951
|
+
clientId: string
|
|
952
|
+
clientSecret: string
|
|
953
|
+
environment?: Environment
|
|
954
|
+
}) {
|
|
955
|
+
const env = (input.environment || (await this.getCurrentEnvironment())) as Environment
|
|
956
|
+
|
|
957
|
+
await this.saveSellerCredentials({
|
|
958
|
+
clientId: input.clientId,
|
|
959
|
+
clientSecret: input.clientSecret,
|
|
960
|
+
environment: env,
|
|
961
|
+
})
|
|
962
|
+
|
|
963
|
+
try {
|
|
964
|
+
const hydrated = await this.fetchSellerProfileFromDirectCredentials(env, {
|
|
965
|
+
clientId: input.clientId,
|
|
966
|
+
clientSecret: input.clientSecret,
|
|
967
|
+
})
|
|
968
|
+
|
|
969
|
+
if (hydrated.sellerEmail || hydrated.sellerMerchantId) {
|
|
970
|
+
await this.saveSellerCredentials({
|
|
971
|
+
clientId: input.clientId,
|
|
972
|
+
clientSecret: input.clientSecret,
|
|
973
|
+
sellerMerchantId: hydrated.sellerMerchantId,
|
|
974
|
+
sellerEmail: hydrated.sellerEmail,
|
|
975
|
+
environment: env,
|
|
976
|
+
})
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
const refreshedRow = await this.getCurrentRow()
|
|
980
|
+
if (refreshedRow) {
|
|
981
|
+
await this.syncRowFieldsFromMetadata(refreshedRow, env)
|
|
982
|
+
}
|
|
983
|
+
} catch (e: any) {
|
|
984
|
+
console.warn("[PayPal] saveAndHydrateSellerCredentials lookup failed:", e?.message || e)
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
return await this.getStatus(env)
|
|
988
|
+
}
|
|
989
|
+
|
|
794
990
|
private async resolveWebhookUrl() {
|
|
795
991
|
const { onboarding } = await this.ensureSettingsDefaults()
|
|
796
992
|
const base = String(onboarding.backend_url || "").replace(/\/$/, "")
|
|
@@ -981,7 +1177,41 @@ class PayPalModuleService extends MedusaService({
|
|
|
981
1177
|
|
|
982
1178
|
const c = this.getEnvCreds(row, env)
|
|
983
1179
|
const hasCreds = !!(c.clientId && c.clientSecret)
|
|
984
|
-
|
|
1180
|
+
let sellerEmail: string | null = c.sellerEmail || row.seller_email || null
|
|
1181
|
+
let sellerMerchantId: string | null = c.sellerMerchantId || row.seller_merchant_id || null
|
|
1182
|
+
let decryptedSecret: string | null = null
|
|
1183
|
+
if (c.clientSecret) {
|
|
1184
|
+
try {
|
|
1185
|
+
decryptedSecret = this.maybeDecryptSecret(c.clientSecret)
|
|
1186
|
+
} catch (e: any) {
|
|
1187
|
+
console.warn("[PayPal] Unable to decrypt seller client secret for status sync:", e?.message || e)
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
if (!sellerEmail && hasCreds) {
|
|
1192
|
+
try {
|
|
1193
|
+
const hydrated = await this.fetchSellerProfileFromDirectCredentials(env)
|
|
1194
|
+
if (hydrated.sellerEmail || hydrated.sellerMerchantId) {
|
|
1195
|
+
await this.saveSellerCredentials({
|
|
1196
|
+
clientId: c.clientId!,
|
|
1197
|
+
clientSecret: decryptedSecret || c.clientSecret!,
|
|
1198
|
+
sellerMerchantId: hydrated.sellerMerchantId || sellerMerchantId,
|
|
1199
|
+
sellerEmail: hydrated.sellerEmail || sellerEmail,
|
|
1200
|
+
environment: env,
|
|
1201
|
+
})
|
|
1202
|
+
|
|
1203
|
+
const refreshedRow = await this.getCurrentRow()
|
|
1204
|
+
if (refreshedRow) {
|
|
1205
|
+
const refreshedCreds = this.getEnvCreds(refreshedRow, env)
|
|
1206
|
+
sellerEmail = refreshedCreds.sellerEmail || refreshedRow.seller_email || sellerEmail
|
|
1207
|
+
sellerMerchantId =
|
|
1208
|
+
refreshedCreds.sellerMerchantId || refreshedRow.seller_merchant_id || sellerMerchantId
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
} catch (e: any) {
|
|
1212
|
+
console.warn("[PayPal] status direct credential lookup failed:", e?.message || e)
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
985
1215
|
|
|
986
1216
|
return {
|
|
987
1217
|
environment: env,
|
|
@@ -991,6 +1221,7 @@ class PayPalModuleService extends MedusaService({
|
|
|
991
1221
|
seller_client_id_present: hasCreds,
|
|
992
1222
|
seller_client_id_masked: this.maskValue(c.clientId),
|
|
993
1223
|
seller_client_secret_masked: c.clientSecret ? "••••••••" : null,
|
|
1224
|
+
seller_merchant_id: sellerMerchantId,
|
|
994
1225
|
seller_email: sellerEmail,
|
|
995
1226
|
updated_at: (row.updated_at as any)?.toISOString?.() ?? null,
|
|
996
1227
|
}
|