Table of Content
- 🕹 Introduction
- 📡 Required Paystack Details and Endpoints
- 🖲 Installing WebView Package
- 🛢 Making API calls in Flutter
- 📲 Displaying Paystack pop-up in webView
- 💾 Listening For Navigation url
- 💙 Important Notes for Release APK
🕹 Introduction
As at the time of writing this article, paystack integration for android and mobile SDK, only supports card payments and bank (with just Zenith as the option).
In this article, you will learn how to include other payment options in your flutter application.
PS: I'm assuming you are familiar with flutter and
paystack with all the necessary keys and how to get them
from your paystack dashboard.
Before we continue, please take a quick look at this article from Paystack, that's where I got ideas from 😋. If you want, you could use that article, or continue reading.
📡 Required Paystack Details and Endpoints
You will need your paystack secret_key (use the test key for testing and live key for prod) as your Bearer token in your Authorization header while making a POST request to the paystack initialize api.
Check the below images for better understanding.
Setting your authorization header with secret_key
POST body details
email: This is the payers email.
amount: This is the amount to be paid, please multiply by
100, to remove the kobo value
reference: This should be randomly generated as it should
be a unique value for each payment.
callback_url: This is the most important part. If you
already have a callback url, setup from your
paystack dashboard, you don't need this
parameter. If you still go ahead to include
it, it'll override that of the dashboard.
This callback_url is what we will be
listening for from our webview.
cancel_action: This will be used to listen for when the
user wants to cancel payment, we then pop
the webview screen.
Response from paystack API
authorization_url: This is the most important data we will
be needing for our webview, so hold on
to it 😎.
🖲 Installing WebView Package
To install this package, please visit this link, read through the setup and install it.
🛢 Making API calls in Flutter
This approach depends on which architecture you're using to build your application, at the end, it's all the same response you will receive. In this article, i'll be keeping it really simple 🥹.
var headers = {
'Authorization': 'Bearer sk_test_039***************',
'Content-Type': 'application/json',
};
var request = http.Request('POST', Uri.parse('https://api.paystack.co/transaction/initialize'));
request.body = json.encode({
"email": "g.ikwegbu@gmail.com",
"amount": "10000",
"reference": "randomDetails",
"callback_url": "https://github.com/gikwegbu",
"metadata": {"cancel_action": "https://www.google.com/"}
});
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
PS: I personally love using the flutter dio package
Retrieve the authorization_url from the response and store
it in a global variable.
📲 Displaying Paystack pop-up in webView
Ok, let's be on the same page here 🙃. We are building an application that allows users make payment for an item via paystack.
🏳️ The Data Flow:
when the user clicks on the PAY button, the paystack pops-up, user selects whichever option that's suitable, and proceed. Once the payment is successful, we will be redirected to a callback_url. Once this happens, we will have to be listening for that callback_url, which when detected, allows us to close the webview widget, and then continue with sending our reference code to our server to complete checking out of the PAID item.
🏳️ Implementation:
To make the process seamless, i'd be using a popup dialog, set it to fullscreen to overlay our current page, add the webview widget.
Below is a code snippet that will help you understand more:
// This is called when the PAY button is clicked.
_showPaystack() async {
var _ref = 'ChargedFromMyApp_${DateTime.now().millisecondsSinceEpoch}';
Map data = {
// Removing the kobo by multiplying with 100
"amount": double.parse('${_amount * 100}').toInt(),
"email": _user.email,
"reference": _ref,
"callback_url": "https://github.com/gikwegbu",
"metadata": {"cancel_action": "https://www.google.com/"}
};
// This awaits the [authorization_url](#authUrl). NB: I'm using the MVVM architecture in my live code, but it's still the same process of retrieving the authURL.
var authUrl = await _profileCtrl.paystackWebViewChargeCard(data);
// only pull-up the dialog box when we get the authURL
if (authUrl != null) {
return showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel:
MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black45,
transitionDuration: const Duration(milliseconds: 200),
pageBuilder: (BuildContext buildContext, Animation animation,
Animation secondaryAnimation) {
return Center(
child: Container(
width: MediaQuery.of(context).size.width - 10,
// height: MediaQuery.of(context).size.height - 80,
height: MediaQuery.of(context).size.height - 0,
padding: const EdgeInsets.only(top: 40),
color: Colors.white,
child: WebView(
initialUrl: authUrl.toString(),
javascriptMode: JavascriptMode.unrestricted,
userAgent: 'Flutter;Webview',
navigationDelegate: (navigation) {
//Listen for callback URL
if (navigation.url == "https://standard.paystack.co/close") {
Navigator.of(context).pop(); //close webview
// _txnRef is my glabally created variable to handle my reference
_txnRef = _ref;
_submit();
}
if (navigation.url ==
"github.com/gikwegbu?trxref=$_ref&reference=$_ref") {
Navigator.of(context).pop();
_txnRef = _ref;
_submit();
}
if (navigation.url == "https://www.google.com/") {
Navigator.of(context).pop();
}
return NavigationDecision.navigate;
},
),
));
});
}
}
The _submit(), is a function that sends the reference to
my backend to complete the purchase transaction on the
selected item.
💾 Listening For Navigation url
From the above code snippet, you'd have noticed the navigationDelegate section, this is where you'll handle listening for the callback_url and also, in the case the user is making payments with a Card, and the 3Ds Authentication will have to redirect you to the 'https://standard.paystack.co/close'. Other than that, we will listen for our custom callback_url, and then pop our screen.
💙 Important Note For Release apk
The application will actually work while in debug mode, but will through an error or not work at all in released build, as you'd only be seeing a gray overlay.
Steps Taken to Resolve this.
- Add
<uses-permission android:name="android.permission.INTERNET" />
in your android/app/src/main/AndroidManifest.xml
.
- Add
if (Platform.isAndroid) WebView.platform = AndroidWebView();
Inside of your initState(){}
function of your file. This means you'd have to be using a "Stateful" widget.
- This is the most important. Run
flutter run --release
This would help you build your app as in 'release mode', but you can still be seeing your debugs in your console. Now watch closely if you see an error like I/flutter (18782): Another exception was thrown: Instance of 'DiagnosticsProperty<void>'
, if so, then please look for where Expanded
widget was used in your implementation and remove it.
Finally
We have successfully integrated our paystack payment system with multiply option into our flutter application. To experience the multiple option, please change from your test secret key to your live secret key, only then will you see the
Top comments (1)
Hello @gikwegbu can I get the source code?