Flutter之微信支付实战模板


活动地址:CSDN21天学习挑战赛

安装flutter插件

  fluwx: ^3.8.5 #微信

注册微信接口

  _initfluwx() async {
    print('789879797987979');
    //7ca7229f15fb67f76aa529b98234139f
    await fluwx
        .registerWxApi(
      appId: "自己的id",
      doOnAndroid: true,
      doOnIOS: true,
      universalLink: '',
    )
        .then((value) {
      print(value);
      print('-----------------------');
    });
  }

调用方法

  static Future<bool> payWechat(price) async {
    if(price == null )return false;
    bool isInstalled = await fluwx.isWeChatInstalled;
    if (!isInstalled) {
      ToastUtils.showToast("请先安装微信");
      return false;
    }
    // commonViewModel.sealPrice
    Map<String, dynamic> map = {'amount':price};
    Map data;
 {
     //此处可以进行后端接口请求
    if (data != null && data.data['code'] == 0) {
        data = data.data['data'];
        var result = await fluwx.payWithWeChat(
          appId: data['appId'].toString(),
          partnerId: '自己的id',
          prepayId: data['prepayId'].toString(),
          packageValue: data['package'].toString(),
          nonceStr: data['nonceStr'].toString(),
          timeStamp: int.parse(data['timeStamp']),
          sign: data['paySign'].toString(),
        );
        return result;
      }
    Future.delayed(Duration.zero,(){

    });
    print('-------------------------------------------------------------------$data');
    return false;
    // 应用程序后台地址
  }

监听微信支付事件

    payListen = fluwx.weChatResponseEventHandler.listen((event) {
      //监听调起
      if (event.errCode == 0) {//event.isSuccessful
        print("监听支付调起成功");
        saveSeal();
      } else {
        ToastUtils.showToast(event.errStr ?? "微信支付失败");
        return ;//写或不写都行
      }
    });

事件结束时关闭微信消息订阅

  StreamSubscription _wxPay;
    void wxSubscriptionClose() => _wxPay?.cancel();
        _wxPay?.cancel();
    // 支付回调
    _wxPay = fluwx.weChatResponseEventHandler.listen((event) {
      _wxPay?.cancel();
      if (event is fluwx.WeChatPaymentResponse) {
        if (event.isSuccessful) {
          return onSuccess?.call();
        } else {
          return onError?.call(event.errCode == -1 ? '系统错误,请联系管理员' : '您取消了支付');
        }
      }
    });

出现两次回调,是由于没有注销监听产生的

代码示例

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:fluwx/fluwx.dart' as fluwx;

class WechatPayment {
  StreamSubscription _wxPay;

  /// 关闭微信消息订阅
  void wxSubscriptionClose() => _wxPay?.cancel();

  /// 调起微信支付面板 
  /// 这里的WxPayModel是业务层的数据,即后台返回的有关微信支付订单的信息
  void wxPay(WxPayModel wxPayModel, {VoidCallback onWxPaying, VoidCallback onSuccess, Function(String data) onError}) async {
    // 跳转微信支付前,告诉页面进入微信支付,页面层可以做一些关闭加载框等的操作
    onWxPaying?.call();
    // 一些异常情况的处理
    if (!await fluwx.isWeChatInstalled) return onError?.call('请安装微信完成支付或使用苹果手机支付');
    if (wxPayModel.appId != Config.WX_APP_ID) return onError?.call('AppID不一致,请联系管理员');
    // 此方法笔者没有做单例,因此支付前尝试注销监听,避免重复回调
    _wxPay?.cancel();
    // 支付回调
    _wxPay = fluwx.weChatResponseEventHandler.listen((event) {
      _wxPay?.cancel();
      if (event is fluwx.WeChatPaymentResponse) {
        if (event.isSuccessful) {
          return onSuccess?.call();
        } else {
          return onError?.call(event.errCode == -1 ? '系统错误,请联系管理员' : '您取消了支付');
        }
      }
    });

    // 发起支付
    fluwx.payWithWeChat(
      appId: wxPayModel.appId,
      partnerId: wxPayModel.partnerId,
      prepayId: wxPayModel.prepayId,
      packageValue: wxPayModel.packageValue,
      nonceStr: wxPayModel.nonceStr,
      timeStamp: wxPayModel.timeStamp,
      sign: wxPayModel.sign,
      signType: wxPayModel.signType,
      extData: wxPayModel.extData,
    );
  }
}


WechatPayment paymentUtils = new WechatPayment();
paymentUtils.wxPay(
    state.model.wxPayModel,
    onError: (String err) {
        if (!mounted) return;
        // 微信支付错误,设置支付状态为false,弹框即可
         _isPaying = false;
         SchedulerBinding.instance.addPostFrameCallback((_) {
           CommonUtils.showToast(err, backgroundColor: Theme.of(context).errorColor);
         });
      }, 
      onSuccess:(){ 
        _isPaying = true;
      },
      onWxPaying: () {
        // 启动微信支付,设置支付状态为true,关闭加载框
        _isPaying = true;
        SchedulerBinding.instance.addPostFrameCallback((_) {
          Navigator.pop(context);
        });
   },
);

但是需要注意,微信的回调是异步的,并且有很多种情况是接收不到回调的,以下是确定收不到会调的情况。
现在主流的做法是再支付页面监听app的生命周期,即由后台切回前台的时候,检测下状态,若还在支付中,直接进入查询结果页面,由后台去检验订单,拿到结果显示即可。(后台主动查询理论上还是存在微信服务端延时的问题,因此后台进行查询的时候,建议采取轮询机制,若是没有支付成功的话,延时5秒后再确认下更保险)

class _XXXPageState extends State<XXXPage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this); //添加观察者
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this); //销毁观察者
    super.dispose();
  }

  /// 应用状态监听
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        {
          if (Platform.isAndroid && _isPaying) {
            _isPaying = false;
          // 监听到时安卓设备并且支付还在进行中,程序员要根据业务做一下处理
            break;
        }
      default:
        break;
    }
    super.didChangeAppLifecycleState(state);
  }
}

参考文章

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可鸭~

想吃糖~我会甜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值