支持「微信支付分」 (#90)

This commit is contained in:
Alex Li
2021-09-08 13:50:40 +08:00
committed by GitHub
parent beb3f19f35
commit 6ac02ae5da
5 changed files with 123 additions and 0 deletions

View File

@ -23,6 +23,7 @@ import com.tencent.mm.opensdk.modelbiz.OpenWebview;
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView;
import com.tencent.mm.opensdk.modelmsg.LaunchFromWX;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
@ -85,6 +86,7 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private static final String METHOD_SUBSCRIBEMSG = "subscribeMsg";
private static final String METHOD_LAUNCHMINIPROGRAM = "launchMiniProgram";
private static final String METHOD_OPENCUSTOMERSERVICECHAT = "openCustomerServiceChat";
private static final String METHOD_OPENBUSINESSVIEW = "openBusinessView";
private static final String METHOD_PAY = "pay";
private static final String METHOD_ONLAUNCHFROMWXREQ = "onLaunchFromWXReq";
@ -96,6 +98,7 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private static final String METHOD_ONSUBSCRIBEMSGRESP = "onSubscribeMsgResp";
private static final String METHOD_ONLAUNCHMINIPROGRAMRESP = "onLaunchMiniProgramResp";
private static final String METHOD_ONOPENCUSTOMERSERVICECHATRESP = "onOpenCustomerServiceChatResp";
private static final String METHOD_ONOPENBUSINESSVIEWRESP = "onOpenBusinessViewResp";
private static final String METHOD_ONPAYRESP = "onPayResp";
private static final String METHOD_ONAUTHGOTQRCODE = "onAuthGotQrcode";
private static final String METHOD_ONAUTHQRCODESCANNED = "onAuthQrcodeScanned";
@ -109,6 +112,7 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private static final String ARGUMENT_KEY_TIMESTAMP = "timestamp";
private static final String ARGUMENT_KEY_SIGNATURE = "signature";
private static final String ARGUMENT_KEY_URL = "url";
private static final String ARGUMENT_KEY_QUERY = "query";
private static final String ARGUMENT_KEY_USERNAME = "username";
private static final String ARGUMENT_KEY_SCENE = "scene";
private static final String ARGUMENT_KEY_TEXT = "text";
@ -137,10 +141,12 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private static final String ARGUMENT_KEY_TEMPLATEID = "templateId";
private static final String ARGUMENT_KEY_RESERVED = "reserved";
private static final String ARGUMENT_KEY_CORPID = "corpId";
private static final String ARGUMENT_KEY_BUSINESSTYPE = "businessType";
private static final String ARGUMENT_KEY_PARTNERID = "partnerId";
private static final String ARGUMENT_KEY_PREPAYID = "prepayId";
private static final String ARGUMENT_KEY_PACKAGE = "package";
private static final String ARGUMENT_KEY_SIGN = "sign";
private static final String ARGUMENT_KEY_EXTINFO = "extInfo";
private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode";
private static final String ARGUMENT_KEY_RESULT_ERRORMSG = "errorMsg";
@ -309,6 +315,15 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENCUSTOMERSERVICECHATRESP, map);
}
} else if (resp instanceof WXOpenBusinessView.Resp) {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
WXOpenBusinessView.Resp openBusinessViewResp = (WXOpenBusinessView.Resp) resp;
map.put(ARGUMENT_KEY_BUSINESSTYPE, openBusinessViewResp.businessType);
map.put(ARGUMENT_KEY_RESULT_EXTMSG, openBusinessViewResp.extMsg);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENBUSINESSVIEWRESP, map);
}
} else if (resp instanceof PayResp) {
// 支付
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
@ -363,6 +378,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
handleLaunchMiniProgramCall(call, result);
} else if (METHOD_OPENCUSTOMERSERVICECHAT.equals(call.method)) {
handleOpenCustomerServiceChat(call, result);
} else if (METHOD_OPENBUSINESSVIEW.equals(call.method)) {
handleOpenBusinessView(call, result);
} else if (METHOD_PAY.equals(call.method)) {
handlePayCall(call, result);
} else {
@ -587,6 +604,17 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
result.success(null);
}
private void handleOpenBusinessView(@NonNull MethodCall call, @NonNull Result result) {
final WXOpenBusinessView.Req req = new WXOpenBusinessView.Req();
req.businessType = call.argument(ARGUMENT_KEY_BUSINESSTYPE);
req.query = call.argument(ARGUMENT_KEY_QUERY);
req.extInfo = call.argument(ARGUMENT_KEY_EXTINFO);
if (iwxapi != null) {
iwxapi.sendReq(req);
}
result.success(null);
}
private void handlePayCall(@NonNull MethodCall call, @NonNull Result result) {
final PayReq req = new PayReq();
req.appId = call.argument(ARGUMENT_KEY_APPID);

View File

@ -52,6 +52,7 @@ static NSString *const METHOD_SHAREMINIPROGRAM = @"shareMiniProgram";
static NSString *const METHOD_SUBSCRIBEMSG = @"subscribeMsg";
static NSString *const METHOD_LAUNCHMINIPROGRAM = @"launchMiniProgram";
static NSString *const METHOD_OPENCUSTOMERSERVICECHAT = @"openCustomerServiceChat";
static NSString *const METHOD_OPENBUSINESSVIEW = @"openBusinessView";
#ifndef NO_PAY
static NSString *const METHOD_PAY = @"pay";
#endif
@ -65,6 +66,7 @@ static NSString *const METHOD_ONSHAREMSGRESP = @"onShareMsgResp";
static NSString *const METHOD_ONSUBSCRIBEMSGRESP = @"onSubscribeMsgResp";
static NSString *const METHOD_ONLAUNCHMINIPROGRAMRESP = @"onLaunchMiniProgramResp";
static NSString *const METHOD_ONOPENCUSTOMERSERVICECHATRESP = @"onOpenCustomerServiceChatResp";
static NSString *const METHOD_ONOPENBUSINESSVIEWRESP = @"onOpenBusinessViewResp";
#ifndef NO_PAY
static NSString *const METHOD_ONPAYRESP = @"onPayResp";
#endif
@ -80,6 +82,7 @@ static NSString *const ARGUMENT_KEY_NONCESTR = @"noncestr";
static NSString *const ARGUMENT_KEY_TIMESTAMP = @"timestamp";
static NSString *const ARGUMENT_KEY_SIGNATURE = @"signature";
static NSString *const ARGUMENT_KEY_URL = @"url";
static NSString *const ARGUMENT_KEY_QUERY = @"query";
static NSString *const ARGUMENT_KEY_USERNAME = @"username";
static NSString *const ARGUMENT_KEY_SCENE = @"scene";
static NSString *const ARGUMENT_KEY_TEXT = @"text";
@ -109,6 +112,7 @@ static NSString *const ARGUMENT_KEY_DISABLEFORWARD = @"disableForward";
static NSString *const ARGUMENT_KEY_TEMPLATEID = @"templateId";
static NSString *const ARGUMENT_KEY_RESERVED = @"reserved";
static NSString *const ARGUMENT_KEY_CORPID = @"corpId";
static NSString *const ARGUMENT_KEY_BUSINESSTYPE = @"businessType";
#ifndef NO_PAY
static NSString *const ARGUMENT_KEY_PARTNERID = @"partnerId";
static NSString *const ARGUMENT_KEY_PREPAYID = @"prepayId";
@ -117,6 +121,7 @@ static NSString *const ARGUMENT_KEY_PREPAYID = @"prepayId";
static NSString *const ARGUMENT_KEY_PACKAGE = @"package";
static NSString *const ARGUMENT_KEY_SIGN = @"sign";
#endif
static NSString *const ARGUMENT_KEY_EXTINFO = @"extInfo";
static NSString *const ARGUMENT_KEY_RESULT_ERRORCODE = @"errorCode";
static NSString *const ARGUMENT_KEY_RESULT_ERRORMSG = @"errorMsg";
@ -200,6 +205,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
[self handleLaunchMiniProgramCall:call result:result];
} else if ([METHOD_OPENCUSTOMERSERVICECHAT isEqualToString:call.method]) {
[self handleOpenCustomerServiceChatCall: call result:result];
} else if ([METHOD_OPENBUSINESSVIEW isEqualToString:call.method]) {
[self handleOpenBusinessViewCall: call result:result];
}
#ifndef NO_PAY
else if ([METHOD_PAY isEqualToString:call.method]) {
@ -413,6 +420,19 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
result(nil);
}
- (void)handleOpenBusinessViewCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXOpenBusinessViewReq *req = [[WXOpenBusinessViewReq alloc] init];
req.businessType = call.arguments[ARGUMENT_KEY_BUSINESSTYPE];
req.query = call.arguments[ARGUMENT_KEY_QUERY];
req.extInfo = call.arguments[ARGUMENT_KEY_EXTINFO];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
}];
result(nil);
}
#ifndef NO_PAY
- (void)handlePayCall:(FlutterMethodCall *)call result:(FlutterResult)result {
PayReq *req = [[PayReq alloc] init];
@ -546,6 +566,13 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
[_channel invokeMethod:METHOD_ONLAUNCHMINIPROGRAMRESP arguments:dictionary];
} else if ([resp isKindOfClass:[WXOpenCustomerServiceResp class]]) {
[_channel invokeMethod:METHOD_ONOPENCUSTOMERSERVICECHATRESP arguments:dictionary];
} else if ([resp isKindOfClass:[WXOpenBusinessViewResp class]]) {
if (resp.errCode == WXSuccess) {
WXOpenBusinessViewResp *openBusinessViewResp = (WXOpenBusinessViewResp *)resp;
[dictionary setValue:openBusinessViewResp.businessType forKey:ARGUMENT_KEY_BUSINESSTYPE];
[dictionary setValue:openBusinessViewResp.extMsg forKey:ARGUMENT_KEY_RESULT_EXTMSG];
}
[_channel invokeMethod:METHOD_ONOPENBUSINESSVIEWRESP arguments:dictionary];
} else {
#ifndef NO_PAY
if ([resp isKindOfClass:[PayResp class]]) {

View File

@ -182,6 +182,28 @@ class OpenCustomerServiceChatResp extends BaseResp {
Map<String, dynamic> toJson() => _$OpenCustomerServiceChatRespToJson(this);
}
@JsonSerializable(explicitToJson: true)
class OpenBusinessViewResp extends BaseResp {
const OpenBusinessViewResp({
required this.businessType,
required this.extMsg,
required int errorCode,
String? errorMsg,
}) : super(
errorCode: errorCode,
errorMsg: errorMsg,
);
factory OpenBusinessViewResp.fromJson(Map<String, dynamic> json) =>
_$OpenBusinessViewRespFromJson(json);
final String businessType;
final String extMsg;
@override
Map<String, dynamic> toJson() => _$OpenBusinessViewRespToJson(this);
}
@JsonSerializable(
explicitToJson: true,
)

View File

@ -107,6 +107,24 @@ Map<String, dynamic> _$OpenCustomerServiceChatRespToJson(
'errorMsg': instance.errorMsg,
};
OpenBusinessViewResp _$OpenBusinessViewRespFromJson(Map<String, dynamic> json) {
return OpenBusinessViewResp(
businessType: json['businessType'] as String,
extMsg: json['extMsg'] as String,
errorCode: json['errorCode'] as int? ?? 0,
errorMsg: json['errorMsg'] as String?,
);
}
Map<String, dynamic> _$OpenBusinessViewRespToJson(
OpenBusinessViewResp instance) =>
<String, dynamic>{
'businessType': instance.businessType,
'extMsg': instance.extMsg,
'errorCode': instance.errorCode,
'errorMsg': instance.errorMsg,
};
PayResp _$PayRespFromJson(Map<String, dynamic> json) {
return PayResp(
errorCode: json['errorCode'] as int? ?? 0,

View File

@ -43,6 +43,7 @@ class Wechat {
static const String _METHOD_LAUNCHMINIPROGRAM = 'launchMiniProgram';
static const String _METHOD_OPENCUSTOMERSERVICECHAT =
'openCustomerServiceChat';
static const String _METHOD_OPENBUSINESSVIEW = 'openBusinessView';
static const String _METHOD_PAY = 'pay';
static const String _METHOD_ONLAUNCHFROMWXREQ = 'onLaunchFromWXReq';
@ -56,6 +57,7 @@ class Wechat {
'onLaunchMiniProgramResp';
static const String _METHOD_ONOPENCUSTOMERSERVICECHATRESP =
'onOpenCustomerServiceChatResp';
static const String _METHOD_ONOPENBUSINESSVIEWRESP = 'onOpenBusinessViewResp';
static const String _METHOD_ONPAYRESP = 'onPayResp';
static const String _METHOD_ONAUTHGOTQRCODE = 'onAuthGotQrcode';
static const String _METHOD_ONAUTHQRCODESCANNED = 'onAuthQrcodeScanned';
@ -69,6 +71,7 @@ class Wechat {
static const String _ARGUMENT_KEY_TIMESTAMP = 'timestamp';
static const String _ARGUMENT_KEY_SIGNATURE = 'signature';
static const String _ARGUMENT_KEY_URL = 'url';
static const String _ARGUMENT_KEY_QUERY = 'query';
static const String _ARGUMENT_KEY_USERNAME = 'username';
static const String _ARGUMENT_KEY_SCENE = 'scene';
static const String _ARGUMENT_KEY_TEXT = 'text';
@ -97,10 +100,12 @@ class Wechat {
static const String _ARGUMENT_KEY_TEMPLATEID = 'templateId';
static const String _ARGUMENT_KEY_RESERVED = 'reserved';
static const String _ARGUMENT_KEY_CORPID = 'corpId';
static const String _ARGUMENT_KEY_BUSINESSTYPE = 'businessType';
static const String _ARGUMENT_KEY_PARTNERID = 'partnerId';
static const String _ARGUMENT_KEY_PREPAYID = 'prepayId';
static const String _ARGUMENT_KEY_PACKAGE = 'package';
static const String _ARGUMENT_KEY_SIGN = 'sign';
static const String _ARGUMENT_KEY_EXTINFO = 'extInfo';
static const String _SCHEME_FILE = 'file';
@ -173,6 +178,10 @@ class Wechat {
_respStreamController.add(OpenCustomerServiceChatResp.fromJson(
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
break;
case _METHOD_ONOPENBUSINESSVIEWRESP:
_respStreamController.add(OpenBusinessViewResp.fromJson(
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
break;
case _METHOD_ONPAYRESP:
_respStreamController.add(PayResp.fromJson(
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
@ -569,6 +578,25 @@ class Wechat {
);
}
/// 调起支付分
/// * 免确认模式https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_7.shtml
/// * 需确认授权https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_11.shtml
/// * 拉起小程序https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_23.shtml
Future<void> openBusinessView({
required String businessType,
required String query,
String? extInfo,
}) {
return _channel.invokeMethod<void>(
_METHOD_OPENBUSINESSVIEW,
<String, dynamic>{
_ARGUMENT_KEY_BUSINESSTYPE: businessType,
_ARGUMENT_KEY_QUERY: query,
if (extInfo != null) _ARGUMENT_KEY_EXTINFO: extInfo,
},
);
}
/// 支付 - x.y.z-iOS-NoPay 版本下 iOS 调用会直接抛出异常 No implementation [MissingPluginException]
/// 参数说明https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
Future<void> pay({