GO 微信支付V3SDK回调踩坑

通过微信官网提示安装sdk外部库

SDK,工具 | 微信支付商户平台文档中心

下面只讲解微信支付回调部分

先成功下一单微信支付拿到支付回调的数据,方便后续调试

因为在go里面打印请求参数不方便我使用的php打印全部参数, 圈起来的部分是我们需要用到的数据

GO 微信支付V3SDK回调踩坑_第1张图片

第一步编写代码:

只展示解密部分解密代码示例:

// 微信支付回调逻辑处理
func (orderPayService *OrderPayService) WxOrderPayCallback(c *gin.Context) (err error) {

	notifyReq, err := weixin.Decrypt(c)
	if err != nil {
		fmt.Println("微信回调参数解密失败:", err)
		return err
	}

	//解析Plaintext参数,这里面可以拿到订单的基本信息
	var data = []byte(notifyReq.Resource.Plaintext)
	var result map[string]interface{}
	err = json.Unmarshal(data, &result)
	if err != nil {
		fmt.Println("JSON转换失败:", err)
		return err
	}
	// 处理通知内容
	fmt.Println("解密结果", notifyReq)
	fmt.Println("解密结果Plaintext", result)

	
	return nil
}

// 微信支付回调解密
func Decrypt(c *gin.Context) (notifyReq *notify.Request, err error) {
	var (
		mchID                      = global.GVA_CONFIG.WeiXin.MchID                      // 商户号
		mchCertificateSerialNumber = global.GVA_CONFIG.WeiXin.MchCertificateSerialNumber // 商户证书序列号
		mchAPIv3Key                = global.GVA_CONFIG.WeiXin.MchAPIv3Key                // 商户APIv3密钥
		privateKeyPath             = "./resource/wxPay/apiclient_key.pem"                // 商户私钥文件
	)

	ctx := c             //这个参数是context.Background()
	request := c.Request //这个值是*http.Request

	// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
	mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
	if err != nil {
		return nil, err
	}

	// 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器
	err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(ctx, mchPrivateKey, mchCertificateSerialNumber, mchID, mchAPIv3Key)
	if err != nil {
		return nil, err
	}
	// 2. 获取商户号对应的微信支付平台证书访问器
	certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)
	// 3. 使用证书访问器初始化 `notify.Handler`
	handler := notify.NewNotifyHandler(mchAPIv3Key, verifiers.NewSHA256WithRSAVerifier(certificateVisitor))

	transaction := new(payments.Transaction)
	notifyReq, err = handler.ParseNotifyRequest(ctx, request, transaction)
	// 如果验签未通过,或者解密失败
	if err != nil {
		fmt.Println(err)
		//return
	}
	// 处理通知内容
	fmt.Println(notifyReq.Summary)
	fmt.Println(transaction.TransactionId)
	// 如果验签未通过,或者解密失败
	if err != nil {
		return nil, err
	}

	return notifyReq, nil
}

第二步:

组装回调参数模拟回调请求,通过之前获取到的回调参数组装请求数据

GO 微信支付V3SDK回调踩坑_第2张图片

 值得注意的是php打印出来的参数需要去掉http且下划线换成中划线

HTTP_WECHATPAY_TIMESTAMP =>WECHATPAY-TIMESTAMP

微信传过来的数据是(Wechatpay-Timestamp)可以不区分大小写

接下来就可以模拟数据调试回调接口了。

闭坑:

1、回调参数有一个时间戳,超时的订单验证会报错,切记不可更改请求里的Wechatpay-Timestamp时间戳,因为加密使用这个参数加密的改了之后一定是验证失败的

GO 微信支付V3SDK回调踩坑_第3张图片

修改保存会提示下面的错误,不允许更改,修改不生效

GO 微信支付V3SDK回调踩坑_第4张图片 解决方案直接在终端vim命令行到外部库文件夹去改这个配置扩大超时时间,改完重启一下项目就生效了,这样一来这个订单的参数可以一直模拟使用

GO 微信支付V3SDK回调踩坑_第5张图片

 2、模拟请求的参数一定要不能有空格,不能有换行,不然解密不成功

GO 微信支付V3SDK回调踩坑_第6张图片

 在SDK中他会组装成下面的样子

GO 微信支付V3SDK回调踩坑_第7张图片

 下面例子是异常的参数格式,比如带了空格或者换行

GO 微信支付V3SDK回调踩坑_第8张图片

GO 微信支付V3SDK回调踩坑_第9张图片

继续运行就会报错(verify signature with public key err:crypto/rsa: verification error)

GO 微信支付V3SDK回调踩坑_第10张图片 如果一切顺利我们就可以正确解析出回调的数据后续使用

GO 微信支付V3SDK回调踩坑_第11张图片

你可能感兴趣的:(Go,微信,golang,后端)