# 微信支付

# 开始


微信支付的场景有很多种,付款码支付、Native支付、JSAPI支付、APP支付、H5支付、小程序支付。
此处展开讨论2种。

  • H5支付
  • JSAPI支付

# H5支付

H5支付主要是在手机、ipad等移动设备中通过浏览器来唤起微信支付的支付产品。

# JSAPI支付

JSAPI支付是用户在微信中打开商户的H5页面,商户在H5页面通过调用微信支付提供的JSAPI接口调起微信支付模块完成支付。应用场景有:
◆ 用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付
◆ 用户的好友在朋友圈、聊天窗口等分享商家页面连接,用户点击链接打开商家页面,完成支付
◆ 将商户页面转换成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

# 实例

创建订单后,后台会返回trade_info,

如果是H5支付,
const { mwebUrl } = trade_info;
const redirectUrl = injectQuery(window.location.href, { orderSn: appOrderSn });
window.location.replace(${mwebUrl}&redirect_url=${encodeURIComponent(redirectUrl)});
当支付成功后,微信会按照redirect_url返回,这时候在url上面拼接的orderSn,就会存在,然后做一个modal,用户点击已完成付款,就查询订单状态,
用户点击暂未付款,隐藏modal。


如果是JSAPI支付,
const tradeInfo = Object.assign({}, trade_info, options);
tradeInfo.timestamp = tradeInfo.timestamp || tradeInfo.timeStamp;

const signature = await weixinService.getWeixinSignature();
window.wx.config(signature);
window.wx.chooseWXPay(tradeInfo);
上面的options里面是包含success,cancel,fail三个方法的对象

# 依赖

link.ts

import qs from 'qs';
import { omit } from 'lodash';

interface QueryDict {
  [key: string]: any;
}

/**
 * 增加链接参数
 *
 * @param {string} href 原始链接
 * @param {string[]} keys 剔除字段
 * @return {string} 新链接
 */
export const injectQuery = (href: string, queries: QueryDict): string => {
  const current = document.createElement('a');
  current.href = href;

  const { pathname, origin, search } = current;
  const parsed = qs.parse(search, { ignoreQueryPrefix: true });
  const query = { ...parsed, ...queries };

  if (Object.keys(query).length === 0) {
    return `${origin}${pathname}`;
  }

  return `${origin}${pathname}?${qs.stringify(query)}`;
};

/**
 * 删除链接参数
 *
 * @param {string} href 原始链接
 * @param {string[]} keys 剔除字段
 * @return {string} 新链接
 */
export const omitQuery = (href: string, keys: string[]): string => {
  const current = document.createElement('a');
  current.href = href;

  const { pathname, origin, search } = current;
  const parsed = qs.parse(search, { ignoreQueryPrefix: true });
  const query = omit(parsed, keys);

  if (Object.keys(query).length === 0) {
    return `${origin}${pathname}`;
  }

  return `${origin}${pathname}?${qs.stringify(query)}`;
};

# 关联

# 微信支付weixinjsbridge.invoke()和wx.choosewxpay的区别

  • weixinjsbridge.invoke()出现的版本更早 无需引用jssdk 无需wx.config方法注入 需要参数appId 使用回调 有详细的说明
  • 而wx.choosewxpay出现的版本比较晚 需要jssdk注入 不需要参数appId 使用回调 只有SUCCESS 和 FAIL没有具体的说明
  • weixinjsbridge.invoke()是微信浏览器的内置方法
  • 其实wx.choosewxpay在引用的微信jssdk文件中 也调用了weixinjsbridge.invoke() 是对weixinjsbridge.invoke() 的再次封装
  • 综上所诉 这是微信前后设计的不同方法的支付 还是weixinjsbridge更方便一些 有具体的失败回调

# 参考

  1. 【微信支付】H5支付开发文档 (opens new window)
  2. 微信支付weixinjsbridge.invoke()和wx.choosewxpay的区别 (opens new window)