前语

本篇首要介绍 付出宝付出微信付出、微信共享、微信登陆功用,以及在微信付出过程中需求装备 iosUniversalLink 的问题(没有装备跳转微信时会提示:未验证运用

运用的组件分别为 alipay_kit、wechat_kit,即:付出宝框架,微信框架

当然假如要对接国外的一些付出,则挑选 stripe 更好,这儿不介绍,有需求的能够运用这个

付出宝付出

这儿边首要针对 ios 端设置,android 暂时没发现什么特殊问题

首先增加三方库 alipay_kitalipay_kit_ios,这两个都要增加,前面一个首要准备android,后边一个首要针对于 ios

flutter pub add alipay_kit
flutter pub add alipay_kit_ios

原生端装备

首要ios,android现在不需求装备,呈现了问题,能够参考 alipay_kit 解决

ios端设置,设置 plist,首要设置网络、跳转付出宝的scheme

iOS 9体系战略更新,限制了http协议的拜访,此外运用需求在“Info.plist”中将要运用的URL Schemes列为白名单,才可正常查看其他运用是否装置。
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>alipay</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

ios端设置,除了上面的,还要设置自己的 scheme,用于付出宝跳回咱们的 app

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>alipay</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>alipay123456</string>
        </array>
    </dict>
</array>

其实际上,在咱们的 info 里边设置一下即可,会主动生成上面的代码,前面称号要用 alipay, 后边取一个相对比较仅有的字符串即可

flutter-支付宝、微信支付分享 与 ios UniversalLink

flutter端运用

下面注册付出授权登陆回调,不注册监听,直接运用回来的 Future 也能够,但不确认是否覆盖所有版别或许状况

//导入头文件,无需导入ios的那个库
import 'package:alipay_kit/alipay_kit.dart';
//声明参数用于回调运用
late final StreamSubscription<AlipayResp> _alipaySubs; //用于付出
late final StreamSubscription<AlipayResp> _alipayAuthSubs; //用于授权登陆
//注册付出宝付出和授权成果回调
void registerAlipayResp() {
  _alipaySubs = Alipay.instance.payResp().listen(listenAlipayPay);
  _alipayAuthSubs = Alipay.instance.authResp().listen(_listenAlipayAuth);
}
//付出成功或许失利回调
void listenAlipayPay(AlipayResp resp) {
  final String content = 'pay: ${resp.resultStatus} - ${resp.result}';
  print(content);
}
//收取那登陆成功或许失利回调
void _listenAlipayAuth(AlipayResp resp) {
  final String content = 'auth: ${resp.resultStatus} - ${resp.result}';
  print(content);
}

检测是否装置了付出宝app

//回来的 Future 需求等待
final isInstall = await Alipay.instance.isInstalled();
if (!isInstall) {
  print("未装置付出宝app");
  return;
}

授权登陆,需求传递授权信息字符串,由服务器回来

Alipay.instance.auth(authInfo: "authInfo-123123");

付出接口,需求传递 订单信息字符串,由服务器回来

Alipay.instance.pay(orderInfo: "orderInfo-123123123123")

看到上面你或许知道为什么客户端不需求 appid 之类的信息了,没错,都在服务器回来的信息字符串里边,也是服务器进行部分加密,因而相对客户端比较安全,也是付出宝引荐

ps:对接前需求先到 付出宝商家平台 恳求咱们的运用服务,不然等待就比较浪费时刻了,前后端都会卡到这儿

微信付出、共享、登陆

微信大部分内容和付出宝类似,只不过ios端额定引出了 UniversalLink(下一小节专门介绍了) 作为新版别跳转传参方案,因而需求额定做一些操作

需求增加三方库 wechat_kit

//flutter 增加 alipay_kit
flutter pub add alipay_kit

原生端装备

设置 plist,以便于能够跳转到微信(运用该 scheme 支撑新老版别的跳转),付出宝和微信都存在的状况,内容兼并即可

<array>
   <string>weixinULAPI</string>
   <string>weixin</string>
    <string>alipay</string> //也有付出宝的话便是额定加一条即可,这条注释不要放进去
</array>
<key>NSAppTransportSecurity</key>
<dict>
   <key>NSAllowsArbitraryLoads</key>
   <true/>
</dict>

咱们自己的 schemes 设置,用于付出宝微信跳回咱们的app的,就在 info 里边设置

<array>
   <dict>
      <key>CFBundleTypeRole</key>
      <string>Editor</string>
      <key>CFBundleURLName</key>
      <string>alipay</string>
      <key>CFBundleURLSchemes</key>
      <array>
         <string>alipay123456</string>
      </array>
   </dict>
   <dict>
      <key>CFBundleTypeRole</key>
      <string>Editor</string>
      <key>CFBundleURLName</key>
      <string>weixin</string>
      <key>CFBundleURLSchemes</key>
      <array>
         <string>weixin123456</string> //留意:这儿边填写自己的微信恳求的 key
      </array>
   </dict>
</array>

flutter-支付宝、微信支付分享 与 ios UniversalLink

flutter 端运用

下面是注册微信付出、共享、登陆等回调

//导入包
import 'package:wechat_kit/wechat_kit.dart';
//声明回调参数
late final StreamSubscription<BaseResp> _wechatRespSubs;
AuthResp? _wechatAuthResp;//保存授权的resp码,用于获取后续获取用户信息
//注册微信付出、共享、授权等回调
void registerWechatResp() {
  _wechatRespSubs = Wechat.instance.respStream().listen(listenWechatResp);
}
//监听回调,集多个回调与一身
void listenWechatResp(BaseResp resp) {
  final String content = '基础: ${resp.errorCode} ${resp.errorMsg}';
  print(content);
  if (resp is AuthResp) {
    //能够保存下来授权的状况(没必要这个),用来获取用户信息
    _wechatAuthResp = resp;
    final String content = '登录: ${resp.errorCode} ${resp.errorMsg}';
    print(content);
  } else if (resp is ShareMsgResp) {
    final String content = '共享: ${resp.errorCode} ${resp.errorMsg}';
    print(content);
  } else if (resp is PayResp) {
    final String content = '付出: ${resp.errorCode} ${resp.errorMsg}';
    print(content);
  } else if (resp is LaunchMiniProgramResp) {
    //这儿就不加入案例了
    final String content = '拉起小程序: ${resp.errorCode} ${resp.errorMsg}';
    print(content);
  }
}

运用前需求先注册,运用发动时注册一次即可,传入商户平台恳求的key,还是有便是 UniversalLink(后边讲) 装备后的 link 连,假如仅仅android端则不需求传递该参数,该参数用于新版别微信(但有必要得处理)

await Wechat.instance.registerApp(
  appId: wechatKey,
  //不了解需求的话能够查找ios universalLink 通用链接设置,能够直接经过链接唤起app,我也有相关文章哈
  universalLink: "https://help.wechat.com/$wechatKey ",
);

注册微信回调函数,伴随发动时注册即可,不然不回调注册的函数

await Wechat.instance.handleInitialWXReq();

判别是否,装置了微信

final isInstalled = await Wechat.instance.isInstalled();
if (!isInstalled) {
    print("没装置微信")
    return;
}

微信授权登陆,会回来需求的 id 一般登陆和绑定时运用

Wechat.instance.auth(
  scope: <String>[WechatScope.SNSAPI_USERINFO],
  state: 'auth',
);

共享图片、文字到微信谈天、朋友圈、保藏

//共享办法shareImage、shareText
//scene类型-- SESSION:谈天界面、TIMELINE:朋友圈、FAVORITE:保藏
Wechat.instance.shareText(
  scene: WechatScene.SESSION,
  text: '测验文字共享',
);

微信付出,里边提供了必要的一些参数,建议从服务器,校验加密后回来,也能够写到本地(毕竟注册也用到的appId)

//这就算完结付出了,这些东西最好让后台走校验接口回来
Wechat.instance.pay(
    appId: 'appId', //微信恳求的appid
    partnerId: 'partnerId', //合作伙伴id
    prepayId: 'prepayId', //预付出id
    package: 'package', //微信传递参数
    nonceStr: 'nonceStr', //随机字符串
    timeStamp: 'timeStamp', //时刻戳
    sign: 'sign', //微信签名
);

问题和解决方案

在测验ios app的时分,假如碰到老版别的微信是没问题的,假如碰到用户是新版别的微信,那需求装备 UniversalLink,不然跳转微信时,会提示"未验证引用",不装备甚至都不知道注册时的 universalLink 要传递啥,别说不适配新版别微信用户(那么这个功用或许大部分人ios用户运用或许都有问题)

因而只需求在 ios 端 装备好 UniversalLink即可,此外还需求将json装备文件放到咱们后台服务器

下面会介绍到

UniversalLink 装备

这个是 ios 9 就现已推出的 UniversalLink 通用连接,点击该链接时,iOS 设备能够不经过 Safari 或网页,直接翻开 App,比如在备忘录中直接翻开App

ios开发实际上默许不是有必要的,但是 flutter 想接入微信相关服务,那便是有必要的了,下面介绍下其接入过程

1、创建一个姓名为 apple-app-site-association 的文件

ps:内容为json格局,但是不需求.json为扩展名,扩展名仅仅便利在操作体系中,给运用标记类型,便利调用发生的一种战略,因而不是必要的)

{
  "applinks": {
    "apps": [],
    "details": [ //能够有多组,加入咱们有多个运用,都能够运用这一个文件
      {
        "appID": "teamID.bundleID", //这儿填写的是咱们的 团队id,能够在证书或许开发者账号中查看
        "paths": [ "*" ] //path途径为,域名后边的途径,能够运用通配符,这儿*表明任意途径都能够
      }
      { 
          "appID": "D1I2O3P3PK.com.example.appstore", //案例 teamid + bundleid
          "paths": [ "/qq_zone/*","/qq/*" ]  //通配符表明weixin或许qq途径下,后边任意途径或许参数
      }, 
      { 
          "appID": "D1I2O3P3PP.com.example.enterprise", 
          "paths": [ "/weixin/*","/wechat/10000000/*", /wx/10010/* ] 
      }
    ]
  }
}

留意上面里边的每一个 path 不应当重复,这个或许被运用到多个运用中

假如 teamId 还是不知道,登陆一下开发者账号,下面的位置,或许翻开钥匙串,查看证书,就在咱们证书里边也有

flutter-支付宝、微信支付分享 与 ios UniversalLink

2、将 apple-app-site-association 放到服务器

上面的 apple-app-site-association 文件,咱们需求将其放到咱们的服务器中的根目录.well-known 目录(引荐这个,默许先拜访这个目录)下

例如:
`https://host/.well-known/apple-app-site-association`  
`https://host/apple-app-site-association`
另外
iOS会先恳求`.well-known`的域名
`apple-app-site-association`只会在APP第一次发动的时分恳求一次,
因而文件的任何更新的验证都需求 APP 重新装置或 App Store 更新

假如说 apple-app-site-association为了找到咱们的文件 paths里边设置的途径名便是为了区别app,因而,不同appIdpaths也应当不一样,paths 能够取多个的目的是多个途径都能指向咱们的同一个 app

留意微信运用咱们的 links 的时分,会在咱们途径后边拼接参数,因而,单个 path 后边有必要使用通配符,即运用 /* 收尾

3 设置 Associated Domains

进入开发账号,进入 Identifiers,设置咱们 appIdentifiers 对应的 Associated Domains,加完后,记住更新咱们的 profiles描述文件

然后 app项目装备 加入 Associated Domains,如下所示,需求 applinks: 开头,后边是咱们的域名 host,例如:www.baidu.commail.qq.com(一般app会用子域名,就像腾讯一样)

flutter-支付宝、微信支付分享 与 ios UniversalLink

4、填写 UniversalLink

host / path便是咱们的 UniversalLink 链接了,例如

假定咱们的域名是 www.baidu.com
//这便是咱们的 UniversalLink,途径 wechat 专门给微信运用的
//结尾一定要加上 / ,微信要在后边拼参数传递, 域名 + 途径(wechat) + /
https://www.baidu.com/wechat/
//这便是咱们qq运用的,域名 + 途径(qq) + /
https://www.baidu.com/qq/
//假如咱们的域名是 mail.qq.com,域名 + 途径(qq) + /
https://mail.qq.com/qq/

验证咱们的QQ、微信APP是否支撑

验证当时版别 QQ 是否支撑Universal Link,验证地址:qm.qq.com

验证当时微信版别是否支撑Universal Link,验证地址:help.wechat.com/app/

下面是测验成果,我的手机是支撑的

flutter-支付宝、微信支付分享 与 ios UniversalLink

原生的部分处理

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        NSURL  *webpageURL = userActivity.webpageURL;
        if(webpageURL && [TencentOAuth CanHandleUniversalLink:webpageURL]) { 
            // QQ
            return [QQApiInterface handleOpenUniversallink:webpageURL delegate:self] || [TencentOAuth HandleUniversalLink:webpageURL];
        }else if ([webpageURL.absoluteString hasPrefix:[NSString stringWithFormat:@"https://app.yourDomain.com/test/%@", WeChatAppId]]){
            // 微信
            if([WXApi handleOpenUniversalLink:userActivity delegate:self]){
            }else{
                [WXApi handleOpenURL:webpageURL delegate:self];
            }
            return YES;
        }
        // 编写咱们自己的判别逻辑
    }
    return YES;
}

最后

部分内容无法贴出,或许实际 demo 部分无法真正跳转走动,需求自行走流程,更新一下

开来自己着手测验一下吧