On this page
No Headings
Last updated: June 3, 2026
You can enable your buyers to update their shipping options during checkout. After adding the OnShippingChange callback to your integration, your buyers can:
If a buyer updates their shipping options during checkout, the order must also update the OnShippingChange callback.
Note: In this documentation, we refer to both shipping and pickup as shipping option. The shipping option is represented by the object ShippingMethod.
You can add shipping options to either a client-side or server-side integration.
To provide shipping options to the buyer, add shipping options to the shipping object provided in the OrderRequest object and pass it inside the createOrder callback.
Make sure to have exactly one shipping option with selected: true as a default option. To support Buy Online, Pick up In Store (BOPIS) add only the .pickup shipping type ShippingMethod to the shipping options and set selected: true.
createOrder: { action in
let order = OrderRequest(
intent: .authorize,
purchaseUnits: [
PurchaseUnit(
amount: PurchaseUnit.Amount(currencyCode: .usd, value: "5.00"),
shipping: PurchaseUnit.Shipping(
options: [
ShippingMethod(
id: "SHIP_123",
label: "2-day Shipping",
selected: true,
type: .shipping,
amount: UnitAmount(currencyCode: .usd, value: "2.00")),
ShippingMethod(
id: "PICKUP_123",
label: "Pickup in store",
selected: false,
type: .pickup,
amount: UnitAmount(currencyCode: .usd, value: "0.00"))
],
),
),
],
applicationContext: OrderApplicationContext(userAction: .payNow)
)
action.create(order: order)
}For more information on how to implement the createOrder callback, refer to the initialize SDK instructions.
If you use a server-side integration, refer to the documentation for Server-side integration and use one of our APIs (NVP/SOAP, REST v1, or REST v2) to create an order with shipping options.
onShippingChange callbackImplement the onShippingChange callback to approve or reject a change a buyer makes to their shipping address or shipping option.
onShippingChange callbackDepending on your integration, you need to add the onShippingChange callback to either the PaymentButtonContainer or CheckoutConfig.init() or Checkout.start().
Add the onShippingChange callback to PaymentButtonContainer.
let paymentButton = PaymentButtonContainer()
paymentButton.setup(
...
onShippingChange: { change, action in
...
}
)If your integration programatically starts the SDK, you can add the onShippingChange callback to CheckoutConfig.init().
let config = CheckoutConfig(
...
onShippingChange: { change, action in
...
}
...
)Or you can add the onShippingChange callback when starting the checkout paysheet. Note: If you've already set the callback in CheckoutConfig.init(), setting it again here will overwrite the previous value. It is recommended that you only set it using one of these two ways.
Checkout.start(
...
onShippingChange: { change, action in
...
}
...
)You can approve the update a buyer makes to their address or shipping option.
onShippingChange: { change, action in
action.approve()
},
onApprove: {},
onCancel: {},
onError: {}You can reject an update to an address or shipping option that is not supported. This displays an error to the buyer that requires them to change their shipping option or address in order to proceed.
onShippingChange: { change, action in
switch change.type {
case .shippingAddress:
if !yourSupportedListOfZipCode.contains(change.selectedShippingAddress.postalCode) {
action.reject()
}
default:
break
}
}You can enable your buyers to update their shipping options during checkout. After adding the OnShippingChange callback to your integration, your buyers can:
If a buyer updates their shipping options during checkout, the order must also update the OnShippingChange callback.
Note: In this documentation, we refer to both shipping and pickup as shipping option. The shipping option is represented by the object ShippingMethod.
You can add shipping options to either a client-side or server-side integration.
To provide shipping options to the buyer, add shipping options to the shipping object provided in the OrderRequest object and pass it inside the createOrder callback.
Make sure to have exactly one shipping option with .selected(true) as a default option. To support Buy Online, Pick up In Store (BOPIS) add only the ShippingType.PICKUP shipping type ShippingMethod to the shipping options and set .selected(true).
val orderRequest: OrderRequest = OrderRequest.Builder()
.intent(OrderIntent.AUTHORIZE)
.purchaseUnitList(
arrayListOf(
PurchaseUnit.Builder()
.amount(
Amount.Builder()
.value("5.00")
.currencyCode(CurrencyCode.USD)
.build()
)
.shipping(
Shipping.Builder()
.options(
arrayListOf(
Options.Builder()
.id("1")
.selected(true)
.label("Standard Shipping")
.type(ShippingType.SHIPPING)
.amount(
UnitAmount.Builder()
.currencyCode(CurrencyCode.USD)
.value("10.00")
.build()
).build(),
Options.Builder()
.id("2")
.selected(false)
.label("In store pickup")
.type(ShippingType.PICKUP)
.amount(
UnitAmount.Builder()
.currencyCode(CurrencyCode.USD)
.value("3.00")
.build()
).build()
)
).build()
).build()
)
).build()For more information on how to implement the createOrder callback, refer to the initialize SDK instructions.
If you use a server-side integration, refer to the documentation for Server-side integration and use one of our APIs (NVP/SOAP, REST v1, or REST v2) to create an order with shipping options.
onShippingChange callbackImplement the onShippingChange callback to approve or reject a change a buyer makes to their shipping address or shipping option.
onShippingChange callbackDepending on your integration, you need to add the OnShippingChange callback to either the paymentButtonContainer or PayPalCheckout.startCheckout().
Add the OnShippingChange callback to PaymentButtonContainer.
paymentButtonContainer.setup(
createOrder = CreateOrder {},
onShippingChange = OnShippingChange { shippingChangeData, shippingChangeActions -> }
)If your integration programatically starts the SDK, add the OnShippingChange callback to PayPalCheckout.registerCallbacks().
PayPalCheckout.registerCallbacks(
onShippingChange = OnShippingChange { shippingChangeData, shippingChangeActions -> },
onApprove = OnApprove {}, onCancel = OnCancel {}, onError = OnError {}
)You can approve the update a buyer makes to their address or shipping option.
PayPalCheckout.registerCallbacks(
onShippingChange = OnShippingChange { shippingChangeData, shippingChangeActions ->
shippingChangeActions.approve()
},
onApprove = OnApprove {},
onCancel = OnCancel {},
onError = OnError {}
)You can reject an update to an address or shipping option that is not supported. This displays an error to the buyer that requires them to change their shipping option or address in order to proceed.
OnShippingChange { shippingChangeData, shippingChangeActions ->
when (shippingChangeData.shippingChangeType) {
ShippingChangeType.ADDRESS_CHANGE -> {
// Example - Reject all shipping addresses outside of the US
if (shippingChangeData.shippingAddress.countryCode != "US") {
shippingChangeActions.reject()
}
}
}
}