From 0b9481e712bfec8c8df93e3992c57c8776ddbbfe Mon Sep 17 00:00:00 2001 From: Ruben Cougil Date: Wed, 30 Sep 2026 11:20:44 +0200 Subject: [PATCH 1/3] PAY-6085: Document PayPal Buttons on PDP Documents PayPal Buttons support on the product details page (PDP). - Added the `location` option to the `PayPalButtons` container docs, and a product details page usage example that builds its shadow cart from the `pdp/data` and `pdp/values` events. - Documented the `pdp/data` and `pdp/values` events (listened to by `PayPalButtons` on the `PRODUCT_DETAIL` location) on the Payment Services events page. - Unlike GooglePay on PDP, PayPal Buttons on PDP supports virtual and downloadable products in addition to simple, configurable, and bundle products. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../containers/paypal-buttons.mdx | 28 ++++++++++ .../docs/dropins/payment-services/events.mdx | 54 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx index 14f499c14..03a0fb9cb 100644 --- a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx +++ b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx @@ -7,6 +7,7 @@ sidebar: import TableWrapper from '@components/TableWrapper.astro'; import Link from '@components/Link.astro'; +import { Aside } from '@astrojs/starlight/components'; The `PayPalButtons` container renders a set of checkout buttons that enable shoppers to pay using — including PayPal, Venmo, Pay Later, and debit/credit card, depending on which funding sources are enabled for the merchant. @@ -17,6 +18,7 @@ The `PayPalButtons` container provides the following configuration options: | Option | Type | Req? | Description | |--------|------|------|-------------| +| `location` | string | Yes | Location where the PayPal buttons are rendered. Must be either `CHECKOUT` or `PRODUCT_DETAIL`. | | `onButtonClick` | function | No | Called when the shopper clicks a PayPal button. Receives a `showPaymentSheet` function, which must be called synchronously to begin the PayPal checkout and show the payment sheet. If not provided, clicking the button automatically triggers the payment sheet. | | `onSuccess` | function | No | Called when the payment completes successfully. Receives `{ cartId: string }`. If the function returns a promise, it is awaited before marking the payment as successful. If the promise rejects, the payment is marked as failed and the error is passed to `onError` (if provided). | | `onError` | function | No | Called when the payment flow fails or is aborted. Receives `{ name: string, message: string }`, containing localized, user-facing error details. These values can be translated using `PaymentServices.PayPalButtons.errors` [language definitions](/dropins/payment-services/dictionary/). | @@ -38,9 +40,35 @@ The following example demonstrates how to use the `PayPalButtons` container on t import PayPalButtons from '@dropins/storefront-payment-services/containers/PayPalButtons.js'; import { render as PaymentServices } from '@dropins/storefront-payment-services/render.js'; import * as orderApi from '@dropins/storefront-order/api.js'; +import { PaymentLocation } from '@dropins/storefront-payment-services/api.js'; const $content = document.createElement('div'); PaymentServices.render(PayPalButtons, { + location: PaymentLocation.CHECKOUT, + onSuccess: ({ cartId }) => orderApi.placeOrder(cartId), + onError: (error) => { console.error(error) }, +})($content); +``` + +### Product details page example + +On the product details page, the `PayPalButtons` container builds its own shadow cart from the product details drop-in's and events. + + + +The following example demonstrates how to use the `PayPalButtons` container on a product details page. + +```js +import PayPalButtons from '@dropins/storefront-payment-services/containers/PayPalButtons.js'; +import { render as PaymentServices } from '@dropins/storefront-payment-services/render.js'; +import * as orderApi from '@dropins/storefront-order/api.js'; +import { PaymentLocation } from '@dropins/storefront-payment-services/api.js'; + +const $content = document.createElement('div'); +PaymentServices.render(PayPalButtons, { + location: PaymentLocation.PRODUCT_DETAIL, onSuccess: ({ cartId }) => orderApi.placeOrder(cartId), onError: (error) => { console.error(error) }, })($content); diff --git a/src/content/docs/dropins/payment-services/events.mdx b/src/content/docs/dropins/payment-services/events.mdx index 58fbb54d5..0b4c256c6 100644 --- a/src/content/docs/dropins/payment-services/events.mdx +++ b/src/content/docs/dropins/payment-services/events.mdx @@ -21,6 +21,8 @@ The Payment Services drop-in uses the [event bus](/sdk/reference/events) to emit | [checkout/updated](#checkoutupdated-listens) | Listens | Fired by the [Checkout](/dropins/checkout/events/) drop-in when the checkout state is updated. Read by the `GooglePay` container at button click time to determine the selected shipping method and billing address. | | [payment-services/initialized/checkout](#payment-servicesinitializedcheckout-emits) | Emits | Emitted when the drop-in finishes initializing for the `CHECKOUT` location. | | [payment-services/initialized/product-detail](#payment-servicesinitializedproduct-detail-emits) | Emits | Emitted when the drop-in finishes initializing for the `PRODUCT_DETAIL` location. | +| [pdp/data](#pdpdata-listens) | Listens | Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpdata-emits-and-listens) drop-in with product data for the page. Used by the `PayPalButtons` container on the `PRODUCT_DETAIL` location to build the shadow cart. | +| [pdp/values](#pdpvalues-listens) | Listens | Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpvalues-emits-and-listens) drop-in with the shopper's selected product SKU, quantity, and options. Used by the `PayPalButtons` container on the `PRODUCT_DETAIL` location to build the shadow cart. | ## Event details @@ -130,3 +132,55 @@ See [Payment method availability](/dropins/payment-services/initialization/#paym ### `payment-services/initialized/product-detail` (emits) See [Payment method availability](/dropins/payment-services/initialization/#payment-method-availability). + +--- + +### `pdp/data` (listens) + +Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpdata-emits-and-listens) drop-in with product data for the page. The `PayPalButtons` container listens to this event, together with [`pdp/values`](#pdpvalues-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. + +Both events must have been emitted at least once on the event bus before clicking a PayPal button. + +#### Event payload + +```typescript +PdpDataModel +``` + +See [`PdpDataModel`](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpdata-emits-and-listens) for the full type definition. + +#### Example + +```js +import { events } from '@dropins/tools/event-bus.js'; + +events.on('pdp/data', (payload) => { + console.log('pdp/data event received:', payload); +}); +``` + +--- + +### `pdp/values` (listens) + +Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpvalues-emits-and-listens) drop-in with the shopper's currently selected product SKU, quantity, and options. The `PayPalButtons` container listens to this event, together with [`pdp/data`](#pdpdata-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. + +Both events must have been emitted at least once on the event bus before clicking a PayPal button. + +#### Event payload + +```typescript +PdpValuesModel +``` + +See [`PdpValuesModel`](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpvalues-emits-and-listens) for the full type definition. + +#### Example + +```js +import { events } from '@dropins/tools/event-bus.js'; + +events.on('pdp/values', (payload) => { + console.log('pdp/values event received:', payload); +}); +``` From 8d340cacfb16f43357cd7d75236a25f201d4ccf3 Mon Sep 17 00:00:00 2001 From: Ruben Cougil Date: Mon, 5 Oct 2026 12:27:21 +0200 Subject: [PATCH 2/3] PAY-6085: Apply documentation review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../payment-services/containers/paypal-buttons.mdx | 8 ++++---- src/content/docs/dropins/payment-services/events.mdx | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx index 03a0fb9cb..56926323b 100644 --- a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx +++ b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx @@ -18,7 +18,7 @@ The `PayPalButtons` container provides the following configuration options: | Option | Type | Req? | Description | |--------|------|------|-------------| -| `location` | string | Yes | Location where the PayPal buttons are rendered. Must be either `CHECKOUT` or `PRODUCT_DETAIL`. | +| `location` | string | Yes | Location where the PayPal buttons are rendered. Possible values are: `CHECKOUT` or `PRODUCT_DETAIL`. | | `onButtonClick` | function | No | Called when the shopper clicks a PayPal button. Receives a `showPaymentSheet` function, which must be called synchronously to begin the PayPal checkout and show the payment sheet. If not provided, clicking the button automatically triggers the payment sheet. | | `onSuccess` | function | No | Called when the payment completes successfully. Receives `{ cartId: string }`. If the function returns a promise, it is awaited before marking the payment as successful. If the promise rejects, the payment is marked as failed and the error is passed to `onError` (if provided). | | `onError` | function | No | Called when the payment flow fails or is aborted. Receives `{ name: string, message: string }`, containing localized, user-facing error details. These values can be translated using `PaymentServices.PayPalButtons.errors` [language definitions](/dropins/payment-services/dictionary/). | @@ -52,13 +52,13 @@ PaymentServices.render(PayPalButtons, { ### Product details page example -On the product details page, the `PayPalButtons` container builds its own shadow cart from the product details drop-in's and events. +The `PayPalButtons` container builds its own shadow cart from the product details drop-in's and events on the product details page. -The following example demonstrates how to use the `PayPalButtons` container on a product details page. +The following example demonstrates how to use the `PayPalButtons` container on the product details page. ```js import PayPalButtons from '@dropins/storefront-payment-services/containers/PayPalButtons.js'; diff --git a/src/content/docs/dropins/payment-services/events.mdx b/src/content/docs/dropins/payment-services/events.mdx index 0b4c256c6..cd1cea26a 100644 --- a/src/content/docs/dropins/payment-services/events.mdx +++ b/src/content/docs/dropins/payment-services/events.mdx @@ -7,6 +7,7 @@ sidebar: --- import TableWrapper from '@components/TableWrapper.astro'; +import Link from '@components/Link.astro'; The Payment Services drop-in uses the [event bus](/sdk/reference/events) to emit and listen for events, enabling communication between drop-ins and external integrations. @@ -21,8 +22,8 @@ The Payment Services drop-in uses the [event bus](/sdk/reference/events) to emit | [checkout/updated](#checkoutupdated-listens) | Listens | Fired by the [Checkout](/dropins/checkout/events/) drop-in when the checkout state is updated. Read by the `GooglePay` container at button click time to determine the selected shipping method and billing address. | | [payment-services/initialized/checkout](#payment-servicesinitializedcheckout-emits) | Emits | Emitted when the drop-in finishes initializing for the `CHECKOUT` location. | | [payment-services/initialized/product-detail](#payment-servicesinitializedproduct-detail-emits) | Emits | Emitted when the drop-in finishes initializing for the `PRODUCT_DETAIL` location. | -| [pdp/data](#pdpdata-listens) | Listens | Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpdata-emits-and-listens) drop-in with product data for the page. Used by the `PayPalButtons` container on the `PRODUCT_DETAIL` location to build the shadow cart. | -| [pdp/values](#pdpvalues-listens) | Listens | Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpvalues-emits-and-listens) drop-in with the shopper's selected product SKU, quantity, and options. Used by the `PayPalButtons` container on the `PRODUCT_DETAIL` location to build the shadow cart. | +| [pdp/data](#pdpdata-listens) | Listens | Emitted by the drop-in with product data for the page. The `PayPalButtons` container listens to this event on the `PRODUCT_DETAIL` location to build the shadow cart. | +| [pdp/values](#pdpvalues-listens) | Listens | Sent by the drop-in containing the shopper's selected product SKU, quantity, and options. The `PayPalButtons` container uses this event on the `PRODUCT_DETAIL` location to build the shadow cart. | ## Event details @@ -137,7 +138,7 @@ See [Payment method availability](/dropins/payment-services/initialization/#paym ### `pdp/data` (listens) -Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpdata-emits-and-listens) drop-in with product data for the page. The `PayPalButtons` container listens to this event, together with [`pdp/values`](#pdpvalues-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. +Emitted by the drop-in with product data for the page. The `PayPalButtons` container listens to this event, together with [`pdp/values`](#pdpvalues-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. Both events must have been emitted at least once on the event bus before clicking a PayPal button. @@ -163,7 +164,7 @@ events.on('pdp/data', (payload) => { ### `pdp/values` (listens) -Fired by the [Product Details](https://experienceleague.adobe.com/en/tools/commerce-storefront/dropins/product-details/events/#pdpvalues-emits-and-listens) drop-in with the shopper's currently selected product SKU, quantity, and options. The `PayPalButtons` container listens to this event, together with [`pdp/data`](#pdpdata-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. +Sent by the drop-in with the shopper's currently selected product SKU, quantity, and options. The `PayPalButtons` container listens to this event, together with [`pdp/data`](#pdpdata-listens), to build a shadow cart when the shopper clicks a PayPal button on the `PRODUCT_DETAIL` location. Both events must have been emitted at least once on the event bus before clicking a PayPal button. From 1cdccb47c55d0924d20a88151b95446d658c9d25 Mon Sep 17 00:00:00 2001 From: Ruben Cougil Date: Tue, 13 Oct 2026 12:27:10 +0200 Subject: [PATCH 3/3] PAY-6085: Apply PayPal Buttons documentation feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../dropins/payment-services/containers/paypal-buttons.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx index 56926323b..1d9c79788 100644 --- a/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx +++ b/src/content/docs/dropins/payment-services/containers/paypal-buttons.mdx @@ -18,7 +18,7 @@ The `PayPalButtons` container provides the following configuration options: | Option | Type | Req? | Description | |--------|------|------|-------------| -| `location` | string | Yes | Location where the PayPal buttons are rendered. Possible values are: `CHECKOUT` or `PRODUCT_DETAIL`. | +| `location` | string | Yes | Location where the PayPal buttons are rendered. Possible values are: `CHECKOUT` and `PRODUCT_DETAIL`. | | `onButtonClick` | function | No | Called when the shopper clicks a PayPal button. Receives a `showPaymentSheet` function, which must be called synchronously to begin the PayPal checkout and show the payment sheet. If not provided, clicking the button automatically triggers the payment sheet. | | `onSuccess` | function | No | Called when the payment completes successfully. Receives `{ cartId: string }`. If the function returns a promise, it is awaited before marking the payment as successful. If the promise rejects, the payment is marked as failed and the error is passed to `onError` (if provided). | | `onError` | function | No | Called when the payment flow fails or is aborted. Receives `{ name: string, message: string }`, containing localized, user-facing error details. These values can be translated using `PaymentServices.PayPalButtons.errors` [language definitions](/dropins/payment-services/dictionary/). | @@ -52,7 +52,7 @@ PaymentServices.render(PayPalButtons, { ### Product details page example -The `PayPalButtons` container builds its own shadow cart from the product details drop-in's and events on the product details page. +The `PayPalButtons` container builds its own shadow cart from the Product Details drop-in's and events on the product details page.