fawry_sdk 0.1.5 copy "fawry_sdk: ^0.1.5" to clipboard
fawry_sdk: ^0.1.5 copied to clipboard

Fawry Plugin

Fawry SDK #

fawry_sdk is a cross-platform plugin that helps your app to integrate with Fawry native Android/IOS SDKs.

Getting Started #

Add this to your package's pubspec.yaml file:

dependencies:
  fawry_sdk: ^0.1.5

Android Setup #

Manifest

You have to edit AndroidManifest.xml file with following.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" />
        <application
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="Your App Label"
        tools:replace="android:label"> -->if you're not defining a label remove 'android:label' from tools:replace
    </appliaction>
</manifest>

Finally, Update minimum SDK version to be 21 or higher, to meet the specs of our native android SDK

In build.gradle modify 'minSdkVersion'

android {
    compileSdkVersion flutter.compileSdkVersion
    minSdkVersion 21
    ...
}

iOS Setup #

Need XCode 13.2.x and SWIFT 5.5.x. Set your native runner project's minimum iOS version under "Deployment info" to 12.1 or higher

Minimum deployment target is 12.1

NOTE The plugin supports only real devices, simulators will be supported in later versions of our SDK. #

Usage #

You just have to import the package with

import 'package:fawry_sdk/fawry_sdk.dart';

Then, you need to initialize the SDK. To initialize the SDK you need to pass the follwoing variables to the plugin

  • launchModel: where you can define all data needed by FawrySDK for payment to be done.
  • lang: the language that the SDK will displayed with, We currently support English & Arabic
  • baseURL: a URL provided by our support team
Example
await FawrySdk.instance.init(
launchModel: fawryLaunchModel,
baseURL: "BASE_URL",
lang: FawrySdk.LANGUAGE_ENGLISH or FawrySdk.LANGUAGE_ARABIC);

Building FawryLaunchModel #

As mentioned before, FawryLaunchModel is mandatory to initialize FawrySDK, in this model you can define all the attributes needed for the payment process, some of these attributes are mandatory and some are optional.

FawryLaunchModel – mandatory/optional parameters: -

i. LaunchCustomerModel (optional) – parameters

  1. customerName (optional)
  2. customerEmail (optional - Receives an email with the receipt after the payment is complete)
  3. customerMobile (optional - Receives an SMS with the reference number and payment details)

ii. ChargeItem -> parameters

  1. Price (mandatory)
  2. Quantity (mandatory)
  3. itemId (mandatory)
  4. Description (optional)

iii. LaunchMerchantModel – parameters

  1. merchantCode (provided by support – mandatory)
  2. merchantRefNum (random 10 alphanumeric digits – mandatory)

iv. allow3DPayment (to allow 3dsecure payment) v. secretCode (provided by support) vi. signature (generated by you) vii. skipLogin (you can skip login screen that takes email and mobile) and default value true viii. skipReceipt (to skip the receipt screen) and default value false

Example #

 BillItem item = BillItem(
    itemId: "ITEM_ID",
    description: "",
    quantity: 4,
    price: 15);
List<BillItem>? chargeItems = [item];

LaunchCustomerModel customerModel = LaunchCustomerModel(
    customerName: "John Doe",
    customerEmail: "john.doe@xyz.com",
    customerMobile: "+201000000000");

LaunchMerchantModel merchantModel = LaunchMerchantModel(
    merchantCode: "MERCHANT_CODE",
    merchantRefNum: "MERCHANT_REF_NUM",
    secureKey: "SECURE_KEY or SECRET_CODE");

FawryLaunchModel model = FawryLaunchModel(
    allow3DPayment: true,
    chargeItems: chargeItems,
    launchCustomerModel: customerModel,
    launchMerchantModel: merchantModel,
    skipLogin: true,
    skipReceipt: false);

Now, you can stream the result data that came from SDK.

  FawrySdk.instance.callbackResultStream().listen((event) {
setState(() {
ResponseStatus response = ResponseStatus.fromJson(jsonDecode(event));
switch (response.status) {
case FawrySdk.RESPONSE_SUCCESS:
{
//Success status
debugPrint('Message : ${response.message}');
//Success json response
debugPrint('Json Response : ${response.data}');
}
break;
case FawrySdk.RESPONSE_ERROR:
{
debugPrint('Error : ${response.message}');
}
break;
case FawrySdk.RESPONSE_PAYMENT_COMPLETED:
{
debugPrint('Payment Completed : ${response.message} , ${response.data}');
}
break;
}
});
});

Custom UI #

Sometimes you will need to make some customizations to payment screen; customizations in styles, colors, etc... In this case you will need to override our native SDK UI in both Android and IOS.

Android Setup #

Android UI customization can be achieved by adding 'payment_fragment.xml' to your android native module add this file to android/app/src/main/res/layout directory,

and make sure to add the code below to 'payment_fragment.xml' file

payment_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/home_background"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/rlHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="@color/fawry_blue"
        android:orientation="vertical">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            android:orientation="horizontal">

            <com.app.mylibrary.ui.custom_views.BackImageView
                android:id="@+id/ivBack"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="@dimen/_10sdp"
                android:src="@drawable/ic_back"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <ImageView
                android:layout_width="@dimen/_150sdp"
                android:layout_height="@dimen/_100sdp"
                android:adjustViewBounds="true"
                android:src ="@drawable/fawry_pay_english"
                android:padding="@dimen/_10sdp"
                android:scaleType="fitCenter"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <LinearLayout
            android:id="@+id/llAddressHeader"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_15sdp"
            android:layout_marginEnd="@dimen/_15sdp"
            android:gravity="center_horizontal"
            android:paddingBottom="@dimen/_10sdp"
            android:visibility="gone">

            <LinearLayout
                android:id="@+id/addressConstraint"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:orientation="vertical"
                app:layout_constraintEnd_toStartOf="@id/lineConnector">

                <ImageView
                    android:id="@+id/ivIcAddress"
                    android:layout_width="@dimen/_25sdp"
                    android:layout_height="@dimen/_25sdp"
                    android:layout_gravity="center_horizontal"
                    android:src="@drawable/ic_address" />

                <TextView
                    android:id="@+id/tvIcAddress"
                    style="@style/item_description_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="@string/address"
                    android:textColor="@color/colorBlack" />
            </LinearLayout>

            <View
                android:id="@+id/lineConnector"
                android:layout_width="@dimen/_75sdp"
                android:layout_height="@dimen/_4sdp"
                android:layout_marginStart="-15dp"
                android:layout_marginTop="@dimen/_10sdp"
                android:layout_marginEnd="-16dp"
                android:layout_marginBottom="@dimen/_6sdp"
                android:background="@color/misty_rose" />

            <LinearLayout
                android:id="@+id/paymentConstraint"
                android:layout_width="@dimen/_50sdp"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/ivIcPayment"
                    android:layout_width="@dimen/_25sdp"
                    android:layout_height="@dimen/_25sdp"
                    android:layout_gravity="center_horizontal"
                    android:src="@drawable/ic_payment" />

                <TextView
                    android:id="@+id/tvIcPayment"
                    style="@style/item_description_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_horizontal"
                    android:text="@string/payment"
                    android:textColor="@color/colorBlack" />
            </LinearLayout>
        </LinearLayout>

    </LinearLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/priceContainer"
        android:layout_below="@+id/rlHeader"
        android:background="@color/home_background"
        android:fillViewport="true"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:paddingLeft="@dimen/screen_padding"
        android:paddingRight="@dimen/screen_padding">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <FrameLayout
                android:id="@+id/shippingContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintTop_toTopOf="parent" />

            <FrameLayout
                android:id="@+id/branchContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintTop_toBottomOf="@+id/shippingContainer" />

            <FrameLayout
                android:id="@+id/dateContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_constraintBottom_toTopOf="@id/llContainer"
                app:layout_constraintTop_toBottomOf="@+id/branchContainer" />

            <androidx.appcompat.widget.LinearLayoutCompat
                android:id="@+id/llContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="@dimen/_20sdp"
                android:orientation="vertical"
                app:layout_constraintBottom_toTopOf="@+id/btnConfirm"
                app:layout_constraintTop_toBottomOf="@+id/branchContainer" />

            <androidx.appcompat.widget.LinearLayoutCompat
                android:id="@+id/beanosBalanceContainer"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="@dimen/_20sdp"
                android:orientation="vertical"
                app:layout_constraintBottom_toTopOf="@+id/btnConfirm"
                app:layout_constraintTop_toBottomOf="@+id/branchContainer" />


        </LinearLayout>

    </androidx.core.widget.NestedScrollView>


    <LinearLayout
        android:id="@+id/priceContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/payment_price_background"
        android:orientation="vertical">

        <androidx.appcompat.widget.LinearLayoutCompat
            android:id="@+id/price_breakdown_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/_5sdp"
            android:orientation="vertical"
            android:paddingStart="@dimen/_10sdp"
            android:paddingEnd="@dimen/_10sdp"
            app:layout_constraintBottom_toTopOf="@+id/btnConfirm"
            app:layout_constraintTop_toBottomOf="@+id/branchContainer" />

        <TextView
            android:id="@+id/btnConfirm"
            style="@style/blue_button"
            android:visibility="gone"
            android:layout_marginBottom="@dimen/_5sdp"
            android:background="@drawable/rounded_btn"
            android:backgroundTint="@color/fawry_yellow"
            android:fontFamily="@font/futura_medium_bt"
            android:paddingBottom="@dimen/_10sdp"
            android:text="@string/confirm_payment"
            android:textColor="@color/fawry_blue" />
    </LinearLayout>
</RelativeLayout>

NOTE You can modify styles, colors, position of views etc... on the above code, But make sure that the view ids is as same as the example, otherwise unintended behaviour could happen. #

Reuse existing Android resources #

You will also need to add android native library to your gradle so you can use colors, and styles of our native sdk, In your ```build.gradle add the following

repositories {
    mavenCentral()
    flatDir {
        dirs 'libs'
    }
}

dependencies {
    ...
    implementation(name:'fawrySDK-anonymousFlow-release-X.Y.Z', ext:'aar')
}

NOTE Replace X.Y.Z with the provided native SDK version available in this file. #

IOS Setup #

Handle XCFramework build Configurations #

Add the following build configurations in Podfile

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
  end
end

UI Customizations #

In order to change the SDK's colors on iOS you need to do the following steps: First, in your native runner project, create a new plist file and name it "Style"

Then add the following keys to the file

  • primaryColorHex
  • secondaryColorHex
  • tertiaryColorHex
  • headerColorHex

Set your preferred colors' hex codes to these keys and the colors will be changed accordingly.