1.引入的包

import (
    "context"
	"crypto/x509"
	"encoding/json"
    "github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
	wxutils "github.com/wechatpay-apiv3/wechatpay-go/utils"
)

2.建立请求vx的client

type OrderService struct{}

func (orderService *OrderService)SetUp()(opt []core.ClientOption, err error){
	//商户号
	mchID := global.GVA_CONFIG.VX.Payid
	//商户证书序列号
	mchCertSerialNumber := global.GVA_CONFIG.VX.CerSerial
	//商户私钥文件路径
	privateKeyPath := global.GVA_CONFIG.VX.PrivateKey
	//平台证书文件路径
	wechatCertificatePath := global.GVA_CONFIG.VX.Certificate

	// 加载商户私钥
	privateKey, err := wxutils.LoadPrivateKeyWithPath(privateKeyPath)
	if err != nil {
		fmt.Printf("load private err:%s", err.Error())
		return nil, err
	}
	// 加载微信支付平台证书
	wechatPayCertificate, err := wxutils.LoadCertificateWithPath(wechatCertificatePath)
	if err != nil {
		fmt.Printf("load certificate err:%s",err)
		return nil, err
	}
	//设置header头中authorization信息
	opts := []core.ClientOption{
		option.WithMerchantCredential(mchID, mchCertSerialNumber, privateKey), // 设置商户相关配置
		option.WithWechatPayCertificate([]*x509.Certificate{wechatPayCertificate}), // 设置微信支付平台证书,用于校验回包信息用
		option.WithoutValidator(),//跳过证书的效验
	}
	return opts, nil
}

3.生成预支付请求,并生成签名信息


func (orderService *OrderService)VxCreateOrder(openid string,mineOrder Order)(error, map[string]string) {
	// 初始化客户端
	ctx := context.TODO()
	opts, err := orderService.SetUp() //第二段代码中的函数
	if err != nil {
		return err, nil
	}
	client, err := core.NewClient(ctx, opts...)
	//_, err = core.NewClient(ctx, opts...)
	if err != nil{
		fmt.Printf("init client err:%s",err)
		return err, nil
	}
	//设置请求地址
	URL := "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"
	//设置请求信息,此处也可以使用结构体来进行请求
	mapInfo := map[string]interface{}{
		"mchid": global.GVA_CONFIG.VX.Payid,
		"out_trade_no": mineOrder.OrderId,
		"appid": global.GVA_CONFIG.VX.AppId,
		"description": mineOrder.BuyGoodsInfo(),
		"notify_url": global.GVA_CONFIG.VX.NotifyUrl,
		"amount": map[string]interface{}{
			"total": mineOrder.CurPriceCent(),
			"currency": "CNY",
		},
		"payer": map[string]interface{}{
			"openid": openid,
		},
	}
	//fmt.Print(URL,mapInfo)
	// 发起请求
	response, err := client.Post(ctx, URL, mapInfo)
	if err != nil{
		fmt.Printf("client post err:%s",err)
		return err, nil
	}
	// 校验回包内容是否有逻辑错误
	err = core.CheckResponse(response.Response)
	if err != nil{
		fmt.Printf("check response err:%s",err)
		return err, nil
	}
	// 读取回包信息
	body, err := ioutil.ReadAll(response.Response.Body)
	if err != nil{
		fmt.Printf("read response body err:%s",err)
		return err, nil
	}
	return nil, orderService.MakeReturnMsg(body)
}


func (orderService *OrderService)MakeReturnMsg(body []byte)map[string]string{
	var prepaymap map[string]string
	_ = json.Unmarshal(body,&prepaymap)

    // 时间戳
	timeStamp:=strconv.FormatInt(time.Now().Unix(),10)
	// 任意长度的随机字符串即可
    nonceStr:=comFunc.RandStr(16)
	packageStr:="prepay_id="+prepaymap["prepay_id"]

	sb := strings.Builder{}
	sb.WriteString(global.GVA_CONFIG.VX.AppId+"\n")
	sb.WriteString(timeStamp+"\n")
	sb.WriteString(nonceStr+"\n")
	sb.WriteString(packageStr+"\n")

	privateKey, err := wxutils.LoadPrivateKeyWithPath(global.GVA_CONFIG.VX.PrivateKey)
	if err != nil{
		log.Println("load err:",err)
	}
	sign,err:= wxutils.SignSHA256WithRSA(sb.String(), privateKey)
	if err != nil{
		log.Println("sign error :",err)
	}
	resultMap:=make(map[string]string)
	resultMap["timeStamp"]=timeStamp
	resultMap["nonceStr"]=nonceStr
	resultMap["package"]=packageStr
	resultMap["signType"]="RSA"
	resultMap["paySign"]=sign
	resultMap["prepay_id"]=prepaymap["prepay_id"]

	return resultMap
}

4.收到vx的订单回传信息,注意是使用post回传的

// 使用gin的外部接口
func (orderApi *OrderApi) NotifyOrder(c *gin.Context) {
	body,_ := ioutil.ReadAll(c.Request.Body)
	b,s := orderService.DecodeNotify(body)
	log.Println(b,s)
	response.OkWithMessage("收到", c)
}

// 直接使用接口解密
func (orderService *OrderService)DecodeNotify(body []byte)(bool, string){
	var prepaymap map[string]interface{}
	_ = json.Unmarshal(body,&prepaymap)

	var prepaymap2 = prepaymap["resource"].(map[string]interface{})
	nonce := prepaymap2["nonce"].(string)
	associatedData := prepaymap2["associated_data"].(string)
	ciphertext := prepaymap2["ciphertext"].(string)

	apiV3key := global.GVA_CONFIG.VX.Apiv3Key
	tx,err := wxutils.DecryptAES256GCM(apiV3key, associatedData,nonce,ciphertext)
	if err != nil{
		log.Println(err)
		return false,""
	}
	var datamap map[string]string
	_ = json.Unmarshal([]byte(tx),&datamap)
	return true, datamap["out_trade_no"]

}

*获取商家序列号,参考文档 证书查看

$ openssl x509 -in xxx_xxxx_cert.pem -noout -serial