1.在web目录下微信支付js文件,如图:
2.编写支付js文件,如下:
//微信支付
function onBridgeReady(appId,timeStamp,nonceStr,packageValue,signType,paySign){
window.WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":appId, //公众号ID,由商户传入
"timeStamp":timeStamp, //时间戳,自1970年以来的秒数
"nonceStr":nonceStr, //随机串
"package":packageValue,
"signType":signType, //微信签名方式:
"paySign":paySign //微信签名
},
function(res){
///dart提供的方法,通过js调用wxPayOperate来实现js与dart的通信
wxPayOperate(res.err_msg);
});
}
function toPay(appId,timeStamp,nonceStr,packageValue,signType,paySign){
//下面是解决WeixinJSBridge is not defined 报错的方法
if (typeof WeixinJSBridge == "undefined") {//微信浏览器内置对象。参考微信官方文档
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady(appId,timeStamp,nonceStr,packageValue,signType,paySign);
}
}
//切记回调的地址不能携带# 微信不支持!!!!
3.创建并编写wxPay.dart
import 'dart:js' as js;
import 'package:get/get.dart';
import '../http/HttpConfig.dart';
import 'package:url_launcher/url_launcher.dart';
class WxPay {
factory WxPay() => _instance;
static late final WxPay _instance = WxPay._internal();
WxPay._internal() {}
void wxCourseAuthorize(String orderId) {
//url:HttpConfig.wxUrl为微信授权登录地址 HttpConfig.baseUrl为项目部署的访问域名
//path=后拼接的为授权登录成功后回调访问的页面,以及携带的参数,此处只携带了订单号,一般为支付结果页
//切记回调的地址不能携带# 微信不支持!!!!
final url =
'${HttpConfig.wxUrl}?path=${HttpConfig.baseUrl}/web?orderId=$orderId';
//此处利用的get框架,关闭之前弹出的支付弹窗
Get.back();
//利用url_launcher跳转微信支付
launchUrl(Uri.parse(url), webOnlyWindowName: '_self');
}
toPay(String appId, String timeStamp, String nonceStr, String packageValue,
String signType, String paySign) {
//调用js的函数来执行想要的操作
js.context.callMethod(
"toPay", [appId, timeStamp, nonceStr, packageValue, signType, paySign]);
}
}
3.支付弹窗点击支付时调用
Future goPay() async {
//传入之前生成的订单号,或者自己定义的其他参数
WxPay().wxCourseAuthorize(orderNum);
}
4.支付结果页回调地址处理
由于微信支付回调地址不支持#,而flutter生成的地址带有#,如何去除请参考我的另一篇博客
回调的地址要访问的支付结果页有两种方式,任意一种都可以
4.1 在项目初始页 比如welcome页面中 根据路由参数,中转访问,比如:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
/// 第一次欢迎页面
class RouteWelcomeMiddleware extends GetMiddleware {
// priority 数字小优先级高
@override
int? priority = 0;
RouteWelcomeMiddleware({required this.priority});
@override
RouteSettings? redirect(String? route) {
String temp = '';
if (route != null && route.contains('?')) {
temp = route!.split('?')[1];
}
if (Get.parameters["orderId"] != null &&
Get.parameters["orderId"]!.isNotEmpty) {
//带有订单参数中转到支付结果页
return RouteSettings(name: '${AppRoutes.payResult}?$temp');
} else {
//正常跳转
}
}
}
4.2 另一种在web目录下创建指定访问的目录,创建index.html,拼接#号重定向至指定页面
5.支付结果页监听授权结果,并支付
import 'package:get/get.dart';
import '../../../global.dart';
import 'dart:js' as js;
class PayResultLogic extends StateLogic<Repo> {
final state = PayResultState();
@override
void onReady() {
super.onReady();
if (state.result != 0) {
return;
}
_getPay();
}
Future _getPay() async {
js.context["wxPayOperate"] = wxPayOperate;
//调用服务器接口根据订单号与openid获取支付信息
final payInfo = await repo.getPrepayOrder(
Get.parameters['orderId']!, Get.parameters['openid']!);
//支付信息获取支付
WxPay().toPay(
payInfo.wxParam!.appid!,
payInfo.wxParam!.timestamp!,
payInfo.wxParam!.noncestr!,
payInfo.wxParam!.packageValue!,
payInfo.wxParam!.signType!,
payInfo.wxParam!.sign!);
}
///给js 提供回调的方法
wxPayOperate(String callbackStr) {
if (callbackStr == "get_brand_wcpay_request:ok") {
//刷新页面,显示支付结果
state.result = 1;
} else {
toastInfo(msg: '支付失败!');
state.result = -1;
}
}
}
state.result是个 rxint值,用来刷新支付结果页的显示
class PayResultState {
final _result = 0.obs; //0支付中 1支付成功 -1 支付失败
int get result => _result.value;
set result(v) => _result.value = v;
}
创作不易,望多多支持