---
title: 'Mobile SDKs FAQs '
slug: sdks/mobile-sdks/faqs
hidden: false
sidebar_order: 999
sidebar_label: 'FAQs '
metadata:
  title: Mobile SDK FAQs —  Online Payments | Pine Labs
  description: >-
    Answers to common questions about Pine Labs SDK integration: requirements,
    testing, compatibility, security and troubleshooting.
  keywords: >-
    ios sdk faq, pine labs mobile sdk, swift integration, upi intent, payment
    sdk troubleshooting, ios 16
  robots: index
excerpt: Find answers to common questions about the Pine Labs iOS SDK
---
<div className="pill-tabs">
<CodeTabs>

<Tab label="Android">
<br/>
<h2 class="pl-4">Android Mobile SDK FAQs</h2>
<div className="p-4 faq-section">
<details>
<summary><b>1. Which method should I use to start the checkout flow?</b></summary>

<br/>

Use `initializeSDK` on `ExpressSDKInitializer`.

</details>

---

<details>
<summary><b>2. What should I do when the onSuccess callback is received?</b></summary>

<br/>

Show a "processing" experience immediately, then verify the order on your backend or using the Transaction Status API. Only mark the order as completed after successful verification.

</details>

---

<details>
<summary><b>3. What is the difference between onError and onCancel callbacks?</b></summary>

<br/>

`onError` indicates a technical or business failure.

`onCancel` indicates that the user or payment flow was cancelled.

Treat both outcomes as non-successful transactions, but use different retry flows and user messaging strategies.

</details>

---

<details>
<summary><b>4. Why am I getting token-related errors?</b></summary>

<br/>

The initializer returns invalid token errors for null, empty, or invalid contexts.

Also verify:

- Token generation timing
- Token expiry windows
- Correct environment token usage

Make sure you are using the correct environment token.

</details>

---

<details>
<summary><b>5. Can I retry a payment using the same token?</b></summary>

<br/>

Best practice is no. Generate a fresh backend token for each payment attempt to avoid duplicate, expired, or conflicting order states.

</details>

---

<details>
<summary><b>6. How should I use sandbox mode?</b></summary>

<br/>

Enable sandbox mode only for QA and UAT testing. Keep production builds hard-wired to production configuration and validate this as part of your release checklist.

</details>

---

<details>
<summary><b>7. What information should I store for troubleshooting and support?</b></summary>

<br/>

Store the following information:

- `orderId`
- Your `attemptId`
- Callback type
- SDK code and message
- Timestamp
- Backend verification result
- Traces and logs from Logcat

Avoid storing sensitive payloads.

</details>

---

<details>
<summary><b>8. How do I resolve a Gradle sync error?</b></summary>

<br/>

Please invalidate cache and restart, and make sure you are using the latest version of the SDK.

**Merchant action:**

- In Android Studio, go to **File > Invalidate Caches / Restart**
- Re-sync Gradle
- Ensure the correct JDK and Gradle wrapper versions are configured for the project
- If the issue persists, delete the local `.gradle` cache and sync again

</details>

---

<details>
<summary><b>9. Why am I getting an SDK start error related to device or network checks?</b></summary>

<br/>

If the SDK throws an error while starting, make sure:

- The device is not rooted
- The internet connection is stable
- The SDK can access the internet when using VPNs, proxies, or specific network protocols

**Merchant action:**

- Verify that the device is not rooted (the SDK blocks rooted devices)
- Check active internet connectivity and any firewall, proxy, or VPN restrictions
- Confirm that the app has internet permission and that network security settings allow access to SDK endpoints
- Retry SDK initialization using a fresh token, if applicable

</details>

---

<details>
<summary><b>10. What should I do if the transaction fails?</b></summary>

<br/>

**Transaction Failed** – Transaction failed due to an API error, timeout, or session expiry.

**Merchant action:**

- Do not mark the order as paid based solely on the client callback
- Re-verify the payment status using your backend or reconciliation API
- If the session has expired, generate a fresh token or session and retry

</details>

---

<details>
<summary><b>11. What should I do if the transaction is cancelled?</b></summary>

<br/>

**Transaction Cancelled** – The end user cancelled the transaction.

**Merchant action:**

- Mark the payment attempt as cancelled (not failed) in analytics
- Keep the cart or order recoverable and allow a quick retry
- Avoid creating duplicate orders during repeated payment attempts

</details>
</div>
</Tab>

<Tab label="iOS">
<br/>
<h2 class="pl-4">iOS FAQs</h2>
<div className="p-4 faq-section">

<details>
<summary><b>1. What iOS versions and Swift versions are supported?</b></summary>

<br/>

The SDK requires:

- **iOS 16+**
- **Xcode 15+**
- **Swift 5**

Apps written in Swift 4 or later and Objective-C are supported.

</details>

---

<details>
<summary><b>2. Payments fail on the iOS Simulator but work on a real device. Why?</b></summary>

<br/>

On the iOS Simulator, Apple may block network requests due to stricter security and SSL validation rules.

If the payment request fails during SSL handshake:

- Ensure the Pine Labs domain is allowlisted
- Verify App Transport Security (ATS) settings in Info.plist

**Testing on a physical device is strongly recommended for final validation.**

</details>

---

<details>
<summary><b>3. After adding the SDK, the import Pine Labs Online is not coming up automatically.</b></summary>

<br/>

To resolve this issue:

- Make sure that you see the framework under your app target **Frameworks, Libraries and Embedded Content**
- Make sure that it is in **Embed and Sign**
- If issue still persists, clean the build and build again

</details>

---

<details>
<summary><b>4. My project fails to build after adding the SDK. What could be wrong?</b></summary>

<br/>

Common causes include:

- Unsupported Swift version (must be Swift 5+)
- Incompatible iOS deployment target
- Outdated dependency manager setup (SPM)

Verify that your project meets all SDK prerequisites.

</details>

---

<details>
<summary><b>5. Does the SDK work with both UIKit and SwiftUI apps?</b></summary>

<br/>

Yes. The SDK can be integrated into UIKit-based apps and SwiftUI apps, provided the app meets the required iOS and Swift versions.

</details>

---

<details>
<summary><b>6. How do I handle payment success, failure, or cancellation?</b></summary>

<br/>

The SDK provides callbacks for:

- `onSuccessResponse`
- `onFailureResponse`
- `onCancelTxn`

These callbacks must be implemented to correctly handle the transaction outcome and update your app UI.

In all these cases we get Order ID, in some cases we also get status and error message. **Using the Order ID it is recommended that you do an enquiry API call and verify the status of the order and proceed accordingly.**

</details>

---

<details>
<summary><b>7. Can I test the SDK entirely on the simulator?</b></summary>

<br/>

Basic testing for most of the pay modes is possible except the UPI Intent flow, but end-to-end payment testing should be done on a real device to avoid simulator-specific network and security issues.

</details>

---

<details>
<summary><b>8. How do I switch from test to production?</b></summary>

<br/>

When you initialise the SDK, we have provided an environment variable in the `startPayment` function signature. Using that one can easily switch from testing environment (`.uat`) to live production environment (`.prod`).

**Important:** Make sure that the order is created in the correct environment. If order created in test environment is given to SDK when we have set the `(environment == .prod)` then Order Not Found error will be displayed.

</details>

---

<details>
<summary><b>9. Can API keys be stored directly in the iOS app?</b></summary>

<br/>

**No.** API keys must be generated and passed securely from your backend. Hardcoding keys in the app is not recommended.

</details>

---

<details>
<summary><b>10. My app is written in `Swift 4`. Can I integrate the SDK?</b></summary>

<br/>

**Yes.** Apps written in Swift 4 or later can integrate the SDK as long as they are built using a Swift 5–compatible Xcode version (Xcode 15+) and target iOS 16 or above.

The SDK is distributed as a compiled XCFramework built with Swift 5, which is ABI-stable and backward compatible with Swift 4 source code.

</details>

---

<details>
<summary><b>11. My app is written in `Swift 3`. Can I integrate the SDK?</b></summary>

<br/>

**No.** Apps written in Swift 3 or earlier are not supported.

Reasons:

- Swift 3 does not support Swift 5 ABI stability
- Older Xcode versions cannot build iOS 16 apps
- Apple no longer supports these toolchains

**FIX:** Migration to Swift 5 and a modern Xcode version is required.

</details>

---

<details>
<summary><b>12. Why does the SDK require `iOS 16` or above?</b></summary>

<br/>

Because the SDK depends on:

- Modern WebKit and networking APIs
- Updated security & TLS requirements
- Apple-mandated platform security standards

Apps targeting older iOS versions are increasingly restricted by Apple and App Store policies.

</details>
</div>
</Tab>

<Tab label="Flutter">
<br/>
<h2 class="pl-4">Flutter FAQs</h2>
<div className="p-4 faq-section">

<details>
<summary><b>1. What Flutter and Dart versions are required?</b></summary>

<br/>

The SDK requires Flutter 3.3.0+ and Dart 3.11.1+. Run `flutter --version` to check your current version. If you need to upgrade, run `flutter upgrade`.

</details>

---

<details>
<summary><b>2. What is the orderToken and where do I get it?</b></summary>

<br/>

The orderToken is the token query parameter from the create order API returned by the Create Hosted Checkout API (Step 1.2).

Your backend should extract this token and pass it to your Flutter app.

</details>

---

<details>
<summary><b>3. The payment screen shows a blank screen or crashes immediately. What should I check?</b></summary>

<br/>

- The orderToken is valid and has not expired (tokens are usually valid for a limited time).
- The device has an active internet connection.
- You created the order in the correct environment (UAT token will not work with PinelabsEnvironment.prod and vice versa).
- On Android: Ensure minSdk is set to 26 or higher.
- On iOS: Ensure the deployment target is iOS 13.0 or higher.

</details>

---

<details>
<summary><b>4. UPI apps are not opening from the payment screen. Why?</b></summary>

<br/>

On iOS: Make sure you have added all required LSApplicationQueriesSchemes entries in your Info.plist (see Section 2.3). Without these entries, iOS will block the SDK from launching UPI apps.

On Android: The native SDK handles UPI intents internally. Ensure the UPI app is installed on the device. UPI intent flows do not work on emulators/simulators.

</details>

---

<details>
<summary><b>5. I get a PAYMENT_IN_PROGRESS error. Why?</b></summary>

<br/>

This means you called startPayment while a previous payment is still in progress. The SDK only allows one concurrent payment. Wait for the current startPayment Future to complete before starting a new one.

</details>

---

<details>
<summary><b>6. The SDK returns backPressed — what does this mean?</b></summary>

<br/>

The user pressed the hardware back button (Android) or performed a swipe-to-dismiss gesture (iOS) to exit the payment screen before completing or explicitly cancelling the payment. This is distinct from cancelled, which is triggered when the user cancels from within the payment UI.

</details>

---

<details>
<summary><b>7. Can I test UPI payments on a simulator or emulator?</b></summary>

<br/>

No. UPI intent flows require real payment apps installed on a physical device. The simulator/emulator does not have these apps. For UPI testing, always use a physical device.

Card payments, net banking, and wallet flows work on simulators since they operate within the native payment UI (WebView-based).

</details>

---

<details>
<summary><b>8. My Android minSdk is lower than 26. Can I still use the SDK?</b></summary>

<br/>

No. The SDK requires minSdk 26 (Android 8.0). If your app currently supports a lower version, you must raise it to 26 in your `android/app/build.gradle.kts`:

```kotlin
defaultConfig {
    minSdk = 26
}
````

Apps targeting Android 7 and below will fail to compile with the SDK.

</details>

---

<details>
<summary><b>9. How do I switch between UAT and Production environments?</b></summary>

<br/>

Pass the appropriate PinelabsEnvironment value when creating the request:

```dart
// For testing
PinelabsPaymentRequest(
  orderToken: token,
  environment: PinelabsEnvironment.uat,
)

// For production
PinelabsPaymentRequest(
  orderToken: token,
  environment: PinelabsEnvironment.prod,
)
```

Important: UAT order tokens will not work with PinelabsEnvironment.prod and vice versa. Always ensure the order token matches the environment used in the Create Hosted Checkout API.

</details>

---

<details>
<summary><b>10. Should I store API keys (client_id, client_secret) in my Flutter app?</b></summary>

<br/>

No. API keys must be stored securely on your backend server. Your Flutter app should call your own backend to create orders and obtain the orderToken. Never hardcode or bundle API credentials in client-side code.

</details>

---

<details>
<summary><b>11. The payment succeeded on the gateway but the SDK returned failure. What happened?</b></summary>

<br/>

This can happen in edge cases (network drops during callback, app was force-closed, etc.). To handle this:

* Always verify the final payment status on your backend using the Order Inquiry API with the order ID.
* Do not rely solely on the client-side SDK result for order fulfilment.

</details>

---

<details>
<summary><b>12. Does the SDK log or transmit any sensitive payment data (card numbers, CVV, UPI PIN)?</b></summary>

<br/>

No. The SDK does not log, store, or transmit any payment instrument details. All sensitive data entry (card number, CVV, UPI PIN, OTP) happens entirely within the native Pine Labs SDK UI, which is PCI-DSS compliant. The Flutter wrapper only receives the final outcome (success/failure/cancelled) with order metadata.

</details>

---

<details>
<summary><b>13. I see NO_VIEW_CONTROLLER or NO_ACTIVITY errors. What should I do?</b></summary>

<br/>

This means the SDK was called before the app UI was fully ready. Ensure you are calling startPayment:

* From a widget that is mounted and visible on screen.
* After the app has completed initialization.
* Not from initState() without a post-frame callback.

</details>

---

<details>
<summary><b>14. The build fails on Android with "Could not resolve com.github.plural-pinelabs:Pinelabs-Android-SDK". What should I do?</b></summary>

<br/>

Add the JitPack repository to your project. Open `android/settings.gradle.kts` and add:

```kotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven("https://jitpack.io")
    }
}
```

</details>

</div>
</Tab>
</CodeTabs>
</div>
