From 0e6d0b043f1e333792df8bf771ed27a18282fc0a Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Tue, 8 Oct 2024 13:37:00 +0200 Subject: [PATCH 01/15] feat: add `useScriptPaypal` --- package.json | 1 + .../third-parties/paypal/nuxt-scripts.vue | 8 ++ src/runtime/components/ScriptPayPal.vue | 95 +++++++++++++++++++ src/runtime/registry/paypal.ts | 94 ++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 playground/pages/third-parties/paypal/nuxt-scripts.vue create mode 100644 src/runtime/components/ScriptPayPal.vue create mode 100644 src/runtime/registry/paypal.ts diff --git a/package.json b/package.json index 89fc41e5..34c6172c 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "@nuxt/module-builder": "^1.0.2", "@nuxt/scripts": "workspace:*", "@nuxt/test-utils": "3.19.2", + "@paypal/paypal-js": "^8.1.2", "@types/semver": "^7.7.0", "@typescript-eslint/typescript-estree": "^8.40.0", "acorn-loose": "^8.5.2", diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue new file mode 100644 index 00000000..590eb5e8 --- /dev/null +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -0,0 +1,8 @@ + + + diff --git a/src/runtime/components/ScriptPayPal.vue b/src/runtime/components/ScriptPayPal.vue new file mode 100644 index 00000000..a585f337 --- /dev/null +++ b/src/runtime/components/ScriptPayPal.vue @@ -0,0 +1,95 @@ + + + diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts new file mode 100644 index 00000000..a1cb287d --- /dev/null +++ b/src/runtime/registry/paypal.ts @@ -0,0 +1,94 @@ +import { withQuery } from 'ufo' +import type { PayPalNamespace } from '@paypal/paypal-js' +import { useRegistryScript } from '../utils' +import { object, string, optional, array, union, boolean } from '#nuxt-scripts-validator' +import type { RegistryScriptInput } from '#nuxt-scripts' + +export interface PaypalApi { + paypal: PayPalNamespace +} + +declare global { + interface Window extends PaypalApi { + } +} + +export const PaypalOptions = object({ + clientId: string(), + buyerCountry: optional(string()), + commit: optional(string()), + components: optional(union([string(), array(string())])), + currency: optional(string()), + debug: optional(union([string(), boolean()])), + disableFunding: optional(union([string(), array(string())])), + enableFunding: optional(union([string(), array(string())])), + integrationDate: optional(string()), + intent: optional(string()), + locale: optional(string()), + /** + * loadScript() supports an array for merchantId, even though + * merchant-id technically may not contain multiple values. + * For an array with a length of > 1 it automatically sets + * merchantId to "*" and moves the actual values to dataMerchantId + */ + merchantId: optional(union([string(), array(string())])), + vault: optional(union([string(), boolean()])), + // own props + sandbox: optional(boolean()), +}) + +export type PaypalInput = RegistryScriptInput + +export function useScriptPaypal(_options?: PaypalInput) { + return useRegistryScript('paypal', (options) => { + let dataMerchantId = undefined + + if (Array.isArray(options?.merchantId) && options?.merchantId.length > 1) { + dataMerchantId = JSON.stringify(options.merchantId) + options.merchantId = '*' + } + + if (Array.isArray(options?.components)) { + options.components = options.components.join(',') + } + + if (Array.isArray(options?.disableFunding)) { + options.disableFunding = options.disableFunding.join(',') + } + + if (Array.isArray(options?.enableFunding)) { + options.enableFunding = options.enableFunding.join(',') + } + + return { + scriptInput: { + // todo: default to sandbox if dev mode + src: withQuery(options.sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js', { + 'client-id': options.clientId, + 'buyer-country': options.buyerCountry, + 'commit': options.commit, + 'components': options.components, + 'currency': options.currency, + 'debug': options.debug, + 'disable-funding': options.disableFunding, + 'enable-funding': options.enableFunding, + 'integration-date': options.integrationDate, + 'intent': options.intent, + 'locale': options.locale, + 'merchant-id': options.merchantId, + 'vault': options.vault, + }), + dataMerchantId, + }, + schema: import.meta.dev ? PaypalOptions : undefined, + // trigger: 'client', + scriptOptions: { + use() { + return { + paypal: window.paypal, + } + }, + }, + } + }, _options) +} From 892bb22fe921c5ae3f271fab6ceed02c8793f3cc Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 17:29:44 +0100 Subject: [PATCH 02/15] feat: add `ScriptPaypalButton.vue` component --- .../third-parties/paypal/nuxt-scripts.vue | 28 ++- src/runtime/components/ScriptPayPal.vue | 95 ---------- .../components/ScriptPaypalButtons.vue | 177 ++++++++++++++++++ src/runtime/registry/paypal.ts | 10 +- 4 files changed, 210 insertions(+), 100 deletions(-) delete mode 100644 src/runtime/components/ScriptPayPal.vue create mode 100644 src/runtime/components/ScriptPaypalButtons.vue diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 590eb5e8..026a61cf 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -1,8 +1,30 @@ diff --git a/src/runtime/components/ScriptPayPal.vue b/src/runtime/components/ScriptPayPal.vue deleted file mode 100644 index a585f337..00000000 --- a/src/runtime/components/ScriptPayPal.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue new file mode 100644 index 00000000..289d362b --- /dev/null +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -0,0 +1,177 @@ + + + diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index a1cb287d..b388c839 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -60,14 +60,20 @@ export function useScriptPaypal(_options?: PaypalInput) { options.enableFunding = options.enableFunding.join(',') } + if (options?.sandbox === undefined) { + // TODO: get dev from nuxt (?) + options.sandbox = import.meta.env.DEV + } + + const components = (options.components?.length ? options.components : ['buttons', 'messages', 'marks', 'card-fields', 'funding-eligibility']).join(',') + return { scriptInput: { - // todo: default to sandbox if dev mode src: withQuery(options.sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js', { 'client-id': options.clientId, 'buyer-country': options.buyerCountry, 'commit': options.commit, - 'components': options.components, + 'components': components, 'currency': options.currency, 'debug': options.debug, 'disable-funding': options.disableFunding, From 4b606442bdc1b0dac0e08a3f766649fcfa3538e9 Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 17:51:06 +0100 Subject: [PATCH 03/15] feat: save button instance --- .../components/ScriptPaypalButtons.vue | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index 289d362b..3bb5f13d 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -2,7 +2,6 @@ import { computed, type HTMLAttributes, onMounted, ref, type ReservedProps, shallowRef, watch } from 'vue' import { defu } from 'defu' import type { - PayPalButtonsComponentOptions, OnApproveActions, OnApproveData, OnCancelledActions, @@ -11,6 +10,8 @@ import type { OnShippingAddressChangeData, OnShippingOptionsChangeActions, OnShippingOptionsChangeData, + PayPalButtonsComponent, + PayPalButtonsComponentOptions, } from '@paypal/paypal-js' import type { OnInitActions } from '@paypal/paypal-js/types/components/buttons' import { onBeforeUnmount, resolveComponent, useScriptPaypal, useScriptTriggerElement } from '#imports' @@ -119,27 +120,30 @@ const options = computed(() => { watch(() => props.disabled, handleDisabled) +const buttonInst = shallowRef() + onMounted(() => { onLoaded(async ({ paypal }) => { if (!el.value) return - await paypal?.Buttons?.(options.value).render(el.value) + buttonInst.value = paypal?.Buttons?.(options.value) + await buttonInst.value?.render(el.value) ready.value = true - watch(() => options, () => { + watch(() => options.value, async (_options) => { if (!el.value) return - destroy() - paypal?.Buttons?.(options.value).render(el.value) + await buttonInst.value?.updateProps(_options) }) }) }) -function destroy() { - if (!el.value) return - el.value?.replaceChildren() +async function destroy() { + if (buttonInst.value) { + await buttonInst.value?.close() + } } -onBeforeUnmount(() => { - destroy() +onBeforeUnmount(async () => { + await destroy() }) const ScriptLoadingIndicator = resolveComponent('ScriptLoadingIndicator') From 363d00be366c691becdc5ba6c49cca127f7fd78e Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 17:56:42 +0100 Subject: [PATCH 04/15] chore: add correct aria label --- src/runtime/components/ScriptPaypalButtons.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index 3bb5f13d..55a01495 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -156,8 +156,8 @@ const rootAttrs = computed(() => { 'aria-label': status.value === 'awaitingLoad' ? 'Paypal Script Placeholder' : status.value === 'loading' - ? 'Paypal Embed Loading' - : 'Paypal Embed', + ? 'Paypal Buttons Loading' + : 'Paypal Buttons', 'aria-live': 'polite', 'role': 'application', ...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}), From 11b31de6bd0fd082d912ae41f0cb3a072d3d7ea2 Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 18:00:29 +0100 Subject: [PATCH 05/15] feat: add `ScriptPaypalMarks` component --- .../third-parties/paypal/nuxt-scripts.vue | 3 + src/runtime/components/ScriptPaypalMarks.vue | 98 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/runtime/components/ScriptPaypalMarks.vue diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 026a61cf..782589e9 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -1,5 +1,6 @@ diff --git a/src/runtime/components/ScriptPaypalMarks.vue b/src/runtime/components/ScriptPaypalMarks.vue new file mode 100644 index 00000000..82611e5a --- /dev/null +++ b/src/runtime/components/ScriptPaypalMarks.vue @@ -0,0 +1,98 @@ + + + From 82af7bf91167ef125112d55c50594276fa69e284 Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 18:38:07 +0100 Subject: [PATCH 06/15] chore: minor adjustments --- src/runtime/registry/paypal.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index b388c839..971d97da 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -32,6 +32,7 @@ export const PaypalOptions = object({ * merchantId to "*" and moves the actual values to dataMerchantId */ merchantId: optional(union([string(), array(string())])), + dataPartnerAttributionId: optional(string()), vault: optional(union([string(), boolean()])), // own props sandbox: optional(boolean()), @@ -65,11 +66,20 @@ export function useScriptPaypal(_options?: PaypalInput) { options.sandbox = import.meta.env.DEV } - const components = (options.components?.length ? options.components : ['buttons', 'messages', 'marks', 'card-fields', 'funding-eligibility']).join(',') + let components = ['buttons', 'messages', 'marks', 'card-fields', 'funding-eligibility'].join(',') + + if (options.components) { + if (Array.isArray(options.components)) { + components = options.components.join(',') + } + else { + components = options.components + } + } return { scriptInput: { - src: withQuery(options.sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js', { + 'src': withQuery(options.sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js', { 'client-id': options.clientId, 'buyer-country': options.buyerCountry, 'commit': options.commit, @@ -81,10 +91,10 @@ export function useScriptPaypal(_options?: PaypalInput) { 'integration-date': options.integrationDate, 'intent': options.intent, 'locale': options.locale, - 'merchant-id': options.merchantId, 'vault': options.vault, }), - dataMerchantId, + 'data-merchant-id': dataMerchantId, + 'data-partner-attribution-id': options.dataPartnerAttributionId, // TODO: maybe nuxt specific default }, schema: import.meta.dev ? PaypalOptions : undefined, // trigger: 'client', From 97a75b42b6b89e75216612622256ca5d9c28b994 Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 19:08:20 +0100 Subject: [PATCH 07/15] feat: add `ScriptPaypalMessages` component --- .../third-parties/paypal/nuxt-scripts.vue | 2 + .../components/ScriptPaypalButtons.vue | 9 +- src/runtime/components/ScriptPaypalMarks.vue | 9 +- .../components/ScriptPaypalMessages.vue | 139 ++++++++++++++++++ src/runtime/registry/paypal.ts | 4 +- 5 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 src/runtime/components/ScriptPaypalMessages.vue diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 782589e9..1a6caae6 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -12,6 +12,8 @@

Marks

+

Messages

+ diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index 55a01495..a086cf1c 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -14,7 +14,7 @@ import type { PayPalButtonsComponentOptions, } from '@paypal/paypal-js' import type { OnInitActions } from '@paypal/paypal-js/types/components/buttons' -import { onBeforeUnmount, resolveComponent, useScriptPaypal, useScriptTriggerElement } from '#imports' +import { onBeforeUnmount, type PaypalInput, resolveComponent, useScriptPaypal, useScriptTriggerElement } from '#imports' import type { ElementScriptTrigger } from '#nuxt-scripts' const el = ref(null) @@ -37,6 +37,10 @@ const props = withDefaults(defineProps<{ * The options for the paypal buttons. */ buttonOptions?: PayPalButtonsComponentOptions + /** + * The paypal script options. + */ + paypalScriptOptions?: Partial /** * Disables the paypal buttons. */ @@ -45,12 +49,15 @@ const props = withDefaults(defineProps<{ trigger: 'visible', clientId: 'test', disabled: false, + buttonOptions: () => ({}), + paypalScriptOptions: () => ({}), }) const ready = ref(false) const { onLoaded, status } = useScriptPaypal({ clientId: props.clientId, + ...props.paypalScriptOptions, }) const emit = defineEmits<{ diff --git a/src/runtime/components/ScriptPaypalMarks.vue b/src/runtime/components/ScriptPaypalMarks.vue index 82611e5a..a5d229bc 100644 --- a/src/runtime/components/ScriptPaypalMarks.vue +++ b/src/runtime/components/ScriptPaypalMarks.vue @@ -2,7 +2,7 @@ import { computed, type HTMLAttributes, onMounted, ref, type ReservedProps, shallowRef, watch } from 'vue' import { defu } from 'defu' import type { PayPalMarksComponent, PayPalMarksComponentOptions } from '@paypal/paypal-js' -import { onBeforeUnmount, resolveComponent, useScriptPaypal, useScriptTriggerElement } from '#imports' +import { onBeforeUnmount, type PaypalInput, resolveComponent, useScriptPaypal, useScriptTriggerElement } from '#imports' import type { ElementScriptTrigger } from '#nuxt-scripts' const el = ref(null) @@ -25,15 +25,22 @@ const props = withDefaults(defineProps<{ * The options for the paypal marks. */ marksOptions?: PayPalMarksComponentOptions + /** + * The paypal script options. + */ + paypalScriptOptions?: Partial }>(), { trigger: 'visible', clientId: 'test', + marksOptions: () => ({}), + paypalScriptOptions: () => ({}), }) const ready = ref(false) const { onLoaded, status } = useScriptPaypal({ clientId: props.clientId, + ...props.paypalScriptOptions, }) const marksInst = shallowRef() diff --git a/src/runtime/components/ScriptPaypalMessages.vue b/src/runtime/components/ScriptPaypalMessages.vue new file mode 100644 index 00000000..536f174f --- /dev/null +++ b/src/runtime/components/ScriptPaypalMessages.vue @@ -0,0 +1,139 @@ + + + diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index 971d97da..9ca5596b 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -32,7 +32,7 @@ export const PaypalOptions = object({ * merchantId to "*" and moves the actual values to dataMerchantId */ merchantId: optional(union([string(), array(string())])), - dataPartnerAttributionId: optional(string()), + partnerAttributionId: optional(string()), vault: optional(union([string(), boolean()])), // own props sandbox: optional(boolean()), @@ -94,7 +94,7 @@ export function useScriptPaypal(_options?: PaypalInput) { 'vault': options.vault, }), 'data-merchant-id': dataMerchantId, - 'data-partner-attribution-id': options.dataPartnerAttributionId, // TODO: maybe nuxt specific default + 'data-partner-attribution-id': options.partnerAttributionId, // TODO: maybe nuxt specific default }, schema: import.meta.dev ? PaypalOptions : undefined, // trigger: 'client', From b7ea18e945e962a1ba3b87d1f074661a7fe6e8aa Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 19:17:14 +0100 Subject: [PATCH 08/15] chore: dont remove messages --- playground/pages/third-parties/paypal/nuxt-scripts.vue | 2 +- src/runtime/components/ScriptPaypalMessages.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 1a6caae6..38d1cd0c 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -13,7 +13,7 @@

Marks

Messages

- + diff --git a/src/runtime/components/ScriptPaypalMessages.vue b/src/runtime/components/ScriptPaypalMessages.vue index 536f174f..4cbfebdc 100644 --- a/src/runtime/components/ScriptPaypalMessages.vue +++ b/src/runtime/components/ScriptPaypalMessages.vue @@ -88,7 +88,7 @@ onMounted(() => { watch(() => options.value, async (_options) => { if (!el.value) return - destroy() + // don't destroy the element messageInst.value = paypal?.Messages?.(_options) await messageInst.value?.render(el.value) }) From e660e27662a5142fc8d9dd1ab60a18c0ad5ca039 Mon Sep 17 00:00:00 2001 From: Robin Kehl Date: Mon, 18 Nov 2024 19:36:07 +0100 Subject: [PATCH 09/15] chore: update sandbox dev env --- src/runtime/registry/paypal.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index 9ca5596b..7bafee8b 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -62,8 +62,7 @@ export function useScriptPaypal(_options?: PaypalInput) { } if (options?.sandbox === undefined) { - // TODO: get dev from nuxt (?) - options.sandbox = import.meta.env.DEV + options.sandbox = import.meta.dev } let components = ['buttons', 'messages', 'marks', 'card-fields', 'funding-eligibility'].join(',') From bc68671fbbae4079dd8663a8eaac240dd39da87a Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 10:42:11 +0200 Subject: [PATCH 10/15] chore: update lockfile --- pnpm-lock.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6300f566..96dfa881 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,6 +102,9 @@ importers: '@nuxt/test-utils': specifier: 3.19.2 version: 3.19.2(happy-dom@18.0.1)(magicast@0.3.5)(playwright-core@1.55.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@paypal/paypal-js': + specifier: ^8.1.2 + version: 8.2.0 '@types/semver': specifier: ^7.7.0 version: 7.7.0 @@ -1571,6 +1574,9 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@paypal/paypal-js@8.2.0': + resolution: {integrity: sha512-hLg5wNORW3WiyMiRNJOm6cN2IqjPlClpxd971bEdm0LNpbbejQZYtesb0/0arTnySSbGcxg7MxjkZ/N5Z5qBNQ==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -5749,6 +5755,9 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + promise-polyfill@8.3.0: + resolution: {integrity: sha512-H5oELycFml5yto/atYqmjyigJoAo3+OXwolYiH7OfQuYlAqhxNvTfiNMbV9hsC6Yp83yE5r2KTVmtrG6R9i6Pg==} + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -9063,6 +9072,10 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 + '@paypal/paypal-js@8.2.0': + dependencies: + promise-polyfill: 8.3.0 + '@pkgjs/parseargs@0.11.0': optional: true @@ -14074,6 +14087,8 @@ snapshots: process@0.11.10: {} + promise-polyfill@8.3.0: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 From 737c6b5550ab5b83baf01ebeea43a2060630f593 Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 11:42:50 +0200 Subject: [PATCH 11/15] refactor: update paypal scripts to be compatible with latest scripts --- .../components/ScriptPaypalButtons.vue | 25 +++++++++---------- src/runtime/components/ScriptPaypalMarks.vue | 23 ++++++++--------- .../components/ScriptPaypalMessages.vue | 23 ++++++++--------- src/runtime/registry/paypal.ts | 2 +- 4 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index a086cf1c..7280ecee 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -1,5 +1,5 @@ diff --git a/src/runtime/components/ScriptPaypalMarks.vue b/src/runtime/components/ScriptPaypalMarks.vue index a5d229bc..1ff2817e 100644 --- a/src/runtime/components/ScriptPaypalMarks.vue +++ b/src/runtime/components/ScriptPaypalMarks.vue @@ -1,9 +1,10 @@ diff --git a/src/runtime/components/ScriptPaypalMessages.vue b/src/runtime/components/ScriptPaypalMessages.vue index 4cbfebdc..1c776c57 100644 --- a/src/runtime/components/ScriptPaypalMessages.vue +++ b/src/runtime/components/ScriptPaypalMessages.vue @@ -1,9 +1,10 @@ diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index 7bafee8b..b34e0ffa 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -2,7 +2,7 @@ import { withQuery } from 'ufo' import type { PayPalNamespace } from '@paypal/paypal-js' import { useRegistryScript } from '../utils' import { object, string, optional, array, union, boolean } from '#nuxt-scripts-validator' -import type { RegistryScriptInput } from '#nuxt-scripts' +import type { RegistryScriptInput } from '#nuxt-scripts/types' export interface PaypalApi { paypal: PayPalNamespace From 2a2c691972264c323b4534c7d2ddb4c570e3c3dc Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 13:28:32 +0200 Subject: [PATCH 12/15] docs: basic paypal docs --- docs/content/scripts/payments/paypal.md | 38 +++++++++++++++++++ package.json | 5 ++- playground/pages/index.vue | 4 ++ pnpm-lock.yaml | 6 +-- src/registry.ts | 10 +++++ .../components/ScriptPaypalButtons.vue | 2 +- 6 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 docs/content/scripts/payments/paypal.md diff --git a/docs/content/scripts/payments/paypal.md b/docs/content/scripts/payments/paypal.md new file mode 100644 index 00000000..3bc723aa --- /dev/null +++ b/docs/content/scripts/payments/paypal.md @@ -0,0 +1,38 @@ +--- +title: PayPal +description: Use PayPal in your Nuxt app. +links: + - label: useScriptPayPal + icon: i-simple-icons-github + to: https://github.com/nuxt/scripts/blob/main/src/runtime/registry/paypal.ts + size: xs + - label: "" + 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 + size: xs +--- + +[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. + +## Types + +To use the PayPal with full TypeScript support, you will need +to install the `@paypal/paypal-js` dependency. + +```bash +pnpm add -D @paypal/paypal-js +``` diff --git a/package.json b/package.json index 34c6172c..6bbcccdb 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ }, "peerDependencies": { "@stripe/stripe-js": "^7.0.0", + "@paypal/paypal-js": "^8.1.2", "@types/google.maps": "^3.58.1", "@types/vimeo__player": "^2.18.3", "@types/youtube": "^0.1.0", @@ -82,6 +83,9 @@ "@stripe/stripe-js": { "optional": true }, + "@paypal/paypal-js": { + "optional": true + }, "@types/google.maps": { "optional": true }, @@ -117,7 +121,6 @@ "@nuxt/module-builder": "^1.0.2", "@nuxt/scripts": "workspace:*", "@nuxt/test-utils": "3.19.2", - "@paypal/paypal-js": "^8.1.2", "@types/semver": "^7.7.0", "@typescript-eslint/typescript-estree": "^8.40.0", "acorn-loose": "^8.5.2", diff --git a/playground/pages/index.vue b/playground/pages/index.vue index 2f9e45fe..fe059d1d 100644 --- a/playground/pages/index.vue +++ b/playground/pages/index.vue @@ -54,6 +54,10 @@ const thirdParties = [ name: 'Stripe', path: '/third-parties/stripe/nuxt-scripts', }, + { + name: 'PayPal', + path: '/third-parties/paypal/nuxt-scripts', + }, { name: 'Segment', path: '/third-parties/segment', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96dfa881..ee11aa83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@nuxt/kit': specifier: 'catalog:' version: 4.0.3(magicast@0.3.5) + '@paypal/paypal-js': + specifier: ^8.1.2 + version: 8.2.0 '@stripe/stripe-js': specifier: ^7.0.0 version: 7.8.0 @@ -102,9 +105,6 @@ importers: '@nuxt/test-utils': specifier: 3.19.2 version: 3.19.2(happy-dom@18.0.1)(magicast@0.3.5)(playwright-core@1.55.0)(typescript@5.9.2)(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) - '@paypal/paypal-js': - specifier: ^8.1.2 - version: 8.2.0 '@types/semver': specifier: ^7.7.0 version: 7.7.0 diff --git a/src/registry.ts b/src/registry.ts index c4615b2f..69362750 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -205,6 +205,16 @@ export async function registry(resolve?: (path: string, opts?: ResolvePathOption from: await resolve('./runtime/registry/lemon-squeezy'), }, }, + { + label: 'PayPal', + src: false, // should not be bundled + category: 'payments', + logo: ``, + import: { + name: 'useSciptPaypal', + from: await resolve('./runtime/registry/paypal'), + }, + }, // content { label: 'Vimeo Player', diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index 7280ecee..6c5bedf0 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -45,7 +45,7 @@ const props = withDefaults(defineProps<{ /** * The paypal script options. */ - paypalScriptOptions?: Partial + payppalScriptOptions?: Partial /** * Disables the paypal buttons. * From c682c8b00d4c892950e855aff517944869e4176d Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 13:42:19 +0200 Subject: [PATCH 13/15] docs: add simple demo --- docs/app/components/content/PayPalDemo.vue | 32 ++++++++++++++ docs/content/scripts/payments/paypal.md | 42 +++++++++++++++++++ .../third-parties/paypal/nuxt-scripts.vue | 3 -- 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 docs/app/components/content/PayPalDemo.vue diff --git a/docs/app/components/content/PayPalDemo.vue b/docs/app/components/content/PayPalDemo.vue new file mode 100644 index 00000000..15152fcd --- /dev/null +++ b/docs/app/components/content/PayPalDemo.vue @@ -0,0 +1,32 @@ + + + diff --git a/docs/content/scripts/payments/paypal.md b/docs/content/scripts/payments/paypal.md index 3bc723aa..991ff716 100644 --- a/docs/content/scripts/payments/paypal.md +++ b/docs/content/scripts/payments/paypal.md @@ -36,3 +36,45 @@ to install the `@paypal/paypal-js` dependency. ```bash pnpm add -D @paypal/paypal-js ``` +### Demo + +::code-group + +:pay-pal-demo{label="Output"} + +```vue [Input] + + + +``` + +:: diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 38d1cd0c..15152fcd 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -1,6 +1,5 @@ From f75c1bb3f9872465ed45c7dc27215b8c9022e37e Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 13:43:32 +0200 Subject: [PATCH 14/15] chore: fix typo --- src/runtime/components/ScriptPaypalButtons.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPaypalButtons.vue index 6c5bedf0..7280ecee 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPaypalButtons.vue @@ -45,7 +45,7 @@ const props = withDefaults(defineProps<{ /** * The paypal script options. */ - payppalScriptOptions?: Partial + paypalScriptOptions?: Partial /** * Disables the paypal buttons. * From f6eebebb8e10e14d482f75473e5310acff99383c Mon Sep 17 00:00:00 2001 From: OrbisK Date: Mon, 25 Aug 2025 13:53:41 +0200 Subject: [PATCH 15/15] chore: renaming as `payPal` to be consistent with existing apis --- docs/app/components/content/PayPalDemo.vue | 6 ++--- docs/content/scripts/payments/paypal.md | 26 +++++++++---------- .../third-parties/paypal/nuxt-scripts.vue | 6 ++--- src/registry.ts | 2 +- ...palButtons.vue => ScriptPayPalButtons.vue} | 16 ++++++------ ...tPaypalMarks.vue => ScriptPayPalMarks.vue} | 16 ++++++------ ...lMessages.vue => ScriptPayPalMessages.vue} | 16 ++++++------ src/runtime/registry/paypal.ts | 14 +++++----- 8 files changed, 51 insertions(+), 51 deletions(-) rename src/runtime/components/{ScriptPaypalButtons.vue => ScriptPayPalButtons.vue} (93%) rename src/runtime/components/{ScriptPaypalMarks.vue => ScriptPayPalMarks.vue} (88%) rename src/runtime/components/{ScriptPaypalMessages.vue => ScriptPayPalMessages.vue} (91%) diff --git a/docs/app/components/content/PayPalDemo.vue b/docs/app/components/content/PayPalDemo.vue index 15152fcd..f299c6fb 100644 --- a/docs/app/components/content/PayPalDemo.vue +++ b/docs/app/components/content/PayPalDemo.vue @@ -1,6 +1,6 @@ diff --git a/docs/content/scripts/payments/paypal.md b/docs/content/scripts/payments/paypal.md index 991ff716..8709fa5a 100644 --- a/docs/content/scripts/payments/paypal.md +++ b/docs/content/scripts/payments/paypal.md @@ -6,27 +6,27 @@ links: icon: i-simple-icons-github to: https://github.com/nuxt/scripts/blob/main/src/runtime/registry/paypal.ts size: xs - - label: "" + - label: "" icon: i-simple-icons-github - to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPaypalButtons.vue + to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalButtons.vue size: xs - - label: "" + - label: "" icon: i-simple-icons-github - to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPaypalMarks.vue + to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMarks.vue size: xs - - label: "" + - label: "" icon: i-simple-icons-github - to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPaypalMessages.vue + to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMessages.vue size: xs --- [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. +- `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. ## Types @@ -45,7 +45,7 @@ pnpm add -D @paypal/paypal-js ```vue [Input] diff --git a/playground/pages/third-parties/paypal/nuxt-scripts.vue b/playground/pages/third-parties/paypal/nuxt-scripts.vue index 15152fcd..f299c6fb 100644 --- a/playground/pages/third-parties/paypal/nuxt-scripts.vue +++ b/playground/pages/third-parties/paypal/nuxt-scripts.vue @@ -1,6 +1,6 @@ diff --git a/src/registry.ts b/src/registry.ts index 69362750..aa56ce78 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -211,7 +211,7 @@ export async function registry(resolve?: (path: string, opts?: ResolvePathOption category: 'payments', logo: ``, import: { - name: 'useSciptPaypal', + name: 'useSciptPayPal', from: await resolve('./runtime/registry/paypal'), }, }, diff --git a/src/runtime/components/ScriptPaypalButtons.vue b/src/runtime/components/ScriptPayPalButtons.vue similarity index 93% rename from src/runtime/components/ScriptPaypalButtons.vue rename to src/runtime/components/ScriptPayPalButtons.vue index 7280ecee..736286f8 100644 --- a/src/runtime/components/ScriptPaypalButtons.vue +++ b/src/runtime/components/ScriptPayPalButtons.vue @@ -15,7 +15,7 @@ import type { } from '@paypal/paypal-js' import type { OnInitActions } from '@paypal/paypal-js/types/components/buttons' import type { ElementScriptTrigger } from '#nuxt-scripts/types' -import { type PaypalInput, useScriptPaypal } from '../registry/paypal' +import { type PayPalInput, useScriptPayPal } from '../registry/paypal' import { useScriptTriggerElement } from '../composables/useScriptTriggerElement' const el = ref(null) @@ -45,7 +45,7 @@ const props = withDefaults(defineProps<{ /** * The paypal script options. */ - paypalScriptOptions?: Partial + payPalScriptOptions?: Partial /** * Disables the paypal buttons. * @@ -57,14 +57,14 @@ const props = withDefaults(defineProps<{ clientId: 'test', disabled: false, buttonOptions: () => ({}), - paypalScriptOptions: () => ({}), + payPalScriptOptions: () => ({}), }) const ready = ref(false) -const { onLoaded, status } = useScriptPaypal({ +const { onLoaded, status } = useScriptPayPal({ clientId: props.clientId, - ...props.paypalScriptOptions, + ...props.payPalScriptOptions, }) const emit = defineEmits<{ @@ -166,10 +166,10 @@ const rootAttrs = computed(() => { return defu(props.rootAttrs, { 'aria-busy': status.value === 'loading', 'aria-label': status.value === 'awaitingLoad' - ? 'Paypal Script Placeholder' + ? 'PayPal Script Placeholder' : status.value === 'loading' - ? 'Paypal Buttons Loading' - : 'Paypal Buttons', + ? 'PayPal Buttons Loading' + : 'PayPal Buttons', 'aria-live': 'polite', 'role': 'application', ...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}), diff --git a/src/runtime/components/ScriptPaypalMarks.vue b/src/runtime/components/ScriptPayPalMarks.vue similarity index 88% rename from src/runtime/components/ScriptPaypalMarks.vue rename to src/runtime/components/ScriptPayPalMarks.vue index 1ff2817e..a77661ff 100644 --- a/src/runtime/components/ScriptPaypalMarks.vue +++ b/src/runtime/components/ScriptPayPalMarks.vue @@ -3,7 +3,7 @@ import { computed, type HTMLAttributes, onMounted, ref, type ReservedProps, shal import { defu } from 'defu' import type { PayPalMarksComponent, PayPalMarksComponentOptions } from '@paypal/paypal-js' import type { ElementScriptTrigger } from '#nuxt-scripts/types' -import { type PaypalInput, useScriptPaypal } from '../registry/paypal' +import { type PayPalInput, useScriptPayPal } from '../registry/paypal' import { useScriptTriggerElement } from '../composables/useScriptTriggerElement' const el = ref(null) @@ -33,19 +33,19 @@ const props = withDefaults(defineProps<{ /** * The paypal script options. */ - paypalScriptOptions?: Partial + payPalScriptOptions?: Partial }>(), { trigger: 'visible', clientId: 'test', marksOptions: () => ({}), - paypalScriptOptions: () => ({}), + payPalScriptOptions: () => ({}), }) const ready = ref(false) -const { onLoaded, status } = useScriptPaypal({ +const { onLoaded, status } = useScriptPayPal({ clientId: props.clientId, - ...props.paypalScriptOptions, + ...props.payPalScriptOptions, }) const marksInst = shallowRef() @@ -81,10 +81,10 @@ const rootAttrs = computed(() => { return defu(props.rootAttrs, { 'aria-busy': status.value === 'loading', 'aria-label': status.value === 'awaitingLoad' - ? 'Paypal Script Placeholder' + ? 'PayPal Script Placeholder' : status.value === 'loading' - ? 'Paypal Marks Loading' - : 'Paypal Marks', + ? 'PayPal Marks Loading' + : 'PayPal Marks', 'aria-live': 'polite', 'role': 'application', ...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}), diff --git a/src/runtime/components/ScriptPaypalMessages.vue b/src/runtime/components/ScriptPayPalMessages.vue similarity index 91% rename from src/runtime/components/ScriptPaypalMessages.vue rename to src/runtime/components/ScriptPayPalMessages.vue index 1c776c57..458cdd04 100644 --- a/src/runtime/components/ScriptPaypalMessages.vue +++ b/src/runtime/components/ScriptPayPalMessages.vue @@ -3,7 +3,7 @@ import { computed, type HTMLAttributes, onMounted, ref, type ReservedProps, shal import { defu } from 'defu' import type { PayPalMessagesComponent, PayPalMessagesComponentOptions } from '@paypal/paypal-js' import type { ElementScriptTrigger } from '#nuxt-scripts/types' -import { type PaypalInput, useScriptPaypal } from '../registry/paypal' +import { type PayPalInput, useScriptPayPal } from '../registry/paypal' import { useScriptTriggerElement } from '../composables/useScriptTriggerElement' const el = ref(null) @@ -41,21 +41,21 @@ const props = withDefaults(defineProps<{ /** * The options for the paypal scipt. */ - paypalScriptOptions?: Partial + payPalScriptOptions?: Partial }>(), { trigger: 'visible', clientId: 'test', - paypalScriptOptions: () => ({}), + payPalScriptOptions: () => ({}), messagesOptions: () => ({}), }) const ready = ref(false) -const { onLoaded, status } = useScriptPaypal({ +const { onLoaded, status } = useScriptPayPal({ clientId: props.clientId, merchantId: props.merchantId, partnerAttributionId: props.partnerAttributionId, - ...props.paypalScriptOptions, + ...props.payPalScriptOptions, }) const emit = defineEmits<{ @@ -115,10 +115,10 @@ const rootAttrs = computed(() => { return defu(props.rootAttrs, { 'aria-busy': status.value === 'loading', 'aria-label': status.value === 'awaitingLoad' - ? 'Paypal Script Placeholder' + ? 'PayPal Script Placeholder' : status.value === 'loading' - ? 'Paypal Buttons Loading' - : 'Paypal Buttons', + ? 'PayPal Buttons Loading' + : 'PayPal Buttons', 'aria-live': 'polite', 'role': 'application', ...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}), diff --git a/src/runtime/registry/paypal.ts b/src/runtime/registry/paypal.ts index b34e0ffa..3ca6ceff 100644 --- a/src/runtime/registry/paypal.ts +++ b/src/runtime/registry/paypal.ts @@ -4,16 +4,16 @@ import { useRegistryScript } from '../utils' import { object, string, optional, array, union, boolean } from '#nuxt-scripts-validator' import type { RegistryScriptInput } from '#nuxt-scripts/types' -export interface PaypalApi { +export interface PayPalApi { paypal: PayPalNamespace } declare global { - interface Window extends PaypalApi { + interface Window extends PayPalApi { } } -export const PaypalOptions = object({ +export const PayPalOptions = object({ clientId: string(), buyerCountry: optional(string()), commit: optional(string()), @@ -38,10 +38,10 @@ export const PaypalOptions = object({ sandbox: optional(boolean()), }) -export type PaypalInput = RegistryScriptInput +export type PayPalInput = RegistryScriptInput -export function useScriptPaypal(_options?: PaypalInput) { - return useRegistryScript('paypal', (options) => { +export function useScriptPayPal(_options?: PayPalInput) { + return useRegistryScript('paypal', (options) => { let dataMerchantId = undefined if (Array.isArray(options?.merchantId) && options?.merchantId.length > 1) { @@ -95,7 +95,7 @@ export function useScriptPaypal(_options?: PaypalInput) { 'data-merchant-id': dataMerchantId, 'data-partner-attribution-id': options.partnerAttributionId, // TODO: maybe nuxt specific default }, - schema: import.meta.dev ? PaypalOptions : undefined, + schema: import.meta.dev ? PayPalOptions : undefined, // trigger: 'client', scriptOptions: { use() {