Flutter Fincra Checkout

pub package License: MIT

A production-ready Flutter package that provides a clean, secure, and highly customizable integration for Fincra Checkout payments using an in-app WebView.


🔒 Important Note on Security

DO NOT store your Fincra secret keys inside your Flutter application. This SDK is designed to handle only the mobile frontend checkout experience. The actual payment session must be created securely from your backend server.

✨ Features

  • 📱 Full-screen checkout experience optimized for mobile.
  • 🔗 Automatic detection of payment completion URL changes.
  • 🎨 Highly customizable UI (AppBar, colors, loaders, close icons).
  • 🛡️ Built-in dialogs to prevent accidental user cancellation.
  • Dual integration APIs (Supports both async/await and traditional Callbacks).
  • 🐛 Built-in error handling for seamless debugging.

📦 Installation

Add the dependency to your pubspec.yaml:

dependencies:
  flutter_fincra_checkout: ^1.0.0

🛠️ Setup

Android

Ensure your minSdkVersion in android/app/build.gradle is at least 19 (WebView requirements). Also, add internet permissions in your AndroidManifest.xml if not already present:

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

iOS

No additional configuration is required for recent versions of Flutter.

(Note: If you are using an extremely old Flutter version < 1.22, you may need to opt-in to embedded views in your Info.plist).


🚀 Usage

Integrating Fincra Checkout requires two steps: one on your backend, and one in your Flutter app.

1. Create a Payment Session (Backend)

Your backend should securely communicate with the Fincra API to initiate a checkout session. Here is an example of what that request looks like:

curl --request POST \
     --url https://api.fincra.com/checkout/payments \
     --header 'accept: application/json' \
     --header 'api-key: YOUR_SECRET_KEY' \
     --header 'x-pub-key: YOUR_PUBLIC_KEY' \
     --header 'content-type: application/json' \
     --data '
{
  "currency": "NGN",
  "amount": 1500,
  "customer": {
    "name": "Customer Name",
    "email": "customer@theiremail.com"
  },
  "feeBearer": "business",
  "redirectUrl": "https://your-backend.com/webhook"
}
'

Fincra will return a response containing a link (the checkout URL). Pass this URL to your Flutter app.

2. Open the Fincra Checkout (Flutter)

You can handle the checkout flow using either Async/Await or Callbacks.

import 'package:flutter/material.dart';
import 'package:flutter_fincra_checkout/flutter_fincra_checkout.dart';

Future<void> _startPayment(BuildContext context) async {
  // The URL generated by your backend in Step 1
  const checkoutUrl = "https://checkout.fincra.com/pay/some_session_id";
  
  final result = await FincraCheckout.open(
    context,
    checkoutUrl: checkoutUrl,
    redirectUrl: "https://your-backend.com/webhook", // Optional: secure URL interception
    appBarTitle: "Complete Payment", // Optional UI Customization
    appBarBackgroundColor: Colors.white, 
    showCancelConfirmationDialog: true, // Prevents accidental closing
    closeIcon: const Icon(Icons.arrow_back), 
    loadingWidget: const CircularProgressIndicator(color: Colors.red),
  );
  
  if (!context.mounted) return;

  switch (result) {
    case FincraCheckoutSuccess():
      print("Payment Success! Reference: ${result.response.reference}");
      // Verify payment status with your backend webhook here
      break;
    case FincraCheckoutError():
      print("Payment Failed: ${result.error.message}");
      break;
    case FincraCheckoutCancelled():
      print("User cancelled the payment");
      break;
  }
}

Option B: Using Callbacks

If you prefer a callback-driven approach, you can pass them directly to the open method:

FincraCheckout.open(
  context,
  checkoutUrl: checkoutUrl,
  onSuccess: (response) {
    print("Success callback: ${response.reference}");
  },
  onFailed: (error) {
    print("Error callback: ${error.message}");
  },
  onCancelled: () {
    print("Cancelled callback");
  },
);

Advanced: Custom Layout

If you want full control over the layout (e.g., embedding the checkout in a Bottom Sheet or a specific container instead of a full screen), you can use the raw CheckoutWebView widget directly.

CheckoutWebView(
  checkoutUrl: url,
  redirectUrl: "https://your-backend.com/webhook",
  appBarTitle: "Secure Payment",
)

Customization Parameters

The FincraCheckout.open method accepts several parameters to help you tailor the checkout experience to your app's brand and logic:

Parameter Type Description
checkoutUrl String (Required) The generated payment URL from your backend.
redirectUrl String? The callback URL your backend sent to Fincra. Used to securely intercept the completion page before Fincra redirects back.
appBarTitle String? Sets a custom title for the WebView's AppBar.
appBarBackgroundColor Color? Customizes the background color of the AppBar to match your app's theme.
closeIcon Widget? Replaces the default exit button (e.g., Icon(Icons.close)).
loadingWidget Widget? A custom loading indicator displayed while the payment page is initially loading.
showCancelConfirmationDialog bool Set to true to show a confirmation dialog when the user tries to exit the checkout prematurely. Defaults to false.
onSuccess ValueChanged<FincraPaymentResponse>? Callback triggered when the payment is successful.
onFailed ValueChanged<FincraPaymentError>? Callback triggered when the payment fails.
onCancelled VoidCallback? Callback triggered when the user explicitly cancels/closes the checkout.

📚 Models

FincraPaymentResponse

Property Type Description
reference String The unique transaction reference.
transactionId String Fincra's internal transaction ID.
status String The status of the transaction (e.g., 'success').
message String? Optional message from Fincra.
rawResponse Map The raw parameters extracted from the completion URL.

FincraPaymentError

Property Type Description
code String The error code or status.
message String A description of the error.

💡 Example

Check out the example/ directory for a complete working application demonstrating the payment flow.