From 250fe5a93af44841419f38e28d6b6b3d67d99826 Mon Sep 17 00:00:00 2001 From: Gal Naor Date: Thu, 22 Oct 2026 10:43:14 +0300 Subject: [PATCH 1/2] feat(payments): type the checkout's shipping address and fee Co-Authored-By: Claude Opus 5.5 --- packages/sdk/src/index.ts | 2 ++ packages/sdk/src/modules/payments.types.ts | 38 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index b6658f07..f271c82e 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -146,6 +146,7 @@ export type { CheckoutItem, CheckoutItemRecurring, CheckoutPresentation, + CheckoutShipping, CheckoutElement, CheckoutMount, MountableCheckout, @@ -163,6 +164,7 @@ export type { PurchaseItem, PurchaseStatus, RefundParams, + ShippingAddress, RefundResult, CancelSubscriptionOptions, SubscriptionResult, diff --git a/packages/sdk/src/modules/payments.types.ts b/packages/sdk/src/modules/payments.types.ts index 9e2b1c78..cdda4349 100644 --- a/packages/sdk/src/modules/payments.types.ts +++ b/packages/sdk/src/modules/payments.types.ts @@ -63,6 +63,38 @@ export interface CheckoutBuyer { phone?: string; } +/** + * A shipping address. Returned on a purchase whether your app or the provider collected it. + */ +export interface ShippingAddress { + /** Recipient's full name, 1 to 300 characters. */ + name: string; + /** Street address, 1 to 300 characters. */ + line1: string; + /** Apartment, suite or building, up to 300 characters. */ + line2?: string | null; + /** City, up to 120 characters. Some countries address by region and postal code alone. */ + city?: string | null; + /** State, province or region, up to 300 characters. */ + region?: string | null; + /** Postal or ZIP code, up to 60 characters. */ + postal_code?: string | null; + /** Two-letter ISO 3166-1 country code, such as `'US'`. */ + country: string; +} + +/** + * Shipping for a checkout with at least one `shippable` item. Supported for PayPal one-time checkouts only. + * + * Compute the fee on your server, never in the browser. When the fee depends on the address, such as by distance or zone, collect the address in your app and pass it in `address`: PayPal shows it to the buyer locked, so the order ships where the fee was computed for. When the fee doesn't depend on the address, pass only `amount` and PayPal asks the buyer for the address. + */ +export interface CheckoutShipping { + /** Address your app collected. Omit it to let the provider ask the buyer. */ + address?: ShippingAddress; + /** Shipping fee in minor units, shown to the buyer as its own shipping line. Omit it for free shipping. */ + amount?: number; +} + /** * How the buyer pays. * @@ -91,6 +123,8 @@ export interface CreateCheckoutParams { idempotency_key?: string; /** How the buyer pays. Defaults to `'redirect'`. PayPal apps must pass `'embedded'`, and Wix Payments supports only `'redirect'`. */ presentation?: CheckoutPresentation; + /** Shipping address and fee. Allowed only when at least one item is `shippable`. Supported for PayPal one-time checkouts only; other providers and subscriptions reject it with `invalid_request`. */ + shipping?: CheckoutShipping; } /** @@ -204,6 +238,10 @@ export interface Purchase { metadata?: Record | null; /** ID of the subscription, for recurring purchases. */ subscription_id?: string | null; + /** Where the order ships, whether your app or the provider collected the address. Always `null` unless you call with the service role. Save it on your order record. */ + shipping_address?: ShippingAddress | null; + /** Shipping fee in minor units, when the checkout charged one. */ + shipping_amount?: number | null; /** ID of the payment to pass to [`refund()`](/developers/references/sdk/docs/interfaces/service-role-payments#refund). For a PayPal subscription it's the latest charge, returned only with the service role: read it when you start a refund and reuse it on retries. It's `null` where the provider doesn't name a payment, such as a PayPal subscription whose latest charge is already refunded. */ payment_id?: string | null; } From 3c520abb443e1fe4b57add37abd355ee3ed4ee12 Mon Sep 17 00:00:00 2001 From: Gal Naor Date: Thu, 22 Oct 2026 10:45:08 +0300 Subject: [PATCH 2/2] docs(payments): shippable items skip PayPal's address step when shipping.address is passed Co-Authored-By: Claude Opus 5.5 --- packages/sdk/src/modules/payments.types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/src/modules/payments.types.ts b/packages/sdk/src/modules/payments.types.ts index cdda4349..e027f21f 100644 --- a/packages/sdk/src/modules/payments.types.ts +++ b/packages/sdk/src/modules/payments.types.ts @@ -43,7 +43,7 @@ export interface CheckoutItem { amount: number; /** Number of units, from 1 to 1,000,000. Defaults to `1`. */ quantity?: number; - /** Whether the item ships, so the provider collects a shipping address. */ + /** Whether the item ships. The provider then collects a shipping address, unless you pass one in `shipping.address`. */ shippable?: boolean; /** Billing terms. Set this to sell the item as a subscription. PayPal and Wix Payments allow one recurring item per checkout, and PayPal allows no other items with it. */ recurring?: CheckoutItemRecurring;