Flutter Web: Razorpay Payment Gateway Integration

Subhendu Pratap Singh
ITNEXT
Published in
4 min readAug 11, 2020

--

How to integrate razorpay payment gateway on flutter web platform using razorpay web integration method.

Photo by Morning Brew on Unsplash

Problem: Official razorpay plugin doesn’t yet support the web platform (See GitHub Issue) and flutter official webview plugin also doesn’t support the flutter web platform yet.

This post assumes that you have already signed up with RazorPay and completed all the formalities to get the API keys to start integrating the payment gateway on the platform of your choice.

Overview: Though flutter web is still in beta, with the recent updates, its performance has improved and soon we will see an official stable release. While the flutter team works to support web platform in the webview plugin, we don’t have to wait until then to implement this functionality atleast.

I am currently building a shopping mobile application for iOS, android and web using flutter. So far, I am pleased by the development experience provided by flutter. For this particular use case, I wanted to integrate a payment gateway which works on all the three platforms that I’m targeting. So here is what I did:

  1. Registered a View Factory with IFrameElement to load custom HTML and javascript on a flutter widget.
  2. Added Event listeners to handle payment success and failure events and take further action on the basis of events (for e.g. display success page).
  3. Dispatched message/events from javascript to handle them in flutter.

Solution

RazorPay Payment Integration on Flutter Web

Step 1: Register a View Factory

Create a class named UiFake.dart

import 'dart:ui' as ui;

// ignore: camel_case_types
class
platformViewRegistry {
static registerViewFactory(String viewId, dynamic cb) {
ui.platformViewRegistry.registerViewFactory(viewId, cb);
}
}

Don’t worry about the error which says “the name ‘platformViewRegistry’ is being referenced through the prefix ‘ui’, but it isn’t defined in any of the libraries imported using that prefix.” . Just let it be, it won’t stop you from building the application, although you can add a rule to your analyzer to ignore this error.

Step 2: Create HTML file to initialize razorpay checkout

In your assets folder, create a folder named “html” and create a file named “payment.html” with following contents

<!DOCTYPE html><html>
<meta name="viewport" content="width=device-width">
<head><title>RazorPay Web Payment</title></head>
<body>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<script>

var options = {
"key": "YOUR_KEY_HERE",
"amount": "50000", "currency": "INR",
"name": "Acme Corp",
"description": "Test Transaction",
"image": "https://example.com/your_logo",
"handler": function (response){
window.parent.postMessage("SUCCESS","*"); //2
alert(response.razorpay_payment_id);
alert(response.razorpay_order_id);
alert(response.razorpay_signature)
},
"prefill": {
"name": "Gaurav Kumar",
"email": "gaurav.kumar@example.com",
"contact": "9999999999"
},
"notes": {
"address": "Autofy"
},
"theme": {
"color": "#DF0145"
},
"modal": {
"ondismiss": function(){
window.parent.postMessage("MODAL_CLOSED","*"); //3
}
}
};

var rzp1 = new Razorpay(options);
window.onload = function(e){ //1
rzp1.open();
e.preventDefault();
}

</script>
</body>
</html>
  1. Here I have initated the checkout modal on page load, that means modal should show up as soon as you navigate to the screen (Step 3).
  2. To handle payment success, I have used the window.parent.postMessage(“SUCCESS”,”*”) in javascript to let our flutter code know that payment has been done. You can also send custom events here (Refer: Javascript Custom Events). To learn more about how to safely use postMessage (Refer: this article). Also, please check out razorpay web integration documentation to better understand how these options and handler function work. (RazorPay Web Integration Docs)
  3. To handle event when checkout modal is closed by the user, I have relayed window.parent.postMessage(“MODAL_CLOSED”,”*”) message from the ondismiss method.
  4. In case of any error during payment, razorpay checkout modal simply gives the option to retry payment.

Step 3: Create a widget

Now let’s load this HTML file to display the checkout modal and handle the events.

import 'dart:html';
import 'dart:ui' as ui;
//conditional import
import
'package:autofystore/utils/UiFake.dart' if (dart.library.html) 'dart:ui' as ui;
import 'package:flutter/material.dart';

class RazorPayWeb extends StatelessWidget {
@override
Widget build(BuildContext context) {
//register view factory
ui.platformViewRegistry.registerViewFactory("rzp-html",(int viewId) {
IFrameElement element=IFrameElement();
//Event Listener
window.onMessage.forEach((element) {
print('Event Received in callback: ${element.data}');
if(element.data=='MODAL_CLOSED'){
Navigator.pop(context);
}else if(element.data=='SUCCESS'){
print('PAYMENT SUCCESSFULL!!!!!!!');
}
});

element.requestFullscreen();
element.src='assets/html/payment.html';
element.style.border = 'none';
return element;
});
return Scaffold(
body: Builder(builder: (BuildContext context) {
return Container(
child: HtmlElementView(viewType: 'rzp-html'),
);
}));
}

}

Let me explain what’s going on here.

  1. We have conditionally imported our Uifake.dart class to register our view factory using the static method we created earlier.
  2. We have registred an IFrameElement as our view factory and loaded the HTML to display the checkout modal.
  3. We are handling the messages sent from javascript using the onMessage listener
window.onMessage.forEach((element) {
print('Event Received in callback: ${element.data}');
if(element.data=='MODAL_CLOSED'){
Navigator.pop(context);
}else if(element.data=='SUCCESS'){
print('PAYMENT SUCCESSFULL!!!!!!!');
}
});

In case you want to send events instead of the messages, use window.addEventListener instead.

This should be enough to get the razorpay payments running on flutter web.

That’s all folks. Let me know what you think!

NOTE: Though this post focusses particularly on RazorPay, you can apply the same technique to integrate any other payment gateway.

--

--