How to Integrate Paypal Payment Gateway in Laravel 9

In this article, we will see laravel 9 paypal payment gateway integration. Here, we will learn how to integrate the paypal payment gateway integration in laravel 9. Most of the merchants accept online payments option for payment gateway integration. A payment gateway is a tool that allows merchants to accept online payments like Stripe, PayPal, Payoneer, and Razorpay.

PayPal is the faster, safer way to send and receive money or make an online payment. Also, it can manage digital wallets, money management, and more. We will use paypal/rest-api-sdk-php package. This SDK is deprecated. You can continue to use it, but no new features or support requests will be accepted.

For alternatives, please visit the current SDK homepage on the PayPal Developer Portal.

So, let's see paypal payment gateway integration in laravel 9, paypal integration in laravel 9, paypal/rest-api-sdk-php laravel 9, and laravel 9 paypal integration.

How to integrate PayPal payment gateway integration in laravel 9

Step 1: Install Laravel 9 Application

In this step, we will install the laravel 9 application using the composer command.

composer create-project --prefer-dist laravel/laravel laravel_9_paypal_integration

Step 2: Setup Database Configuration

Now, we will set up database configuration like database name, username, password, etc. So, let's open the .env file and fill in the details like as below.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_username
DB_PASSWORD=your_database_password

Read Also: How To Integrate Razorpay Payment Gateway In Laravel 9

 Step 3: Install paypal/rest-api-sdk-php Package

In this step, we will install paypal/rest-api-sdk-php package using the composer command. composer is the recommended way to install the SDK. Alternatively, if you prefer not to use Composer, but want to install Paypal SDK, you can do it by direct download.

composer require paypal/rest-api-sdk-php

After installation of the PayPal package, we required a client id and secret key for Paypal integration. So, we need to login into PayPal developer mode and create a new sandbox account for the same.

After login into Paypal, you need to get the client id and secret key like the below screenshot.

laravel_9_paypal_payment_gateway_integration_client_id

Step 4: Configuration paypal.php file

Now, we need to configure the paypal.php file. So, we have manually created one file in config/paypal.php and added the below code.

<?php 
return [ 
    'client_id' => 'Enter Your Client ID',
	'secret' => 'Enter Your Secret Key',
    'settings' => array(
        'mode' => 'sandbox',
        'http.ConnectionTimeOut' => 1000,
        'log.LogEnabled' => true,
        'log.FileName' => storage_path() . '/logs/paypal.log',
        'log.LogLevel' => 'FINE'
    ),
];

Step 5: Add Route in web.php File

 In this step, we will add routes on the web.php file

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PaypalController;

Route::get('paywithpaypal', array('as' => 'paywithpaypal','uses' => 'PaypalController@payWithPaypal'));
Route::post('paypal', array('as' => 'paypal','uses' => 'PaypalController@postPaymentWithpaypal'));
Route::get('paypal', array('as' => 'status','uses' => 'PaypalController@getPaymentStatus'));

Read Also: How To Integrate Stripe Payment Gateway In Laravel 9

Step 6: Create Controller

Now, we will create the PaypalController.php file and add the following code to that file.

<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use Illuminate\Http\Request;
use Validator;
use URL;
use Session;
use Redirect;
use Input;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\ExecutePayment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;

class PaypalController extends Controller
{
    private $_api_context;
    
    public function __construct()
    {
            
        $paypal_configuration = \Config::get('paypal');
        $this->_api_context = new ApiContext(new OAuthTokenCredential($paypal_configuration['client_id'], $paypal_configuration['secret']));
        $this->_api_context->setConfig($paypal_configuration['settings']);
    }

    public function payWithPaypal()
    {
        return view('paywithpaypal');
    }

    public function postPaymentWithpaypal(Request $request)
    {
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');

    	$item_1 = new Item();

        $item_1->setName('Product 1')
            ->setCurrency('USD')
            ->setQuantity(1)
            ->setPrice($request->get('amount'));

        $item_list = new ItemList();
        $item_list->setItems(array($item_1));

        $amount = new Amount();
        $amount->setCurrency('USD')
            ->setTotal($request->get('amount'));

        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription('Enter Your transaction description');

        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(URL::route('status'))
            ->setCancelUrl(URL::route('status'));

        $payment = new Payment();
        $payment->setIntent('Sale')
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));            
        try {
            $payment->create($this->_api_context);
        } catch (\PayPal\Exception\PPConnectionException $ex) {
            if (\Config::get('app.debug')) {
                \Session::put('error','Connection timeout');
                return Redirect::route('paywithpaypal');                
            } else {
                \Session::put('error','Some error occur, sorry for inconvenient');
                return Redirect::route('paywithpaypal');                
            }
        }

        foreach($payment->getLinks() as $link) {
            if($link->getRel() == 'approval_url') {
                $redirect_url = $link->getHref();
                break;
            }
        }
        
        Session::put('paypal_payment_id', $payment->getId());

        if(isset($redirect_url)) {            
            return Redirect::away($redirect_url);
        }

        \Session::put('error','Unknown error occurred');
    	return Redirect::route('paywithpaypal');
    }

    public function getPaymentStatus(Request $request)
    {        
        $payment_id = Session::get('paypal_payment_id');

        Session::forget('paypal_payment_id');
        if (empty($request->input('PayerID')) || empty($request->input('token'))) {
            \Session::put('error','Payment failed');
            return Redirect::route('paywithpaypal');
        }
        $payment = Payment::get($payment_id, $this->_api_context);        
        $execution = new PaymentExecution();
        $execution->setPayerId($request->input('PayerID'));        
        $result = $payment->execute($execution, $this->_api_context);
        
        if ($result->getState() == 'approved') {         
            \Session::put('success','Payment success !!');
            return Redirect::route('paywithpaypal');
        }

        \Session::put('error','Payment failed !!');
		return Redirect::route('paywithpaypal');
    }
}

 

Step 7: Create Blade File

Now, we need to create one blade file for view. So, add the below code in your paywithpaypal.php file.

<html>
<head>
	<meta charset="utf-8">
	<title>Laravel 9 Paypal Payment Gateway Integration - Websolutionstuff</title>
	<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
	<div class="container">
    <div class="row">    	
        <div class="col-md-8 col-md-offset-2">        	
        	<h3 class="text-center" style="margin-top: 30px;">Laravel 9 Paypal Payment Gateway Integration - Websolutionstuff</h3>
            <div class="panel panel-default" style="margin-top: 60px;">

                @if ($message = Session::get('success'))
                <div class="custom-alerts alert alert-success fade in">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true"></button>
                    {!! $message !!}
                </div>
                <?php Session::forget('success');?>
                @endif

                @if ($message = Session::get('error'))
                <div class="custom-alerts alert alert-danger fade in">
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true"></button>
                    {!! $message !!}
                </div>
                <?php Session::forget('error');?>
                @endif
                <div class="panel-heading"><b>Paywith Paypal</b></div>
                <div class="panel-body">
                    <form class="form-horizontal" method="POST" id="payment-form" role="form" action="{!! URL::route('paypal') !!}" >
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('amount') ? ' has-error' : '' }}">
                            <label for="amount" class="col-md-4 control-label">Enter Amount</label>

                            <div class="col-md-6">
                                <input id="amount" type="text" class="form-control" name="amount" value="{{ old('amount') }}" autofocus>

                                @if ($errors->has('amount'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('amount') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        
                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Paywith Paypal
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

Output:

laravel_9_paypal_payment_gateway_integration_home_page

Once you will enter the amount you will get a form like this.

laravel_9_paypal_payment_gateway_integration_payment_page

After clicking on continue, you will get a success form like the below screenshot.

laravel_9_paypal_payment_gateway_integration_payment_success

Original article source at: https://websolutionstuff.com/

#laravel #paypal #payment 

How to Integrate Paypal Payment Gateway in Laravel 9

Flutter plugin for Paymentgateway SDK

Paymentgateway Flutter

Flutter plugin for Paymentgateway SDK.

Getting Started

This flutter plugin is a wrapper around our Android and iOS SDKs.

The following documentation is only focused on the wrapper around our native Android and iOS SDKs.

Prerequisites

Development Tools:

  • Xcode 12 and above
  • Android Studio 4.1 and above
  • Flutter 2.2.3 & Dart 2.12.0 and above

Installation

This plugin is available on Pub: https://pub.dev/packages/payment_gateway_flutter

Add this to dependencies in your app's pubspec.yaml

payment_gateway_flutter: ^1.0.0

Note for Android: Make sure that the minimum API level for your app is 19 or higher.

Note for iOS: Make sure that the minimum deployment target for your app is iOS 10.0 or higher. Also, This is not support SIMULATOR you can run onlly in real iPhone devices.

Run flutter packages get in the root directory of your app.

Usage

Sample code to integrate can be found in example/lib/main.dart.

Import package

import 'package:payment_gateway_flutter/payment_gateway_flutter.dart';

Create Paymentgateway instance

PaymentGatewayFlutter.open(
          '<PAYMENT_URL>', request)

Passing Payment params and URL

// For payment parammeters to refer 
// https://pgandroidintegrations.docs.stoplight.io/request-param-list

var params = {
'api_key': '<API_KEY>',
'hash': '<HASH_KEY>',
'order_id': 'TEST4000',
'mode': 'LIVE',
'description': 'Test',
'currency': 'INR',
'amount': '2',
'name': 'Senthil',
'email': 'emailsenthil@test.com',
'phone': '9597403366',
'city': 'Chennai',
'state': 'Tamilnadu',
'country': 'IND',
'zip_code': '630501',
'address_line_1': 'ad1',
'address_line_2': 'ad2',
'return_url': 'http://localhost:8888/paymentresponse'};

PaymentGatewayFlutter.open(
          '<PAYMENT_URL>', params)

Accessing response


response = await PaymentGatewayFlutter.open(
          '<PAYMENT_API_URL>', request);
      // Response Handling
      //Please refre this url for reponse code https://pgandroidintegrations.docs.stoplight.io/response-codes
      var r=jsonDecode(response);
      print(r['status']);
      print(r['payment_response']);
    

List of Request Parameters

Request parameters are the parameters that will be send to our server API for payment initiation. Client should store the order id and the amount before payment initiation and compare it with the order id and amount in the response Json from our server post payment process to ensure no end user tampering on the requested parameters.

Please use this link for all params reference link

List of Response Codes

Note

Below are the response codes that comes in the payment response post payment from our server, that must be handled by the client.

Please use this link for reference link

HASH Calculation

Please use this link for reference link

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add payment_gateway_flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  payment_gateway_flutter: ^1.0.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:payment_gateway_flutter/payment_gateway_flutter.dart'; 

example/lib/main.dart

// @dart=2.9
import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:payment_gateway_flutter/payment_gateway_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: _AppState(),
    );
  }
}

class _AppState extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<_AppState> {
  dynamic response;
  String paymentResponse = "";

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Payment Gateway'),
        ),
        body: Padding(
            padding: EdgeInsets.all(10),
            child: ListView(
              children: <Widget>[
                Container(
                    alignment: Alignment.center,
                    padding: EdgeInsets.all(10),
                    child: Text(
                      'Welcome Payment Gateway',
                      style: TextStyle(
                          color: Colors.blue,
                          fontWeight: FontWeight.w500,
                          fontSize: 30),
                    )),
                Container(
                    height: 50,
                    padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                    child: RaisedButton(
                      textColor: Colors.white,
                      color: Colors.blue,
                      child: Text('Pay Now'),
                      onPressed: () {
                    // For payment parammeters to refer 
                    //https://pgandroidintegrations.docs.stoplight.io/request-param-list
                    var params = {
                    'api_key': '<API_KEY>',
                    'hash': '<HASH_KEY>',
                    'order_id': 'TEST4000',
                    'mode': 'LIVE',
                    'description': 'Test',
                    'currency': 'INR',
                    'amount': '2',
                    'name': 'Senthil',
                    'email': 'emailsenthil@test.com',
                    'phone': '9597403366',
                    'city': 'Chennai',
                    'state': 'Tamilnadu',
                    'country': 'IND',
                    'zip_code': '630501',
                    'address_line_1': 'ad1',
                    'address_line_2': 'ad2',
                    'return_url': 'http://localhost:8888/paymentresponse'};
                    // Initiate payemnt
                    open(params, context);
                      },
                    )),
                if (paymentResponse.isNotEmpty)
                  Container(
                      alignment: Alignment.center,
                      padding: EdgeInsets.all(10),
                      child: Text(
                        'Payment Response : ' + paymentResponse,
                        style: TextStyle(
                            color: Colors.blue,
                            fontWeight: FontWeight.w500,
                            fontSize: 20),
                      ))
              ],
            )),
      ),
    );
  }

  void open(Map<String, dynamic> request, BuildContext context) async {
    try {
      response = await PaymentGatewayFlutter.open(
          '<PAYMENT_API_URL>', request);
      // Response Handling
      //Please refre this url for reponse code https://pgandroidintegrations.docs.stoplight.io/response-codes
      var r=jsonDecode(response);
      print(r['status']);
      print(r['payment_response']);

    } on PlatformException {
      response = 'Failed to get initiate.';
    }
    setState(() {
      paymentResponse = response;
    });
  }


} 

Download Details:

Author: paymentgatewayintegration

Source Code: https://github.com/paymentgatewayintegration/payment-gateway-flutter

#flutter  #payment 

Flutter plugin for Paymentgateway SDK

Midtrans Payment Gateway for Flutter

Midtrans Payment Gateway for Flutter

Platform Support

AndroidiOSMacOSWebLinuxWindows
✔️✔️️X️X️ X️X

Android setup

Add style to your android/app/src/main/res/values/styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

And full styles.xml will be like below :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <!-- Show a splash screen on the activity. Automatically removed when
             Flutter draws its first frame -->
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>

And add the style to you Android Manifest in your application tag :

tools:replace="android:label"
android:theme="@style/AppTheme"

IOS

No specific setup required

BASE_URL

goto midtrans official documentation or merchant server github

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add midpay

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  midpay: ^1.1.7

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:midpay/midpay.dart'; 

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:midpay/midpay.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final midpay = Midpay();

  //test payment
  _testPayment() {
    //for android auto sandbox when debug and production when release
    midpay.init("CLIENT KEY", "BASE_URL", environment: Environment.sandbox);
    midpay.setFinishCallback(_callback);
    var midtransCustomer = MidtransCustomer(
        'Zaki', 'Mubarok', 'kakzaki@gmail.com', '085704703691');
    List<MidtransItem> listitems = [];
    var midtransItems = MidtransItem('IDXXX', 50000, 2, 'Charger');
    listitems.add(midtransItems);
    var midtransTransaction = MidtransTransaction(
        100000, midtransCustomer, listitems,
        skipCustomer: true);
    midpay
        .makePayment(midtransTransaction)
        .catchError((err) => print("ERROR $err"));
  }

  //calback
  Future<void> _callback(TransactionFinished finished) async {
    print("Finish $finished");
    return Future.value(null);
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Midpay Plugin example app'),
        ),
        body: new Center(
          child: ElevatedButton(
            child: Text("Payment"),
            onPressed: () => _testPayment(),
          ),
        ),
      ),
    );
  }
} 

Download Details:

Author: kakzaki

Source Code: https://github.com/kakzaki/midpay

#flutter #payment 

Midtrans Payment Gateway for Flutter

A Simple Way to Integrate Payments Into Mobile Application In Flutter

Flutter Tinkoff Acquiring SDK is a simple way to integrate payments into your mobile application.


Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add tinkoff_acquiring_flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  tinkoff_acquiring_flutter: ^3.0.6

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:tinkoff_acquiring_flutter/tinkoff_acquiring_flutter.dart'; 

example/README.md

The Example is in the corresponding folder 

Download Details:

Author: MadBrains

Source Code: https://github.com/MadBrains/Tinkoff-Acquiring-SDK-Flutter

#flutter #payment 

A Simple Way to Integrate Payments Into Mobile Application In Flutter

Simpay SDK Module for Payment integration In Chile

SDK Simpay

Módulo SDK de Simpay para la integración de pagos en Chile.

Uso

Para usar este complemento agréguelo como dependencia en su archivo pubspec.yaml.

Importar la dependencia

import 'package:simpay/simpay.dart';

Inicializar la instancia

final simpay = Simpay(
    commerceCode: commerceCode,
    apiKey: apikey,
    secretKey: secretkey,
    production: true);

Obtener medios de pago disponibles

simpay.getMethodsPayments().then((ListPayments payments) {
    print(payments);
});

Crear una transacción

simpay.createPay(data).then((ResponsePayment value) {
    print(value);
});

Realizar el pago

simpay.getPay(context, response_for_create_transaction);

Listener de eventos

Evento de respuesta de transacción

simpay.success.stream.listen((ResPayment res) {
    switch (res.status) {
        case StatusPayment.AUTHORIZED:
            print("Transacción exitosa");
            break;
        case StatusPayment.FAILED:
            print("Transacción Fallida");
            break;
        case StatusPayment.CANCEL:
            print("Transaccion cancelada por el cliente");
            break;

        case StatusPayment.TIMEOUT:
            print("Timeout transacción");
            break;
    }
});

Evento de proceso de transacción

simpay.onProcess.stream.listen((EventStatusPayment ev) {
    switch (ev.event) {
        case "create_pay":
          switch (ev.status) {
            case "inProcess":
              return print("Creando transacción");
            case "ok":
              return print("Transacción creada");
            case "err":
              return print("Ah ocurrido un error al creal la transacción");
          }
          break;
        case "get_payments":
          switch (ev.status) {
            case "inProcess":
              return print("Cargando métodos de pago");
            case "ok":
              return print("Medios de pago cargados");
            case "err":
              return print("Ah ocurrido un error al cargar los métodos de pago");
          }
          break;
        case "get_pay":
          switch (ev.status) {
            case "inProcess":
            case "ok":
          }
          break;
      }
    });
}

Características

  • Transacciones a través de tarjetas bancarias, crédito, débito y prepago.
  • Transacciones a través de transferencia electrónica.
  • Fácil implementación

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add simpay

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  simpay: ^0.2.3

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:simpay/simpay.dart'; 

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:simpay/simpay.dart';
import 'package:simpay/colors.dart';
import './const.dart';
import 'dart:math';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  _MyApp createState() => _MyApp();
}

class _MyApp extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Simpay',
      home: Pay(),
    );
  }
}

class Pay extends StatefulWidget {
  const Pay({Key? key}) : super(key: key);

  @override
  State<Pay> createState() => _PayState();
}

class _PayState extends State<Pay> {
  final GlobalKey _scaffold = GlobalKey();

  final simpay = Simpay(
      commerceCode: commerceCode,
      apiKey: apikey,
      secretKey: secretkey,
      production: false);

  DataPayments data = DataPayments(
    amount: 0,
    order: "",
    subject: "",
  );

  bool active = false;
  ResponsePayment response = ResponsePayment(
      success: false, order: '', url: '', session: '', amount: 0);
  ListPayments _methods = ListPayments(list: []);
  int num = 0;
  String message = "Cargando medios de pago";
  TextStyle sTitle = TextStyle(color: AppColor.primary, fontSize: 16);
  TextStyle sMethodTtitle =
      TextStyle(fontWeight: FontWeight.bold, color: AppColor.primary);
  Image logo =
      const Image(image: AssetImage('assets/isotipo.png', package: 'simpay'));
  String currentMethod = "";
  TextStyle sMethods =
      TextStyle(fontWeight: FontWeight.bold, color: AppColor.primary, fontSize: 16);
  TextStyle sMessage =
      TextStyle(fontSize: 13, color: AppColor.secondary);

  @override
  void initState() {
    super.initState();
    Timer.run(() {
      simpayInit();
    });
  }

  @override
  void didChangeDependencies() {
    context.dependOnInheritedWidgetOfExactType();
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    context.dependOnInheritedWidgetOfExactType();
    super.dispose();
  }

  void setMessage(msg) {
    setState(() => message = msg);
  }

  void setLoad(b) {
    setState(() => active = b);
  }

  void showNotify(String text, Color? color) {
    var snackBar = SnackBar(
      content: Text(text),
      backgroundColor: color,
      duration: const Duration(milliseconds: 500),
    );
    ScaffoldMessenger.of(_scaffold.currentContext!).showSnackBar(snackBar);
  }

  void simpayInit() async {
    simpay.getMethodsPayments().then((ListPayments payments) {
      setState(() => _methods = payments);
    });

    simpay.success.stream.listen((ResPayment res) {
      switch (res.status) {
        case StatusPayment.AUTHORIZED:
          showNotify("Transacción exitosa", AppColor.success);
          break;
        case StatusPayment.FAILED:
          showNotify("Transacción Fallida", AppColor.error);
          break;
        case StatusPayment.CANCEL:
          showNotify("Transaccion cancelada por el cliente", AppColor.secondary);
          break;
        case StatusPayment.TIMEOUT:
          showNotify("Timeout transacción", AppColor.secondary);
          break;
      }
    });

    simpay.onProcess.stream.listen((EventStatusPayment ev) {
      switch (ev.event) {
        case "create_pay":
          switch (ev.status) {
            case "inProcess":
              setLoad(false);
              return showNotify("Creando transacción", AppColor.secondary);
            case "ok":
              return showNotify("Transacción creada", AppColor.secondary);
            case "err":
              return showNotify("Ah ocurrido un error al creal la transacción",
                  AppColor.secondary);
          }
          break;
        case "get_payments":
          switch (ev.status) {
            case "inProcess":
              return showNotify("Cargando métodos de pago", AppColor.secondary);
            case "ok":
              setMessage("");
              return showNotify("Medios de pago cargados", AppColor.secondary);
            case "err":
              return showNotify(
                  "Ah ocurrido un error al cargar los métodos de pago",
                  AppColor.secondary);
          }
          break;
        case "get_pay":
          switch (ev.status) {
            case "inProcess":
            case "ok":
          }
          break;
      }
    });
  }

  void createPayment(PaymentMethods payment, context) {
    if (num < 100) {
      showNotify(
          r"Debes agregar un  monto superior a $99 pesos", AppColor.secondary);
    } else {
      data.order = "O-00" + Random().nextInt(100000).toString();
      data.subject = "Prueba de integracion SDK simpay for Flutter";
      data.method = payment.code;
      data.amount = num;
      data.contact = "luis@bukitech.cl";

      simpay.createPay(data).then((ResponsePayment value) {
        setState(() {
          response = value;
          active = true;
          currentMethod = "con " + toCapitalize(payment.name);
        });
      });
    }
  }

  void setAmountValue(v) {
    setState(() => num = v.isEmpty ? 0 : int.parse(v));
  }

  String toCapitalize(String text) {
    return "${text.characters.first.toUpperCase()}${text.substring(1)}";
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        key: _scaffold,
        appBar: AppBar(
          backgroundColor: AppColor.light,
          elevation: 1,
          title: Text('SDK Simpay for Flutter', style: sTitle),
          leading: Container(padding: const EdgeInsets.all(10), child: logo),
        ),
        body: SingleChildScrollView(
            child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(20),
              child: Column(
                children: [
                  Column(children: [
                    TextField(
                      onChanged: (v) {
                        setAmountValue(v);
                        setState(() => active = false);
                      },
                      decoration:
                          const InputDecoration(labelText: "Ingresa un monto"),
                      keyboardType:
                          const TextInputType.numberWithOptions(decimal: true),
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp('[0-9]'))
                      ],
                    ),
                    Container(
                      height: 20,
                    ),
                    Container(
                      margin: const EdgeInsets.symmetric(vertical: 15),
                      child: Text("Métodos de pago disponibles", style: sMethods,),
                    ),
                    Column(
                        children: _methods.list.map((PaymentMethods payment) {
                      return GestureDetector(
                        onTap: () => createPayment(payment, context),
                        child: Card(
                          child: Container(
                            padding: const EdgeInsets.all(15),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              crossAxisAlignment: CrossAxisAlignment.center,
                              mainAxisSize: MainAxisSize.max,
                              children: [
                                Container(
                                  width: 100,
                                  child: Text(
                                    toCapitalize(payment.name),
                                    style: sMethodTtitle,
                                  ),
                                ),
                                Expanded(
                                  child: Container(
                                    alignment: Alignment.centerRight,
                                    child: Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.center,
                                        crossAxisAlignment:
                                            CrossAxisAlignment.center,
                                        mainAxisSize: MainAxisSize.max,
                                        children: [
                                          Expanded(
                                              child: Text(
                                                  payment.desc.toString())),
                                          Container(
                                              child: const Icon(
                                                  Icons.chevron_right))
                                        ]),
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                      );
                    }).toList()),
                    Container(
                      padding: const EdgeInsets.symmetric(vertical: 8),
                      child: Text(message, style: sMessage,),
                    ),
                    Container(
                      height: 60,
                    ),
                    ElevatedButton(
                      child: Text("Pagar " + currentMethod),
                      onPressed: () {
                        if (active) simpay.getPay(context, response);
                      },
                      style: ElevatedButton.styleFrom(
                        primary: active ? AppColor.primary : Colors.grey,
                        minimumSize: const Size(250, 50),
                      ),
                    )
                  ])
                ],
              ),
            ),
          ],
        )),
      ),
    );
  }
} 

Download Details:

Author: 

Source Code: https://pub.dev/packages/simpay

#flutter #pay #payment 

Simpay SDK Module for Payment integration In Chile

A Flutter Package for adding Mobile Money Payments

Add Mobile Money payments to your flutter apps using the FlutterWave api gateway.

Features

  • Recieve Payments through Mobile Money in Uganda
  • Supports MTN Momo Transactions
  • Supports Airtel Money Transactions
  • Verify Charges your have made before adding value

Getting started

Get your api keys, head over to https://dashboard.flutterwave.com/settings/apis

You might also want to read about flutterwaves documentation. For this head to https://developer.flutterwave.com/reference

Usage

Create an instance of the UgandaMobileMoney class.

const secretKey = "FLWSECK-XXXXX-X"; // flutterwave secret key
UgandaMobileMoney _mobileMoney = UgandaMobileMoney(secretKey); 

Initiate Payments

void chargeClient() async {
    MomoPayResponse response = await _mobileMoney.chargeClient(
        MomoPayRequest(
            txRef: "MC-01928403", // should be unique for each transaction
            amount: "1500", // amount in UGX you want to charge
            email: "tst@gmail.com", // email of the person you want to charge
            phoneNumber: "256123456723", // clients phone number
            fullname: "Ojangole Joran", // full name of client
            redirectUrl: "https://yoursite.com", // redirect url after payment
            voucher: "128373", // useful for vodafone. you can ignore this
            network: UgandaNetwork.mtn // network, can be either mtn or airtel
            ),
        );

    print(response.message);
  }

To Verify transactions

   void verifyTransaction() {
    _mobileMoney.verifyTransaction(taxRef).then((value) {
      if (value == TransactionStatus.failed) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text("Failed")));
      } else if (value == TransactionStatus.pending) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text("Pending")));
      } else if (value == TransactionStatus.success) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text("Success")));
      } else if (value == TransactionStatus.unknown) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text("Unknown")));
      } else {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text("Unknown")));
      }
    });
  }

Additional information

Please contact me if your have any feature requests or file issues via the respository.

You can also buy me a rolex : https://dashboard.flutterwave.com/donate/7nacgysd7ilf

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add uganda_mobile_money

With Flutter:

 $ flutter pub add uganda_mobile_money

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  uganda_mobile_money: ^0.0.4

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:uganda_mobile_money/uganda_mobile_money.dart'; 

Download Details:

Author: jordanopos

Source Code: https://github.com/jordanopos/uganda_mobile_money

#flutter #android #payment #mobile 

A Flutter Package for adding Mobile Money Payments

A Widget and Functions Library for The Swedish Payment Service Swish

flutter_swish_payment

A widget and functions library for the Swedish payment service Swish.

What is Swish?

Swish is a mobile payment system in Sweden. The service works through a smartphone application, through which the user's phone number is connected to their bank account, and which makes it possible to transfer money in real time. Learn more at Swish.

Usage

After installing and importing flutter_swish_payment, follow these steps to start using it:

  1. Get the Swish certificates for your organization either from the Swish Company Portal or from your internal organization. If you are developing a private project and want to test around in the Swish environment, Swish provides downloadable test certificates on their environments page.
  2. Initialize a SwishAgent with the certificates. This could be done directly in the main function. (Be careful about how you store your certificates!)
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  ByteData cert = await rootBundle.load(
    'assets/swish_certificate.pem',
  );
  ByteData key = await rootBundle.load(
    'assets/swish_certificate.key',
  );

  String credential = "passwordForCertificates";

  SwishAgent swishAgent = SwishAgent.initializeAgent(
    cert: cert,
    key: key,
    credential: credential,
  );
  ...
}
  1. Create a SwishClient and provide it the SwishAgent.
SwishClient swishClient = SwishClient(
  swishAgent: swishAgent,
);
  1. You are now all set to start sending payment requests. Check out the documentation for SwishClient for guidance.

Open Swish

Redirecting the user to the Swish app upon a payment request differs from device to device. Currently the only supported device is Android. Swish provides a callbackUrl and this can be used to navigate the user back to the app after a completed payment. For more details on how to navigate back to the app read this FAQ from Swish: What is needed in order to get the user back to the original application?

Android 11 and later

Declare intent to open Swish in AndroidManifest.xml. Add the following in <queries> … </queries> (if no queries section is present, create it inside of manifest).

<intent>
  <action android:name="android.intent.action.VIEW" />
  <data android:scheme="swish" />
</intent>

The end result should look something like this:

<manifest>
  <application>
    ...
  </application>
  <queries>
    <!-- Open Swish -->
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <data android:scheme="swish" />
    </intent>
  </queries>
</manifest>

Learn more at:

What is the future goal for flutter_swish_payment?

The goal is to have a full library covering everything from the Swish API. Everything from a Swish QR code widget, to managing refunds from your online store.

Contributing

flutter_swish_payment is still in its early development. Help us out by reporting bugs, propose new features or even contribute with your own code on our Github. Together we can take this project to the next level and release a final version.


Disclaimer

As the project stands now, it has only been tested against the Merchant Swish Simulator (MMS). Before using this package for real transactions contact the Swish team for guidance.

 

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_swish_payment

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_swish_payment: ^0.0.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_swish_payment/flutter_swish_payment.dart'; 

example/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_swish_payment/flutter_swish_payment.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Load all PKI files. These are test files from the Merchant Swish Simulator
  // that can be downloaded from Swish. Remember to store your files securely.
  ByteData cert = await rootBundle.load(
    'assets/Swish_Merchant_TestCertificate.pem',
  );
  ByteData key = await rootBundle.load(
    'assets/Swish_Merchant_TestCertificate.key',
  );

  // The password for the certificate files. Swish uses standard "swish" for the
  // test files. Store your private password securely.
  String credential = "swish";

  SwishAgent swishAgent = SwishAgent.initializeAgent(
    key: key,
    cert: cert,
    credential: credential,
  );

  SwishClient swishClient = SwishClient(
    swishAgent: swishAgent,
  );

  runApp(
    MyApp(
      swishClient: swishClient,
    ),
  );
}

class MyApp extends StatelessWidget {
  final SwishClient swishClient;
  const MyApp({
    Key? key,
    required this.swishClient,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Swish Payment Demo',
      home: HomePage(
        swishClient: swishClient,
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  final SwishClient swishClient;
  const HomePage({
    Key? key,
    required this.swishClient,
  }) : super(key: key);

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // Create the payment data that should be paid and sent to the end Swish user.
  final SwishPaymentData swishPaymentData = const SwishPaymentData(
    payeeAlias: '1231181189',
    amount: '100',
    currency: 'SEK',
    callbackUrl: 'https://example.com/api/swishcb/paymentrequest',
    message: 'Kingston USB FLash drive 8 GB',
  );

  bool isWaiting = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: isWaiting
          ? Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: const [
                  Text('Please open the Swish app.'),
                  SizedBox(
                    height: 12.0,
                  ),
                  CircularProgressIndicator(),
                ],
              ),
            )
          : Center(
              child: SizedBox(
                width: 200,
                height: 75,
                child: SwishButton.secondaryElevatedButton(
                  onPressed: () async {
                    try {
                      // Create the payment requst
                      SwishPaymentRequest swishPaymentRequest =
                          await widget.swishClient.createPaymentRequest(
                        swishPaymentData: swishPaymentData,
                      );
                      // Ensure that the payment request is valid.
                      if (swishPaymentRequest.errorCode != null) {
                        throw Exception(swishPaymentRequest.errorMessage);
                      }
                      setState(() {
                        isWaiting = true;
                      });
                      // Wait until the Swish user receives the payment request and
                      // decides to either pay it or decline it. A timeout is also
                      // possible (the user does nothing).
                      swishPaymentRequest =
                          await widget.swishClient.waitForPaymentRequest(
                        location: swishPaymentRequest.location!,
                      );
                      setState(() {
                        isWaiting = false;
                      });
                      // The payment is now done (or failed).
                      // ignore: avoid_print
                      print(
                        swishPaymentRequest.toString(),
                      );
                    } catch (error) {
                      // ignore: avoid_print
                      print(
                        error.toString(),
                      );
                    }
                  },
                ),
              ),
            ),
    );
  }
} 

Download Details:

Author: johanehinger

Source Code: https://github.com/johanehinger/flutter_swish_payment

#flutter #payment 

A Widget and Functions Library for The Swedish Payment Service Swish

Flutter Widgets That Make It Easy to Implement Payment

Payment Lib

Payment Lib package lets you add UI Template for Payment Method, Payment Summary, Payment Instructions to your Flutter app.

🎖 Installing

dependencies:
  payment_lib: ^0.0.4+3

⚡️ Import

import 'package:payment_lib/payment_lib.dart';

🎮 How To Use

  • Payment Method
body: PaymentMethodListView(
        paymentMethod: paymentMethodList,
        selectPaymentMethod: selectPaymentMethod,
        onTap: () => Navigator.of(context).push(MaterialPageRoute(
            builder: (context) => const PaymentSummaryPage())),
      ),
body: SafeArea(
        child: ValueListenableBuilder(
          valueListenable: selectPaymentMethod,
          builder: (context, _, __) => Column(
            children: [
              Expanded(
                child: ListView.builder(
                  itemCount: paymentMethodList.length,
                  itemBuilder: (context, i) => PaymentMethodCard(
                    selectPaymentMethod: selectPaymentMethod,
                    categoryName: paymentMethodList[i].paymentTypes.name,
                    payments: paymentMethodList[i].payments,
                    onChanged: (id) {
                      selectPaymentMethod.value = id!;

                    },
                  ),
                ),
              ),
              if (selectPaymentMethod.value != null)
                SizedBox(
                  width: double.infinity,
                  child: Card(
                    margin: EdgeInsets.zero,
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                            minimumSize: const Size(double.infinity, 45)),
                        onPressed: () {},
                        child: Text("Pilih",
                            style: Theme.of(context)
                                .textTheme
                                .button!
                                .copyWith(color: Colors.white)),
                      ),
                    ),
                  ),
                )
            ],
          ),
        ),
      ),
  • Payment Summary
body: PaymentSummaryCard(
        paymentSummaryType: PaymentSummaryType.one,
        paymentSummaryModel: paymentSummaryDataDummy,
        paymentDetail: true,
        onTapPaymentDetail: (){},
      ),
  • Payment Instructions
PaymentInstructionCard(
            paymentIntruction: paymentSummaryModel.paymentIntructions,
          ),

🐛 Bugs/Requests

If you encounter any problems feel free to open an issue. If you feel the library is missing a feature, please raise a ticket on Gitlab and I'll look into it.

❗️ Note

For help getting started with Flutter, view our online documentation.

For help on editing plugin code, view the documentation.

☀️ Authors

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add payment_lib

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  payment_lib: ^0.0.4+8

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:payment_lib/payment_lib.dart'; 

example/lib/main.dart

import 'package:flutter/material.dart';

import 'package:payment_lib/payment_lib.dart';
import 'package:payment_lib_example/payment_summary_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const PaymentSummaryPage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final selectPaymentMethod = ValueNotifier<String?>(null);
  final selectId = ValueNotifier<String?>(null);

  final showButton = ValueNotifier(false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Payment Lib Example'),
      ),
      body: PaymentMethodListView(
        selectId: selectId,
        paymentMethod: paymentMethodList,
        selectPaymentMethod: selectPaymentMethod,
        onTap: () => Navigator.of(context).push(MaterialPageRoute(
            builder: (context) => const PaymentSummaryPage())),
      ),

      //* without PaymentMethodListView

      // body: SafeArea(
      //   child: ValueListenableBuilder(
      //     valueListenable: selectPaymentMethod,
      //     builder: (context, _, __) => Column(
      //       children: [
      //         Expanded(
      //           child: ListView.builder(
      //             itemCount: paymentMethodList.length,
      //             itemBuilder: (context, i) => PaymentMethodCard(
      //               selectPaymentMethod: selectPaymentMethod,
      //               categoryName: paymentMethodList[i].paymentTypes.name,
      //               payments: paymentMethodList[i].payments,
      //               onChanged: (id) {
      //                 selectPaymentMethod.value = id!;
      //                 log(selectPaymentMethod.value!);
      //               },
      //             ),
      //           ),
      //         ),
      //         if (selectPaymentMethod.value != null)
      //           SizedBox(
      //             width: double.infinity,
      //             child: Card(
      //               margin: EdgeInsets.zero,
      //               child: Padding(
      //                 padding: const EdgeInsets.all(8.0),
      //                 child: ElevatedButton(
      //                   style: ElevatedButton.styleFrom(
      //                       minimumSize: const Size(double.infinity, 45)),
      //                   onPressed: () {},
      //                   child: Text("Pilih",
      //                       style: Theme.of(context)
      //                           .textTheme
      //                           .button!
      //                           .copyWith(color: Colors.white)),
      //                 ),
      //               ),
      //             ),
      //           )
      //       ],
      //     ),
      //   ),
      // ),
    );
  }
}

// //! dummy models
class PaymentMethodModel {
  final String iconUrl;
  final String name;
  final String description;
  final String id;
  final String paymentTypeId;
  final bool active;

  PaymentMethodModel({
    required this.iconUrl,
    required this.name,
    required this.description,
    required this.id,
    required this.paymentTypeId,
    required this.active,
  });
}

class PaymentsDummy {
  PaymentsDummy({required this.paymentTypes, required this.payments});
  final PaymentTypes paymentTypes;
  final List<PaymentMethodModel> payments;
}

class PaymentTypes {
  final String id;
  final String name;
  PaymentTypes({
    required this.id,
    required this.name,
  });
}

final List<PaymentsDummy> paymentMethodList = [
  PaymentsDummy(
      paymentTypes: PaymentTypes(id: '11', name: 'Virtual Account'),
      payments: [
        PaymentMethodModel(
            active: true,
            paymentTypeId: 'a',
            iconUrl:
                'https://brandslogos.com///wp-content///uploads///images///large///bca-bank-central-asia-logo.png',
            name: 'Bank BCA',
            description: 'Bayar melalui ATM atau internet banking',
            id: '1'),
        PaymentMethodModel(
            active: true,
            paymentTypeId: 'b',
            iconUrl:
                'https://3.bp.blogspot.com/-T0htKAVwhFY/WgO3xeAGgNI/AAAAAAAAEoI/Bkm5sC20cNImE1gKgb29BgCNm3138PelwCLcBGAs/w1200-h630-p-k-no-nu/bni.jpg',
            name: 'Bank BNI',
            description: 'Bayar melalui ATM atau internet banking',
            id: '2'),
        PaymentMethodModel(
            paymentTypeId: 'c',
            active: true,
            iconUrl:
                'https://www.bankmandiri.co.id/documents/20143/44881086/ag-branding-logo-1.png/842d8cf8-b7fb-3014-9620-21f0f88d8377?t=1623309819034',
            name: 'Bank Mandiri',
            description: 'Bayar melalui ATM atau internet banking',
            id: '3'),
        PaymentMethodModel(
            paymentTypeId: 'd',
            active: true,
            iconUrl:
                'https://ver02.rumahpiatu.org/wp-content/uploads/2020/04/logo-bri.png',
            name: 'Bank BRI',
            description: 'Bayar melalui ATM atau internet banking',
            id: '4'),
        PaymentMethodModel(
            active: true,
            paymentTypeId: 'e',
            iconUrl:
                'https://1.bp.blogspot.com/-JzE0sLzAWHo/YOe2f1p3GMI/AAAAAAAAIuc/Q025IJ3aAREYqHaATcrbFnaC3ZpV-OOUQCLcBGAsYHQ/s1222/logo-bank-jago.png',
            name: 'Bank Jago',
            description: 'Bayar melalui ATM atau internet banking',
            id: '5'),
      ]),
  PaymentsDummy(
    paymentTypes: PaymentTypes(id: '22', name: 'Pembayaran via E-Wallet'),
    payments: [
      PaymentMethodModel(
          active: true,
          paymentTypeId: 'f',
          iconUrl:
              'https://1.bp.blogspot.com/-zqvCZXYnnfA/XciTU6Ikw_I/AAAAAAAABJc/TrUNMleviBsRtXgnDWzFEhZjxN03ET7_gCLcBGAsYHQ/s1600/Logo%2BOVO.png',
          name: 'OVO',
          description: 'Bayar melalui ATM atau internet banking',
          id: '7'),
      PaymentMethodModel(
          active: true,
          paymentTypeId: 'g',
          iconUrl:
              'https://www.rajabeli.com/wp-content/uploads/2020/07/applikasi-gopay.png',
          name: 'Gopay',
          description: 'Bayar melalui ATM atau internet banking',
          id: '8'),
    ],
  ),
  PaymentsDummy(
    paymentTypes: PaymentTypes(id: '33', name: 'Pembayaran Gerai Retail'),
    payments: [
      PaymentMethodModel(
          active: true,
          paymentTypeId: 'h',
          iconUrl:
              'https://upload.wikimedia.org/wikipedia/commons/9/9e/ALFAMART_LOGO_BARU.png',
          name: 'Alfamart',
          description: 'Bayar melalui Alfamart',
          id: '9'),
      PaymentMethodModel(
          active: true,
          paymentTypeId: 'j',
          iconUrl:
              'https://upload.wikimedia.org/wikipedia/id/thumb/0/04/Logo_Indomaret.svg/1200px-Logo_Indomaret.svg.png',
          name: 'Indomaret',
          description: 'Bayar melalui Indomaret',
          id: '6'),
    ],
  ),
]; 

Download Details:

Author: 

Source Code: https://pub.dev/packages/payment_lib

#flutter #widget #payment 

Flutter Widgets That Make It Easy to Implement Payment

Midtrans Payment Gateway for Flutter

Midtrans Payment Gateway for Flutter

Flutter Midtrans Payment Plugin

Please Read Midtrans Documentation before use this library and make sure you are already has Midtrans account for accessing the dashboard.

Android setup

Only support AndroidX and compile targe minimum 28

Add style to your android/app/src/main/res/values/styles.xml :

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

And full styles.xml will be like below :

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <!-- Show a splash screen on the activity. Automatically removed when
             Flutter draws its first frame -->
        <item name="android:windowBackground">@drawable/launch_background</item>
    </style>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>

And add the style to you Android Manifest in your application tag :

android:theme="@style/AppTheme"

IOS

No specific setup required

Example usage

Make sure you are already prepare these variables.

  • YOUR_CLIENT_ID: Midtrans CLIENT ID
  • YOUR_URL_BASE: Your backend URL base API to process payment

Pay

import 'package:flutter_midtrans_payment/flutter_midtrans_payment.dart';
...

var midtransPayParam = MidtransPayParam();
midtransPayParam.clientKey = "=";
midtransPayParam.merchantBaseUrl = "";
midtransPayParam.totalPrice = 0;
midtransPayParam.orderId = "";
midtransPayParam.selectedPaymentMethod = MidtransPaymentMethod.SHOPEEPAY.index; //optional
var result = await FlutterMidtransPayment.pay(midtransPayParam);

Pay with token

import 'package:flutter_midtrans_payment/flutter_midtrans_payment.dart';
...


var midtransPayParam = MidtransPayWithTokenParam();
midtransPayParam.clientKey = "";
midtransPayParam.merchantBaseUrl = "";
midtransPayParam.snapToken = "";
var result = await FlutterMidtransPayment.payWithToken(midtransPayParam); 

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_midtrans_payment

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_midtrans_payment: ^0.3.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_midtrans_payment/flutter_midtrans_payment.dart'; 

example/lib/main.dart

import 'dart:developer';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_midtrans_payment/flutter_midtrans_payment.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _platformVersion = 'Unknown';

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    log("mulai");
    String platformVersion;
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      platformVersion = await FlutterMidtransPayment.platformVersion;
    } on PlatformException {
      platformVersion = 'Failed to get platform version.';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {
      _platformVersion = platformVersion;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: Column(
            children: [
              Text('Running on: $_platformVersion\n'),
              ElevatedButton(
                  child: Text('Pay'),
                  onPressed: () async {
                    var midtransPayParam = MidtransPayParam();
                    midtransPayParam.clientKey = "=";
                    midtransPayParam.merchantBaseUrl = "";
                    midtransPayParam.totalPrice = 0;
                    midtransPayParam.orderId = "";
                    midtransPayParam.selectedPaymentMethod =
                        MidtransPaymentMethod.SHOPEEPAY.index;
                    var result =
                        await FlutterMidtransPayment.pay(midtransPayParam);
                    log(result);
                  }),
              ElevatedButton(
                  child: Text('Pay with token2'),
                  onPressed: () async {
                    log("start");
                    var midtransPayParam = MidtransPayWithTokenParam();
                    midtransPayParam.clientKey =
                        "SB-Mid-client-lqSYrzuU0C8KghnG";
                    midtransPayParam.merchantBaseUrl =
                        "https://kesan-api.bangun-kreatif.com";
                    midtransPayParam.snapToken =
                        "3143c741-3e24-4251-96e5-e5391cd19280";
                    try {
                      var result = await FlutterMidtransPayment.payWithToken(
                          midtransPayParam);
                      log('result');
                      log(result.toString());
                    } catch (err) {

                      log(err.toString());
                    }
                  })
            ],
          ),
        ),
      ),
    );
  }
} 

Download Details:

Author: knax

Source Code: https://github.com/knax/flutter-midtrans-payment

#flutter #payment 

Midtrans Payment Gateway for Flutter

RMS Mobile Payment for Flutter

rms_mobile_xdk_flutter

RMS Mobile Payment for Flutter

Getting Started

This project is a starting point for a Flutter plug-in package, a specialized package that includes platform-specific implementation code for Android and/or iOS.

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

rms_mobile_xdk_flutter

This is the beta but functional Razer Merchant Services Flutter payment module that is ready to be implemented into any Flutter project. An example application project is provided for Razer Merchant Services XDK framework integration reference.

Recommended configurations

Minimum Android SDK Version: 27 ++

Minimum Android API level: 19 ++

Minimum Android target version: Android 4.4

Minimum Flutter version : 0.2.8 ++

Xcode version: 9 ++

Minimum target version: iOS 8

Installation

  1. Add rms_mobile_xdk_flutter in pubspec.yaml
dependencies:
  rms_mobile_xdk_flutter: "<put latest release version here>"

flutter packages get

Add the following import to dart code of your application

    import 'package:rms_mobile_xdk_flutter/rms_mobile_xdk_flutter.dart';

Add the following keys to Info.plist file for iOS:

'App Transport Security Settings > Allow Arbitrary Loads > YES'

'NSPhotoLibraryUsageDescription' > 'Payment images'

'NSPhotoLibraryAddUsageDescription' > 'Payment images'

Sample Result

=========================================
Sample transaction result in JSON string:
=========================================

{"status_code":"11","amount":"1.01","chksum":"34a9ec11a5b79f31a15176ffbcac76cd","pInstruction":0,"msgType":"C6","paydate":1459240430,"order_id":"3q3rux7dj","err_desc":"","channel":"Credit","app_code":"439187","txn_ID":"6936766"}

Parameter and meaning:

"status_code" - "00" for Success, "11" for Failed, "22" for *Pending. 
(*Pending status only applicable to cash channels only)
"amount" - The transaction amount
"paydate" - The transaction date
"order_id" - The transaction order id
"channel" - The transaction channel description
"txn_ID" - The transaction id generated by Razer Merchant Services

* Notes: You may ignore other parameters and values not stated above

=====================================
* Sample error result in JSON string:
=====================================

{"Error":"Communication Error"}

Parameter and meaning:

"Communication Error" - Error starting a payment process due to several possible reasons, please contact Razer Merchant Services support should the error persists.
1) Internet not available
2) API credentials (username, password, merchant id, verify key)
3) Razer Merchant Services server offline.

Prepare the Payment detail object

var paymentDetails = {
    // Optional, REQUIRED when use online Sandbox environment and account credentials.
    'mp_dev_mode': false,

    // Mandatory String. Values obtained from Razer Merchant Services.
    'mp_username' : 'username',
    'mp_password' : 'password',
    'mp_merchant_ID' : 'merchantid',
    'mp_app_name' : 'appname',
    'mp_verification_key' : 'vkey123', 

    // Mandatory String. Payment values.
    'mp_amount' : '1.10',, // Minimum 1.01
    'mp_order_ID' : 'orderid123', 
    'mp_currency' : 'MYR',
    'mp_country' : 'MY',  
    
    // Optional String.
    'mp_channel' : '', // Use 'multi' for all available channels option. For individual channel seletion, please refer to https://github.com/RazerMS/rms-mobile-xdk-examples/blob/master/channel_list.tsv
    'mp_bill_description' : '',
    'mp_bill_name' : '',
    'mp_bill_email' : '',
    'mp_bill_mobile' : '',
    'mp_channel_editing' : false, // Option to allow channel selection.
    'mp_editing_enabled' : false, // Option to allow billing information editing.

    // Optional, for Escrow.
    'mp_is_escrow': '0', // Put "1" to enable escrow

    // Optional, for credit card BIN restrictions and campaigns.
    'mp_bin_lock' : ['414170', '414171'],   

    // Optional, for mp_bin_lock alert error.
    'mp_bin_lock_err_msg': 'Only UOB allowed',
    
    // WARNING! FOR TRANSACTION QUERY USE ONLY, DO NOT USE THIS ON PAYMENT PROCESS.
    // Optional, provide a valid cash channel transaction id here will display a payment instruction screen. Required if mp_request_type is 'Receipt'.
    'mp_transaction_id': '',
    // Optional, use 'Receipt' for Cash channels, and 'Status' for transaction status query.
    'mp_request_type': '',

    // Optional, use this to customize the UI theme for the payment info screen, the original XDK custom.css file can be obtained at https://github.com/RazerMS/rms-mobile-xdk-examples/blob/master/custom.css.
    'mp_custom_css_url': '',

    // Optional, set the token id to nominate a preferred token as the default selection, set "new" to allow new card only.
    'mp_preferred_token': '',

    // Optional, credit card transaction type, set "AUTH" to authorize the transaction.
    'mp_tcctype': '',

    // Optional, required valid credit card channel, set true to process this transaction through the recurring api, please refer the Razer Merchant Services Recurring API pdf. 
    'mp_is_recurring': false,

    // Optional, show nominated channels.
    'mp_allowed_channels': ['credit', 'credit3'],

    // Optional, simulate offline payment, set boolean value to enable. 
    'mp_sandbox_mode': true,

    // Optional, required a valid mp_channel value, this will skip the payment info page and go direct to the payment screen.
    'mp_express_mode': true,

    // Optional, extended email format validation based on W3C standards.
    'mp_advanced_email_validation_enabled': true,

    // Optional, extended phone format validation based on Google i18n standards.
    'mp_advanced_phone_validation_enabled': true,

    // Optional, explicitly force disable user input.
    'mp_bill_name_edit_disabled': true,
    'mp_bill_email_edit_disabled': true,
    'mp_bill_mobile_edit_disabled': true,
    'mp_bill_description_edit_disabled': true,

    // Optional, EN, MS, VI, TH, FIL, MY, KM, ID, ZH.
    'mp_language': 'EN',

    // Optional, Cash channel payment request expiration duration in hour.
    'mp_cash_waittime': 48,
    
    // Optional, allow bypass of 3DS on some credit card channels.
    'mp_non_3DS': true,

    // Optional, disable card list option.
    'mp_card_list_disabled': true,

    // Optional for channels restriction, this option has less priority than mp_allowed_channels.
    'mp_disabled_channels': ['credit']  
};

Start the payment module

//import package
import 'package:rms_mobile_xdk_flutter/rms_mobile_xdk_flutter.dart';

//start payment
String result = await MobileXDK.start(paymentDetails);
print("Result" + result);

Cash channel payment process (How does it work?)

This is how the cash channels work on XDK:

1) The user initiate a cash payment, upon completed, the XDK will pause at the “Payment instruction” screen, the results would return a pending status.

2) The user can then click on “Close” to exit the MOLPay XDK aka the payment screen.

3) When later in time, the user would arrive at say 7-Eleven to make the payment, the host app then can call the XDK again to display the “Payment Instruction” again, then it has to pass in all the payment details like it will for the standard payment process, only this time, the host app will have to also pass in an extra value in the payment details, it’s the “mp_transaction_id”, the value has to be the same transaction returned in the results from the XDK earlier during the completion of the transaction. If the transaction id provided is accurate, the XDK will instead show the “Payment Instruction” in place of the standard payment screen.

4) After the user done the paying at the 7-Eleven counter, they can close and exit MOLPay XDK by clicking the “Close” button again.

XDK built-in checksum validator caveats

All XDK come with a built-in checksum validator to validate all incoming checksums and return the validation result through the "mp_secured_verified" parameter. However, this mechanism will fail and always return false if merchants are implementing the private secret key (which the latter is highly recommended and prefereable.) If you would choose to implement the private secret key, you may ignore the "mp_secured_verified" and send the checksum back to your server for validation. 

Private Secret Key checksum validation formula

chksum = MD5(mp_merchant_ID + results.msgType + results.txn_ID + results.amount + results.status_code + merchant_private_secret_key)

Support

Submit issue to this repository or email to our support-sa@razer.com

Merchant Technical Support / Customer Care : support-sa@razer.com
Sales/Reseller Enquiry : sales-sa@razer.com
Marketing Campaign : marketing-sa@razer.com
Channel/Partner Enquiry : channel-sa@razer.com
Media Contact : media-sa@razer.com
R&D and Tech-related Suggestion : technical-sa@razer.com
Abuse Reporting : abuse-sa@razer.com

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add rms_mobile_xdk_flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  rms_mobile_xdk_flutter: ^3.32.3

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:rms_mobile_xdk_flutter/rms_mobile_xdk_flutter.dart'; 

example/lib/main.dart

import 'package:flutter/material.dart';

import 'package:rms_mobile_xdk_flutter/rms_mobile_xdk_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('RMS XDK Example'),
        ),
        body: new Center(
          child: new Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              new ElevatedButton(
                child: const Text('Start XDK'),
                onPressed: () async {
                  
                  var paymentDetails = {
                    // Mandatory String. A value more than '1.00'
                    'mp_amount': '1.01',

                    // Mandatory String. Values obtained from MOLPay
                    'mp_username': '',
                    'mp_password': '',
                    'mp_merchant_ID': '',
                    'mp_app_name': '',
                    'mp_verification_key': '',

                    // Mandatory String. Payment values
                    'mp_order_ID': '60186547890',
                    'mp_currency': 'MYR',
                    'mp_country': 'MY',

                    // Optional String.
                    'mp_channel': 'multi', // Use 'multi' for all available channels option. For individual channel seletion, please refer to "Channel Parameter" in "Channel Lists" in the MOLPay API Spec for Merchant pdf.
                    'mp_bill_description': 'description',
                    'mp_bill_name': 'name',
                    'mp_bill_email': 'example@mail.com',
                    'mp_bill_mobile': '+60123456789',
                    // 'mp_channel_editing': true, // Option to allow channel selection.
                    //'mp_editing_enabled': true, // Option to allow billing information editing.

                    // Optional for Escrow
                    // 'mp_is_escrow': '', // Optional for Escrow, put "1" to enable escrow

                    // Optional for credit card BIN restrictions
                    // 'mp_bin_lock': ['414170', '414171'], // Optional for credit card BIN restrictions
                    // 'mp_bin_lock_err_msg': 'Only UOB allowed', // Optional for credit card BIN restrictions

                    // For transaction request use only, do not use this on payment process
                    // 'mp_transaction_id': '', // Optional, provide a valid cash channel transaction id here will display a payment instruction screen.
                    // 'mp_request_type': '', // Optional, set 'Status' when doing a transactionRequest

                    // Optional, use this to customize the UI theme for the payment info screen, the original XDK custom.css file is provided at Example project source for reference and implementation.
                    // 'mp_custom_css_url': 'assets/res/custom.css',

                    // Optional, set the token id to nominate a preferred token as the default selection, set "new" to allow new card only
                    //'mp_preferred_token': '',

                    // Optional, credit card transaction type, set "AUTH" to authorize the transaction
                    // 'mp_tcctype': '',

                    // Optional, set true to process this transaction through the recurring api, please refer the MOLPay Recurring API pdf  
                    // 'mp_is_recurring': false,

                    // Optional for channels restriction 
                    // 'mp_allowed_channels': ['credit','credit3'],

                    // Optional for sandboxed development environment, set boolean value to enable.
                    // 'mp_sandbox_mode': false,

                    // Optional, required a valid mp_channel value, this will skip the payment info page and go direct to the payment screen.
                    // 'mp_express_mode': false,
                    // 'mp_bill_description_edit_disabled': false,
                    // 'mp_timeout' : 300,
                    // 'mp_dev_mode' : true
                  };
                  
                  String result = await MobileXDK.start(paymentDetails);
                  print("Result" + result);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
} 

Download Details:

Author: RazerMS

Source Code: https://github.com/RazerMS/Mobile-XDK-RazerMS_Flutter

#flutter #payment 

RMS Mobile Payment for Flutter

A New Flutter Project on CMB Payment SDK

CmbpbFlutter

Flutter 招商一网通支付 SDK。

相关文档

添加依赖

pubspec.yaml 文件中添加cmbpbflutter依赖: 

dependencies:
  cmbpbflutter: ^${latestVersion}

相关配置

Android

需要在Android工程AndroidManifest.xml下配置回调入口, 并配置招行分配给商户的「URL scheme」

       <activity
           android:name="cmb.pb.flutter.cmbpbflutter.CmbPbPayCallbackActivity"
           android:label="@string/app_name"
           android:exported="true"
           android:theme="@style/CmbPbPay.Theme.Transparent"
           android:taskAffinity="${applicationId}"
           android:launchMode="singleTop">

           <intent-filter>
               <action android:name="android.intent.action.VIEW"/>
               <category android:name="android.intent.category.DEFAULT"/>
               <data android:scheme="${招行给的回调url scheme}"/>
           </intent-filter>
       </activity>

IOS

配置Xcode中

  • 在info.plist中增加LSApplicationQueriesSchemes白名单配置,值为cmbmobilebank。
  • 在URL Types中新增URL Schemes,值设置为招行分配给商户的scheme(需与安卓设置的scheme保持一致),如分配到的scheme为abcdefg则配置如下图所示。

基本使用


// 注册appId
CmbPbPay.instance.registerApp(appId: "12306");

//设置支付回调
CmbPbPay.instance.respStream().listen((event) {
      print("支付结果回调了");
      setState(() {
        _payResultDesc = "${event.code} ===${event.msg}";
      });
    });

//发起支付
void _startPay() {
    final requestData = "xxx";
    final appUrl = "cmbmobilebank://CMBLS/FunctionJump?action=gofuncid&funcid=200013&serverid=CMBEUserPay&requesttype=post&cmb_app_trans_parms_start=here";
    final h5Url = "http://121.15.180.66:801/netpayment/BaseHttp.dll?H5PayJsonSDK";
    CmbPbPay.instance.pay(requestData: requestData, appUrl: appUrl, h5Url: h5Url, method: "pay");
}

捐助

开源不易,请作者喝杯咖啡。

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add cmbpbflutter

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  cmbpbflutter: ^1.0.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:cmbpbflutter/cmbpbflutter.dart'; 

example/lib/main.dart

import 'package:cmbpbflutter/cmbpbflutter.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  StreamSubscription<CmbPbPayResp>? _respSubs;

  String _payResultDesc = "";

  @override
  void initState() {
    super.initState();
    _respSubs = CmbPbPay.instance.respStream().listen((event) {
      print("支付结果回调了");
      setState(() {
        _payResultDesc = "${event.code} ===${event.msg}";
      });
    });
    CmbPbPay.instance.registerApp(appId: "12306");
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('招行一网通支付demo'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: _startPay,
                child: Text("支付"),
              ),
              Text("支付结果回调:$_payResultDesc")
            ],
          ),
        ),
      ),
    );
  }

  void _startPay() {
    //Url 编码后的结果
    final requestData = "jsonRequestData=%7B%22charset%22%3A%22UTF-8%22%2C%22reqData%22%3A%7B%22amount%22%3A%2240.00%22%2C%22branchNo%22%3A%220021%22%2C%22date%22%3A%2220210927%22%2C%22dateTime%22%3A%2220210927165358%22%2C%22expireTimeSpan%22%3A%2210%22%2C%22merchantNo%22%3A%22000719%22%2C%22orderNo%22%3A%222109271000098854%22%2C%22payNoticeUrl%22%3A%22https%3A%2F%2Fapp.mjcampus.com%2Fmpay%2Fv100%2Fnotify_cmbchina%22%2C%22returnUrl%22%3A%22aacbaaahbj%3A%2F%2F%22%7D%2C%22sign%22%3A%221566368d8dcf5782add5439b3cdb5f83047f87cc6f35c7903e65916e97df1b0b%22%2C%22signType%22%3A%22SHA-256%22%2C%22version%22%3A%221.0%22%7D";
    final tempAppUrl = "cmbmobilebank://CMBLS/FunctionJump?action=gofuncid&funcid=200013&serverid=CMBEUserPay&requesttype=post&cmb_app_trans_parms_start=here";
    final h5Url = "http://121.15.180.66:801/netpayment/BaseHttp.dll?H5PayJsonSDK";
    CmbPbPay.instance.pay(requestData: requestData, appUrl: tempAppUrl, h5Url: h5Url, method: "pay");
  }
} 

Download Details:

Author: leon2017

Source Code: https://github.com/leon2017/cmbpb-flutter

#flutter #payment 

A New Flutter Project on CMB Payment SDK

How IoT is Digitally Transforming Payments.

Contactless payments have improved the convenience and security of transactions. This article will explain what IoT payment is and how it has transformed the digital banking industry.

https://multiqos.com/how-iot-payment-shaping-future-payment-models/

#iot #iotpayment #payment #digitalpayment #onlinepayment 

How IoT is Digitally Transforming Payments.

A Flutter plugin for the Adyen Payment Provider DropIn UI

adyen_dropin

Note: This library is not official from Adyen.

Flutter plugin to integrate with the Android and iOS libraries of Adyen. This library enables you to open the Drop-in method of Adyen with just calling one function.

The Plugin supports 3dSecure v2 and one time payment. It was not tested in a recurring payment scenario.

Prerequisites

Credentials

You need to have the following information:

  • publicKey (from Adyen)
  • clientKey (from Adyen)
  • amount & currency
  • shopperReference (e.g userId)
  • baseUrl from your backend
  • Adyen Environment (Test, LIVE_EU etc..)
  • locale (de_DE, en_US etc..)
  • return url after payment (ios URLScheme of you app) for redirecting back to the app

Payment Methods

Before calling the plugin, make sure to get the payment methods from your backend. For this, call the a /paymentMethods endpoint:

An example response from payment methods can be seen here:

{
    "groups": [
        {
            "name": "Credit Card",
            "types": [
                "amex",
                "mc",
                "visa"
            ]
        }
    ],
    "paymentMethods": [
        {
            "brands": [
                "amex",
                "mc",
                "visa"
            ],
            "details": [
                {
                    "key": "encryptedCardNumber",
                    "type": "cardToken"
                },
                {
                    "key": "encryptedSecurityCode",
                    "type": "cardToken"
                },
                {
                    "key": "encryptedExpiryMonth",
                    "type": "cardToken"
                },
                {
                    "key": "encryptedExpiryYear",
                    "type": "cardToken"
                },
                {
                    "key": "holderName",
                    "optional": true,
                    "type": "text"
                }
            ],
            "name": "Credit Card",
            "type": "scheme"
        },
        {
            "name": "PayPal",
            "supportsRecurring": true,
            "type": "paypal"
        }
    ]
}

The app uses these endpoints for payment submit and payment details calls:

<your base url>/payment
<your base url>/payment/details

The plugin will send data for the payment submit call wrapped into another object like this:

{
  payment: <all data for payment which has to be sent to adyen>,
  additionalData: {key: value}
}

// additonalData can be used to send additional data to your own backend for payment


Setup

Android

And in the AndroidManifest.xml in your application tag add this service, this allows adyen to tell the android app the result of the payment.

<application ...>
    ...
 <service
            android:name="app.adyen.flutter_adyen.AdyenDropinService"
            android:permission="android.permission.BIND_JOB_SERVICE"/>

</application>

Proguard

you need to add this to your proguard rules

-keep class com.adyen.** { *; }
-keep class app.adyen.flutter_adyen.**  { *; }

iOS

You need to add a URL_SCHEME if you do not have one yet.

Here is how to add one.

Flutter Implementation

To start a Payment you need to call the plugin like so:

 try {
      String dropInResponse = await FlutterAdyen.openDropIn(
          paymentMethods: paymentMethods,  // the result of your payment methods call
          baseUrl: 'https://your-server.com/',
          clientKey: <ADYEN_CLIENT_KEY>,
          amount: '1000', // amount in cents
          lineItem: {'id': 'your product ID', 'description': 'Your product description'},
          additionalData: {
            'someKey': 'Some String'
          },
          shopperReference: <YouShopperReference>,
          returnUrl: 'yourAppScheme://payment', //required for iOS
          environment: 'TEST',  // add you environment for produciton here: LIVE_US, LIVE_AUSTRALIA or LIVE_EUROPE
          locale: 'de_DE', // your preferred locale
          publicKey: <your adyen public key>,
          currency: 'EUR');  // your preferred currency


    } on PlatformException {
      // Network Error or other system errors
      return PaymentResponse.paymentError.rawValue;
    }
      // the dropin returns the following responses as string
      PAYMENT_CANCELLED
      PAYMENT_ERROR
      Authorised
      Refused
      Pending
      Cancelled
      Error
      Received

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add adyen_dropin

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  adyen_dropin: ^0.10.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:adyen_dropin/flutter_adyen.dart'; 

example/lib/main.dart

import 'dart:convert';

import 'package:adyen_dropin/flutter_adyen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'mock_data.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? _payment_result = 'Unknown';

  String? dropInResponse;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () async {
            try {
              dropInResponse = await FlutterAdyen.openDropIn(
                  paymentMethods: jsonEncode(examplePaymentMethods),
                  baseUrl: 'https://yourdomain.com',
                  clientKey: 'clientkey',
                  publicKey: 'publickey',
                  locale: 'de_DE',
                  shopperReference: 'asdasda',
                  returnUrl: 'http://asd.de',
                  amount: '1230',
                  lineItem: {'id': '1', 'description': 'adyen test'},
                  currency: 'EUR',
                  additionalData: {});
            } on PlatformException catch (e) {
              if (e.code == 'PAYMENT_CANCELLED')
                dropInResponse = 'Payment Cancelled';
              else
                dropInResponse = 'Payment Error';
            }

            setState(() {
              _payment_result = dropInResponse;
            });
          },
        ),
        appBar: AppBar(
          title: const Text('Flutter Adyen'),
        ),
        body: Center(
          child: Text('Payment Result: $_payment_result\n'),
        ),
      ),
    );
  }
} 

Download Details:

Author: intive

Source Code: https://github.com/intive/adyen_flutter

#flutter #android #ios #payment 

A Flutter plugin for the Adyen Payment Provider DropIn UI

A Flutter Plugin for Mollie Payments

Flutter Mollie

A Flutter plugin for mollie payments

NEWS

With version 0.8.0 the Mollie plugin supports client requests directly from your app. This feature is currently in beta.

Currently supported APIs:

  • Orders API
  • Customers API
  • Subscription API
  • Payment API
  • Invoice API (NEW BETA)

ROADMAP

Adding support for client calls for the following APIs:

  • Shipment API
  • Chargebacks API
  • Refunds API

Getting started

Before you can use the plugin you have to setup a few things to implement the browser switch for iOS and Android:

ANDROID

1. Setup your scheme in AndroidManifest.xml under android > app > src > main > AndroidManifest.xml. This is needed because if the user starts the checkout process this plugin will switch to the browser and will open the checkout page of Mollie. After the checkout is done the browser will switch back to your app. The scheme will help the browser to open the correct app.

Modify your AndroidManifest.xml like the following. Be sure that you use an unique host and scheme name. The host and scheme are important in the next steps. We will use "payment-return" as host and "mollie" as scheme in this example.

<intent-filter>
     <data
       android:host="payment-return"
       android:scheme="mollie" />
     <action android:name="android.intent.action.MAIN"/>
     <category android:name="android.intent.category.LAUNCHER"/>
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

Your Manifest could look like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.plugon.fluttermollie_example">

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="mollie_example"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <data
                    android:host="payment-return"
                    android:scheme="molli" />
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
            </intent-filter>
        </activity>
    </application>
</manifest>


2. Go to your MainActivity.java in android > app > src > java > com.yourcompany.appname > MainActivity and paste the follwing into it:


@Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
      getFlutterView().pushRoute("paymentDone");
    }

  }

Change the route name to the route which you want to call after the payment process is done.

IMPORTANT Currently this plugin supports only navigation with routes. Your MaterialApp() or CupertinoApp() widget should use the routes attribute to define routes. Otherwise this plugin will not process with the payment. You can ignore this step but then you have to process manually to the next step in your checkout process.

Your MainActivity could look like this:


public class MainActivity extends FlutterActivity {

  boolean isSuccess;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
  }


  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (Intent.ACTION_VIEW.equals(intent.getAction())) {
      getFlutterView().pushRoute("paymentDone");
    }

  }
}

iOS

1. Open your AppDelegate.swift in xCode and past this into it:


 override func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey :   Any] = [:]) -> Bool {
        if (url.host! == "payment-return") {

            let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
            controller.pushRoute("paymentDone");

            return true;
        }

        return false;
    }

Be sure that the "payment-return" part equals your android:host in your AndroidManifest.xml.

IMPORTANT Currently this plugin supports only navigation with routes. Your MaterialApp() or CupertinoApp() widget should use the routes attribute to define routes. Otherwise this plugin will not process with the payment. You can ignore this step but then you have to process manually to the next step in your checkout process.

2. Go to your Info.plist file. Right click any blank area and select Add Row to create a new key. (This part is from molli: https://docs.mollie.com/mobile-apps/getting-started-payments)

alt text

You’ll be prompted to select a key from a drop-down menu. Scroll to the bottom and select URL types. This creates an array item. You can further click the disclosure icon to expand it and you need to select Item 0. Expand that row as well and you should see URL identifier. Double-click the value field and fill in your identifier. Most of the time will this be the same as your bundle ID, e.g. com.mollie.MollieApp. Click on the plus-button next to Item 0 and choose URL Schemes from the drop-down menu. Expand the URL Schemes row and another Item 0 will show up. Type in the value-field the scheme you want to handle, in our case mollie-app. Make sure to pick a unique scheme.

alt text

USING THE PLUGIN

The MollieCheckout widget works with the client method and the client-server method. We will show you both implementations. If you want to use the client method step over this step an go to "Getting started to use the plugin".

If you are using a client-server architecture you have to setup your server first for example with heroku. In the following example we will use Node.js with Express.js to do our API calls.

1. After you setup your Node.js server you have to install the Mollie package. Go into your working directory and type:

npm install @mollie/api-client@beta --save

For detailed instructions go to https://github.com/mollie/mollie-api-node

2. Initialize Mollie:


const { createMollieClient } = require('@mollie/api-client');
const mollieClient = createMollieClient({ apiKey: 'test_AFkJP7UuC3wddaeGasdG2UffGTdkmd8re'});

You can find your API test and public keys in your Mollie Dashboard under the developer tab.

3. Create an order:


const { createMollieClient } = require('@mollie/api-client');
const mollieClient = createMollieClient({ apiKey: 'test_AFkJP7UuC3wddaeGasdG2UffGTdkmd8re'});

app.post("/your/custom/path",(req,res) => {

  mollieClient.orders.create(req.body).then(order => {
    res.send(order);
  }).catch(error => {
    res.send(error);
  });
});

Getting started to use the plugin

1. Import the plugin

import 'package:fluttermollie/fluttermollie.dart';

2. Create a new MollieOrderRequest:


MollieOrderRequest requestOrder = new MollieOrderRequest(
      amount: MollieAmount(
          value: "1396.00",
          currency: "EUR"
      ),
      orderNumber: "900",
      redirectUrl: "mollie://payment-return",
      locale: "de_DE",
      webhookUrl: 'https://example.org/webhook',
      billingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      shippingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      products: [
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl: 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        ),
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl: 'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        )
      ]

  );


3. IMPORTANT Setup the redirectUrl attribute in your MollieOrderRequest.


 MollieOrderRequest order = new MollieOrderRequest(
      ...
      redirectUrl: "mollie://payment-return",
      ...
);

The redirectUrl should follow this pattern scheme://host. For our example it should be mollie://payment-return.

Cheat Sheet:

(We use mollie and payment-return in this example)

File | Scheme | Host | RedirectUrl --- | --- | --- | --- AndroidManifest | android:scheme="mollie" | android:host="payment-return"| mollie://payment-return Info.plist | URL Schemes -> item0 -> "mollie" | Set up "payment-return" in AppDelegate.swift (see top)| mollie://payment-return

4. Call your api endpoint or use the client instance to send your MollieOrderRequest to the server to retrieve an order object:

For client-server architecture:


  Future<void> createOrder(MollieOrderRequest order) async{

    /// send a POST request to your server with the created MollieOrderRequest
    var orderResponse = await http.post(
        "http://yourserver.herokuapp.com/mollie/create/order",
        headers: {"Content-Type": "application/json"},
        body: order.toJson()
    );

    /// get a order object from your server and parse it
    var data = json.decode(orderResponse.body);
    MollieOrderResponse res = MollieOrderResponse.build(data);

    /// set the current order to retrieve this order from other widgets easily with Mollie.getCurrentOrder()
    Mollie.setCurrentOrder(res);

    /// Start the checkout process with the browser switch
    Mollie.startPayment(res.checkoutUrl);

  }

For calling directly from client. The client.init() function has to be called only once:


  Future<void> createOrder(MollieOrderRequest order) async{

    client.init("test_TUIAGS980q2ezahdoas");

    var createdOrder = await client.orders.create(order);

    /// set the current order to retrieve this order from other widgets easily with Mollie.getCurrentOrder()
    Mollie.setCurrentOrder(createdOrder);

    /// Start the checkout process with the browser switch
    Mollie.startPayment(createdOrder.checkoutUrl);

  }

5. Use the MollieCheckout widget to show nicely multiple payment methods:


   @override
  Widget build(BuildContext context) {
    return MollieCheckout(
      order: requestOrder,
      onMethodSelected: (order) {

        createOrder(order);

      },
      useCredit: true,
      usePaypal: true,
      useSepa: true,
      useSofort: true,
      useIdeal: true,
      useApplePay: true
    );
  }
  

6. Optionally you can enable other payment methods. PayPal and Creditcard payment is enabled by default.

Currently supported payment methods:

  • CreditCard
  • Paypal
  • SEPA
  • Klarna Sofort
  • Apple Pay
  • iDEAL

PROFIT! :)

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add fluttermollie

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  fluttermollie: ^0.8.11

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:fluttermollie/fluttermollie.dart'; 

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:fluttermollie/fluttermollie.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MaterialApp(initialRoute: "home", routes: {
      "home": (context) => MyApp(),
      "done": (context) => ShowOrderStatus()
    }));

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  MollieOrderRequest o = new MollieOrderRequest(
      amount: MollieAmount(value: "1396.00", currency: "EUR"),
      orderNumber: "900",
      redirectUrl: "molli://payment-return",
      locale: "de_DE",
      webhookUrl: 'http://blackboxshisha.herokuapp.com/mollie/order/status',
      billingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      shippingAddress: new MollieAddress(
        organizationName: 'Mollie B.V.',
        streetAndNumber: 'Keizersgracht 313',
        city: 'Amsterdam',
        region: 'Noord-Holland',
        postalCode: '1234AB',
        country: 'DE',
        title: 'Dhr.',
        givenName: 'Piet',
        familyName: 'Mondriaan',
        email: 'piet@mondriaan.com',
        phone: '+31309202070',
      ),
      products: [
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl:
              'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        ),
        MollieProductRequest(
          type: 'physical',
          sku: '5702016116977',
          name: 'LEGO 42083 Bugatti Chiron',
          productUrl: 'https://shop.lego.com/nl-NL/Bugatti-Chiron-42083',
          imageUrl:
              'https://sh-s7-live-s.legocdn.com/is/image//LEGO/42083_alt1?',
          quantity: 2,
          vatRate: '21.00',
          unitPrice: MollieAmount(
            currency: 'EUR',
            value: '399.00',
          ),
          totalAmount: MollieAmount(
            currency: 'EUR',
            value: '698.00',
          ),
          discountAmount: MollieAmount(
            currency: 'EUR',
            value: '100.00',
          ),
          vatAmount: MollieAmount(
            currency: 'EUR',
            value: '121.14',
          ),
        )
      ]);

  Future<void> createOrder(MollieOrderRequest order) async {
    // use this in a new widget with a future builder

    //only client example
    client.init('test_HbkjP7PuCPwdveGWG2UffGTdkmd8re');

    //Test
    MollieSubscriptionRequest s = new MollieSubscriptionRequest(
      amount: MollieAmount(
        currency: 'EUR',
        value: '25.00',
      ),
      times: 4,
      interval: '3 months',
      description: 'Quarterly payment',
      webhookUrl: 'https://webshop.example.org/subscriptions/webhook/',
    );

    MolliePaymentRequest r = new MolliePaymentRequest(
      amount: MollieAmount(
        currency: 'EUR',
        value: '30.00',
      ),
      description: 'My first payment',
      redirectUrl: 'https://webshop.example.org/order/12345/',
      webhookUrl: 'https://webshop.example.org/payments/webhook/',
    );

    var payment = await client.payments.listPayments();
    print(payment.length);

    // client-server example
    //var orderResponse = await http.post(
    //    "http://blackboxshisha.herokuapp.com/mollie/create/order",
    //    headers: {"Content-Type": "application/json"},
    //    body: order.toJson());

    //var data = json.decode(orderResponse.body);
    //MollieOrderResponse res = MollieOrderResponse.build(data);

    //Mollie.setCurrentOrder(res);

    //Mollie.startPayment(res.checkoutUrl);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(onPressed: () {
          createOrder(null);
        }),
      ),
    );
    /*MollieCheckout(
      order: o,
      onMethodSelected: (order) {
        createOrder(order);
      },
      useCredit: true,
      usePaypal: true,
      useApplePay: true,
      useSofort: true,
      useSepa: true,
      useIdeal: true,
    );*/
  }
}

class ShowOrderStatus extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MollieOrderStatus(
      orders: [Mollie.getCurrentOrder()],
    );
  }
} 

Download Details:

Author: Oni22

Source Code: https://github.com/Oni22/fluttermollie

#flutter #android #ios #payment 

A Flutter Plugin for Mollie Payments

A Flutter Library for integrating Card and Mobile Payments

MobPay - A Flutter library for integrating card and mobile payments through Interswitch

Focus on running your business and spend less time reconciling payments. Quickteller Business unifies payments from different channels (Card, Mobile Money and through pesalink) all in one payments platform that grows with you. With Quickteller Business, you’ll never worry about payments again.

Supported Features

Pay with Mobile money

  • Mpesa
  • T-Kash

Pay with Card

  • Verve
  • Mastercard
  • Visa

Pay with Bank

Pay with Pesalink

Usage

Merchant Details

You will have to create an instance of the Merchant class with the following details:

  • Merchant Id
  • Domain Id
Merchant merchant = Merchant("ISWKEN0001", "ISWKE");

Payment Details

Create an instance of the Payment class with the following items:

Amount

  • The amount would be sent to us in the double currency format. i.e you will have to multiply the amount by 100. An example is if the value of an apple fruit is 99.90 (Ninety nine Shillings and ninety cents) you will have to send it to us as 9990

Order Id

  • Merchant's orderId for the payment item, similar to receipt number, duplicates allowed.

Transaction Reference

  • A unique identifier of the transaction on the merchant's side – maximum 15 characters, duplicates will be rejected.

Payment Item

Currency Code

  • The ISO currency code e.g. KES

Narration

Payment payment = Payment( 100,
Random().nextInt(1000).toString(),
Random().nextInt(1000).toString(),
"food",
"KES",
"Buying food Items");

Customer Details

id

  • The customer's id from the merchant's point of view e.g. email, phone, or database/registration id.

First Name

  • Customer's first name

Second Name

  • Customer's second name

Email

  • Customer's email

Mobile

  • Customer's mobile

City

  • Customer's city

Country

  • Customer's country

Postal Code

  • Customer's postal code

Street

  • Customer's street

State

  • Customer's state
Customer customer =  Customer(
"1",
"John",
"Doe",
"someone@yopmail.com",
"0700000000",
"NBI",
"KE",
"00100",
'KIBIKO',
"KAJIADO");

Extra Configuration

In order to change a few elements in the UI we have an object for that (Config) The items that we allow extra configuration for are:

  • Logo on the top left

In order to change the logo on the top left

  • Create a instance of the config class
  • Pass the logo url (HTTPS) as the parameter

Below is an example

Config config =  Config(

iconUrl:

"https://images.pexels.com/photos/104372/pexels-photo-104372.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260",


// the primary accent color should be a hex value
primaryAccentColor: '#D433FF');


Mobpay Instance

Create a mobpay instance and pass the merchant details and also whether you are on live or not

Mobpay mobpay =  new  Mobpay(merchant, false);

Transaction Success And Failure Callbacks

For both success and failure you will have to pass the functions and example is as below:

Transaction Success Example:

void  transactionSuccessCallback(payload) {
	{
		final snackBar =  SnackBar(
		content:  Text(payload.toString()),
		action:  SnackBarAction(
		label:  'Undo',
		onPressed: () {
		// Some code to undo the change.
		},),);
		// Find the ScaffoldMessenger in the widget tree
		// and use it to show a SnackBar.
		ScaffoldMessenger.of(context).showSnackBar(snackBar);
		}
	}

Transaction Failure Example:

void  transactionFailureCallback(payload) {
	{
		final snackBar =  SnackBar(
		content:  Text(payload.toString()),
		action:  SnackBarAction(
		label:  'Undo',
		onPressed: () {
		// Some code to undo the change.
		},),);
		// Find the ScaffoldMessenger in the widget tree
		// and use it to show a SnackBar.
		ScaffoldMessenger.of(context).showSnackBar(snackBar);
		}
	}

Pay

To pay call the pay function as follows:

mobpay.pay(

payment: payment,

customer: customer,

transactionSuccessfulCallback:

transactionSuccessCallback,

transactionFailureCallback:

transactionFailureCallback,

config: config,

context: context);

Source code

Visit the Github repository to get the source code and releases of this project if you want to try a manual integration process that does not make use of gradle.

Frequently Asked Questions

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add mobpay

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  mobpay: ^0.1.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:mobpay/mobpay.dart'; 

example/lib/main.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:mobpay/mobpay.dart';
import 'package:mobpay/models/Config.dart';
import 'package:mobpay/models/Customer.dart';
import 'package:mobpay/models/Merchant.dart';
import 'package:mobpay/models/Payment.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Interswitch IPG Example Application',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Interswitch IPG Example Application'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _keyForm = GlobalKey<FormState>();

  final _formKey = GlobalKey<FormState>();
  final _merchantId = TextEditingController(text: "ISWKEN0001");
  final _domainId = TextEditingController(text: "ISWKE");

  final _amount = TextEditingController(text: "100");
  final _transactionRef =
      TextEditingController(text: Random().nextInt(1000).toString());
  final _orderId =
      TextEditingController(text: Random().nextInt(1000).toString());
  final _paymentItem = TextEditingController(text: "food");
  final _currencyCode = TextEditingController(text: "KES");
  final _narration = TextEditingController(text: "Buying tings");

  final _id = TextEditingController(text: "1");
  final _firstName = TextEditingController(text: "Jane");
  final _secondName = TextEditingController(text: "Doe");
  final _email = TextEditingController(text: "john.doe@yopmail.com");
  final _mobile = TextEditingController(text: "0700000000");
  final _city = TextEditingController(text: "NBI");
  final _country = TextEditingController(text: "KEN");
  final _postalCode = TextEditingController(text: "00100");
  final _street = TextEditingController(text: "KIBIKO");
  final _state = TextEditingController(text: "KAJIADO");

  final _iconUrl = TextEditingController(
      text:
          "https://images.pexels.com/photos/104372/pexels-photo-104372.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
  final _primaryAccentColor = TextEditingController(text: '#D433FF');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Container(
          child: ListView(
            // mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              SizedBox(
                height: MediaQuery.of(context).size.height, // fixed height
                child: Form(
                  key: _keyForm,
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: ListView(
                      children: [
                        TextFormField(
                          controller: _merchantId,
                          decoration: InputDecoration(
                              hintText: 'Merchant Id',
                              labelText: 'Merchant Id'),
                        ),
                        TextFormField(
                          controller: _domainId,
                          decoration: InputDecoration(
                              hintText: 'Domain Id', labelText: 'Domain Id'),
                        ),
                        //payment details
                        TextFormField(
                          controller: _amount,
                          decoration: InputDecoration(
                              hintText: 'Amount', labelText: 'Amount'),
                        ),
                        TextFormField(
                          controller: _transactionRef,
                          decoration: InputDecoration(
                              hintText: 'Transaction Reference',
                              labelText: 'Transaction Reference'),
                        ),
                        TextFormField(
                          controller: _orderId,
                          decoration: InputDecoration(
                              hintText: 'Order Id', labelText: 'Order Id'),
                        ),
                        TextFormField(
                          controller: _paymentItem,
                          decoration: InputDecoration(
                              hintText: 'Payment Item',
                              labelText: 'Payment Item'),
                        ),
                        TextFormField(
                          controller: _currencyCode,
                          decoration: InputDecoration(
                              hintText: 'Currency Code',
                              labelText: 'Currency Code'),
                        ),
                        TextFormField(
                          controller: _narration,
                          decoration: InputDecoration(
                              hintText: 'Narration', labelText: 'Narration'),
                        ),
                        // customer details
                        TextFormField(
                          controller: _id,
                          decoration: InputDecoration(
                              hintText: 'Customer Id',
                              labelText: 'Customer Id'),
                        ),
                        TextFormField(
                          controller: _firstName,
                          decoration: InputDecoration(
                              hintText: 'First Name', labelText: 'First Name'),
                        ),
                        TextFormField(
                          controller: _secondName,
                          decoration: InputDecoration(
                              hintText: 'Second Name',
                              labelText: 'Second Name'),
                        ),
                        TextFormField(
                          controller: _email,
                          decoration: InputDecoration(
                              hintText: 'Email', labelText: 'Email'),
                        ),
                        TextFormField(
                          controller: _mobile,
                          decoration: InputDecoration(
                              hintText: 'Mobile', labelText: 'Mobile'),
                        ),
                        TextFormField(
                          controller: _city,
                          decoration: InputDecoration(
                              hintText: 'City', labelText: 'City'),
                        ),
                        TextFormField(
                          controller: _country,
                          decoration: InputDecoration(
                              hintText: 'Country Code',
                              labelText: 'Country Code'),
                        ),
                        TextFormField(
                          controller: _postalCode,
                          decoration: InputDecoration(
                              hintText: 'Postal Code',
                              labelText: 'Postal Code'),
                        ),
                        TextFormField(
                          controller: _street,
                          decoration: InputDecoration(
                              hintText: 'Street', labelText: 'Street'),
                        ),
                        TextFormField(
                          controller: _state,
                          decoration: InputDecoration(
                              hintText: 'State', labelText: 'State'),
                        ),
                        //config
                        TextFormField(
                          controller: _iconUrl,
                          decoration: InputDecoration(
                              hintText: 'Icon Url', labelText: 'Icon Url'),
                        ),
                        TextFormField(
                          controller: _primaryAccentColor,
                          decoration: InputDecoration(
                              hintText: 'primaryAccentColor',
                              labelText: 'primaryAccentColor'),
                        ),
                        Padding(
                          padding: EdgeInsets.only(bottom: 50, top: 50),
                          child: ElevatedButton(
                              onPressed: () {
                                Merchant merchant = Merchant(
                                    _merchantId.value.text,
                                    _domainId.value.text);
                                Payment payment = Payment(
                                    int.parse(_amount.value.text),
                                    _transactionRef.value.text,
                                    _orderId.value.text,
                                    _paymentItem.value.text,
                                    _currencyCode.value.text,
                                    _narration.value.text);
                                Customer customer = Customer(
                                    _id.value.text,
                                    _firstName.value.text,
                                    _secondName.value.text,
                                    _email.value.text,
                                    _mobile.value.text,
                                    _city.value.text,
                                    _country.value.text,
                                    _postalCode.value.text,
                                    _street.value.text,
                                    _state.value.text);
                                Config config = Config(
                                    iconUrl: _iconUrl.value.text,
                                    primaryAccentColor:
                                        _primaryAccentColor.value.text);
                                Mobpay mobpay =
                                    new Mobpay(merchant: merchant, live: false);
                                mobpay.pay(
                                    payment: payment,
                                    customer: customer,
                                    transactionSuccessfullCallback:
                                        transactionSuccessfullCallback,
                                    transactionFailureCallback:
                                        transactionFailureCallback,
                                    config: config,
                                    context: context);
                              },
                              child: Text("Pay")),
                        ),
                        Padding(
                          padding: EdgeInsets.all(10),
                          child: Text(""),
                        )
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ) // This trailing comma makes auto-formatting nicer for build methods.
        );
  }

  void transactionSuccessfullCallback(payload) {
    Clipboard.setData(ClipboardData(text: payload.toString()));
    final snackBar = SnackBar(
      content: Text("transaction success" + payload.toString()),
      action: SnackBarAction(
        label: 'Undo',
        onPressed: () {
          // Some code to undo the change.
        },
      ),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }

  void transactionFailureCallback(payload) {
    {
      final snackBar = SnackBar(
        content: Text("transaction failure" + payload.toString()),
        action: SnackBarAction(
          label: 'Undo',
          onPressed: () {
            // Some code to undo the change.
          },
        ),
      );
      ScaffoldMessenger.of(context).showSnackBar(snackBar);
    }
  }
} 

Download Details:

Author: 

Source Code: https://pub.dev/packages/mobpay

#flutter #payment 

 A Flutter Library for integrating Card and Mobile Payments