mpay_plugin 1.4.0 copy "mpay_plugin: ^1.4.0" to clipboard
mpay_plugin: ^1.4.0 copied to clipboard

Flutter plugin integrating Macau Pass (MPay), Alipay, WeChat Pay, HK Wallet, and scan-to-pay QR codes with a unified adapter architecture.

mpay_plugin #

A Flutter plugin that integrates Macau Pass (MPay) payment into Android and iOS apps. In addition to the MPay unified channel, the plugin exposes direct Alipay and WeChat Pay (including Hong Kong WeChat Wallet) as first-class payment paths.


Features #

Feature Android iOS HarmonyOS
MPay unified channel (MPay / Alipay / WeChat)
Direct Alipay payment
Direct WeChat Pay (mainland)
Hong Kong WeChat Wallet
Scan-to-pay QR code (native rendering)
Alipay sandbox environment
MPay SIT / UAT / Production switching

Architecture #

The plugin follows the Adapter pattern. On each platform, a single PayChannelAdapter interface abstracts the differences between the vendor SDKs (MPay OpenSDK, Alipay SDK, WeChat Open SDK), and one adapter exists per payment channel:

Channel Android iOS HarmonyOS
MPay unified channel MPayAdapter + MPayHandler MPayAdapter
Direct Alipay AliPayAdapter AliPayAdapter AliPayChannel
Direct WeChat Pay WeChatPayAdapter + WXAPIEventHandler WeChatPayAdapter + WXAPIEventHandler WeChatChannel
Hong Kong WeChat Wallet HongKongWalletAdapter HongKongWalletAdapter
Scan-to-pay QR code QrCodeAdapter QrCodeAdapter QrCodeGenerator

MpayPlugin itself is a thin dispatcher: method-channel calls are routed to the matching adapter through PayChannelAdapterRegistry, and payment result text mapping lives in a shared PayResultMapper. Vendor-specific code stays isolated, so adding a new payment channel only requires one new adapter class.

The Dart public API and the method-channel protocol are unchanged.


Installation #

dependencies:
  mpay_plugin: ^1.3.0

Android Setup #

1. AndroidManifest.xml #

The plugin registers a transparent WXEntryActivity / WXPayEntryActivity automatically via its own manifest merge. No manual Activity declaration is needed.

Add the following permissions if not already present:

<uses-permission android:name="android.permission.INTERNET" />

2. WeChat payment callback #

WeChat calls back to <your.package>.wxapi.WXPayEntryActivity. The plugin ships an activity-alias that routes this to its internal WechatCallbackActivity, so no extra Kotlin/Java file is required. Ensure applicationId is set correctly in android/app/build.gradle.

3. ProGuard / R8 #

If you use code shrinking, add the following rules:

-keep class com.tencent.mm.opensdk.** { *; }
-keep class com.alipay.sdk.** { *; }
-keep class com.macau.pay.sdk.** { *; }

iOS Setup #

1. URL Schemes #

In Xcode → Target → Info → URL Types, register:

Identifier Schemes
WeChat wx<your_wechat_appid>
Alipay <your_app_bundle_id> (or custom scheme passed to aliPay)
MPay <your_mpay_scheme> (provided by Macau Pass)

2. LSApplicationQueriesSchemes #

Add the following to Info.plist so the app can query whether WeChat and Alipay are installed:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>weixin</string>
    <string>weixinULAPI</string>
    <string>alipay</string>
    <string>alipays</string>
</array>

WeChat requires a Universal Link for iOS 9+ deep-linking. Pass it when registering:

await _mpay.registerApi(
  appId: 'wx1234567890abcdef',
  universalLink: 'https://your.domain/app/',  // must start with https
);

Configure the corresponding apple-app-site-association file on your web server.

4. AppDelegate #

In your AppDelegate.swift (or AppDelegate.m), make sure GeneratedPluginRegistrant is called before anything else — Flutter handles this automatically for new projects.


Quick Start #

import 'package:mpay_plugin/mpay_plugin.dart';

final _mpay = MpayPlugin();

// 1. Initialise environments (call once, e.g. in initState or main)
await _mpay.init(
  aliPayEnv: AliPayEnv.ONLINE,      // ONLINE | SANDBOX (Android only)
  mPayEnv: MPayEnv.PRODUCTION,      // PRODUCTION | SIT | UAT
);

// 2. Register WeChat (required before any WeChat payment)
final registered = await _mpay.registerApi(
  appId: 'wx1234567890abcdef',
  universalLink: 'https://your.domain/app/',  // iOS only
);

API Reference #

init #

Configure the Alipay and MPay runtime environments. Call once at app startup.

await _mpay.init(
  aliPayEnv: AliPayEnv.ONLINE,   // default
  mPayEnv: MPayEnv.PRODUCTION,   // default
);
Parameter Type Description
aliPayEnv AliPayEnv ONLINE (production) or SANDBOX (Android only)
mPayEnv MPayEnv PRODUCTION, SIT, or UAT

registerApi #

Register your WeChat AppID. Must be called before any WeChat payment.

final bool ok = await _mpay.registerApi(
  appId: 'wx1234567890abcdef',
  universalLink: 'https://your.domain/app/',
  doOnIOS: true,      // default
  doOnAndroid: true,  // default
);
Parameter Type Description
appId String WeChat Open Platform AppID
universalLink String? Required on iOS; must start with https
doOnIOS bool Whether to register on iOS (default true)
doOnAndroid bool Whether to register on Android (default true)

mPay — MPay unified channel #

Routes payment through the MPay SDK, which internally handles MPay, Alipay, or WeChat Pay based on the channel argument.

final ResultModel result = await _mpay.mPay(
  signedOrderData,        // server-signed order JSON string
  PayChannel.mPay,        // mPay | aliPay | wechatPay
  withScheme: 'myapp',    // iOS URL scheme registered for your app
);

if (result.resultStatus == '9000') {
  // success
}
Parameter Type Description
data String? Server-signed order data from your back-end
channel PayChannel mPay, aliPay, or wechatPay
withScheme String? iOS URL scheme (required on iOS)

aliPay — Direct Alipay #

Calls the Alipay SDK directly, bypassing the MPay channel.

final ResultModel result = await _mpay.aliPay(
  payInfo,          // server-signed order string (Alipay format)
  'myapp',          // iOS URL scheme
);
Parameter Type Description
payInfo String Alipay order string from your server
setIosUrlSchema String iOS URL scheme for Alipay callback

wechatPay — Direct WeChat Pay #

Call registerApi first. Uses a sealed PayType class to distinguish payment modes.

Mainland WeChat Pay

final ResultModel result = await _mpay.wechatPay(
  Payment(
    appId:        'wx1234567890abcdef',
    partnerId:    '1234567890',
    prepayId:     'wx20240101000000xxxxxxxxxxxxxxxx',
    packageValue: 'Sign=WXPay',
    nonceStr:     'random32chars',
    timestamp:    1717000000,       // Unix timestamp (UInt32)
    sign:         'ABCDEF...',
    signType:     'RSA',            // optional, default MD5
    extData:      null,             // optional
  ),
);

Hong Kong WeChat Wallet

final ResultModel result = await _mpay.wechatPay(
  HongKongWallet(prepayId: 'hk_token_from_server'),
);

ResultModel #

All payment methods return a ResultModel:

class ResultModel {
  final String? resultStatus;  // '9000' = success; other = error/cancel
  final String? result;        // human-readable description
  final String? memo;          // extra info / error detail
  final String? type;          // 'mPay' | 'aliPay' | 'WeChatPay' | 'HKWallet' | ...
}

Common resultStatus values:

Value Meaning
9000 Payment successful
6001 User cancelled
5000 Result unknown (query your server)
-1 Payment error / exception
-2 WeChat user cancelled

Enums #

enum AliPayEnv  { ONLINE, SANDBOX }          // SANDBOX is Android-only
enum MPayEnv    { PRODUCTION, SIT, UAT }
enum PayChannel { mPay, aliPay, wechatPay }

Scan-to-Pay (QR code) #

For scan-to-pay (the customer scans a QR shown in your app with another device), the QR payload is issued by your merchant server — the client SDKs provide no merchant-QR generation API:

  • Alipay: call alipay.trade.precreate with product_code=QR_CODE_OFFLINE; the response contains the qr_code string (e.g. https://qr.alipay.com/bax...).
  • WeChat Pay: call the unified order API (trade_type=NATIVE); the response contains the code_url string (e.g. weixin://wxpay/bizpayurl?pr=...).

The plugin renders that string as a QR image natively (ZXing on Android, CoreImage CIQRCodeGenerator on iOS — no Dart-side QR library):

import 'package:mpay_plugin/qr_pay.dart';

// One-liner: renders the QR with loading/error states built in.
QrPayView(code: qrCodeFromServer, size: 240)

// Or fetch raw PNG bytes and render them yourself:
final Uint8List? png = await _mpay.generateQrCode(qrCodeFromServer, size: 240);

size is clamped to 64..1024 on the native side; the QR is black-on-white with error-correction level M. No init() call is required — generation is purely local.

Important: confirming the payment result (polling alipay.trade.query / WeChat order query, or handling async notifications) is the merchant server's responsibility. The client only displays the QR code and never receives the payment receipt.


Error Handling #

try {
  final result = await _mpay.wechatPay(Payment(...));
  switch (result.resultStatus) {
    case '9000': /* success */ break;
    case '6001': /* cancelled by user */ break;
    default:     /* failure — check result.memo */ break;
  }
} on PlatformException catch (e) {
  // Plugin-level error (e.g. no Activity, WeChat not registered)
  debugPrint('Payment error: ${e.code} — ${e.message}');
}

Notes #

  • WeChat registration must happen before the first wechatPay call; calling wechatPay without registering will return a PlatformException with code WXAPI_NOT_REGISTERED.
  • Alipay sandbox is only supported on Android. iOS always uses the production Alipay SDK regardless of aliPayEnv.
  • For the Hong Kong WeChat Wallet flow, the initial call returns once WeChat has confirmed receipt of the payment request. The actual payment result (success/failure) is handled inside the WeChat app; your server should query the order status afterwards.
  • The plugin requires iOS 12.0+ and Android API 21+.
  • HarmonyOS (Flutter-OH) supports direct Alipay, direct WeChat Pay, and scan-to-pay QR codes. The MPay unified channel and Hong Kong WeChat Wallet return an unsupported result. See README.OpenHarmony.md for setup. The Macau Pass SDK is not public — if you can provide the official HarmonyOS SDK from Macau Pass, please contact the author: 1980705744@qq.com.
0
likes
140
points
56
downloads

Documentation

API reference

Publisher

verified publisherchihero.com

Weekly Downloads

Flutter plugin integrating Macau Pass (MPay), Alipay, WeChat Pay, HK Wallet, and scan-to-pay QR codes with a unified adapter architecture.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on mpay_plugin

Packages that implement mpay_plugin