Flutter

Masterpass Example

pub issues forks stars style license


Table of Contents

About The Project

Screenshot 1 Screenshot 2 Screenshot 3

Masterpass provides a great way to handle in-app card payments on Android and iOS devices. However, they only provide native iOS and Android libraries to work with their API. This project provides a Flutter plugin for working with the masterpass in-app API on both iOS and Android devices.

  • The spec for the native android masterpass API can be found here.
  • The spec for the native iOS masterpass API can be found here.

Built With

Getting Started

Prerequisites

Since this is a Flutter plugin, you will need to use it from within a Flutter App. A few resources to get you started with your first Flutter project:

Also, in order to use this plugin, a masterpass merchant account has to be setup on the Masterpass System After setting up your merchant account, you will receive an API key that you can use for this plugin.

Installation

Add masterpass as a dependency in your pubspec.yaml file.

iOS

Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location will be used to prevent fraud.</string>

Android

No configuration required - the plugin should work out of the box.

Usage

The example below shows how the plugin can be used. You can test this yourself by using the example app in the example folder.

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

import 'package:masterpass/masterpass.dart';

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

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

class HomePage extends StatelessWidget {
  ///The form key to use for the amount form.
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  /// The controller for the amount to pay.
  final TextEditingController _amountController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Masterpass Example App'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Center(
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                _amountField(),
                _payButton(context),
              ],
            ),
          ),
        ),
      ),
    );
  }

  /// Returns the pay button.
  Widget _payButton(context) {
    return RaisedButton(
      child: Text("PAY"),
      onPressed: () async {
        if (_formKey.currentState.validate()) {
          //show loading dialog
          showDialog(
            context: context,
            barrierDismissible: false,
            builder: (context) => SimpleDialog(
              title: Center(child: CircularProgressIndicator()),
              backgroundColor: Colors.transparent,
            ),
          );

          String txnCode =
              await _getTransactionId(double.parse(_amountController.text));

          String apiKey =
              "enter-your-api-key-here"; // Your masterpass API key.
          String system = MasterpassSystem
              .TEST; // The masterpass system you want to use (TEST or LIVE)
          Masterpass masterpass = Masterpass(apiKey, system);
          CheckoutResult paymentResult = await masterpass.checkout(txnCode);

          if (paymentResult is PaymentSucceeded) {
            bool paymentVerified =
                await _verifyTransaction(txnCode, paymentResult.reference);
            Navigator.of(context).pop(); //pop the loading dialog
            if (paymentVerified) {
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text("Payment succeeded."),
              ));
            } else {
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text("Could not verify payment."),
              ));
            }
          } else {
            Navigator.of(context).pop(); //pop the loading dialog
            Scaffold.of(context).showSnackBar(SnackBar(
              content: Text("Payment failed."),
            ));
          }
        }
      },
    );
  }

  /// Returns the amount field
  TextFormField _amountField() {
    return TextFormField(
      controller: _amountController,
      decoration: InputDecoration(
        labelText: "Amount",
      ),
      validator: (text) {
        try {
          double.parse(text);
        } catch (e) {
          return "Please enter a valid amount";
        }

        return null;
      },
    );
  }

  /// Make a call to your backend to get a code for the transaction.
  Future<String> _getTransactionId(double amount) async {
    //You should replace this code with the call to your backend which requests a new transaction from masterpass.
    return Future.value("sample-transaction-code-from-your-backend");
  }

  /// Make a call to your backend to verify the payment
  Future<bool> _verifyTransaction(String txnCode, String paymentRef) async {
    //You should replace this code with the call to your backend which verifies that the transaction was successful.
    return Future.value(true);
  }
}

Response classes

The checkout method will return an instance of one of the following classes which will describe the result:

InvalidTxnCode - the transaction code used was invalid.

MasterpassError - an error occurred with asterpass before the payment was initiated.

UserCancelled - the user cancelled the transaction.

PaymentFailed - the payment failed (the reference field contains the payment reference)

PaymentSucceeded - the payment was successful (the reference field contains the payment reference)

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Contact

BornIdeas - born.dev - info@born.dev

Project Link: https://github.com/born-ideas/masterpass

Acknowledgements

Libraries

masterpass