From 7531414855d45da372dcbaf740686d68a5266985 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Thu, 5 Mar 2026 21:40:38 +1100 Subject: [PATCH 1/7] feat(paypal)!: migrate to PayPal JavaScript SDK v6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: PayPal integration now uses SDK v6 (`/web-sdk/v6/core`) instead of v5 (`/sdk/js`). Key changes: - Script URL changed to `https://www.paypal.com/web-sdk/v6/core` - `useScriptPayPal` options simplified to `clientId`, `clientToken`, `sandbox` - v5 query-param options removed (buyerCountry, commit, components, currency, debug, disableFunding, enableFunding, integrationDate, intent, locale, merchantId, partnerAttributionId, vault) - `ScriptPayPalButtons` now exposes SDK v6 instance via scoped slot instead of rendering PayPal buttons directly — use `paypal.createInstance()` + `findEligibleMethods()` + payment sessions - `ScriptPayPalMarks` removed (no v6 equivalent) - `ScriptPayPalMessages` updated for v6 messages API - Types now from `@paypal/paypal-js/sdk-v6` instead of `@paypal/paypal-js` --- docs/content/scripts/paypal.md | 78 ++++---- .../third-parties/paypal/nuxt-scripts.vue | 53 +++-- scripts/generate-registry-types.ts | 1 - .../components/ScriptPayPalButtons.vue | 183 +++++++----------- src/runtime/components/ScriptPayPalMarks.vue | 110 ----------- .../components/ScriptPayPalMessages.vue | 128 ++++++------ src/runtime/registry/paypal.ts | 55 +----- src/runtime/registry/schemas.ts | 77 +------- src/script-meta.ts | 2 +- 9 files changed, 229 insertions(+), 458 deletions(-) delete mode 100644 src/runtime/components/ScriptPayPalMarks.vue diff --git a/docs/content/scripts/paypal.md b/docs/content/scripts/paypal.md index e6249a1f..0c705476 100644 --- a/docs/content/scripts/paypal.md +++ b/docs/content/scripts/paypal.md @@ -11,10 +11,6 @@ links: icon: i-simple-icons-github to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalButtons.vue size: xs - - label: "" - icon: i-simple-icons-github - to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMarks.vue - size: xs - label: "" icon: i-simple-icons-github to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMessages.vue @@ -24,11 +20,10 @@ links: [PayPal](https://www.paypal.com) is a popular payment gateway that allows you to accept payments online. -Nuxt Scripts provides multiple PayPal features: -- `useScriptPayPal` composable which loads the script `https://www.paypal.com/sdk/js`. -- `ScriptPayPalButtons` component that allows you to embed [PayPal Buttons](https://developer.paypal.com/sdk/js/reference/#buttons) on your site. -- `ScriptPayPalMarks` component that allows you to embed [PayPal Marks](https://developer.paypal.com/sdk/js/reference/#marks) on your site. -- `ScriptPayPalMessages` component that allows you to embed [PayPal Messages](https://developer.paypal.com/studio/checkout/pay-later/us/customize/reference) on your site. +Nuxt Scripts provides PayPal SDK v6 integration: +- `useScriptPayPal` composable which loads the script `https://www.paypal.com/web-sdk/v6/core`. +- `ScriptPayPalButtons` component that initializes the PayPal SDK v6 instance and exposes it via a scoped slot. +- `ScriptPayPalMessages` component that allows you to use [PayPal Messages](https://developer.paypal.com/sdk/js/reference/) on your site. ::script-stats :: @@ -38,13 +33,15 @@ Nuxt Scripts provides multiple PayPal features: ## Types -To use the PayPal with full TypeScript support, you will need +To use PayPal with full TypeScript support, you will need to install the `@paypal/paypal-js` dependency. ```bash pnpm add -D @paypal/paypal-js ``` +The v6 types are available from `@paypal/paypal-js/sdk-v6`. + ### Demo ::code-group @@ -55,34 +52,49 @@ pnpm add -D @paypal/paypal-js ``` diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index f299c6fb..64950f06 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -2,31 +2,42 @@
- - - + :components="['paypal-payments']" + page-type="checkout" + @ready="onReady" + > + + +
diff --git a/scripts/generate-registry-types.ts b/scripts/generate-registry-types.ts index a02eef8a..e374302e 100644 --- a/scripts/generate-registry-types.ts +++ b/scripts/generate-registry-types.ts @@ -236,7 +236,6 @@ const componentToSlug: Record = { ScriptLemonSqueezy: 'lemon-squeezy', ScriptStripePricingTable: 'stripe', ScriptPayPalButtons: 'paypal', - ScriptPayPalMarks: 'paypal', ScriptPayPalMessages: 'paypal', } diff --git a/src/runtime/components/ScriptPayPalButtons.vue b/src/runtime/components/ScriptPayPalButtons.vue index 74e642b7..b819a8ae 100644 --- a/src/runtime/components/ScriptPayPalButtons.vue +++ b/src/runtime/components/ScriptPayPalButtons.vue @@ -1,22 +1,16 @@ diff --git a/src/runtime/components/ScriptPayPalMarks.vue b/src/runtime/components/ScriptPayPalMarks.vue deleted file mode 100644 index 5742ddf8..00000000 --- a/src/runtime/components/ScriptPayPalMarks.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - diff --git a/src/runtime/components/ScriptPayPalMessages.vue b/src/runtime/components/ScriptPayPalMessages.vue index 54074184..d79d29e8 100644 --- a/src/runtime/components/ScriptPayPalMessages.vue +++ b/src/runtime/components/ScriptPayPalMessages.vue @@ -1,10 +1,18 @@ diff --git a/src/runtime/components/ScriptPayPalMessages.vue b/src/runtime/components/ScriptPayPalMessages.vue index d79d29e8..4b2dbeb0 100644 --- a/src/runtime/components/ScriptPayPalMessages.vue +++ b/src/runtime/components/ScriptPayPalMessages.vue @@ -72,12 +72,11 @@ const emit = defineEmits<{ const el = ref(null) const rootEl = ref(null) const ready = ref(false) +const failed = ref(false) const messagesSession = shallowRef() const { onLoaded, status } = useScriptPayPal({ ...(props.clientToken ? { clientToken: props.clientToken } : { clientId: props.clientId }), - ...(props.merchantId && { merchantId: props.merchantId }), - ...(props.partnerAttributionId && { partnerAttributionId: props.partnerAttributionId }), ...props.paypalScriptOptions, }) @@ -105,6 +104,8 @@ onMounted(() => { emit('ready', messagesSession.value) } catch (err) { + messagesSession.value = undefined + failed.value = true emit('error', err) } }) @@ -142,14 +143,14 @@ const rootAttrs = computed(() => {
- + placeholder - + - + diff --git a/src/runtime/registry/schemas.ts b/src/runtime/registry/schemas.ts index d605afc6..d37e088a 100644 --- a/src/runtime/registry/schemas.ts +++ b/src/runtime/registry/schemas.ts @@ -584,22 +584,32 @@ export const NpmOptions = object({ provider: optional(union([literal('jsdelivr'), literal('cdnjs'), literal('unpkg')])), }) -export const PayPalOptions = object({ - /** - * Your PayPal client ID. Required if `clientToken` is not provided. - * @see https://developer.paypal.com/sdk/js/reference/ - */ - clientId: optional(string()), - /** - * A server-generated client token for authentication. Required if `clientId` is not provided. - * @see https://docs.paypal.ai/payments/methods/paypal/sdk/js/v6/paypal-checkout - */ - clientToken: optional(string()), - /** - * Use the PayPal sandbox environment. Defaults to `true` in development. - */ - sandbox: optional(boolean()), -}) +export const PayPalOptions = union([ + object({ + /** + * Your PayPal client ID. + * @see https://developer.paypal.com/sdk/js/reference/ + */ + clientId: string(), + clientToken: optional(string()), + /** + * Use the PayPal sandbox environment. Defaults to `true` in development. + */ + sandbox: optional(boolean()), + }), + object({ + clientId: optional(string()), + /** + * A server-generated client token for authentication. + * @see https://docs.paypal.ai/payments/methods/paypal/sdk/js/v6/paypal-checkout + */ + clientToken: string(), + /** + * Use the PayPal sandbox environment. Defaults to `true` in development. + */ + sandbox: optional(boolean()), + }), +]) export const PostHogOptions = object({ /** From 38450770bad2d14b9606db0bd87dc29485afe3fc Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Thu, 5 Mar 2026 23:19:02 +1100 Subject: [PATCH 4/7] chore: sync --- src/runtime/components/ScriptPayPalButtons.vue | 4 ++-- src/runtime/components/ScriptPayPalMessages.vue | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/runtime/components/ScriptPayPalButtons.vue b/src/runtime/components/ScriptPayPalButtons.vue index 65e75aad..60ca99ab 100644 --- a/src/runtime/components/ScriptPayPalButtons.vue +++ b/src/runtime/components/ScriptPayPalButtons.vue @@ -140,10 +140,10 @@ const rootAttrs = computed(() => {
- + placeholder - + diff --git a/src/runtime/components/ScriptPayPalMessages.vue b/src/runtime/components/ScriptPayPalMessages.vue index 4b2dbeb0..3dc87eda 100644 --- a/src/runtime/components/ScriptPayPalMessages.vue +++ b/src/runtime/components/ScriptPayPalMessages.vue @@ -143,10 +143,10 @@ const rootAttrs = computed(() => {
- + placeholder - + From 4bb848dc0353f6d4ec3fe5898e6b314e888438c2 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Thu, 5 Mar 2026 23:54:33 +1100 Subject: [PATCH 5/7] chore: sync --- src/registry-types.json | 2 +- src/runtime/components/ScriptPayPalButtons.vue | 6 +++--- src/runtime/components/ScriptPayPalMessages.vue | 7 +++---- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/registry-types.json b/src/registry-types.json index 1895ab33..7d102f99 100644 --- a/src/registry-types.json +++ b/src/registry-types.json @@ -795,4 +795,4 @@ "code": "interface ScriptCarbonAdsProps {\n serve: string\n placement: string\n format: string\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n}" } ] -} \ No newline at end of file +} diff --git a/src/runtime/components/ScriptPayPalButtons.vue b/src/runtime/components/ScriptPayPalButtons.vue index 60ca99ab..0d1755c8 100644 --- a/src/runtime/components/ScriptPayPalButtons.vue +++ b/src/runtime/components/ScriptPayPalButtons.vue @@ -136,9 +136,9 @@ const rootAttrs = computed(() => {