评论

使用「官方小程序发券插件」发送「商家券」签名的二三事儿

微信支付官方「小程序发券插件」(≤1.1.3) 的商家券数据签名,单独抽离出数据转换函数,配合使用云开发NodeJS环境,让签名不再麻烦。

官方「小程序发券插件API」(≤1.1.3) 签名概要

先来看看「小程序发券插件」所需参数,yaml格式如下:

type: object
required:
  - send_coupon_params
  - sign
  - send_coupon_merchant
properties:
  bindcustomevent:
    type: string
    description: 自定义事件
  send_coupon_params:
    type: array
    description: 发券参数
    items:
      type: object
      required:
        - stock_id
        - out_request_no
      properties:
        stock_id:
          type: string
          description: 批次号
          example: abc123
        out_request_no:
          type: string
          description: 发券凭证
          example: '1234567'
  sign:
    type: string
    description: 签名
    example: 9A0A8659F005D6984697E2CA0A9CF3B79A0A8659F005D6984697E2CA0A9CF3B7
  send_coupon_merchant:
    type: string
    description: 发券商户号
    example: '10016226'

转换成数据结构即:

{
  bindcustomevent: 'getcoupon',
  send_coupon_params: [
    {out_request_no:'1234567',stock_id:'abc123'}
  ],
  send_coupon_merchant: '10016226'
}

签名时,文档说明是需要把上述参数,以key下标从0开始拉平成1维对象,即:

{
  out_request_no0: '1234567',
  stock_id0: 'abc123',
  send_coupon_merchant: '10016226'
}

参数key下标以index记录了顺序,最大支持十张券刚好是0-9,有点儿 Array.prototype.flatMap() 的味道,但不完全是。

转换函数如下:

// 可单独抽离成模块
exports.busiFavorFlat = ({send_coupon_merchant, send_coupon_params = []} = {}) => {
  return {
    send_coupon_merchant,
    ...send_coupon_params.reduce((des, row, idx) => (Object.keys(row).map(one => des[`${one}${idx}`] = row[one]), des), {}),
  }
}

使用如下:

const responder = {
  send_coupon_params: [
    {out_request_no:'1234567',stock_id:'abc123'},
    {out_request_no:'7654321',stock_id:'321cba'},
  ],
  send_coupon_merchant: '10016226'
}

const waitToSign = busiFavorFlat(responder)

v2版nodejs签名代码为例,把以上输出,代入签名,大功告成,如下~

// let key = 'exposed_your_key_here_have_risks'
responder.sign = signHmacSha256(toSignString(ksort(waitToSign), key), key)
// console.info(responder.sign)
// 20FB971D442A119C85CA1A49DBDEA61A14944D98AFC1D2B040030C5C8792A83A
// 签名及数据结构,以JSON串发送给小程序端
// bindcustomevent是前端事件,由前端决定就好
// server.response.toMiniProgram(JSON.stringify(responder))
最后一次编辑于  2020-07-21  
点赞 4
收藏
评论
登录 后发表内容