# 腾讯微卡机具支付对接指引

# 基础方案

  1. 机具出厂前,需要提供机具编号给到我方,由微校团队在支付管理系统提前录入机具信息,并返回指纹到对接方。

  2. 机具厂商提供序列号列表给微校生成对应机具指纹,并将指纹信息写入机具内或维护在机具网关中,请求微校接口时根据指纹完成鉴权

# 接入方式

提供两种接入方式,一种是GRPC,另外一种是HTTPS,厂商可以根据自己实际开发情况选择接入方式。

  • GRPC

需要特殊申请,请联系对接的商务人员

  • HTTPS

请求方式:POST 接口前缀:

key value 描述
api_prefix https://payapi.weixiao.qq.com 生产环境

# 签名算法

  • 算法采用有AES256/CFB128/NOPADDING加密模式,IV为硬件指纹的前16位,KEY为硬件指纹,加密内容为随机串:当前时间戳:固件版本号 nonce:timestamp:version ,加密后对密文进行hex 操作。

  • 注意每次请求都必须重新计算签名,后台会根据时间和随机串检测是否重复请求,若被判断为重复请求则会直接拒绝的。

参数名 类型 必填 描述
nonce string Y 随机串(10位)
timestamp int Y unix时间戳(10位)
version string Y 调用方版本号,用于提示升级(建议纯数字)

GO实现

func buildWxToken(deviceId, Key string) (string, error) {
	time1 := time.Now().Unix()
	timeStr := strconv.FormatInt(time1, 10)
	fmt.Println("Key", Key, Key[:15])
	version := "Ver1.0"
	noce := "abcdefghi"
	token, err := encrypt([]byte(Key), []byte(Key[:16]), []byte(fmt.Sprintf("%s:%s:%s",noce,timeStr,version)))
	if err != nil {
		return "", err
	}
	return "WxToken " + deviceId + ":" + token, nil
}
func encrypt(key, iv, data []byte) (string, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", err
	}
	stream := cipher.NewCFBEncrypter(block, iv)
	ciphertext := make([]byte, len(data))
	stream.XORKeyStream(ciphertext, data)

	return hex.EncodeToString(ciphertext), nil
}
func main() {
	deviceId := ""//设备编号
	key:=""//32位机具指纹信息
	fmt.Println(buildWxToken(deviceId,key))
}

# HTTPS协议

在请求API时需要把加密后的字段放到header中,对应的字段为:Authorization,字段规则为 WxToken 机具id:签名

GO实现

// customCredential ⾃定义认证
package main
import "context"
type customCredential struct{}
func (c customCredential) GetRequestMetadata(ctx context.Context, uri...string) (map[string]string, error) {
    return map[string]string{
		"Authorization": "WxToken wx_1:ec551f89f56e20e12a7612202879b5a90a66aeb2e6",
	}, nil
}
func (c customCredential) RequireTransportSecurity() bool {
	return true
}

PHP实现

<?php
//$data为需要加密的字符串
function encrypt($Key, $iv, $data){
 $sign = openssl_encrypt($data, 'AES-256-CFB',$Key, OPENSSL_RAW_DATA ,
$iv);
 $sign = bin2hex($sign);
 return $sign;
}

# GRPC协议

在请求API时需要把加密后的字段放到metadata中,对应的字段为:Authorization,字段规则为 WxToken 机具id:签名

Go的实现:

package main
import "context"
type customCredential struct{}
func (c customCredential) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
	return map[string]string{"Authorization": "WxToken wx_1:ec551f89f56e20e12a7612202879b5a90a66aeb2e6"}, nil
}
func (c customCredential) RequireTransportSecurity() bool {
	return true
}