flutter_to_mobilepay 1.0.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 70

flutter_to_mobilepay #

Flutter to MobilePay provides easy integration with MobilePay. It uses the MobilePay AppSwitch SDK to switch to the MobilePay app, perform the payment and then return the transaction information back to Flutter.

Flutter to MobilePay works on both Android* and iOS.

* see caveats further down

Warning #

This plugin has not yet been tested with a real merchant id or in a production application.

Usage #

import "package:flutter_to_mobilepay/flutter_to_mobilepay.dart";
import "package:uuid/uuid.dart";

void main() async {
    await MobilePay.initialize(
        merchantID: TestMerchantID.denmark,
        country: Country.denmark,
        urlScheme: "myapp", // iOS only, see installation
    );
    runApp(MobilePayButton());
}

class MobilePayButton extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return RaisedButton(
            child: const Text("Pay with MobilePay"),
            onPressed: () async {

                Payment payment = Payment(
                    orderID: Uuid().v4(),
                    price: 100, // double
                );
                Transaction transaction = await MobilePay.createPayment(payment);
                print("transaction id: ${transaction.id}");
                print("order id: ${transaction.orderID}");
                print("total withdrawn: ${transaction.withdrawnFromCard}");

            }
        );
    }
}

Installing #

Add the package as a dependency to your project

pubspec.yaml

dependencies:
  # ...
  flutter_to_mobilepay: ^1.0.0

Android should be ready to go, however iOS requires a bit more work.

iOS #

Opening other apps on iOS requires registering their URL schemes (and your own). Add your app's URL scheme to your Info.plist if you haven't already.

ios/Info.plist

<!-- ... -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string> -- your bundle id -- </string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>
                -- your url scheme --
<!--
This must match the one provided to `MobilePay.initialize(urlScheme: "")`

Documentation: https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app
-->
            </string>
        </array>
    </dict>
</array>

If you wish to check if the MobilePay app is installed, you have to add the following URL schemes (or exclude the ones you don't need) to your Info.plist.

ios/Info.plist

<!-- ... -->
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>mobilepay</string> <!-- denmark -->
    <string>mobilepayfi</string> <!-- finland -->
    <string>mobilepayno</string> <!-- norway -->
</array>

Caveats #

  • The MobilePay AppSwitch SDK does not target the latest Android SDK version. It uses deprecated APIs on newer versions and is not compatible with Android P at all.

Alternatives #

Contributing #

Implementation #

On the native side of things, Flutter to MobilePay is written in Objective C and Java. It does most things by calling the platform with maps as arguments, containing the needed data. However the payments are implemented using an EventChannel stream. This is because the payment callback is sent to the Android activity and iOS app delegate, not the function creating the payment. When the payment callback is received, it transforms it into a map and sends it to Flutter through the EventChannel. createPayment() awaits the payment and returns it to the user.

1.0.0 #

Release, woo-hoo!

  • Works on both Android on iOS
  • Uses the AppSwitch SDK provided by the MobilePay development team

example/lib/main.dart

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

void main() async {
  await MobilePay.initialize(
    merchantID: TestMerchantID.denmark,
    country: Country.denmark,
    urlScheme: "flmpexample",
  );
  runApp(MyApp());
}

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

class _MyAppState extends State<MyApp> {
  bool _isInstalled = false;

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

  void _checkIfInstalled() async {
    final installed = await MobilePay.isInstalled();
    setState(() {
      _isInstalled = installed;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter to MobilePay'),
        ),
        body: ListView(
          children: <Widget>[
            ListTile(
              title: const Text("Is MobilePay installed"),
              subtitle: Text(_isInstalled.toString()),
            ),
            ListTile(
              title: const Text("Create (test) payment"),
              subtitle: Builder(
                // The reason this is in a Builder has nothing to do with
                // Flutter to MobilePay, but because otherwise the dialogs
                // could not access something from the context.
                builder: (context) {
                  return OutlineButton(
                    child: Text("New payment"),
                    onPressed: _isInstalled
                        ? () async {
                            Payment payment = Payment(
                              orderID: "generate custom id here",
                              price: 10,
                            );
                            try {
                              final transaction =
                              await MobilePay.createPayment(payment);
                              // The purchase was successful
                              await showDialog(
                                context: context,
                                builder: (context) => AlertDialog(
                                  title: const Text("Your purchase was successful"),
                                  content: Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    mainAxisSize: MainAxisSize.min,
                                    children: <Widget>[
                                      Text("Transaction id: ${transaction.id}"),
                                      Text("Order id: ${transaction.orderID}"),
                                      Text("Total (not) withdrawn: ${transaction.withdrawnFromCard}"),
                                    ],
                                  ),
                                ),
                              );
                            } on MobilePayError catch (e) {
                              // The MobilePay AppSwitch SDK threw an error
                              switch (e.code) {
                                case 0:
                                case 1:
                                case 4:
                                case 5:
                                case 9:
                                case 10:
                                case 11:
                                case 12:
                                  await showDialog(
                                    context: context,
                                    builder: (context) => AlertDialog(
                                      title: const Text("An unknown error has occured"),
                                    ),
                                  );
                                  break;
                                default:
                                  String title;
                                  String message;
                                  switch (e.code) {
                                    case 3:
                                      title = "The MobilePay app is outdated";
                                      message = "Update the MobilePay app to pay using MobilePay";
                                      break;
                                    case 6:
                                    case 8:
                                      title = "The payment timed out";
                                      message = "The purchase took longer than expected. Please try again";
                                      break;
                                    case 7:
                                      title = "You have exceeded you limits";
                                      message = "Open MobilePay 'Beløbsgrænser' to see your status";
                                      break;
                                  }
                                  await showDialog(
                                    context: context,
                                    builder: (context) => AlertDialog(
                                      title: Text(title),
                                      content: Text(message),
                                    ),
                                  );
                              }
                            } on CancelledPaymentException catch (_) {
                              // The user cancelled the payment
                              await showDialog(
                                context: context,
                                builder: (context) => AlertDialog(
                                  title: const Text("You cancelled the payment"),
                                ),
                              );
                            }

                          }
                        : null,
                  );
                }
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  flutter_to_mobilepay: ^1.0.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_to_mobilepay/flutter_to_mobilepay.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
49
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
77
Overall:
Weighted score of the above. [more]
70
Learn more about scoring.

We analyzed this package on Jul 8, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.14
  • Flutter: 1.17.5

Analysis suggestions

Package does not support Flutter platform linux

Because:

  • package:flutter_to_mobilepay/flutter_to_mobilepay.dart that declares support for platforms: android, ios

Package does not support Flutter platform macos

Because:

  • package:flutter_to_mobilepay/flutter_to_mobilepay.dart that declares support for platforms: android, ios

Package does not support Flutter platform web

Because:

  • package:flutter_to_mobilepay/flutter_to_mobilepay.dart that declares support for platforms: android, ios

Package does not support Flutter platform windows

Because:

  • package:flutter_to_mobilepay/flutter_to_mobilepay.dart that declares support for platforms: android, ios

Package not compatible with SDK dart

Because:

  • flutter_to_mobilepay that is a package requiring null.

Maintenance suggestions

The package description is too short. (-18 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Package is getting outdated. (-4.93 points)

The package was last published 54 weeks ago.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
meta 1.1.8 1.2.1
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8
Dev dependencies
flutter_test