# Troubleshooting (/sdk/ios/troubleshooting)

Common problems integrating the PayPal Mobile SDK v3.0.0 on iOS, organized by symptom.



Common problems integrating the PayPal Mobile SDK v3.0.0 on iOS, organized by symptom. For an error that happens inside one specific flow, also check that guide's Result handling section.

## Build and dependency [#build-and-dependency]

This is the build error you're most likely to hit while adding the SDK.

### Swift Package Manager or CocoaPods cannot resolve the PayPal products [#swift-package-manager-or-cocoapods-cannot-resolve-the-paypal-products]

* **Cause:** the product name is wrong or not added.
* **Fix:** add `CorePayments` plus the products you use (`PayPalPayments`, `FraudProtection`, `PaymentButtons`, `CardPayments`).
* **Verify:** the package resolves and the app builds successfully.

## Setup and initialization [#setup-and-initialization]

These errors show up early, usually on your first call into the SDK, and generally trace back to config or call order.

### `PayPalError.sessionNotStartedError` returned on `start()` or `vault()` [#paypalerrorsessionnotstartederror-returned-on-start-or-vault]

* **Cause:** `createPayPalSession()` was not called first.
* **Fix:** call `createPayPalSession(sessionType:userIdentity:urlConfig:userAction:)` on `PayPalClient` in your button's action, before or alongside order creation.
* **Verify:** `start()` or `vault()` proceeds without a `sessionNotStartedError` failure.

### Auth or configuration errors right after `start()` [#auth-or-configuration-errors-right-after-start]

* **Cause:** wrong `environment`, or a missing or not-valid `merchantID`, required in v3 and distinct from your client ID.
* **Fix:** recheck `CoreConfig`: confirm `clientID`, `merchantID`, and whether you're using `.sandbox` or `.live`.
* **Verify:** `start()` launches the checkout flow without an auth or configuration error.

## Return and redirect [#return-and-redirect]

These problems appear once the buyer leaves your app for checkout and needs to find their way back.

### The buyer completes checkout but never returns to your app [#the-buyer-completes-checkout-but-never-returns-to-your-app]

* **Cause:** your Universal Link is not associated with your domain, or the return/cancel URLs are not under the associated domain.
* **Fix:** confirm the **Associated Domains** entitlement, `applinks:example.com`, and that your AASA file is served at `https://<domain>/.well-known/apple-app-site-association`. Keep return/cancel URLs on that domain. Setting `fallbackSchemeURL` in `CFBundleURLTypes` covers Universal Link delivery failures.
* **Verify:** completing checkout returns the buyer to your app.

### The completion handler never fires after the buyer returns [#the-completion-handler-never-fires-after-the-buyer-returns]

* **Cause:** the return URL was not forwarded to the SDK.
* **Fix:** call `checkoutClient.handleReturnURL(url)` on your `PayPalClient`, from `scene(_:continue:)`, or `.onOpenURL` in SwiftUI.
* **Verify:** the completion handler fires with a result after the buyer returns.

### Checkout stayed in the in-app browser instead of opening the PayPal app [#checkout-stayed-in-the-in-app-browser-instead-of-opening-the-paypal-app]

* **Cause:** `LSApplicationQueriesSchemes` is missing `paypal`, or expected fallback: the buyer is not eligible, the PayPal app is not installed, the buyer is not in the US, or the identity email does not match the signed-in PayPal account.
* **Fix:** declare `paypal` under `LSApplicationQueriesSchemes`. To exercise the app-switch path in testing, meet all trigger conditions; see [PayPal Checkout](/sdk/ios/add-payment-methods/paypal-checkout#test-and-go-live) → Test and go live.
* **Verify:** with all trigger conditions met, checkout opens in the PayPal app instead of the in-app browser.

## Result and challenge [#result-and-challenge]

These come up after the buyer returns, when the SDK is reporting an outcome you didn't expect.

### Unexpected cancel, or a `.failure` you expected to be a cancel [#unexpected-cancel-or-a-failure-you-expected-to-be-a-cancel]

* **Cause:** cancellation is always surfaced as a `.failure`, never a separate `.cancel` case, for either PayPal or Card.
* **Fix:** before treating a failure as an error, check `PayPalError.isCheckoutCanceled(error)` / `isVaultCanceled(error)` for PayPal, or `CardError.isThreeDSecureCanceled(error)` for Card, and route the buyer back to checkout.
* **Verify:** a genuine cancel is now identified by the `isCanceled` check instead of falling through as an unhandled error.

### Card fails with a 3DS URL error [#card-fails-with-a-3ds-url-error]

* **Cause:** `CardError.threeDSecureURLError`: the challenge URL failed iOS's PayPal 3DS validation. On `approveOrder()`, the SDK checks the URL is a genuine PayPal Helios `flow=3ds` page before opening it. On `vault()`, the check is slightly weaker: it only confirms the URL contains `helios`, without also requiring `flow=3ds`.
* **Fix:** confirm you are on a genuine PayPal environment and order. If it persists, capture the URL and contact support.
* **Verify:** the 3DS challenge opens without a `threeDSecureURLError`.

## Still stuck? [#still-stuck]

* Re-check Install and set up.
* Look up exact class and method signatures in the generated API reference, DocC.
* Run the sample app to compare against a known-good integration.
* Contact your PayPal account team or support.

## See also [#see-also]

* [Install and set up](/sdk/ios/install-and-setup): add the SDK, initialize `CoreConfig`, and register your return links.
* [PayPal Checkout](/sdk/ios/add-payment-methods/paypal-checkout): integrate One-Time Checkout, save payment methods, Pay Later, and PayPal Credit.
* [Cards](/sdk/ios/add-payment-methods/card): integrate card payments and saving cards.
