解决iOS微信H5支付跳转微信后不返回App问题(Swift-WKWebview)

本文详细介绍了如何优化微信H5支付流程,特别是针对支付完成后返回App的问题进行了深入探讨。通过拦截请求、修改重定向URL及处理白屏现象等步骤,实现了良好的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

微信支付其实在日常的开发中是经常接触的,但是在H5跳转问题上有或多或少的坑本,其中最难解决的是支付完成后返回App,并且返回App后白屏的解决。本次使用的是Swift:WKWebview OC 和WebView同理

建议阅读时间:10mins


  • 问题分析

    正常的H5支付流程如下

    按照上面的支付流程会出现 App -> 微信 -> 支付 -> 点击 完成 -> safari访问redirect_url设置的URL,这种流程其实用户体验是有点糟糕的,我们期望是 App -> 微信 -> 支付 -> 点击 完成 -> App访问redirect_url设置的URL

    问题分析到上面已经非常明了了,无非就是拦截处理,下面讲讲具体的实施。

  • 问题分析

    根据上面的分析解决的思路应该非常的清晰

    拦截请求

    首先在decidePolicyFor 回调里拦截支付的请求拦截的字符串:https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb 如果包含了该链接做如下处理,isload变量是控制是否是第一次没有修改redirect_url参数的请求防止重复请求

      if urlString?.range(of: "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb") != nil && !self.isload{
          if let mUrlStr = urlString{
              let array : Array = mUrlStr.components(separatedBy: "redirect_url=")
              self.redirect_url =  array[1]
              let rs = "\(WXH5SchemeURL)://".urlEncoded()
              let mNewUrl = array[0] + "redirect_url=\(rs)"
              let newURLS = URL(string: mNewUrl)
              var mRequest = URLRequest.init(url: newURLS!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)
              mRequest.setValue("\(WXH5SchemeURL)://", forHTTPHeaderField: "Referer")
              webView.load(mRequest)
              self.isload = true
              decisionHandler(.cancel)
              return
          }
      }
      self.isload = false
      decisionHandler(.allow)
      }
    复制代码
    拦截weixin://wap/pay? 打开微信
      if urlString?.range(of: "weixin://wap/pay?") != nil{
          if let mUrlStr = urlString{
              let openWX = URL(string: mUrlStr)
              if (UIApplication.shared.canOpenURL(openWX!)){
                  if #available(iOS 10.0, *){
                      UIApplication.shared.open(openWX!, options: [UIApplicationOpenSettingsURLString:false], completionHandler: nil)
                  }else{
                      UIApplication.shared.openURL(openWX!)
                  }
              }
              decisionHandler(.cancel)
              return
          }
      }
    复制代码

    这一步的话没甚好介绍的就是拦截打开微信支付即可。

    在项目设置Scheme链接用于支付完后返回App

    具体操作如下图

    到这一步已经成功了一大半了,你会发现现在支付成功后能返回App了但是返回的时候webView是白屏。白屏其实就是网页没有任何请求导致的,接下来我们就要使用上步提前记录好后台给的redirect_url的url了。

    在AppDelegate里监听url.scheme的值

    在AppDelegate里监听url.scheme的值是否为我们之前设置好的xxxx.com 如果是xxxx.com 发起通知 通知webview加载提前记录好的redirect_url的url了

      if ([url.scheme rangeOfString:@"quanzidian.net"].length!=0) {
      	[NSNotificationCenter defaultCenter] postNotificationName:@"WX_H5_PAY" object:nil];
      	return YES;
      }
    复制代码

    在wkWebView接收通知

      NotificationCenter.default.addObserver(self, selector: #selector(goBackWhitWXPay), name: NSNotification.Name(rawValue: "WX_H5_PAY"), object: nil)
    复制代码

    重新刷新WKWebview

      @objc func goBackWhitWXPay(){
      	if !self.redirect_url.isEmpty{
          	self.request = URLRequest(url: URL(string: self.redirect_url)!)
          	redirect_url = ""
      	}
      }
    复制代码

    项目使用的oc/Swift 混编有些地方和你使用的语言不一致时请自行模仿做写。

    到这里微信H5支付所有的问题就完美解决了 唯一的坑就是在截取请求时,重写redirect_url时注意一定时授权的URL://的协议。

    更多详情请访问https://siterzzz.github.io

<think>我们正在讨论在App中直接调起支付宝或微信支付跳转。根据提供的引用,我们可以总结如下: 1. 引用[1]提到,在Android WebView中调起支付宝时,正确的URL协议应该是`platformapi/startapp`,而作者发现自己的代码中使用了错误的协议(`platformapi/startapp` 与 `platformapi/startApp` 的大小写问题?)导致无法跳转。这提示我们,在实现支付宝调起时,需要确保使用正确的协议和大小写。 2. 引用[2]展示了调用支付宝商家付款签约接口的示例,其中包含了一个签约地址,该地址用于引导用户到支付宝页面进行签约。但用户的需求是“跳转直接拉起支付”,因此我们需要的是在用户已经签约的情况下,通过后台接口生成支付订单,然后在App端直接调用支付宝或微信的SDK完成支付,而需要跳转支付宝或微信App。 然而,需要注意的是,微信支付支付支付移动端(尤其是Android和iOS)通常有两种方式: - 方式一:通过H5页面调起支付(需要跳转到浏览器或支付宝/微信App- 方式二:通过集成官方SDK,在App内直接调起支付(无需跳转,但需要用户安装对应的支付App) 用户的需求是“跳转”,所以我们应该采用方式二,即使用官方SDK进行支付。 ### 实现步骤 #### 支付App支付跳转) 1. **集成支付宝SDK**:在项目中添加支付宝SDK依赖(Android和iOS分别集成)。 2. **生成订单信息**:商户后台调用支付宝的接口(如`alipay.trade.app.pay`)生成订单信息(一个签名字符串)。 3. **调起支付支付**:在App端使用SDK提供的方法,传入订单信息,直接调起支付支付- Android示例: ```java PayTask alipay = new PayTask(activity); Map<String, String> result = alipay.payV2(orderInfo, true); ``` - 注意:支付结果通过异步回调返回。 #### 微信App支付跳转) 1. **集成微信SDK**:在项目中添加微信SDK依赖(同样需要区分平台)。 2. **生成预支付订单**:商户后台调用微信支付统一下单接口(`pay/unifiedorder`)生成预支付交易会话标识(prepay_id)。 3. **调起微信支付**:在App端使用SDK提供的方法,传入支付参数(包括appId、partnerId、prepayId、nonceStr、timeStamp、package、sign等),直接调起微信支付- Android示例: ```java IWXAPI api = WXAPIFactory.createWXAPI(context, APP_ID); PayReq request = new PayReq(); request.appId = APP_ID; request.partnerId = partnerId; request.prepayId = prepayId; request.packageValue = "Sign=WXPay"; request.nonceStr = nonceStr; request.timeStamp = timeStamp; request.sign = sign; api.sendReq(request); ``` - 支付结果通过微信的`WXPayEntryActivity`接收回调。 ### 注意事项 1. **支付宝的URL协议问题**:在H5调起支付宝时,URL协议必须正确(如`platformapi/startapp`)。但如果是使用SDK方式,则需要关心这个。 2. **微信支付的特殊性**:微信支付要求App必须注册一个回调Activity(`WXPayEntryActivity`)来处理支付结果。 3. **用户未安装支付App**:如果用户没有安装支付宝或微信,则无法调起支付,需要做降级处理(例如提示用户安装或改为H5支付)。 ### 相关问题 1. 如何判断用户是否安装了支付宝或微信App? 2. 支付宝和微信支付在集成SDK时有哪些常见问题? 3. 支付结果如何安全地通知到商户服务器? [^1]: Android WebView调起支付微信支付。很奇怪的是网上搜的跳支付宝判断的url都是platformapi/startapp 然后发现我的会跳,一开始还以为是适配,结果debug发现是platformapi/startApp 其他的就好了 [^2]: 微信中直接唤起支付宝商家付款。1. 调用支付宝的商家付款签约接口,读取签约返回的内容,里面有签约地址,内容类似 https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=12021004130639609&biz_content=%7B%22access_params%22%3A%7B%22channel%22%3A%22ALIPAYAPP%22%7D%2C%22agreement_effect_type%22%3A%22DIRECT%22%2C%22external_agreement_no%22%3A%222024040709110931266%22%2C%22period_rule_params%22%3A%7B%22execute_time%22%3A%222024-04-07%22%2C%22period%22%3A30%2C%22period_type%22%3A%22DAY%22%2C%22single_amount%22%3A%220.01%22%2C%22total_amount%22%3A%220.12%22%2C%22total_payments%22%3A12%7D%2C%22personal_product_code%22%3A%22CYCLE_PAY_AUTH_P%22%2C%22product_code%22%3A%22GENERAL_WITHHOLDING%22%2C%22sign_scene%22%3A%22INDUSTRY%7CDEFAULT_SCENE%22%2C%22third_party_type%22%3A%22PARTNER%22%7D&charset=UTF8&format=json&method=alipay.user.agreement.page.sign&notify_url=http%3A%2F%2F111.231.77.235%3A9080%2Fmgrapi%2Fga....</think>### 在App中直接调起支付宝/微信支付跳转方案) #### 1. **支付支付App内直调)** **核心原理**:使用支付宝的`alipays`协议 + `intent`方案 **实现步骤**: 1. **生成支付链接**: 服务端调用支付宝接口(如`alipay.trade.app.pay`)生成支付参数`orderInfo`(需包含`alipays://platformapi/startapp`协议头) ```js alipays://platformapi/startapp?appId=20000067&url=encodeURIComponent(orderInfo) ``` 2. **Android端调起**: ```java Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("alipays://platformapi/startapp?appId=20000067&url=" + URLEncoder.encode(orderInfo))); startActivity(intent); ``` **关键点**: - 必须使用`alipays://platformapi/startapp`协议头[^1] - 支付参数需进行URL编码 3. **iOS端调起**: ```swift if let url = URL(string: "alipays://platformapi/startapp?appId=20000067&url=\(orderInfo.addingPercentEncoding(...))") { UIApplication.shared.open(url, options: [:]) } ``` #### 2. **微信支付App内直调)** **核心原理**:通过微信SDK的`WXLaunchMiniProgramReq`唤起支付 **实现步骤**: 1. **集成SDK**:添加微信SDK依赖(Android需配置`WXEntryActivity`) 2. **调起支付**: ```java // Android示例 IWXAPI api = WXAPIFactory.createWXAPI(context, APP_ID); WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req(); req.userName = "gh_xxxxxx"; // 微信小程序原始ID req.path = "pages/pay?order_id=xxx"; // 支付路径 req.miniprogramType = WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_PREVIEW; api.sendReq(req); ``` 3. **参数配置**: - `userName`:固定为微信分配的商户小程序ID - `path`:携带支付订单参数(需服务端预生成) #### 3. **通用注意事项** 1. **URL协议校验**: - 支付宝:必须使用`alipays://`而非`alipay://` - 微信:需在`AndroidManifest.xml`声明`<data android:scheme="weixin"/>`[^2] 2. **降级方案**: ```java try { // 尝试调起支付 } catch (Exception e) { // 跳转应用商店下载 Uri marketUri = Uri.parse("market://details?id=com.tencent.mm"); startActivity(new Intent(Intent.ACTION_VIEW, marketUri)); } ``` 3. **安全校验**: - 支付参数需服务端签名(防止篡改) - 支付结果通过服务端异步通知验证 #### 4. **最新限制说明** - **支付宝**:2023年起新签约商户需开通「小程序支付」能力 - **微信**:必须通过商户小程序跳转(原生App需关联小程序) - **iOS限制**:需在`Info.plist`声明协议: ```xml <key>LSApplicationQueriesSchemes</key> <array> <string>alipays</string> <string>weixin</string> </array> ``` > ⚠️ **实测建议**: > 支付宝成功率:`alipays://platformapi/startapp?appId=20000067` > `alipay://` > 微信兼容性:SDK版本需≥6.7.3(支持小程序跳转)[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值