Revamped Flutter Edfapay SoftPos SDK
Helps developers to easly integrate EdfaPay SoftPos to flutter mobile application with few simple steps.
Wiki & Documentation
EdfaPay SoftPos SDK
Important
Install edfapay-softpos-sdk
flutter pub add edfapay_softpos_sdk
or add the dependency in project pubspec.yaml
dependencies:
edfapay_softpos_sdk: 1.0.0+1 # or specify 'any' to always look for the latest version
Important
FlutterFragmentActivity
- Change the android MainActivity super class from
FlutterActivitytoFlutterFragmentActivity - ./android/app/src/main/kotlin/app_package_tree/MainActivity.kt
Example
package com.edfapay.sample_app // your application package
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity()
Usage
1: Imports
import 'package:edfapay_softpos_sdk/edfapay_softpos_sdk.dart';
import 'package:edfapay_softpos_sdk/models/edfapay_credentials.dart';
import 'package:edfapay_softpos_sdk/models/txn_params.dart';
import 'package:edfapay_softpos_sdk/enums/env.dart';
import 'package:edfapay_softpos_sdk/helpers.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
2: Initialization
2.1: Create Credentials
-
I will prompt for the credentials whether user Email/Password or Token
EdfaPayCredentials credentials = EdfaPayCredentials.withEmailPassword( environment: Env.DEVELOPMENT, email: null, password: null ); -
I will also prompt for the credentials whether user Email/Password or Token
EdfaPayCredentials credentials = EdfaPayCredentials.withInput( environment: Env.PRODUCTION, ); -
I will prompt for the credentials with prefilled user Email/Password
EdfaPayCredentials credentials = EdfaPayCredentials.withEmailPassword( environment: Env.DEVELOPMENT, email: "user@email.com", password: "Password@123" ); -
I will prompt for the credentials with prefilled user Email
EdfaPayCredentials credentials = EdfaPayCredentials.withEmail( environment: Env.DEVELOPMENT, email: "user@email.com", ); -
I will silently prepare and initialize the SDK with prefilled terminal Token
- This should be Terminal Token to behave as silent SDK initialization
EdfaPayCredentials credentials = EdfaPayCredentials.withToken( environment: Env.DEVELOPMENT, token: "****Terminal Token Should be Generated at Edfapay SoftPOS Portal****", );
2.2: Initialize with Created Credentials
- This function will begin initialization and configure your phone for transactions.
- Note: Make sure to catch the exception and observe the reason of failed initialization.
EdfaPayPlugin.initiate(credentials: credentials).then((value){ if(value == false){ // Handle initialization failed // inform the developer or user initializing failed // Developer should observe this and take necessary action // Note: If exception is not caught see the console for error through. }else{ // Allow user to start payment process in next step } }).catchError((e) { if (e is PlatformException) { toast(e.message ?? e.code); } else { toast("Error Initializing SDK: ${e.toString()}"); } });
3: Setting Theme (Optional)
final logo = "base64 of image";
// final logo = await assetsBase64('path to image asset');
EdfaPayPlugin.theme()
.setPrimaryColor("#06E59F")
.setSecondaryColor("#000000")
.setPoweredByImage(logo)
.setHeaderImage(logo);
Tip
There is an helper method in SDK to convert image asset to base64
final logo = await assetsBase64('path to image asset');
4: Pay
final params = TxnParams(
amount: "10.000",
transactionType: TransactionType.purchase,
orderId: "12340987" // Optional, If not provided the transactionId will be considered as orderId
);
EdfaPayPlugin.pay(
params,
onPaymentProcessComplete: (status, code, result, isProcessComplete){
if(status){
print(' >>> [ Success ]');
print(' >>> [ ${jsonEncode(result)} ]');
}else{
print(' >>> [ Failed ]');
print(' >>> [ ${jsonEncode(result)} ]');
}
},
onServerTimeOut: (){
print('>>> Server Timeout');
print(' >>> The request timeout while performing transaction at backend');
},
onScanCardTimeOut: (){
print('>>> Scan Card Timeout');
print(' >>> The scan card timeout, no any card tap on device');
},
onCancelByUser: (){
print('>>> Canceled By User');
print(' >>> User have cancel the scanning/payment process on its own choice');
},
onError: (error){
print('>>> Exception');
print(' >>> "Scanning/Payment process through an exception, Check the logs');
print(' >>> ${error.toString()}');
}
);
Example
Instruction to Run Example:
- Make sure to install below plugins to your sample flutter app
- Dont forget to apply Important marked configuration/change at the top in to your project
- Copy the below content and paste it to main.dart (make sure to replace all)
// ignore_for_file: avoid_print
import 'package:edfapay_softpos_sdk/edfapay_softpos_sdk.dart';
import 'package:edfapay_softpos_sdk/enums/env.dart';
import 'package:edfapay_softpos_sdk/helpers.dart';
import 'package:edfapay_softpos_sdk/models/txn_params.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:edfapay_softpos_sdk/models/edfapay_credentials.dart';
import 'helper_methods.dart';
/* add the plugin for below: (hexcolor: any) https://pub.dev/packages/hexcolor */
import 'package:hexcolor/hexcolor.dart';
// add the plugin for below: (fluttertoast: any) https://pub.dev/packages/fluttertoast
import 'package:fluttertoast/fluttertoast.dart';
const TERMINAL_TOKEN = "1C55275E0D3E7E527881B05FB2C22C2247FE477223B5B116E12D9A151A17FD68";
const logoPath = "assets/images/edfa_logo.png";
const amountToPay = "01.010";
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _edfaPluginInitiated = false;
@override
void initState() {
super.initState();
// initiate();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 20),
Expanded(
flex: 2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FractionallySizedBox(widthFactor: 0.3, child: Image.asset(logoPath)),
const SizedBox(height: 30),
const Text("SDK", style: TextStyle(fontSize: 65, fontWeight: FontWeight.w700), textAlign: TextAlign.center),
const SizedBox(height: 10),
const Text("v0.0.1", style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold), textAlign: TextAlign.center),
],
),
),
const Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.all(10),
child: Text("You're on your way to enabling your Android App to allow your customers to pay in a very easy and simple way just click the payment button and tap your payment card on NFC enabled Android phone.",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: Colors.black45), textAlign: TextAlign.center),
),
),
if(!_edfaPluginInitiated)
ElevatedButton(onPressed: initiate, style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(HexColor("06E59F"))), child: const Text("Initiate", style: TextStyle(color: Colors.black))),
if(_edfaPluginInitiated)
...[
ElevatedButton(onPressed: pay, style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(HexColor("06E59F"))), child: const Text("Pay $amountToPay", style: TextStyle(color: Colors.black))),
ElevatedButton(onPressed: refund, style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(HexColor("06E59F"))), child: const Text("Refund With RRN", style: TextStyle(color: Colors.black))),
ElevatedButton(onPressed: reconcile, style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(HexColor("06E59F"))), child: const Text("Reconciliation", style: TextStyle(color: Colors.black))),
ElevatedButton(onPressed: txnHistory, style: ButtonStyle(backgroundColor: MaterialStatePropertyAll(HexColor("06E59F"))), child: const Text("Txn History $amountToPay", style: TextStyle(color: Colors.black))),
],
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text("Click on button above to test the card processing with 10.00 SAR", style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400), textAlign: TextAlign.center),
),
],
),
),
),
);
}
initiate() async {
EdfaPayPlugin.enableLogs(true);
/*
EdfaPayCredentials credentials = EdfaPayCredentials.withEmailPassword(
environment: Env.DEVELOPMENT,
email: null,
password: null
);
EdfaPayCredentials credentials = EdfaPayCredentials.withEmailPassword(
environment: Env.DEVELOPMENT,
email: "user@mail.com",
password: "Password@123"
);
EdfaPayCredentials credentials = EdfaPayCredentials.withInput(
environment: Env.PRODUCTION,
);
EdfaPayCredentials credentials = EdfaPayCredentials.withEmail(
environment: Env.DEVELOPMENT,
email: "user@mail.com",
);
EdfaPayCredentials credentials = EdfaPayCredentials.withToken(
environment: Env.DEVELOPMENT,
token: TERMINAL_TOKEN,
);
*/
/* Above are all possible ways to create credentials*/
EdfaPayCredentials credentials = EdfaPayCredentials.withEmailPassword(
environment: Env.DEVELOPMENT,
email: null,
password: null
);
setTheme();
EdfaPayPlugin.initiate(credentials: credentials).then((value) {
setState(() {
_edfaPluginInitiated = value.status;
});
}).catchError((e) {
if (e is PlatformException) {
toast(e.message ?? e.code);
} else {
toast("Error Initializing SDK");
}
});
}
setTheme() async {
final logo = await assetsBase64(logoPath);
EdfaPayPlugin.theme()
.setButtonBackgroundColor("#06E59F")
.setButtonTextColor("#000000")
.setHeaderImage(logo)
.setPoweredByImage(logo);
}
pay() async {
if (!_edfaPluginInitiated) {
toast("Edfapay plugin not initialized.");
return;
}
final params = TxnParams.purchase(
amount: amountToPay,
orderId: "12340987"
);
EdfaPayPlugin.enableLogs(true);
EdfaPayPlugin.pay(params, onPaymentProcessComplete: (status, code, result, isProcessComplete) {
toast("Card Payment Process Completed");
print('>>> Payment Process Complete');
}, onServerTimeOut: () {
toast("Server Request Timeout");
print('>>> Server Timeout');
print(' >>> The request timeout while performing transaction at backend');
}, onScanCardTimeOut: () {
toast("Card Scan Timeout");
print('>>> Scan Card Timeout');
print(' >>> The scan card timeout, no any card tap on device');
}, onCancelByUser: () {
toast("Cancel By User");
print('>>> Canceled By User');
print(' >>> User have cancel the scanning/payment process on its own choice');
}, onError: (Exception error) {
toast(error.toString());
print('>>> Exception');
print(' >>> "Scanning/Payment process through an exception, Check the logs');
print(' >>> ${error.toString()}');
});
}
refund() async {
if (!_edfaPluginInitiated) {
toast("Edfapay plugin not initialized.");
return;
}
final params = TxnParams.refundWithRrn(
amount: amountToPay,
transactionDate: DateTime(2025, 08, 26),
rrn: null,
);
EdfaPayPlugin.enableLogs(true);
EdfaPayPlugin.refund(params, onPaymentProcessComplete: (status, code, result, isProcessComplete) {
toast("Card Payment Process Completed");
print('>>> Payment Process Complete');
}, onServerTimeOut: () {
toast("Server Request Timeout");
print('>>> Server Timeout');
print(' >>> The request timeout while performing transaction at backend');
}, onScanCardTimeOut: () {
toast("Card Scan Timeout");
print('>>> Scan Card Timeout');
print(' >>> The scan card timeout, no any card tap on device');
}, onCancelByUser: () {
toast("Cancel By User");
print('>>> Canceled By User');
print(' >>> User have cancel the scanning/payment process on its own choice');
}, onError: (Exception error) {
toast(error.toString());
print('>>> Exceptio¬n');
print(' >>> "Scanning/Payment process through an exception, Check the logs');
print(' >>> ${error.toString()}');
});
}
reconcile() async {
if (!_edfaPluginInitiated) {
toast("Edfapay plugin not initialized.");
return;
}
EdfaPayPlugin.reconcile(
onSuccess: (response){
toast("Success reconcile");
},
onError: (error){
print('>>> Exception');
print(' >>> "Scanning/Payment process through an exception, Check the logs');
print(' >>> ${error.toString()}');
}
);
}
txnHistory() async {
if (!_edfaPluginInitiated) {
toast("Edfapay plugin not initialized.");
return;
}
EdfaPayPlugin.txnHistory(
onSuccess: (response){
toast("Success txnHistory");
},
onError: (error){
print('>>> Exception');
print(' >>> "Scanning/Payment process through an exception, Check the logs');
print(' >>> ${error.toString()}');
}
);
}
toast(String text) {
Fluttertoast.showToast(msg: text);
}
}
License
MIT