Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 45 additions & 33 deletions docs/content/scripts/paypal.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: "<ScriptPayPalMarks>"
icon: i-simple-icons-github
to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMarks.vue
size: xs
- label: "<ScriptPayPalMessages>"
icon: i-simple-icons-github
to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptPayPalMessages.vue
Expand All @@ -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
::
Expand All @@ -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
Expand All @@ -55,34 +52,49 @@ pnpm add -D @paypal/paypal-js
<template>
<div>
<ScriptPayPalButtons
class="border border-gray-200 dark:border-gray-800 rounded-lg"
:button-options="buttonOptions"
:disabled="disabled"
/>
<label>
Disabled
<input v-model="disabled" type="checkbox">
</label>
<ScriptPayPalMarks />
<ScriptPayPalMessages :messages-options="{ style: { color: 'white-no-border', layout: 'flex' } }" />
:client-id="clientId"
:components="['paypal-payments']"
page-type="checkout"
@ready="onSdkReady"
>
<template #default="{ sdkInstance }">
<button @click="startPayment(sdkInstance)">
Pay with PayPal
</button>
</template>
</ScriptPayPalButtons>
</div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { PayPalButtonsComponentOptions } from '@paypal/paypal-js'

const buttonOptions = computed(() => ({
style: {
layout: 'vertical',
color: 'blue',
shape: 'rect',
label: 'paypal',
},
message: { amount: '10.00' },
} satisfies PayPalButtonsComponentOptions))
import type { SdkInstance, Components } from '@paypal/paypal-js/sdk-v6'

const clientId = 'YOUR_CLIENT_ID'

const disabled = ref(false)
function onSdkReady(instance: SdkInstance<Components[]>) {
console.log('PayPal SDK v6 ready', instance)
}

async function startPayment(instance?: SdkInstance<Components[]>) {
if (!instance)
return

const eligibility = await instance.findEligibleMethods()
if (eligibility.isEligible('paypal')) {
const session = instance.createPayPalOneTimePaymentSession({
onApprove: async (data) => {
console.log('Payment approved:', data.orderId)
},
onError: (error) => {
console.error('Payment error:', error)
},
})
await session.start(
{ presentationMode: 'auto' },
fetch('/api/create-order').then(r => r.json()),
)
}
}
</script>
```

Expand Down
53 changes: 32 additions & 21 deletions playground/pages/third-parties/paypal/nuxt-scripts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,42 @@
<div>
<ScriptPayPalButtons
class="border border-gray-200 dark:border-gray-800 rounded-lg"
:button-options="buttonOptions"
:disabled="disabled"
/>
<label>
Disabled
<input v-model="disabled" type="checkbox">
</label>
<ScriptPayPalMarks />
<ScriptPayPalMessages :messages-options="{ style: { color: 'white-no-border', layout: 'flex' } }" />
:components="['paypal-payments']"
page-type="checkout"
@ready="onReady"
>
<template #default="{ sdkInstance }">
<button @click="startPayment(sdkInstance)">
Pay with PayPal
</button>
</template>
</ScriptPayPalButtons>
<ScriptPayPalMessages />
</div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { PayPalButtonsComponentOptions } from '@paypal/paypal-js'
import type { Components, SdkInstance } from '@paypal/paypal-js/sdk-v6'

const buttonOptions = computed(() => ({
style: {
layout: 'vertical',
color: 'blue',
shape: 'rect',
label: 'paypal',
},
message: { amount: '10.00' },
} satisfies PayPalButtonsComponentOptions))
function onReady(instance: SdkInstance<Components[]>) {
console.log('PayPal SDK v6 ready', instance)
}

const disabled = ref(false)
async function startPayment(instance?: SdkInstance<Components[]>) {
if (!instance)
return

const eligibility = await instance.findEligibleMethods()
if (eligibility.isEligible('paypal')) {
const session = instance.createPayPalOneTimePaymentSession({
onApprove: async (data) => {
console.log('Payment approved:', data.orderId)
},
onError: (error) => {
console.error('Payment error:', error)
},
})
await session.start({ presentationMode: 'auto' })
}
}
</script>
1 change: 0 additions & 1 deletion scripts/generate-registry-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,6 @@ const componentToSlug: Record<string, string> = {
ScriptLemonSqueezy: 'lemon-squeezy',
ScriptStripePricingTable: 'stripe',
ScriptPayPalButtons: 'paypal',
ScriptPayPalMarks: 'paypal',
ScriptPayPalMessages: 'paypal',
}

Expand Down
22 changes: 6 additions & 16 deletions src/registry-types.json
Original file line number Diff line number Diff line change
Expand Up @@ -474,37 +474,27 @@
{
"name": "PayPalOptions",
"kind": "const",
"code": "export const PayPalOptions = object({\n /**\n * Your PayPal client ID.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#client-id\n */\n clientId: string(),\n /**\n * The buyer's country code (for testing with sandbox).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#buyer-country\n */\n buyerCountry: optional(string()),\n /**\n * Set to `true` to show a \"Pay Now\" button instead of \"Continue\".\n * @default 'true'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#commit\n */\n commit: optional(string()),\n /**\n * The PayPal SDK components to load.\n * @default 'buttons,messages,marks,card-fields,funding-eligibility'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#components\n */\n components: optional(union([string(), array(string())])),\n /**\n * The currency code for the transaction.\n * @default 'USD'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#currency\n */\n currency: optional(string()),\n /**\n * Enable debug mode for the PayPal SDK.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#debug\n */\n debug: optional(union([string(), boolean()])),\n /**\n * Funding sources to disable (e.g., `'credit'`, `'card'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#disable-funding\n */\n disableFunding: optional(union([string(), array(string())])),\n /**\n * Funding sources to enable (e.g., `'venmo'`, `'paylater'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#enable-funding\n */\n enableFunding: optional(union([string(), array(string())])),\n /**\n * The date of integration to ensure backwards-compatible defaults.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#integration-date\n */\n integrationDate: optional(string()),\n /**\n * The transaction intent.\n * @default 'capture'\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#intent\n */\n intent: optional(string()),\n /**\n * The locale for the PayPal buttons (e.g., `'en_US'`).\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#locale\n */\n locale: optional(string()),\n /**\n * The merchant ID(s). For multiple merchants, pass an array and the SDK\n * will automatically set `merchant-id` to `*` and use `data-merchant-id`.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#merchant-id\n */\n merchantId: optional(union([string(), array(string())])),\n /**\n * The partner attribution ID for revenue sharing.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#data-partner-attribution-id\n */\n partnerAttributionId: optional(string()),\n /**\n * Enable vault mode to save payment methods for future transactions.\n * @see https://developer.paypal.com/docs/checkout/reference/customize-sdk/#vault\n */\n vault: optional(union([string(), boolean()])),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n})"
"code": "export const PayPalOptions = union([\n object({\n /**\n * Your PayPal client ID.\n * @see https://developer.paypal.com/sdk/js/reference/\n */\n clientId: string(),\n clientToken: optional(string()),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n }),\n object({\n clientId: optional(string()),\n /**\n * A server-generated client token for authentication.\n * @see https://docs.paypal.ai/payments/methods/paypal/sdk/js/v6/paypal-checkout\n */\n clientToken: string(),\n /**\n * Use the PayPal sandbox environment. Defaults to `true` in development.\n */\n sandbox: optional(boolean()),\n }),\n])"
},
{
"name": "PayPalApi",
"kind": "interface",
"code": "export interface PayPalApi {\n paypal: PayPalNamespace\n}"
"code": "export interface PayPalApi {\n paypal: PayPalV6Namespace\n}"
},
{
"name": "ScriptPayPalButtonsProps",
"kind": "interface",
"code": "interface ScriptPayPalButtonsProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal buttons.\n */\n buttonOptions?: PayPalButtonsComponentOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial<PayPalInput>\n /**\n * Disables the paypal buttons.\n */\n disabled?: boolean\n}"
"code": "interface ScriptPayPalButtonsProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * Client ID or client token for PayPal SDK v6 authentication.\n */\n clientId?: string\n /**\n * Server-generated client token for SDK v6.\n */\n clientToken?: string\n /**\n * The v6 SDK components to load.\n * @default ['paypal-payments']\n */\n components?: Components[]\n /**\n * The page type context hint.\n */\n pageType?: PageTypes\n /**\n * The locale for the SDK (BCP-47 code).\n */\n locale?: string\n /**\n * The merchant ID(s).\n */\n merchantId?: string | string[]\n /**\n * Partner attribution ID for revenue sharing.\n */\n partnerAttributionId?: string\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial<PayPalInput>\n}"
},
{
"name": "ScriptPayPalButtonsDefaults",
"kind": "const",
"code": "const ScriptPayPalButtonsDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"disabled\": \"false\",\n \"buttonOptions\": \"() => ({})\",\n \"paypalScriptOptions\": \"() => ({})\"\n}"
},
{
"name": "ScriptPayPalMarksProps",
"kind": "interface",
"code": "interface ScriptPayPalMarksProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal marks.\n */\n marksOptions?: PayPalMarksComponentOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial<PayPalInput>\n}"
},
{
"name": "ScriptPayPalMarksDefaults",
"kind": "const",
"code": "const ScriptPayPalMarksDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"marksOptions\": \"() => ({})\",\n \"paypalScriptOptions\": \"() => ({})\"\n}"
"code": "const ScriptPayPalButtonsDefaults = {\n \"trigger\": \"'visible'\",\n \"clientId\": \"'test'\",\n \"components\": \"() => ['paypal-payments'] as Components[]\",\n \"paypalScriptOptions\": \"() => ({})\"\n}"
},
{
"name": "ScriptPayPalMessagesProps",
"kind": "interface",
"code": "interface ScriptPayPalMessagesProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * The client id for the paypal script.\n */\n clientId?: string\n /**\n * The options for the paypal buttons.\n */\n messagesOptions?: PayPalMessagesComponentOptions\n /**\n * The merchant id for the paypal script.\n */\n merchantId?: string\n /**\n * The partner attribution id for the paypal script.\n */\n partnerAttributionId?: string\n /**\n * The options for the paypal scipt.\n */\n paypalScriptOptions?: Partial<PayPalInput>\n}"
"code": "interface ScriptPayPalMessagesProps {\n /**\n * Customize the root element attributes.\n */\n rootAttrs?: HTMLAttributes & ReservedProps & Record<string, unknown>\n /**\n * Defines the trigger event to load the script.\n */\n trigger?: ElementScriptTrigger\n /**\n * Client ID or client token for PayPal SDK v6 authentication.\n */\n clientId?: string\n /**\n * Server-generated client token for SDK v6.\n */\n clientToken?: string\n /**\n * The merchant ID for the paypal script.\n */\n merchantId?: string | string[]\n /**\n * The partner attribution ID.\n */\n partnerAttributionId?: string\n /**\n * The page type context hint.\n */\n pageType?: PageTypes\n /**\n * The locale for the SDK (BCP-47 code).\n */\n locale?: string\n /**\n * Options for the PayPal Messages session.\n */\n messagesOptions?: PayPalMessagesOptions\n /**\n * The paypal script options.\n */\n paypalScriptOptions?: Partial<PayPalInput>\n}"
},
{
"name": "ScriptPayPalMessagesDefaults",
Expand Down Expand Up @@ -795,4 +785,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}"
}
]
}
}
Loading
Loading