@easypayment/medusa-payment-paypal 0.9.4 → 0.9.5
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.d.ts +2 -0
- package/.medusa/server/src/admin/index.d.ts.map +1 -0
- package/.medusa/server/src/admin/index.js +194 -239
- package/.medusa/server/src/admin/index.js.map +1 -0
- package/.medusa/server/src/admin/index.mjs +195 -240
- package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.d.ts +8 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.js +8 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/FieldRow.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.d.ts +8 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.js +8 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/SectionCard.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.js +25 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Tabs.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.d.ts +12 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.js +22 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_components/Toast.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.d.ts +7 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.js +40 -0
- package/.medusa/server/src/admin/routes/settings/paypal/_utils/adminFetch.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.js +76 -0
- package/.medusa/server/src/admin/routes/settings/paypal/additional-settings/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.js +81 -0
- package/.medusa/server/src/admin/routes/settings/paypal/advanced-card-payments/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.js +9 -0
- package/.medusa/server/src/admin/routes/settings/paypal/apple-pay/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts +20 -0
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js +440 -0
- package/.medusa/server/src/admin/routes/settings/paypal/connection/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.js +9 -0
- package/.medusa/server/src/admin/routes/settings/paypal/google-pay/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/page.d.ts +4 -0
- package/.medusa/server/src/admin/routes/settings/paypal/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/page.js +14 -0
- package/.medusa/server/src/admin/routes/settings/paypal/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.js +9 -0
- package/.medusa/server/src/admin/routes/settings/paypal/pay-later-messaging/page.js.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.d.ts +2 -0
- package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.d.ts.map +1 -0
- package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.js +109 -0
- package/.medusa/server/src/admin/routes/settings/paypal/paypal-settings/page.js.map +1 -0
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts +1 -1
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js +24 -9
- package/.medusa/server/src/api/admin/payment-collections/[id]/payment-sessions/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/disconnect/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/disconnect/route.js +10 -3
- package/.medusa/server/src/api/admin/paypal/disconnect/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/environment/route.js +2 -2
- package/.medusa/server/src/api/admin/paypal/environment/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js +3 -2
- package/.medusa/server/src/api/admin/paypal/onboard-complete/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-link/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js +4 -4
- package/.medusa/server/src/api/admin/paypal/onboarding-status/route.js.map +1 -1
- 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 +21 -8
- package/.medusa/server/src/api/admin/paypal/save-credentials/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/settings/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/settings/route.js +34 -4
- package/.medusa/server/src/api/admin/paypal/settings/route.js.map +1 -1
- package/.medusa/server/src/api/admin/paypal/status/route.d.ts.map +1 -1
- package/.medusa/server/src/api/admin/paypal/status/route.js +11 -5
- package/.medusa/server/src/api/admin/paypal/status/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/capture-order/route.js +21 -3
- package/.medusa/server/src/api/store/paypal/capture-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/config/route.js +2 -2
- 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 +13 -9
- package/.medusa/server/src/api/store/paypal/create-order/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/settings/route.js +3 -3
- package/.medusa/server/src/api/store/paypal/settings/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal/webhook/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal/webhook/route.js +10 -3
- package/.medusa/server/src/api/store/paypal/webhook/route.js.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.d.ts.map +1 -1
- package/.medusa/server/src/api/store/paypal-complete/route.js +7 -4
- package/.medusa/server/src/api/store/paypal-complete/route.js.map +1 -1
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js +3 -3
- package/.medusa/server/src/modules/paypal/clients/paypal-seller.client.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.js.map +1 -1
- package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.d.ts +6 -0
- package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.d.ts.map +1 -0
- package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.js +25 -0
- package/.medusa/server/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.js.map +1 -0
- package/.medusa/server/src/modules/paypal/models/paypal_connection.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_connection.js +3 -3
- package/.medusa/server/src/modules/paypal/models/paypal_connection.js.map +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_metric.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_metric.js +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_metric.js.map +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.d.ts +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js +1 -1
- package/.medusa/server/src/modules/paypal/models/paypal_webhook_event.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js +95 -76
- package/.medusa/server/src/modules/paypal/payment-provider/card-service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/service.js +39 -89
- package/.medusa/server/src/modules/paypal/payment-provider/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js +7 -0
- package/.medusa/server/src/modules/paypal/payment-provider/webhook-utils.js.map +1 -1
- package/.medusa/server/src/modules/paypal/service.d.ts +10 -8
- package/.medusa/server/src/modules/paypal/service.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/service.js +56 -51
- package/.medusa/server/src/modules/paypal/service.js.map +1 -1
- package/.medusa/server/src/modules/paypal/types/config.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/types/config.js +11 -2
- package/.medusa/server/src/modules/paypal/types/config.js.map +1 -1
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.js +1 -0
- package/.medusa/server/src/modules/paypal/utils/paypal-auth.js.map +1 -1
- package/.medusa/server/src/modules/paypal/webhook-processor.d.ts.map +1 -1
- package/.medusa/server/src/modules/paypal/webhook-processor.js +1 -1
- package/.medusa/server/src/modules/paypal/webhook-processor.js.map +1 -1
- package/.medusa/server/src/subscribers/paypal-order-invoice.js +4 -4
- package/.medusa/server/src/subscribers/paypal-order-invoice.js.map +1 -1
- package/package.json +1 -1
- package/src/admin/index.ts +1 -7
- package/src/admin/routes/settings/paypal/_components/FieldRow.tsx +29 -0
- package/src/admin/routes/settings/paypal/_components/SectionCard.tsx +26 -0
- package/src/admin/routes/settings/paypal/_components/Toast.tsx +4 -3
- package/src/admin/routes/settings/paypal/_utils/adminFetch.ts +32 -0
- package/src/admin/routes/settings/paypal/additional-settings/page.tsx +23 -83
- package/src/admin/routes/settings/paypal/advanced-card-payments/page.tsx +17 -77
- package/src/admin/routes/settings/paypal/connection/page.tsx +86 -45
- package/src/admin/routes/settings/paypal/paypal-settings/page.tsx +23 -101
- package/src/api/admin/payment-collections/[id]/payment-sessions/route.ts +26 -9
- package/src/api/admin/paypal/disconnect/route.ts +9 -3
- package/src/api/admin/paypal/environment/route.ts +2 -2
- package/src/api/admin/paypal/onboard-complete/route.ts +4 -3
- package/src/api/admin/paypal/onboarding-link/route.ts +1 -1
- package/src/api/admin/paypal/onboarding-status/route.ts +5 -5
- package/src/api/admin/paypal/save-credentials/route.ts +24 -9
- package/src/api/admin/paypal/settings/route.ts +35 -4
- package/src/api/admin/paypal/status/route.ts +10 -5
- package/src/api/store/paypal/capture-order/route.ts +27 -3
- package/src/api/store/paypal/config/route.ts +2 -2
- package/src/api/store/paypal/create-order/route.ts +16 -10
- package/src/api/store/paypal/settings/route.ts +3 -3
- package/src/api/store/paypal/webhook/route.ts +13 -3
- package/src/api/store/paypal-complete/route.ts +8 -4
- package/src/modules/paypal/clients/paypal-seller.client.ts +3 -3
- package/src/modules/paypal/migrations/20270101090000_set_paypal_environment_default_live.ts +1 -1
- package/src/modules/paypal/migrations/20270102090000_add_paypal_seller_email.ts +1 -1
- package/src/modules/paypal/migrations/20270103090000_add_paypal_seller_merchant_id.ts +1 -1
- package/src/modules/paypal/migrations/20270202000000_align_nullable_defaults.ts +44 -0
- package/src/modules/paypal/models/paypal_connection.ts +3 -3
- package/src/modules/paypal/models/paypal_metric.ts +1 -1
- package/src/modules/paypal/models/paypal_webhook_event.ts +1 -1
- package/src/modules/paypal/payment-provider/card-service.ts +120 -80
- package/src/modules/paypal/payment-provider/service.ts +44 -93
- package/src/modules/paypal/payment-provider/webhook-utils.ts +9 -0
- package/src/modules/paypal/service.ts +79 -66
- package/src/modules/paypal/types/config.ts +18 -2
- package/src/modules/paypal/utils/paypal-auth.ts +1 -0
- package/src/modules/paypal/webhook-processor.ts +8 -5
- package/src/subscribers/paypal-order-invoice.ts +4 -4
|
@@ -30,7 +30,7 @@ export class PayPalSellerClient {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
async getOrder(orderId: string) {
|
|
33
|
-
const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${orderId}`, {
|
|
33
|
+
const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${encodeURIComponent(orderId)}`, {
|
|
34
34
|
method: "GET",
|
|
35
35
|
headers: this.headers(),
|
|
36
36
|
})
|
|
@@ -40,7 +40,7 @@ export class PayPalSellerClient {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
async captureOrder(orderId: string) {
|
|
43
|
-
const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${orderId}/capture`, {
|
|
43
|
+
const res = await fetch(`${this.baseUrl()}/v2/checkout/orders/${encodeURIComponent(orderId)}/capture`, {
|
|
44
44
|
method: "POST",
|
|
45
45
|
headers: this.headers(),
|
|
46
46
|
})
|
|
@@ -50,7 +50,7 @@ export class PayPalSellerClient {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
async refundCapture(captureId: string, body?: any) {
|
|
53
|
-
const res = await fetch(`${this.baseUrl()}/v2/payments/captures/${captureId}/refund`, {
|
|
53
|
+
const res = await fetch(`${this.baseUrl()}/v2/payments/captures/${encodeURIComponent(captureId)}/refund`, {
|
|
54
54
|
method: "POST",
|
|
55
55
|
headers: this.headers(),
|
|
56
56
|
body: body ? JSON.stringify(body) : "{}",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Migration } from "@medusajs/framework/mikro-orm/migrations"
|
|
2
|
+
|
|
3
|
+
export class Migration20270202000000 extends Migration {
|
|
4
|
+
async up(): Promise<void> {
|
|
5
|
+
this.addSql(
|
|
6
|
+
`ALTER TABLE IF EXISTS "paypal_connection" ALTER COLUMN "metadata" DROP NOT NULL;`
|
|
7
|
+
)
|
|
8
|
+
this.addSql(
|
|
9
|
+
`ALTER TABLE IF EXISTS "paypal_webhook_event" ALTER COLUMN "payload" DROP NOT NULL;`
|
|
10
|
+
)
|
|
11
|
+
this.addSql(
|
|
12
|
+
`ALTER TABLE IF EXISTS "paypal_metric" ALTER COLUMN "data" DROP NOT NULL;`
|
|
13
|
+
)
|
|
14
|
+
this.addSql(
|
|
15
|
+
`CREATE INDEX IF NOT EXISTS "idx_paypal_connection_status" ON "paypal_connection" ("status", "created_at" DESC);`
|
|
16
|
+
)
|
|
17
|
+
this.addSql(
|
|
18
|
+
`CREATE INDEX IF NOT EXISTS "idx_paypal_webhook_event_type" ON "paypal_webhook_event" ("event_type");`
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async down(): Promise<void> {
|
|
23
|
+
this.addSql(
|
|
24
|
+
`UPDATE "paypal_connection" SET "metadata" = '{}'::jsonb WHERE "metadata" IS NULL;`
|
|
25
|
+
)
|
|
26
|
+
this.addSql(
|
|
27
|
+
`ALTER TABLE IF EXISTS "paypal_connection" ALTER COLUMN "metadata" SET NOT NULL;`
|
|
28
|
+
)
|
|
29
|
+
this.addSql(
|
|
30
|
+
`UPDATE "paypal_webhook_event" SET "payload" = '{}'::jsonb WHERE "payload" IS NULL;`
|
|
31
|
+
)
|
|
32
|
+
this.addSql(
|
|
33
|
+
`ALTER TABLE IF EXISTS "paypal_webhook_event" ALTER COLUMN "payload" SET NOT NULL;`
|
|
34
|
+
)
|
|
35
|
+
this.addSql(
|
|
36
|
+
`UPDATE "paypal_metric" SET "data" = '{}'::jsonb WHERE "data" IS NULL;`
|
|
37
|
+
)
|
|
38
|
+
this.addSql(
|
|
39
|
+
`ALTER TABLE IF EXISTS "paypal_metric" ALTER COLUMN "data" SET NOT NULL;`
|
|
40
|
+
)
|
|
41
|
+
this.addSql(`DROP INDEX IF EXISTS "idx_paypal_connection_status";`)
|
|
42
|
+
this.addSql(`DROP INDEX IF EXISTS "idx_paypal_webhook_event_type";`)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -3,8 +3,8 @@ import { model } from "@medusajs/framework/utils"
|
|
|
3
3
|
const PayPalConnection = model.define("paypal_connection", {
|
|
4
4
|
id: model.id().primaryKey(),
|
|
5
5
|
|
|
6
|
-
environment: model.text(),
|
|
7
|
-
status: model.text(),
|
|
6
|
+
environment: model.text().default("live"),
|
|
7
|
+
status: model.text().default("disconnected"),
|
|
8
8
|
|
|
9
9
|
shared_id: model.text().nullable(),
|
|
10
10
|
auth_code: model.text().nullable(),
|
|
@@ -17,7 +17,7 @@ const PayPalConnection = model.define("paypal_connection", {
|
|
|
17
17
|
app_access_token: model.text().nullable(),
|
|
18
18
|
app_access_token_expires_at: model.dateTime().nullable(),
|
|
19
19
|
|
|
20
|
-
metadata: model.json().
|
|
20
|
+
metadata: model.json().default({}),
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
export default PayPalConnection
|
|
@@ -3,7 +3,7 @@ import { model } from "@medusajs/framework/utils"
|
|
|
3
3
|
const PayPalMetric = model.define("paypal_metric", {
|
|
4
4
|
id: model.id().primaryKey(),
|
|
5
5
|
name: model.text().unique(),
|
|
6
|
-
data: model.json().
|
|
6
|
+
data: model.json().default({}),
|
|
7
7
|
})
|
|
8
8
|
|
|
9
9
|
export default PayPalMetric
|
|
@@ -13,7 +13,7 @@ const PayPalWebhookEvent = model.define("paypal_webhook_event", {
|
|
|
13
13
|
processed_at: model.dateTime().nullable(),
|
|
14
14
|
last_error: model.text().nullable(),
|
|
15
15
|
resource_id: model.text().nullable(),
|
|
16
|
-
payload: model.json().
|
|
16
|
+
payload: model.json().default({}),
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
export default PayPalWebhookEvent
|
|
@@ -25,7 +25,7 @@ import type {
|
|
|
25
25
|
WebhookActionResult,
|
|
26
26
|
} from "@medusajs/framework/types"
|
|
27
27
|
import { getPayPalWebhookActionAndData } from "./webhook-utils"
|
|
28
|
-
import { formatAmountForPayPal
|
|
28
|
+
import { formatAmountForPayPal } from "../utils/amounts"
|
|
29
29
|
import {
|
|
30
30
|
assertPayPalCurrencySupported,
|
|
31
31
|
normalizeCurrencyCode,
|
|
@@ -68,24 +68,10 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
68
68
|
private async resolveSettings() {
|
|
69
69
|
const paypal = this.resolvePayPalService()
|
|
70
70
|
if (!paypal) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
.query("SELECT data FROM paypal_settings ORDER BY created_at DESC LIMIT 1")
|
|
76
|
-
.finally(() => _sPool.end())
|
|
77
|
-
const _sData = _sResult.rows[0]?.data || {}
|
|
78
|
-
return {
|
|
79
|
-
additionalSettings: (_sData.additional_settings || {}) as Record<string, any>,
|
|
80
|
-
advancedCardSettings: (_sData.advanced_card_payments || {}) as Record<string, any>,
|
|
81
|
-
apiDetails: (_sData.api_details || {}) as Record<string, any>,
|
|
82
|
-
}
|
|
83
|
-
} catch {
|
|
84
|
-
return {
|
|
85
|
-
additionalSettings: {} as Record<string, any>,
|
|
86
|
-
advancedCardSettings: {} as Record<string, any>,
|
|
87
|
-
apiDetails: {} as Record<string, any>,
|
|
88
|
-
}
|
|
71
|
+
return {
|
|
72
|
+
additionalSettings: {} as Record<string, any>,
|
|
73
|
+
advancedCardSettings: {} as Record<string, any>,
|
|
74
|
+
apiDetails: {} as Record<string, any>,
|
|
89
75
|
}
|
|
90
76
|
}
|
|
91
77
|
const settings = await paypal.getSettings().catch(() => ({}))
|
|
@@ -110,60 +96,21 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
110
96
|
|
|
111
97
|
private async getPayPalAccessToken() {
|
|
112
98
|
const paypal = this.resolvePayPalService()
|
|
113
|
-
let client_id: string
|
|
114
|
-
let client_secret: string
|
|
115
|
-
let environment: string
|
|
116
|
-
|
|
117
99
|
if (!paypal) {
|
|
118
|
-
|
|
119
|
-
const _fbPool = new _FbPool({ connectionString: process.env.DATABASE_URL })
|
|
120
|
-
const _fbResult = await _fbPool
|
|
121
|
-
.query(
|
|
122
|
-
"SELECT metadata, environment, seller_client_id, seller_client_secret FROM paypal_connection WHERE status='connected' ORDER BY created_at DESC LIMIT 1"
|
|
123
|
-
)
|
|
124
|
-
.finally(() => _fbPool.end())
|
|
125
|
-
const _fbRow = _fbResult.rows[0]
|
|
126
|
-
if (!_fbRow) throw new Error("No active PayPal connection found in DB")
|
|
127
|
-
environment = _fbRow.environment || "sandbox"
|
|
128
|
-
const _fbCreds = (_fbRow.metadata?.credentials?.[environment]) || {}
|
|
129
|
-
client_id = _fbCreds.client_id || _fbRow.seller_client_id
|
|
130
|
-
client_secret = _fbCreds.client_secret || _fbRow.seller_client_secret
|
|
131
|
-
console.info("[PayPal Card] getPayPalAccessToken fallback via DB for env:", environment)
|
|
132
|
-
} else {
|
|
133
|
-
const creds = await paypal.getActiveCredentials()
|
|
134
|
-
client_id = creds.client_id
|
|
135
|
-
client_secret = creds.client_secret
|
|
136
|
-
environment = creds.environment
|
|
100
|
+
throw new Error("PayPal service is not available. Cannot obtain access token without a valid PayPal connection.")
|
|
137
101
|
}
|
|
138
|
-
|
|
102
|
+
const creds = await paypal.getActiveCredentials()
|
|
139
103
|
const base =
|
|
140
|
-
environment === "live"
|
|
104
|
+
creds.environment === "live"
|
|
141
105
|
? "https://api-m.paypal.com"
|
|
142
106
|
: "https://api-m.sandbox.paypal.com"
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
const resp = await fetch(`${base}/v1/oauth2/token`, {
|
|
146
|
-
method: "POST",
|
|
147
|
-
headers: {
|
|
148
|
-
Authorization: `Basic ${auth}`,
|
|
149
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
150
|
-
"PayPal-Partner-Attribution-Id": BN_CODE,
|
|
151
|
-
},
|
|
152
|
-
body: "grant_type=client_credentials",
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
const text = await resp.text()
|
|
156
|
-
if (!resp.ok) {
|
|
157
|
-
throw new Error(`PayPal token error (${resp.status}): ${text}`)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const json = JSON.parse(text)
|
|
161
|
-
return { accessToken: String(json.access_token), base }
|
|
107
|
+
const accessToken = await paypal.getAppAccessToken()
|
|
108
|
+
return { accessToken, base }
|
|
162
109
|
}
|
|
163
110
|
|
|
164
111
|
private async getOrderDetails(orderId: string) {
|
|
165
112
|
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
166
|
-
const resp = await fetch(`${base}/v2/checkout/orders/${orderId}`, {
|
|
113
|
+
const resp = await fetch(`${base}/v2/checkout/orders/${encodeURIComponent(orderId)}`, {
|
|
167
114
|
method: "GET",
|
|
168
115
|
headers: {
|
|
169
116
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -422,7 +369,7 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
422
369
|
if (existingAuthorization) {
|
|
423
370
|
authorization = order
|
|
424
371
|
} else {
|
|
425
|
-
const authorizeResp = await fetch(`${base}/v2/checkout/orders/${orderId}/authorize`, {
|
|
372
|
+
const authorizeResp = await fetch(`${base}/v2/checkout/orders/${encodeURIComponent(orderId)}/authorize`, {
|
|
426
373
|
method: "POST",
|
|
427
374
|
headers: {
|
|
428
375
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -513,7 +460,7 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
513
460
|
order?.intent || paypalData.order?.intent || data.intent || ""
|
|
514
461
|
).toUpperCase()
|
|
515
462
|
if (!authorizationId && resolvedIntent === "AUTHORIZE") {
|
|
516
|
-
const authorizeResp = await fetch(`${base}/v2/checkout/orders/${orderId}/authorize`, {
|
|
463
|
+
const authorizeResp = await fetch(`${base}/v2/checkout/orders/${encodeURIComponent(orderId)}/authorize`, {
|
|
517
464
|
method: "POST",
|
|
518
465
|
headers: {
|
|
519
466
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -541,13 +488,12 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
541
488
|
data.is_final_capture ??
|
|
542
489
|
data.final_capture ??
|
|
543
490
|
undefined
|
|
544
|
-
const captureExponent = getCurrencyExponent(currencyCode || "EUR")
|
|
545
491
|
const capturePayload =
|
|
546
492
|
amount > 0
|
|
547
493
|
? {
|
|
548
494
|
amount: {
|
|
549
495
|
currency_code: currencyCode || "EUR",
|
|
550
|
-
value: amount
|
|
496
|
+
value: formatAmountForPayPal(amount, currencyCode || "EUR"),
|
|
551
497
|
},
|
|
552
498
|
...(typeof isFinalCapture === "boolean"
|
|
553
499
|
? { is_final_capture: isFinalCapture }
|
|
@@ -560,8 +506,8 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
560
506
|
}
|
|
561
507
|
|
|
562
508
|
const captureUrl = authorizationId
|
|
563
|
-
? `${base}/v2/payments/authorizations/${authorizationId}/capture`
|
|
564
|
-
: `${base}/v2/checkout/orders/${orderId}/capture`
|
|
509
|
+
? `${base}/v2/payments/authorizations/${encodeURIComponent(authorizationId)}/capture`
|
|
510
|
+
: `${base}/v2/checkout/orders/${encodeURIComponent(orderId)}/capture`
|
|
565
511
|
|
|
566
512
|
const ppResp = await fetch(captureUrl, {
|
|
567
513
|
method: "POST",
|
|
@@ -613,9 +559,108 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
613
559
|
|
|
614
560
|
async cancelPayment(_input: CancelPaymentInput): Promise<CancelPaymentOutput> {
|
|
615
561
|
const data = (_input.data || {}) as Record<string, any>
|
|
562
|
+
const paypalData = (data.paypal || {}) as Record<string, any>
|
|
563
|
+
const orderId = String(paypalData.order_id || data.order_id || "")
|
|
564
|
+
const captureId = String(paypalData.capture_id || data.capture_id || "")
|
|
565
|
+
const storedAuthorizationId = String(
|
|
566
|
+
paypalData.authorization_id || data.authorization_id || ""
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
const order = orderId ? await this.getOrderDetails(orderId) : null
|
|
570
|
+
const intent = String(order?.intent || "").toUpperCase()
|
|
571
|
+
const authorizationId =
|
|
572
|
+
order?.purchase_units?.[0]?.payments?.authorizations?.[0]?.id ||
|
|
573
|
+
storedAuthorizationId
|
|
574
|
+
|
|
575
|
+
if (intent === "AUTHORIZE" && authorizationId) {
|
|
576
|
+
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
577
|
+
const requestId = this.getIdempotencyKey(_input, `void-${authorizationId}`)
|
|
578
|
+
|
|
579
|
+
const resp = await fetch(
|
|
580
|
+
`${base}/v2/payments/authorizations/${encodeURIComponent(authorizationId)}/void`,
|
|
581
|
+
{
|
|
582
|
+
method: "POST",
|
|
583
|
+
headers: {
|
|
584
|
+
Authorization: `Bearer ${accessToken}`,
|
|
585
|
+
"Content-Type": "application/json",
|
|
586
|
+
"PayPal-Request-Id": requestId,
|
|
587
|
+
"PayPal-Partner-Attribution-Id": BN_CODE,
|
|
588
|
+
},
|
|
589
|
+
}
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
if (!resp.ok) {
|
|
593
|
+
const text = await resp.text()
|
|
594
|
+
const debugId = resp.headers.get("paypal-debug-id")
|
|
595
|
+
throw new Error(
|
|
596
|
+
`PayPal void error (${resp.status}): ${text}${
|
|
597
|
+
debugId ? ` debug_id=${debugId}` : ""
|
|
598
|
+
}`
|
|
599
|
+
)
|
|
600
|
+
}
|
|
601
|
+
} else if (captureId) {
|
|
602
|
+
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
603
|
+
const requestId = this.getIdempotencyKey(_input, `refund-${captureId}`)
|
|
604
|
+
|
|
605
|
+
const resp = await fetch(
|
|
606
|
+
`${base}/v2/payments/captures/${encodeURIComponent(captureId)}/refund`,
|
|
607
|
+
{
|
|
608
|
+
method: "POST",
|
|
609
|
+
headers: {
|
|
610
|
+
Authorization: `Bearer ${accessToken}`,
|
|
611
|
+
"Content-Type": "application/json",
|
|
612
|
+
"PayPal-Request-Id": requestId,
|
|
613
|
+
"PayPal-Partner-Attribution-Id": BN_CODE,
|
|
614
|
+
},
|
|
615
|
+
body: JSON.stringify({}),
|
|
616
|
+
}
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
if (!resp.ok) {
|
|
620
|
+
const text = await resp.text()
|
|
621
|
+
const debugId = resp.headers.get("paypal-debug-id")
|
|
622
|
+
throw new Error(
|
|
623
|
+
`PayPal refund error (${resp.status}): ${text}${
|
|
624
|
+
debugId ? ` debug_id=${debugId}` : ""
|
|
625
|
+
}`
|
|
626
|
+
)
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const refund = await resp.json().catch(() => ({}))
|
|
630
|
+
const existingRefunds = Array.isArray(paypalData.refunds) ? paypalData.refunds : []
|
|
631
|
+
const refundEntry = {
|
|
632
|
+
id: refund?.id,
|
|
633
|
+
status: refund?.status,
|
|
634
|
+
amount: refund?.amount,
|
|
635
|
+
raw: refund,
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return {
|
|
639
|
+
data: {
|
|
640
|
+
...(data || {}),
|
|
641
|
+
paypal: {
|
|
642
|
+
...paypalData,
|
|
643
|
+
order: order || undefined,
|
|
644
|
+
authorization_id: authorizationId || storedAuthorizationId,
|
|
645
|
+
capture_id: captureId || paypalData.capture_id,
|
|
646
|
+
refund_id: refund?.id,
|
|
647
|
+
refund_status: refund?.status,
|
|
648
|
+
refunds: [...existingRefunds, refundEntry],
|
|
649
|
+
},
|
|
650
|
+
canceled_at: new Date().toISOString(),
|
|
651
|
+
},
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
616
655
|
return {
|
|
617
656
|
data: {
|
|
618
657
|
...(data || {}),
|
|
658
|
+
paypal: {
|
|
659
|
+
...paypalData,
|
|
660
|
+
order: order || undefined,
|
|
661
|
+
authorization_id: authorizationId || storedAuthorizationId,
|
|
662
|
+
capture_id: captureId || paypalData.capture_id,
|
|
663
|
+
},
|
|
619
664
|
canceled_at: new Date().toISOString(),
|
|
620
665
|
},
|
|
621
666
|
}
|
|
@@ -626,32 +671,27 @@ class PayPalAdvancedCardProvider extends AbstractPaymentProvider<Options> {
|
|
|
626
671
|
const paypalData = (data.paypal || {}) as Record<string, any>
|
|
627
672
|
const captureId = String(paypalData.capture_id || data.capture_id || "")
|
|
628
673
|
if (!captureId) {
|
|
629
|
-
|
|
630
|
-
data: {
|
|
631
|
-
...(data || {}),
|
|
632
|
-
refunded_at: new Date().toISOString(),
|
|
633
|
-
},
|
|
634
|
-
}
|
|
674
|
+
throw new Error("PayPal capture_id is required to refund payment. No capture found in session data.")
|
|
635
675
|
}
|
|
636
676
|
|
|
637
677
|
const requestId = this.getIdempotencyKey(_input, `refund-${captureId}`)
|
|
638
678
|
const amount = Number(data.amount ?? 0)
|
|
679
|
+
const currencyOverride = await this.resolveCurrencyOverride()
|
|
639
680
|
const currencyCode = normalizeCurrencyCode(
|
|
640
|
-
data.currency_code ||
|
|
681
|
+
data.currency_code || currencyOverride || "EUR"
|
|
641
682
|
)
|
|
642
683
|
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
643
|
-
const refundExponent = getCurrencyExponent(currencyCode)
|
|
644
684
|
const refundPayload: Record<string, any> =
|
|
645
685
|
amount > 0
|
|
646
686
|
? {
|
|
647
687
|
amount: {
|
|
648
688
|
currency_code: currencyCode,
|
|
649
|
-
value: amount
|
|
689
|
+
value: formatAmountForPayPal(amount, currencyCode),
|
|
650
690
|
},
|
|
651
691
|
}
|
|
652
692
|
: {}
|
|
653
693
|
|
|
654
|
-
const resp = await fetch(`${base}/v2/payments/captures/${captureId}/refund`, {
|
|
694
|
+
const resp = await fetch(`${base}/v2/payments/captures/${encodeURIComponent(captureId)}/refund`, {
|
|
655
695
|
method: "POST",
|
|
656
696
|
headers: {
|
|
657
697
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -68,28 +68,15 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
68
68
|
async resolveSettings() {
|
|
69
69
|
const paypal = this.resolvePayPalService()
|
|
70
70
|
if (!paypal) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const _sResult = await _sPool
|
|
75
|
-
.query("SELECT data FROM paypal_settings ORDER BY created_at DESC LIMIT 1")
|
|
76
|
-
.finally(() => _sPool.end())
|
|
77
|
-
const _sData = _sResult.rows[0]?.data || {}
|
|
78
|
-
return {
|
|
79
|
-
additionalSettings: (_sData.additional_settings || {}) as Record<string, unknown>,
|
|
80
|
-
apiDetails: (_sData.api_details || {}) as Record<string, unknown>,
|
|
81
|
-
}
|
|
82
|
-
} catch {
|
|
83
|
-
return {
|
|
84
|
-
additionalSettings: {} as Record<string, unknown>,
|
|
85
|
-
apiDetails: {} as Record<string, unknown>,
|
|
86
|
-
}
|
|
71
|
+
return {
|
|
72
|
+
additionalSettings: {} as Record<string, unknown>,
|
|
73
|
+
apiDetails: {} as Record<string, unknown>,
|
|
87
74
|
}
|
|
88
75
|
}
|
|
89
76
|
const settings = await paypal.getSettings().catch(() => ({}))
|
|
90
77
|
const data =
|
|
91
78
|
settings && typeof settings === "object" && "data" in settings
|
|
92
|
-
? ((settings as
|
|
79
|
+
? ((settings as { data?: Record<string, unknown> }).data ?? {})
|
|
93
80
|
: {}
|
|
94
81
|
return {
|
|
95
82
|
additionalSettings: (data.additional_settings || {}) as Record<string, unknown>,
|
|
@@ -108,66 +95,22 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
108
95
|
private async getPayPalAccessToken() {
|
|
109
96
|
const paypal = this.resolvePayPalService()
|
|
110
97
|
if (!paypal) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.query(
|
|
115
|
-
"SELECT metadata, environment, seller_client_id, seller_client_secret FROM paypal_connection WHERE status='connected' ORDER BY created_at DESC LIMIT 1"
|
|
116
|
-
)
|
|
117
|
-
.finally(() => _fbPool.end())
|
|
118
|
-
const _fbRow = _fbResult.rows[0]
|
|
119
|
-
if (!_fbRow) throw new Error("No active PayPal connection found in DB")
|
|
120
|
-
const _fbEnv = _fbRow.environment || "sandbox"
|
|
121
|
-
const _fbCreds =
|
|
122
|
-
(_fbRow.metadata && _fbRow.metadata.credentials && _fbRow.metadata.credentials[_fbEnv]) || {}
|
|
123
|
-
const _fbId = _fbCreds.client_id || _fbRow.seller_client_id
|
|
124
|
-
const _fbSec = _fbCreds.client_secret || _fbRow.seller_client_secret
|
|
125
|
-
const _fbBase =
|
|
126
|
-
_fbEnv === "live" ? "https://api-m.paypal.com" : "https://api-m.sandbox.paypal.com"
|
|
127
|
-
const _fbAuth = Buffer.from(`${_fbId}:${_fbSec}`).toString("base64")
|
|
128
|
-
const _fbResp = await fetch(`${_fbBase}/v1/oauth2/token`, {
|
|
129
|
-
method: "POST",
|
|
130
|
-
headers: {
|
|
131
|
-
Authorization: `Basic ${_fbAuth}`,
|
|
132
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
133
|
-
"PayPal-Partner-Attribution-Id": BN_CODE,
|
|
134
|
-
},
|
|
135
|
-
body: "grant_type=client_credentials",
|
|
136
|
-
})
|
|
137
|
-
const _fbText = await _fbResp.text()
|
|
138
|
-
if (!_fbResp.ok) throw new Error(`PayPal token error (${_fbResp.status}): ${_fbText}`)
|
|
139
|
-
const _fbJson = JSON.parse(_fbText)
|
|
140
|
-
return { accessToken: String(_fbJson.access_token), base: _fbBase }
|
|
98
|
+
throw new Error(
|
|
99
|
+
"PayPal module service is unavailable. Ensure the paypal module is registered."
|
|
100
|
+
)
|
|
141
101
|
}
|
|
142
102
|
const creds = await paypal.getActiveCredentials()
|
|
143
103
|
const base =
|
|
144
104
|
creds.environment === "live"
|
|
145
105
|
? "https://api-m.paypal.com"
|
|
146
106
|
: "https://api-m.sandbox.paypal.com"
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
const resp = await fetch(`${base}/v1/oauth2/token`, {
|
|
150
|
-
method: "POST",
|
|
151
|
-
headers: {
|
|
152
|
-
Authorization: `Basic ${auth}`,
|
|
153
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
154
|
-
"PayPal-Partner-Attribution-Id": BN_CODE,
|
|
155
|
-
},
|
|
156
|
-
body: "grant_type=client_credentials",
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
const text = await resp.text()
|
|
160
|
-
if (!resp.ok) {
|
|
161
|
-
throw new Error(`PayPal token error (${resp.status}): ${text}`)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const json = JSON.parse(text)
|
|
165
|
-
return { accessToken: String(json.access_token), base }
|
|
107
|
+
const accessToken = await paypal.getAppAccessToken()
|
|
108
|
+
return { accessToken, base }
|
|
166
109
|
}
|
|
167
110
|
|
|
168
111
|
private async getOrderDetails(orderId: string) {
|
|
169
112
|
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
170
|
-
const resp = await fetch(`${base}/v2/checkout/orders/${orderId}`, {
|
|
113
|
+
const resp = await fetch(`${base}/v2/checkout/orders/${encodeURIComponent(orderId)}`, {
|
|
171
114
|
method: "GET",
|
|
172
115
|
headers: {
|
|
173
116
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -488,7 +431,7 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
488
431
|
authorization = order
|
|
489
432
|
} else {
|
|
490
433
|
const authorizeResp = await fetch(
|
|
491
|
-
`${base}/v2/checkout/orders/${newOrderId}/authorize`,
|
|
434
|
+
`${base}/v2/checkout/orders/${encodeURIComponent(newOrderId)}/authorize`,
|
|
492
435
|
{
|
|
493
436
|
method: "POST",
|
|
494
437
|
headers: {
|
|
@@ -671,7 +614,7 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
671
614
|
|
|
672
615
|
if (!authorizationId && resolvedIntent === "AUTHORIZE") {
|
|
673
616
|
const authorizeResp = await fetch(
|
|
674
|
-
`${base}/v2/checkout/orders/${orderId}/authorize`,
|
|
617
|
+
`${base}/v2/checkout/orders/${encodeURIComponent(orderId)}/authorize`,
|
|
675
618
|
{
|
|
676
619
|
method: "POST",
|
|
677
620
|
headers: {
|
|
@@ -701,13 +644,15 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
701
644
|
data.is_final_capture ??
|
|
702
645
|
data.final_capture ??
|
|
703
646
|
undefined
|
|
704
|
-
const
|
|
647
|
+
const captureValue = amount > 0
|
|
648
|
+
? formatAmountForPayPal(amount, currencyCode || "EUR")
|
|
649
|
+
: null
|
|
705
650
|
const capturePayload =
|
|
706
|
-
|
|
651
|
+
captureValue
|
|
707
652
|
? {
|
|
708
653
|
amount: {
|
|
709
654
|
currency_code: currencyCode || "EUR",
|
|
710
|
-
value:
|
|
655
|
+
value: captureValue,
|
|
711
656
|
},
|
|
712
657
|
...(typeof isFinalCapture === "boolean"
|
|
713
658
|
? { is_final_capture: isFinalCapture }
|
|
@@ -720,8 +665,8 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
720
665
|
}
|
|
721
666
|
|
|
722
667
|
const captureUrl = authorizationId
|
|
723
|
-
? `${base}/v2/payments/authorizations/${authorizationId}/capture`
|
|
724
|
-
: `${base}/v2/checkout/orders/${orderId}/capture`
|
|
668
|
+
? `${base}/v2/payments/authorizations/${encodeURIComponent(authorizationId)}/capture`
|
|
669
|
+
: `${base}/v2/checkout/orders/${encodeURIComponent(orderId)}/capture`
|
|
725
670
|
|
|
726
671
|
const ppResp = await fetch(captureUrl, {
|
|
727
672
|
method: "POST",
|
|
@@ -801,12 +746,9 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
801
746
|
paypalData.refund_reason_code || data.refund_reason_code || data.reason_code || ""
|
|
802
747
|
).trim()
|
|
803
748
|
if (!captureId) {
|
|
804
|
-
|
|
805
|
-
data
|
|
806
|
-
|
|
807
|
-
refunded_at: new Date().toISOString(),
|
|
808
|
-
},
|
|
809
|
-
}
|
|
749
|
+
throw new Error(
|
|
750
|
+
"PayPal capture_id is required to refund payment. No capture found in session data."
|
|
751
|
+
)
|
|
810
752
|
}
|
|
811
753
|
|
|
812
754
|
const requestId = this.getIdempotencyKey(input, `refund-${captureId}`)
|
|
@@ -816,11 +758,10 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
816
758
|
data.currency_code || currencyOverride || "EUR"
|
|
817
759
|
)
|
|
818
760
|
|
|
819
|
-
const exponent = currencyCode.toUpperCase() === "JPY" ? 0
|
|
820
|
-
: ["BHD", "JOD", "KWD", "OMR", "TND"].includes(currencyCode.toUpperCase()) ? 3
|
|
821
|
-
: 2
|
|
822
761
|
const refundAmount = Number(input.amount ?? 0)
|
|
823
|
-
const refundValue = refundAmount > 0
|
|
762
|
+
const refundValue = refundAmount > 0
|
|
763
|
+
? formatAmountForPayPal(refundAmount, currencyCode)
|
|
764
|
+
: null
|
|
824
765
|
|
|
825
766
|
let debugId: string | null = null
|
|
826
767
|
|
|
@@ -840,7 +781,7 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
840
781
|
refundPayload.note_to_payer = refundReason
|
|
841
782
|
}
|
|
842
783
|
|
|
843
|
-
const ppResp = await fetch(`${base}/v2/payments/captures/${captureId}/refund`, {
|
|
784
|
+
const ppResp = await fetch(`${base}/v2/payments/captures/${encodeURIComponent(captureId)}/refund`, {
|
|
844
785
|
method: "POST",
|
|
845
786
|
headers: {
|
|
846
787
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -931,7 +872,7 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
931
872
|
const requestId = this.getIdempotencyKey(input, `void-${authorizationId}`)
|
|
932
873
|
|
|
933
874
|
const resp = await fetch(
|
|
934
|
-
`${base}/v2/payments/authorizations/${authorizationId}/void`,
|
|
875
|
+
`${base}/v2/payments/authorizations/${encodeURIComponent(authorizationId)}/void`,
|
|
935
876
|
{
|
|
936
877
|
method: "POST",
|
|
937
878
|
headers: {
|
|
@@ -962,7 +903,7 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
962
903
|
const { accessToken, base } = await this.getPayPalAccessToken()
|
|
963
904
|
const requestId = this.getIdempotencyKey(input, `refund-${captureId}`)
|
|
964
905
|
|
|
965
|
-
const resp = await fetch(`${base}/v2/payments/captures/${captureId}/refund`, {
|
|
906
|
+
const resp = await fetch(`${base}/v2/payments/captures/${encodeURIComponent(captureId)}/refund`, {
|
|
966
907
|
method: "POST",
|
|
967
908
|
headers: {
|
|
968
909
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -991,11 +932,24 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
991
932
|
amount: refund?.amount,
|
|
992
933
|
raw: refund,
|
|
993
934
|
}
|
|
994
|
-
paypalData.refund_id = refund?.id
|
|
995
|
-
paypalData.refund_status = refund?.status
|
|
996
|
-
paypalData.refunds = [...existingRefunds, refundEntry]
|
|
997
935
|
|
|
998
936
|
await this.recordSuccess("cancel_refund_success")
|
|
937
|
+
|
|
938
|
+
return {
|
|
939
|
+
data: {
|
|
940
|
+
...(input.data || {}),
|
|
941
|
+
paypal: {
|
|
942
|
+
...((input.data || {}).paypal as Record<string, unknown>),
|
|
943
|
+
order: order || undefined,
|
|
944
|
+
authorization_id: authorizationId || storedAuthorizationId,
|
|
945
|
+
capture_id: captureId || paypalData.capture_id,
|
|
946
|
+
refund_id: refund?.id,
|
|
947
|
+
refund_status: refund?.status,
|
|
948
|
+
refunds: [...existingRefunds, refundEntry],
|
|
949
|
+
},
|
|
950
|
+
canceled_at: new Date().toISOString(),
|
|
951
|
+
},
|
|
952
|
+
}
|
|
999
953
|
}
|
|
1000
954
|
|
|
1001
955
|
return {
|
|
@@ -1006,9 +960,6 @@ class PayPalPaymentProvider extends AbstractPaymentProvider<Options> {
|
|
|
1006
960
|
order: order || undefined,
|
|
1007
961
|
authorization_id: authorizationId || storedAuthorizationId,
|
|
1008
962
|
capture_id: captureId || paypalData.capture_id,
|
|
1009
|
-
refund_id: paypalData.refund_id,
|
|
1010
|
-
refund_status: paypalData.refund_status,
|
|
1011
|
-
refunds: paypalData.refunds,
|
|
1012
963
|
},
|
|
1013
964
|
canceled_at: new Date().toISOString(),
|
|
1014
965
|
},
|