Pine LabsDOCS

Flutter Web SDKs

Integrate Pine Labs payments into your web application using our Flutter Web SDK.

Integration Steps

Learn how you can integrate with Pine Labs Web SDK across all platforms. The SDK provides a secure hosted checkout experience using backend APIs and client-side SDKs for seamless payment processing.

  1. Prerequisites
  2. Integrate APIs in Your Backend
  3. SDK Installation and Initialization
  4. Handle Payments
  5. Manage Transactions

ā—ļø SecurityĀ BestĀ Practices:

  • Ensure you store your client_id and client_secret in your Backend securely.
  • Integrate our APIs on your backend system.
  • We strictly recommend not to call our APIs from the frontend.
  • Failure to adhere to the above guidelines may result in legal implications. In such cases, you will be held responsible for any damage or loss arising from non-compliance.

1. Prerequisites

Before integrating the Flutter SDK, make sure your app and build environment meet the minimum requirements listed below.

Minimum Compatibility Matrix

Platform and Build Environment

CategoryMinimum SupportedNotes
Flutter Version3.24.0Apps must use Flutter 3.24.0 or higher.
Dart SDK3.9.2Required for null-safe SDK APIs.
Android minSdkAPI 26 / Android 8.0Required by WebView and UPI intent dependencies.
Android compileSdkAPI 34+Recommended to use the latest stable version.
iOS Deployment TargetiOS 13.0Required for WKWebView features used by the SDK.
Xcode VersionXcode 15.0+Required to build iOS 13+ apps.

Supported Platforms

PlatformSupported
Android phone/tabletāœ… Supported
iOS iPhone/iPadāœ… Supported
WebāŒ Not supported
macOS DesktopāŒ Not supported
Windows DesktopāŒ Not supported
Linux DesktopāŒ Not supported

SDK Dependencies

The following packages are included automatically as transitive dependencies. You do not need to add them manually to your app.

PackageVersionPurpose
webview_flutter^4.13.0Core WebView widget.
webview_flutter_android^4.5.0Android WebView implementation.
webview_flutter_wkwebview^3.23.0iOS WKWebView implementation.
url_launcher^6.3.2Launching external UPI apps.

Unsupported Configurations

The SDK does not support the following configurations:

  • Flutter versions below 3.24.0
  • Dart SDK versions below 3.9.2
  • Android apps with minSdk below API 26
  • iOS apps targeting versions below iOS 13.0
  • Web apps
  • Desktop apps, including macOS, Windows, and Linux

2. Integrate APIs in Your Backend

Start a payment by triggering the payment flow. To start a payment follow the below steps:

2.1. Generate Auth Token

Integrate our Generate Token API in your backend servers to generate the auth token. Use the token generated to authenticate Pine Labs Online APIs.

Below are the sample requests and response for the Generate Token API.

cURL
curl --location 'https://pluraluat.v2.pinepg.in/api/auth/v1/token' \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --header 'Request-Timestamp: 2024-07-09T07:57:08.022Z' \ --header 'Request-ID: c17ce30f-f88e-4f81-ada1-c3b4909ed235' \ --data ' { "client_id": "a17ce30e-f88e-4f81-ada1-c3b4909ed232", "client_secret": "fgwei7egyhuggwp39w8rh", "grant_type": "client_credentials" } '

Refer to our Generate Token API documentation to learn more.

2.2. Generate Checkout Link

Use this API to Generate a checkout link, for authentication use the generated access token in the headers of the API request.

Below are the sample requests and response for a Generate Checkout Link API.

cURL
curl --request POST \ --url https://pluraluat.v2.pinepg.in/api/checkout/v1/orders \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data ' { "merchant_order_reference": "112345", "order_amount": { "value": 1100, "currency": "INR" }, "integration_mode": "SDK", "pre_auth": false, "allowed_payment_methods": [ "CARD", "UPI", "NETBANKING", "POINTS", "WALLET" ], "notes": "order1", "callback_url": "https://sample-callback-url", "failure_callback_url": "https://sample-failure-callback-url", "purchase_details": { "customer": { "email_id": "kevin.bob@example.com", "first_name": "Kevin", "last_name": "Bob", "customer_id": "123456", "mobile_number": "9876543210", "country_code": "91", "billing_address": { "address1": "10 Downing Street Westminster London", "address2": "Oxford Street Westminster London", "address3": "Baker Street Westminster London", "pincode": "51524036", "city": "Westminster", "state": "Westminster", "country": "London", "full_name": "harsh kumar", "address_type": "HOME/WORK/OTHER", "address_category": "BILLING" }, "shipping_address": { "address1": "10 Downing Street Westminster London", "address2": "Oxford Street Westminster London", "address3": "Baker Street Westminster London", "pincode": "51524036", "city": "Westminster", "state": "Westminster", "country": "London", "full_name": "harsh kumar", "address_type": "HOME/WORK/OTHER", "address_category": "BILLING" } }, "merchant_metadata": { "express_checkout_enabled": "TRUE", "express_checkout_allowed_action": "checkoutCollectAddress", "key1": "DD", "key2": "XOF" } }, "cart_details": { "cart_items": [ { "item_id": "cart_id_1", "item_name": "T Shirt", "item_description": "Test Description", "item_details_url": "https://chriscross.in/cdn/shop/files/95_800x.jpg", "item_image_url": "https://chriscross.in/cdn/shop/files/95_800x.jpg", "item_original_unit_price": 1, "item_discounted_unit_price": 1, "item_quantity": 1, "item_currency": "INR" } ] } } '

Refer to our Generate Checkout Link documentation to learn more.

3. SDK Installation & Initialization

Installation

Add the SDK to Your Flutter Project

Before integrating the SDK, ensure your project meets the following requirements:

RequirementVersion
Flutter3.24.0 or later
Dart SDK3.9.2 or later

Add pine_payment_sdk to your app’s pubspec.yaml file under dependencies:

YAML
dependencies: flutter: sdk: flutter pine_payment_sdk: ^1.0.0

Then run:

Bash
flutter pub get

This downloads the SDK and all required dependencies automatically.

Android Configuration

The SDK requires Android 8.0 or later, which corresponds to API level 26.

Set Minimum SDK Version

Open your app’s android/app/build.gradle.kts or android/app/build.gradle file and ensure minSdk is set to 26 or higher:

Kotlin
android { defaultConfig { minSdk = 26 // ... } }

šŸ“˜ Note:

  • If your app already targets minSdk 26 or higher, no changes are needed. If your current minSdk is lower than 26, you must update it to 26.

Add Internet Permission

The SDK requires internet access. Most Flutter apps already include this permission, but verify that your android/app/src/main/AndroidManifest.xml file contains:

XML
<uses-permission android:name="android.permission.INTERNET" />

UPI App Queries

The SDK includes built-in manifest <queries> entries for common UPI apps such as Google Pay, PhonePe, Paytm, and others.

No additional configuration is required for standard UPI payments.

If your app uses a custom deep-link scheme for payment callbacks, add an <intent-filter> to your AndroidManifest.xml:

XML
<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="yourapp" android:host="payment" /> </intent-filter> </activity>

Replace yourapp and payment with your actual callback scheme and host.

iOS Configuration

The SDK requires iOS 13.0 or later.

Set iOS Deployment Target

Open your ios/Podfile and ensure the platform version is set to 13.0 or higher:

Ruby
platform :ios, '13.0'

Add UPI Query Schemes in Info.plist

To allow the SDK to detect and launch UPI payment apps installed on the user’s device, declare the required URL schemes in your app’s Info.plist.

Open ios/Runner/Info.plist and add:

XML
<key>LSApplicationQueriesSchemes</key> <array> <string>upi</string> <string>phonepe</string> <string>gpay</string> <string>paytm</string> <string>tez</string> <string>credpay</string> </array>

Starting from iOS 9, apps must declare the URL schemes they intend to query using LSApplicationQueriesSchemes.

Without these entries, the SDK will not be able to detect installed UPI apps, and payment app redirection may fail silently.

Add Custom Callback Scheme

If your app uses a custom callback scheme, such as:

Code
yourapp://payment

add a CFBundleURLTypes entry in Info.plist:

XML
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>yourapp</string> </array> </dict> </array>

Replace yourapp with your app’s actual callback scheme.

Initialize the SDK

Import the SDK in your Dart file:

Dart
import 'package:pine_payment_sdk/pine_payment_sdk.dart';

The SDK provides two methods to start a payment flow, depending on how your payment gateway handles callbacks.

Pass the Redirect URL to SDK

Your backend creates an order using the Generate Checkout Link API and receives a redirect_url in the response. Pass this URL directly to the SDK.

Dart
Future<void> startPayment(String redirectUrl) async { final PaymentResult result = await PinePaymentSdk.startPaymentFromRedirectUrl( redirectUrl: redirectUrl, appBarTitle: 'Complete Payment', ); if (result.success) { // Payment was successful print('Transaction ID: ${result.transactionId}'); } else { // Payment failed or was cancelled print('Status: ${result.status}'); print('Message: ${result.message}'); } }

Parameters

ParameterTypeRequiredDescription
redirectUrlStringYesThe callback URL the payment gateway redirects to after payment completion. For Plural checkout, this is the same as paymentUrl. The SDK monitors this URL to detect when the payment flow is complete.
appBarTitleStringNoTitle displayed in the app bar at the top of the payment screen. Defaults to Complete Payment.

Complete Integration Example

Below is an example showing how to integrate the SDK in a Flutter app:

Code
import 'package:flutter/material.dart'; import 'package:pine_payment_sdk/pine_payment_sdk.dart'; class CheckoutScreen extends StatefulWidget { const CheckoutScreen({super.key}); @override State<CheckoutScreen> createState() => _CheckoutScreenState(); } class _CheckoutScreenState extends State<CheckoutScreen> { bool _isProcessing = false; Future<void> _startPayment() async { // The redirect URL from your Create Hosted Checkout API response const redirectUrl = 'https://pluraluat.v2.pinepg.in/api/v3/checkout-bff/redirect/checkout?token=YOUR_TOKEN'; setState(() => _isProcessing = true); try { final result = await PinePaymentSdk.startPaymentWithRedirect( paymentUrl: redirectUrl, redirectUrl: redirectUrl, appBarTitle: 'Complete Payment', ); if (!mounted) return; switch (result.status) { case PaymentStatus.success: _showMessage('Payment Successful!'); // IMPORTANT: Verify the payment on your backend using the Order Inquiry API break; case PaymentStatus.failure: _showMessage('Payment Failed: ${result.message}'); break; case PaymentStatus.cancelled: _showMessage('Payment Cancelled'); break; case PaymentStatus.invalidRequest: _showMessage('Invalid Request: ${result.message}'); break; default: _showMessage('Unknown status: ${result.status}'); } } catch (e) { _showMessage('Error: $e'); } finally { if (mounted) setState(() => _isProcessing = false); } } void _showMessage(String message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message)), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Checkout')), body: Center( child: ElevatedButton( onPressed: _isProcessing ? null : _startPayment, child: Text(_isProcessing ? 'Processing...' : 'Pay Now'), ), ), ); } }

šŸ“˜ Important:

  • Always confirm the final payment status from your backend by calling the Get Order by Order ID API with the order ID. Do not use the client-side SDK response alone to fulfil or complete an order.

4. Handle Payments

You need to implement call-back methods to handle your payment responses. This will provide the payment status and reason for transaction failures. Based on the reasons for failures, handling can be built at your end. Transaction callbacks can be listened to via overriding methods ofĀ EdgeResponseCallback.

PaymentResult

Both SDK payment methods return a PaymentResult object when the payment flow ends.

Dart
class PaymentResult { final bool success; // true if the payment succeeded final String status; // payment status value final String finalUrl; // final WebView URL when the flow ended final String? transactionId; // transaction ID, if available final String? message; // additional message, if available }

Parameters

ParametersTypeDescription
successboolIndicates whether the payment was successful.
statusStringFinal payment status returned by the SDK.
finalUrlStringThe final URL loaded in the WebView when the payment flow ended.
transactionIdString?Transaction ID received from the callback URL, if available.
messageString?Additional message describing the result, failure reason, or cancellation.

šŸ“˜ Note:

  • Always confirm the final payment status from your backend by calling the Get Order by Order ID API with the order ID. Do not use the client-side SDK response alone to fulfil or complete an order.

PaymentStatus

The SDK returns one of the following standard status values:

StatusValueDescription
PaymentStatus.successsuccessPayment completed successfully.
PaymentStatus.failurefailurePayment failed due to bank decline, timeout, or another error.
PaymentStatus.cancelledcancelledUser pressed the back button or cancelled the payment flow.
PaymentStatus.invalidRequestinvalid_requestInvalid payment URL or parameters were passed to the SDK.

Handling Payment Outcomes

Use the status field in PaymentResult to handle each payment outcome.

Dart
final result = await PinePaymentSdk.startPaymentWithRedirect( paymentUrl: redirectUrl, redirectUrl: redirectUrl, ); switch (result.status) { case PaymentStatus.success: // Payment succeeded. // Use result.transactionId and result.finalUrl for backend verification. // Important: // Always call your backend Order Inquiry API using the order ID // before fulfilling or completing the order. break; case PaymentStatus.failure: // Payment failed. // result.message may contain the failure reason, // such as "declined", "timeout", or another error message. // Show an appropriate failure message to the user // and provide an option to retry the payment. break; case PaymentStatus.cancelled: // User cancelled the payment flow or pressed the back button. // result.message may contain: // "Payment was cancelled by the user." // Allow the user to retry the payment if required. break; case PaymentStatus.invalidRequest: // The SDK could not process the provided payment URL or parameters. // result.message describes what went wrong. // Check the paymentUrl, redirectUrl, successUrl, or failureUrl // and try again with valid values. break; }

How Callback Detection Works

The SDK automatically detects payment callbacks. You do not need to write custom URL-matching logic.

During the payment flow, the SDK performs the following actions:

StepDescription
URL monitoringThe SDK monitors every URL change inside the WebView, including navigation requests, page loads, and redirects.
Callback matchingWhen the current URL matches the configured redirectUrl, successUrl, or failureUrl, the SDK identifies it as the payment callback.
Parameter parsingThe SDK parses query parameters from the callback URL. It checks for common payment parameters such as status, transactionId, txnId, orderId, message, and their variants.
Status detectionIf the callback URL contains a status parameter, the SDK uses it to determine the result. If no status is available, the SDK infers the result based on the matched callback URL.
Flow completionThe SDK automatically closes the WebView and returns a PaymentResult to your app. No manual WebView dismissal is required.

External UPI and Intent Handling

When the payment flow requires opening an external UPI app such as Google Pay, PhonePe, Paytm, or another supported app, the SDK handles the redirection automatically.

The SDK automatically:

  • Detects external payment URL schemes such as upi://, intent://, phonepe://, gpay://, paytm://, tez://, credpay://, and other non-web schemes.
  • Prevents these URLs from opening inside the WebView.
  • Launches the relevant external payment app installed on the user’s device.
  • Resumes callback URL monitoring when the user returns to your app.
  • Uses the browser fallback URL for intent:// links when the target app is not installed.

No additional code is required for UPI app handling. External UPI and intent-based redirections are fully managed by the SDK.

5. Manage Transactions

Track and verify transaction status using Pine Labs APIs. To retrieve the latest status, use the Fetch APIs or subscribe to webhooks for real-time transaction updates.

Get Order by Order ID

Fetch real-time transaction status by order ID.

Learn More →

Webhooks

Configure webhook events for automatic transaction updates.

Learn More →