A Step-by-Step Guide to Integrated BBPS (Bharat Bill Payment System) in Your Flutter Application

Yashesh

Oct 07, 2024

6 min readLast Updated Oct 07, 2024

Guide to Integrated BBPS in Your Flutter Application

What is BBPS?

BBPS, or Bharat Bill Payment System, allows customers to pay 20k+ businesses across categories like utility bills, loan EMIs, school fees, and more—using a network of offline and online agents.

Who is an Agent?

An agent is a registered BBPS entity that is allowed to collect payments for BBPS billers across all categories.

You may register as an agent on BBPS, to collect BBPS bill payments with Setu APIs on your supported collection channels (offline or online).


Use Case: Enabling Secure Bill Payment for Utility Providers

Imagine you are developing an app for utility providers, allowing customers to pay their electricity, water, and gas bills directly through your platform. With Setu BillPay, you can enable a complete BBPS (Bharat Bill Payment System) experience for your users—from selecting the business they want to pay, to fetching and securely paying bills.

If you are a BBPS biller, you can even use Setu BBPS BillPay to collect payments for your business directly within the app. The Setu BBPS BillPay system connects seamlessly with NPCI (National Payments Corporation of India) and provides simple RESTful APIs. Some of these APIs are asynchronous, giving you the flexibility to subscribe to real-time notifications via webhooks or handle the transactions purely through API requests.

For instance, once a customer selects their biller and views their pending bills, they can choose to pay using a range of payment methods like UPI, debit/credit cards, or net banking. The app can also handle essential functions like generating transaction receipts and storing payment history, providing a smooth and secure bill payment experience all within your app.

In this blog, we'll walk through the process of integrating Setu BBPS (Bharat Bill Payment System) into a Flutter app step by step. We'll cover the necessary API requests, handling responses, and implementing the integration in Flutter using the provided Setu documentation.

Prerequisites

  1. Flutter Development Environment: Make sure you have Flutter installed. If not, follow the Flutter installation guide.
  2. Setu API Credentials: Obtain your API credentials from Setu.

Step 1: Implement WebView in Your Flutter App

First, we need to load the Setu payment link in a WebView within our Flutter app.

The link returned by the Create link API should be loaded within the Webview. Our sample below uses the flutter_inappwebview plugin for webviews. Feel free to use a plugin as per your requirements.

The controller will need to implement two JavaScript handlers -

  • Initiate Payment:- Used to initiate payment & transfer control from the Setu webview to the Flutter application.
  • Unload:- Used by the parent app to dismiss the webview.

Special Use Case: This unload function can also be used for dismissing the webview and redirecting a user back to your native app once a bill payment journey is completed (i.e. payment is successful) via a CTA from the Setu webview. Please let our team know if you would like to enable this use case for your app.

Note: For downloading and saving transaction receipts from the webview, the webview will need to handle a onDownloadStartRequest (or a similar function as per your webview plugin).

Our sample below uses the flutter_downloader and path_provider plugins for downloading and saving transaction receipts. Please follow the plugin-specific documentation for implementation. Make sure you have added the necessary permissions in your AndroidManifest.xml and Info.plist files for downloading and saving files.

1.1 Add Dependencies:

Update your pubspec.yaml file to include necessary dependencies.

dependencies:
flutter:
sdk: flutter
flutter_inappwebview: ^5.3.2
flutter_downloader: ^1.7.11
path_provider: ^2.0.9
url_launcher: ^6.0.20

1.2 Initialize Flutter Downloader:

Modify your main.dart file to initialize the Flutter Downloader.

 import 'dart:io';
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';

Future main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await FlutterDownloader.initialize(
        debug: true, // optional: set false to disable printing logs to console
    );
    runApp(MyApp());

}

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            home: RpWebPage(
                link: 'https://billpay.setu.co/1234', // Replace with the actual URL
            ),
        );
    }
}

1.3 Create WebView Page

Create a new stateful widget to handle the WebView.

class RpWebPage extends StatefulWidget {
const RpWebPage({super.key, required this.link});
final String link;

@override
State<RpWebPage> createState() => _RpWebPageState();

}

class _RpWebPageState extends State {
late InAppWebViewController webView;
bool isButtonClicked = false;

@override
void initState() {
    super.initState();
}

void _loadUrl() {
    setState(() {
        isButtonClicked = true;
    });
}

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text('Bill Payments'),
        ),
        body: Column(
            children: [
                if (!isButtonClicked)
                    ElevatedButton(
                        onPressed: _loadUrl,
                        child: Text('Load webview'),
                    ),
                Expanded(
                    child: isButtonClicked
                        ? InAppWebView(
                            initialSettings: InAppWebViewSettings(
                                allowFileAccess: true,
                                allowFileAccessFromFileURLs: true
                            ),
                            initialUrlRequest: URLRequest(
                                url: WebUri.uri(Uri.parse(widget.link))
                            ),
                            onWebViewCreated: (InAppWebViewController controller) {
                                webView = controller;
                            },
                            onLoadStop: (controller, url) async {
                                controller.addJavaScriptHandler(
                                    handlerName: 'initiatePayment',
                                    callback: (args) async {
                                        print('Received from WebView: $args');
                                        var paymentData = args[0];
                                        print('Payment data: $paymentData');
                                        // add your custom payment logic here
                                    },
                                );
                                controller.addJavaScriptHandler(
                                    handlerName: 'unload',
                                    callback: (args) async {
                                        // logic to close webview and return to app
                                    },
                                );
                            },
                            onDownloadStartRequest: (controller, request) async {
                                print("onDownloadStart $request");
                                final dir = Platform.isAndroid
                                    ? (await getExternalStorageDirectory())?.path
                                    : (await getApplicationDocumentsDirectory()).uri.path;
                                print("saving in $dir");
                                final taskId = await FlutterDownloader.enqueue(
                                    url: request.url.toString(),
                                    savedDir: dir!,
                                    showNotification: true,
                                    openFileFromNotification: true,
                                    saveInPublicStorage: true,
                                    allowCellular: true
                                );
                                await FlutterDownloader.open(taskId: taskId!);
                            },
                        )
                        : Container(),
                ),
            ],
        ),
    );
}

}

Step 2: Handle Payment Flow

The initiatePayment method in the controller takes an object parameter with several fields required for the payment flow. Here's a breakdown of what needs to be done:

  1. Payment Data: The object will include fields such as orderId, amount, callback URL, beneVpa, remarks, mobileNumber, refId, customerId, and allowedPaymentModes.
  2. Handle JavaScript Handlers: Ensure that your JavaScript handlers (initiatePayment and unload) are set up to process the payment and handle the WebView unloading.

To create a payment link, you'll need to use Setu's Create Link API. The detailed API reference can be found here.

3.1 API Endpoint

The endpoint for creating a payment link is

  • UAT (Testing Environment): https://qa-coudc.setu.co/api/v1/ethereal/link
  • Production: https://coudc.setu.co/api/v1/ethereal/link

3.2 Required Headers

When making the request, you need to include the following headers

  • Authorization:- Your authorization string (e.g Bearer token)
  • X-Partner-ID: Your partner ID was provided by Setu.
  • Content-Type: Should be set to application/json.

3.3 Request Body

The request body should be in JSON format and include the following fields

  • orgld: Your organization ID.
  • MobileNumber: The mobile number associated with the bill payment.
  • redirectTo: The URL to which the user should be redirected after the payment is complete.
  • billerId: The ID of the biller (e.g., electricity provider).
  • categoryName: The category of the bill (e.g., Electricity).
  • billParams: A list of parameters specific to the bill, such as account number or loan number.

Here's an example of a complete request body:

{
  "orgId": "122337203685477",
  "mobileNumber": "9082718673",
  "redirectTo": "transactions",
  "billerId": "BESCOM000KAR01",
  "categoryName": "Electricity",
  "billParams": [
    {
      "name": "Loan Number",
      "value": "1895159"
    }
  ]
}


3.4 cURL Command

Below is an example cURL command to create a payment link

curl --request POST \
  --url https://coudc.setu.co/api/v1/ethereal/link \
  --header 'Authorization: YOUR_AUTH_STRING' \
  --header 'X-PARTNER-ID: YOUR_PARTNER_ID' \
  --header 'Content-Type: application/json' \
  --data '{
    "orgId": "122337203685477",
    "mobileNumber": "9082718673",
    "redirectTo": "transactions",
    "billerId": "BESCOM000KAR01",
    "categoryName": "Electricity",
    "billParams": [
        {
            "name": "Loan Number",
            "value": "1895159"
        }
    ]
}'

3.5 Response

A successful request will return a JSON response with the payment link and other details

{
  "link": "billpay.setu.co/12617771219030",
  "sessionId": "12617771219030",
  "success": true,
  "traceId": "C3SFG0O6N88R6UI7EQ"
}
  • link: The payment link generated by Setu
  • SessionId: A unique identifier for the session.
  • Success: A boolean indicating the success of the request.
  • traceld: A unique identifier for tracking the request.

3.6 Handling the Response in Flutter

After receiving the response, you can load the link in a WebView within your Flutter app, as demonstrated in Step 1 and Step 2 of this guide. This allows users to complete the payment process directly within your app.

Conclusion

By following these thorough instructions, you can use Setu's API to build a payment link and include it in your Flutter application. This will allow your users to pay their bills easily. For further information, see the official Setu API documentation.

FAQs

  1. What is BBPS, and how does it work?

    BBPS, or Bharat Bill Payment System, is a centralized platform in India; with the help of that system, users are able to pay bills for utilities, loans, and much more. It connects offline and online agents to allow seamless and secure bill payments for over 20,000+ businesses.
  2. Can I integrate BBPS into my Flutter app?

    Yes, you can integrate BBPS into your Flutter app using Setu APIs; this blog gives you a step-by-step guide on how to incorporate BBPS functionality, including loading payment links in a WebView and handling payment processes.
  3. What payment methods can users select in the BBPS integration?

    Users can choose from a variety of payment methods, including UP, debit/credit card, and net banking, depending on what your app supports through the BBPS integration.
  4. What is the Create Link API, and how does it work?

    The Create Link API provided by Setu allows you to generate payment links for specific bills. The generated link is then loaded into a WebView in your Flutter app, allowing users to complete their payment securely.

Projects Completed till now.

Discover how we can help your business grow.

"Third Rock Techkno's work integrates complex frameworks and features to offer everything researchers need. They are open-minded and worked smoothly with the academic subject matter."

- Dr Daniel T. Michaels, NINS

Related Resources

You May Also Like

Our Services

Related Resources

Our Services

You May Also Like