Open shizhihuang opened 1 year ago
我也有相同问题,之前好的,SDK没升级,前几周开始有用户反馈不行了,是不是支付宝的SDK升级了,需要同步适配啊。安卓是正常回调的。 测试过最新的 6.0.0 也有这个问题
昨天已经升级sdk了
另外,支付宝sdk新增了一个应用链接回调,不过没给文档也没有demo … 故而通用链接回调没敢用 …
我这边没有iOS支付宝应用,你们能配合debug一下不?我这边新建一个分支来调试 …
试试我这代码,用了这么久基本没翻车 ...
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:alipay_kit/alipay_kit_platform_interface.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:wechat_kit/wechat_kit.dart';
class SocialClub with WidgetsBindingObserver {
SocialClub._() {
WidgetsBinding.instance.addObserver(this);
}
static SocialClub get instance => _instance ??= SocialClub._();
static SocialClub? _instance;
StreamSubscription<WechatAuthResp>? _wechatAuthSub;
StreamSubscription<WechatPayResp>? _wechatPaySub;
StreamSubscription<AlipayResp>? _alipayPaySub;
void init() {
WechatKitPlatform.instance.registerApp(
appId: appId,
universalLink: universalLink,
);
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
// super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed) {
_clearSubscription();
}
}
Future<void> _clearSubscription() async {
final StreamSubscription<WechatAuthResp>? maybeIncompleteWechatAuthSub = _wechatAuthSub;
final StreamSubscription<WechatPayResp>? maybeIncompleteWechatPaySub = _wechatPaySub;
await Future<void>.delayed(const Duration(seconds: 1));
//
if (_wechatAuthSub != null && _wechatAuthSub == maybeIncompleteWechatAuthSub) {
await _wechatAuthSub?.cancel();
_wechatAuthSub = null;
}
//
if (_wechatPaySub != null && _wechatPaySub == maybeIncompleteWechatPaySub) {
await _wechatPaySub?.cancel();
_wechatPaySub = null;
}
}
// --- apple
Future<bool> isAppleAvailable() async {
return Platform.isIOS && await SignInWithApple.isAvailable();
}
Future<AuthorizationCredentialAppleID?> appleAuth() async {
//
String generateNonce([int length = 32]) {
const String charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final Random random = Random.secure();
return List<String>.generate(length, (int index) => charset[random.nextInt(charset.length)]).join();
}
String sha256ofString(String input) {
final List<int> bytes = utf8.encode(input);
final Digest digest = sha256.convert(bytes);
return digest.toString();
}
//
final String rawNonce = generateNonce();
final String nonce = sha256ofString(rawNonce);
try {
final AuthorizationCredentialAppleID appleID = await SignInWithApple.getAppleIDCredential(
scopes: <AppleIDAuthorizationScopes>[
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
nonce: nonce,
);
return appleID;
} on SignInWithAppleException catch (e) {
if (e is SignInWithAppleAuthorizationException && e.code == AuthorizationErrorCode.canceled) {
return null;
} else {
rethrow;
}
}
}
// --- wechat
Future<bool> isWechatAvailable() {
return WechatKitPlatform.instance.isInstalled();
}
// 在华为 nova 4 上,因微信在其他手机上登录了,重新登录,会造成无法接收 resumed 事件,从而无法正常完成授权流程。
// 因此,需在调用授权时,不能阻塞用户后续再次发起授权登录行为
Future<WechatAuthResp?> wechatAuth(bool isInstalled) {
_wechatAuthSub?.cancel();
_wechatAuthSub = null;
//
final Completer<WechatAuthResp?> completer = Completer<WechatAuthResp?>();
_wechatAuthSub = WechatKitPlatform.instance.respStream().where((WechatResp event) => event is WechatAuthResp).cast<WechatAuthResp>().listen(
(WechatAuthResp event) {
if (completer.isCompleted) {
return;
}
completer.complete(event);
},
onError: (Object error, [StackTrace? stackTrace]) {
if (completer.isCompleted) {
return;
}
completer.completeError(error, stackTrace);
},
cancelOnError: true,
);
WechatKitPlatform.instance.auth(
scope: <String>[WechatScope.kSNSApiUserInfo],
state: 'auth',
type: Platform.isIOS && !isInstalled ? WechatAuthType.kWeb : WechatAuthType.kNormal,
);
return completer.future.whenComplete(() {
_wechatAuthSub?.cancel();
_wechatAuthSub = null;
});
}
Future<void> wechatShareWebpage({
required int scene,
required String url,
String? title,
String? desc,
Uint8List? thumbData,
}) {
return WechatKitPlatform.instance.shareWebpage(
scene: scene,
webpageUrl: url,
title: title,
description: desc,
thumbData: thumbData,
);
}
Future<void> wechatShareImage({
required int scene,
required Uri imageUri,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? imageData,
}) {
return WechatKitPlatform.instance.shareImage(
scene: scene,
imageUri: imageUri,
title: title,
description: description,
thumbData: thumbData,
imageData: imageData,
);
}
Future<void> wechatCustomerServiceChat({
required String corpId,
required String url,
}) {
return WechatKitPlatform.instance.openCustomerServiceChat(
corpId: corpId,
url: url,
);
}
Future<WechatPayResp> wechatPay({
required String appId,
required String partnerId,
required String prepayId,
required String package,
required String nonceStr,
required String timeStamp,
required String sign,
}) {
_wechatPaySub?.cancel();
_wechatPaySub = null;
//
final Completer<WechatPayResp> completer = Completer<WechatPayResp>();
_wechatPaySub = WechatKitPlatform.instance.respStream().where((WechatResp event) => event is WechatPayResp).cast<WechatPayResp>().listen(
(WechatPayResp event) {
if (completer.isCompleted) {
return;
}
completer.complete(event);
},
onError: (Object error, [StackTrace? stackTrace]) {
if (completer.isCompleted) {
return;
}
completer.completeError(error, stackTrace);
},
cancelOnError: true,
);
WechatKitPlatform.instance.pay(
appId: appId,
partnerId: partnerId,
prepayId: prepayId,
package: package,
nonceStr: nonceStr,
timeStamp: timeStamp,
sign: sign,
);
return completer.future.whenComplete(() {
_wechatPaySub?.cancel();
_wechatPaySub = null;
});
}
// --- alipay
Future<bool> isAlipayAvailable() {
return AlipayKitPlatform.instance.isInstalled();
}
Future<AlipayResp> alipayUnsafePay({
required String orderInfo,
required String rsaPrivate,
}) {
return alipayPay(
orderInfo:
'$orderInfo&sign="${Uri.encodeQueryComponent(base64.encode(RsaSigner.sha1Rsa('-----BEGIN PRIVATE KEY-----\n$rsaPrivate\n-----END PRIVATE KEY-----').sign(utf8.encode(orderInfo))))}"&sign_type="RSA"',
);
}
Future<AlipayResp> alipayPay({
required String orderInfo,
}) {
_alipayPaySub?.cancel();
_alipayPaySub = null;
//
final Completer<AlipayResp> completer = Completer<AlipayResp>();
_alipayPaySub = AlipayKitPlatform.instance.payResp().listen(
(AlipayResp event) {
if (completer.isCompleted) {
return;
}
completer.complete(event);
},
onError: (Object error, [StackTrace? stackTrace]) {
if (completer.isCompleted) {
return;
}
completer.completeError(error, stackTrace);
},
cancelOnError: true,
);
AlipayKitPlatform.instance.pay(orderInfo: orderInfo);
return completer.future.whenComplete(() {
_alipayPaySub?.cancel();
_alipayPaySub = null;
});
}
}
我这边解决了, 看了下源码。
原因:老版本中手动配置的 scheme,与后来在 pubspec.yaml 中配置的不一致
我在执行 pod install
的时候会提示找不到 plist
Analyzing dependencies
alipaysdk utdid
Runner/Info-$(CONFIGURATION).plist is not exist
Runner/Info-$(CONFIGURATION).plist is not exist
wechatsdk pay
Runner/Info-$(CONFIGURATION).plist is not exist
Downloading dependencies
Generating Pods project
Integrating client project
实际目录下是有的,这里暂时不清楚怎么解决
所以我手动修改文件,重新编译后就正常
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>alipay</string>
<key>CFBundleURLSchemes</key>
<array>
<string>必须和pubspec.yaml中的alipay_kit.scheme一致</string>
</array>
</dict>
我这边解决了, 看了下源码。
执行 pod install 的时候从 pubspec.yaml 提取 scheme 配置
然后通过 alipay_setup.rb 把 scheme 写到宿主当前 xxx.plist 中的 CFBundleURLTypes 里面
插件侧通过 ALIPAY_KIT_SCHEME 绑定 scheme 信息
原因:老版本中手动配置的 scheme,与后来在 pubspec.yaml 中配置的不一致
我在执行
pod install
的时候会提示找不到 plistAnalyzing dependencies alipaysdk utdid Runner/Info-$(CONFIGURATION).plist is not exist Runner/Info-$(CONFIGURATION).plist is not exist wechatsdk pay Runner/Info-$(CONFIGURATION).plist is not exist Downloading dependencies Generating Pods project Integrating client project
实际目录下是有的,这里暂时不清楚怎么解决
所以我手动修改文件,重新编译后就正常
<dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>alipay</string> <key>CFBundleURLSchemes</key> <array> <string>必须和pubspec.yaml中的alipay_kit.scheme一致</string> </array> </dict>
ruby代码里明确了不支持这种动态配置info.plist … pod install过程中是无法获取 configuration 变量的 … 所以,你这才报错了 … 建议配置一个 info.plist,变量通过 xconfig 文件来配置,参考 debug.xconfig 等 …
iOS端调用支付宝返回应用后不走回调