微信H5支付——通过deeplink方式进行支付

3,049 阅读2分钟

1.背景

微信H5支付方式无非是MWEB和JSAPI,而MWEB就是在非微信浏览器下跳转至支付中间页,进而唤起微信客户端进行微信支付。

但是问题来了,如果你使用京东或美团的微信支付,你会发现,点击即可唤起微信客户端进行支付,而支付中间页消失了

不得不说,这大大提高了用户的支付体验。而这正是通过deeplink方式进行支付。

2.如何实现deeplink

其实deeplink方式已经被官方弃用了,甚至官方不推荐,能继续使用这个功能的,懂得都懂。感兴趣的话可以理解下。

所以网上微信deeplink支付方式描述甚少,不过有幸找到一篇# 微信支付开发-- H5支付。其中介绍了deeplink支付方式。总结如下:

  • deeplink前缀:weixin://wap/pay?

  • deeplink参数说明如下所示:

字段名变量名必填类型示例值描述
随机字符串noncestrString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS随机字符串,不长于32位。
订单详情扩展字符串packageString(32)WAP扩展字段,固定填写WAP
预支付交易会话标识prepayidString(64)wx201410272009395522657a690389285100微信统一下单接口返回的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
签名signString(32)C380BEC2BFD727A4B6845133519F3AD6签名,现在获取方法已经没有了
  • deeplink生成步骤:
    • 步骤1:按URL 格式组装参数, $value 部分进行URL 编码,生成string1:
string1 = 'noncestr:' + Urlencode($value1) + '&package:' + Urlencode($value2) + ...
    • 步骤2:对string1作整体的Urlencode,生成string2:
string2 = Urlencode(stirng1)
    • 步骤3:拼接前缀,生成最终的deeplink

3.通过爬虫的方式提取deeplink

支付中间页唤起微信客户端,实质就是同过deeplink

为何这么说呢?因为浏览器H5页面唤起应用的方式就是通过一个deeplink,它偏离不了这个方向,如下所示。

image.png

所以我们可以通过爬虫用正则匹配出中间页的deeplink。如下仅供参考,请谨慎使用。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class payUrl {
  private static String readUrl(String url) throws Exception{
    String regex = "weixin:\/\/wap\/pay?.[^\x{4e00}-\x{9fa5}-\"]+"; // 定义好匹配规则
    Pattern pattern = Pattern.compile(regex);

    URL payUrl = new URL(url);
    URLConnection con = payUrl.openConnection();
    con.setRequestProperty("Referer", "https://..."); // 加referer防盗链,必须是你申请的支付白名单

    BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"UTF-8"));
    String result = "";
    String realLineStr = null;
    while((realLineStr = br.readLine()) != null){
      Matcher matcher = pattern.matcher(realLineStr); // 一行行查找
      if(matcher.find()){
        result = matcher.group(); // 匹配deeplink
        break; // 跳出循环
      }
    }
    return result;
  }

  public static void main(String[] args) throws Exception {
    String url =
        "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?...";
    System.out.println(readUrl(url));
  }
}