Last updated: September 14, 2026
This guide describes how to move an existing PayPal Mobile SDK v2 (2.x) iOS integration to v3.0.0. The largest changes are in PayPal Checkout: the client was replaced with a new class in a new module, checkout is now session-first, CoreConfig requires a merchantID, return URLs moved into a URL config, and App Switch now requires Universal Links (v2's web flow used a hardcoded callback scheme for its own redirects).
| Area | v2 (2.x) | v3 |
|---|---|---|
| Client class | PayPalWebCheckoutClient (module PayPalWebPayments) | PayPalClient (module PayPalPayments) |
CoreConfig | client ID + environment | adds required merchantID, optional bnCode |
| Session | none | createPayPalSession(sessionType:userIdentity:urlConfig:userAction:) is required before start() |
| Return URLs | hardcoded sdk.ios.paypal callback scheme | PayPalURLConfig passed to createPayPalSession(). App Switch uses Universal Links |
start() | start(request:) | start(orderID:completion:) |
| Result | completion or delegate | completion with .success or .failure; cancellation is a .failure, so check PayPalError.isCheckoutCanceled(error) or isVaultCanceled(error) |
| Return handling | handled internally by ASWebAuthenticationSession | forward the Universal Link through handleReturnURL(url) |
Card (ACDC) keeps its own client; the main change it inherits is the merchantID on CoreConfig. Card's approveOrder() still resolves 3DS inline on iOS.
sdk.ios.paypal scheme for its own redirect.Bump CorePayments and swap the PayPal Checkout product for its v3 successor. The module was renamed along with the client:
# Podfile
pod 'PayPal/CorePayments', '~> 3.0'
pod 'PayPal/PayPalPayments', '~> 3.0' # was PayPal/PayPalWebPayments in v2
pod 'PayPal/PaymentButtons', '~> 3.0'
pod 'PayPal/FraudProtection', '~> 3.0'Use this diff to guide the change:
let config = CoreConfig(
clientID: "<CLIENT_ID>",
environment: .sandbox,
+ merchantID: "<MERCHANT_ID>" // now required, distinct from your client ID
)
- let client = PayPalWebCheckoutClient(config: config)
+ let client = PayPalClient(config: config)
+ let urlConfig = PayPalURLConfig(
+ returnAppURL: URL(string: "https://example.com/merchant-app/return")!,
+ cancelAppURL: URL(string: "https://example.com/merchant-app/cancel")!,
+ fallbackSchemeURL: URL(string: "merchantapp://return")!
+ )
func onPayPalButtonTapped() async throws {
+ // NEW: prepare the session before start()
+ client.createPayPalSession(
+ sessionType: .checkout,
+ userIdentity: PayPalUserIdentity(email: "buyer@example.com", phone: nil),
+ urlConfig: urlConfig,
+ userAction: .continue
+ )
let orderID = try await myServer.createOrder()
- client.start(request: PayPalWebCheckoutRequest(orderID: orderID)) { result in /* ... */ }
+ client.start(orderID: orderID) { result in
+ switch result {
+ case .success(let checkout): captureOrder(checkout.orderID)
+ case .failure(let error):
+ if PayPalError.isCheckoutCanceled(error) {
+ showCheckoutScreen()
+ } else {
+ showError(error.localizedDescription)
+ }
+ }
+ }
}
+ // NEW in v3: forward the Universal Link return to the SDK
+ func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
+ guard let url = userActivity.webpageURL else { return }
+ client.handleReturnURL(url)
+ }Add the custom-scheme fallbackSchemeURL under CFBundleURLTypes. It's optional on PayPalURLConfig; see Install and set up for why you should set it regardless. Also declare paypal under LSApplicationQueriesSchemes so the SDK can detect the PayPal app, and add the Associated Domains entitlement for your return domain. v2's web flow needed none of these for PayPal Checkout, because its return handling was internal to ASWebAuthenticationSession, built on the hardcoded sdk.ios.paypal scheme.
sdk.ios.paypal isn't retired
sdk.ios.paypal isn't retired in v3. It's still the SDK's internal callback scheme for Card's 3D Secure ASWebAuthenticationSession challenge, and it also still backs the PayPal Checkout in-app-browser fallback's own redirect internally. What changed is the buyer-facing, merchant-configured return path for PayPal Checkout and saving payment methods: that's now Universal Links, with fallbackSchemeURL as backup, not something built on sdk.ios.paypal that you need to register or handle yourself.
PayPalClient (module PayPalPayments) and no references to PayPalWebCheckoutClient or PayPalWebPayments remain.createPayPalSession(sessionType:) → start(orderID:) → return through handleReturnURL(url) → capture.sessionNotStarted does not occur, confirming createPayPalSession() runs before start().CoreConfig, and register your return links.Cards
Accept Advanced Credit and Debit Card (ACDC) payments on iOS, including saving payment methods, with PayPal Mobile SDK v3.0.0.
From v1 to v2
Update your iOS integration from PayPal Mobile SDK v1 to v2. Move from delegate callbacks to completion handlers and async/await. Adopt the unified CoreSDKError type. Handle cancellations as errors.