Paystack Payment with Flutter

Felix Hope
3 min readMay 22, 2020

--

A few days back, I was working on a light weight mobile application with flutter and so I wanted to integrate an online payment gateway. I wanted to integrate paystack and I could not find any article or tutorial that explained the process. So I just read the flutter_paystack package readme, and paystack documentation and after a few hours, I got it working. So i thought to myself, why not write an article about it, so others can just spend a few minutes integrating what took me a few hours. So in this article, I would be talking about how you an integrate paystack in flutter using the flutter_paystack package

So if you are here, then I’m assuming that you know flutter, that you use flutter and you’ve got it installed on your machine and you know how to start a project. Its always a privilege to upgrade your skillsets through my write-ups. So lets jump in.

First thing to do will be to create a paystack account and get your publick key and sktest keys.

https://dashboard.paystack.com/#/signup

First thing you would wanna do is add flutter paystack package to your dependencies and run pub get.

Then initialize the plugin preferably in the initState of your widget.

import 'package:flutter_paystack/flutter_paystack.dart';

class _PaymentPageState extends State<PaymentPage> {
var publicKey = '[YOUR_PAYSTACK_PUBLIC_KEY]';

@override
void initState() {
PaystackPlugin.initialize(
publicKey: publicKey);
}
}

There are two ways of making payment with the plugin.

  1. Checkout: This is the easy way; as the plugin handles all the processes involved in making a payment (except transaction initialization and verification which should be done from your backend).
  2. Charge Card: This is a longer approach; you handle all callbacks and UI states.

In this article, I’m only going to talk about the checkout method.

🌟 Checkout (Recommended)

You initialize a charge object with an amount, email & accessCode or reference. Pass an accessCode only when you have initialized the transaction from your backend. Otherwise, pass a reference.

You can create a reference ID, but it has to be different for every transaction

String _getReference() {
String platform;
if (Platform.isIOS) {
platform = 'iOS';
} else {
platform = 'Android';
}

return 'ChargedFrom${platform}_${DateTime.now().millisecondsSinceEpoch}';
}

To initialize the transaction, You can do…

import 'dart:convert';                                               import 'package:http/http.dart' as http;                                               Future<String>createAccessCode(skTest, _getReference) async {                        
// skTest -> Secret key
Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $skTest'};
Map data = {"amount": 600, "email": "emailaddress@gmail.com", "reference": _getReference};
String payload = json.encode(data); http.Response response = await http.post(
'https://api.paystack.co/transaction/initialize',
headers: headers,
body: payload);
final Map data = jsonDecode(response.body);
String accessCode = data['data']['access_code'];
return accessCode;
}

Please, note that an accessCode is required if the method is CheckoutMethod.bank or CheckoutMethod.selectable.

It is recommended that when PaystackPlugin.checkout() returns, the payment should be verified on your backend, before you tell the user that the payment was successful. This is because the intialization may be successful but the payment might not be. The response from the verification status could be ‘success’, ‘abandoned’, or ‘failed’.

void _verifyOnServer(String reference) async {


try {
Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $skTest'};
http.Response response = await http.get('https://api.paystack.co/transaction/verify/'+reference, headers: headers);
final Map body = json.decode(response.body);
if(body['data']['status'] == 'success'){
//do something with the response. show success}
else{//show error prompt}
} catch (e) {
print(e);
}
}

PaystackPlugin.checkout() returns the state and details of the payment in an instance of CheckoutResponse .

chargeCard() async {
Charge charge = Charge()
..amount = 10000
..reference = _getReference()
//..accessCode = _createAcessCode(skTest, _getReference())
..email = 'customer@email.com';
CheckoutResponse response = await PaystackPlugin.checkout(
context,
method: CheckoutMethod.card,
charge: charge,);
if (response.status == true) {
verifyOnServer(response.reference)}
else {
//show error}}

Please note that you can only use the paystack available test cards when you are using your test keys.

https://developers.paystack.co/docs/test-cards

If you want to try a real card, then you would have to register and verify your business on paystack so you can get your live keys. And remember, do not commit your keys to github.

--

--

Felix Hope
Felix Hope

Written by Felix Hope

Data Analyst. Software Developer

Responses (3)