Go语言对接微信支付与退款全流程指南

news2024/10/9 18:35:41

在互联网技术日益发展的今天,线上支付已成为不可或缺的一部分。作为一门简洁高效的编程语言,Go(又称Golang)凭借其强大的并发处理能力和高效性能,在后端开发领域越来越受到开发者的青睐。本文将详细介绍如何使用Go语言对接微信支付,并实现支付和退款功能,帮助开发者快速上手。

一、准备工作

在开始编写代码之前,你需要先准备好以下几项工作:

1、注册成为微信支付商户:如果你还没有微信支付商户账号,需要先前往微信支付商户平台完成注册。

2、获取必要的配置信息

  • 商户号 (MchId)

  • AppID (Appid)

  • API v3 密钥 (ApiV3Key)

  • 商户证书序列号 (MchSerialNo)

  • 私钥 (PrivateKey)

  • 支付通知地址 (NotifyUrl)

  • 退款通知地址 (RefundUrl)

3、安装第三方库:为了简化微信支付接口的调用,推荐使用github.com/go-pay/gopay这个库。可以通过go get命令安装:

go get github.com/go-pay/gopay

二、初始化微信支付客户端

首先,我们需要创建一个WechatPayService结构体来封装微信支付的相关操作。该结构体包含上下文、配置信息和微信支付客户端实例。

type WechatPayService struct {
	ctx       context.Context
	config    WechatPayConfig
	wechatPay *wechat.ClientV3
}

type WechatPayConfig struct {
	Appid       string
	Appid1      string
	MchId       string
	ApiV3Key    string
	MchSerialNo string
	PrivateKey  string
	NotifyUrl   string
	RefundUrl   string
}

接着,我们通过NewWechatPayService函数来初始化WechatPayService实例。

func NewWechatPayService(ctx context.Context, config WechatPayConfig) *WechatPayService {
	client, err := wechat.NewClientV3(config.MchId, config.MchSerialNo, config.ApiV3Key, config.PrivateKey)
	if err != nil {
		fmt.Println(err)
		return nil
	}
	err = client.AutoVerifySign()
	if err != nil {
		fmt.Println(err)
		return nil
	}
	client.DebugSwitch = gopay.DebugOn

	return &WechatPayService{
		ctx:       ctx,
		wechatPay: client,
		config:    config,
	}
}

此代码段中,我们通过NewClientV3方法初始化了微信支付客户端,传入商户号、证书序列号、API v3密钥和私钥等关键参数。为了保障支付的安全性,开启了自动验签功能。

三、实现支付功能

1. 付款时序图

2. 实现不同场景下的支付

WAP端支付

func (w *WechatPayService) WapPay(charge *Charge) (result string, err error) {
	amount := decimal.NewFromInt(charge.MoneyFee).DivRound(decimal.NewFromInt(1), 2).IntPart()
	expire := time.Now().Add(10 * time.Minute).Format(time.RFC3339)
	bm := make(gopay.BodyMap)
	bm.Set("appid", w.config.Appid).
		Set("mchid", w.config.MchId).
		Set("description", charge.Describe).
		Set("out_trade_no", charge.TradeNum).
		Set("time_expire", expire).
		Set("notify_url", w.config.NotifyUrl).
		SetBodyMap("amount", func(bm gopay.BodyMap) {
			bm.Set("total", amount).
				Set("currency", "CNY")
		}).
		SetBodyMap("scene_info", func(bm gopay.BodyMap) {
			bm.Set("payer_client_ip", "127.0.0.1").
				SetBodyMap("h5_info", func(bm gopay.BodyMap) {
					bm.Set("type", "Wap")
				})
		})

	rsp, err := w.wechatPay.V3TransactionH5(w.ctx, bm)
	if err != nil {
		return
	}
	result = rsp.Response.H5Url
	return
}

PC端支付

func (w *WechatPayService) PcPay(charge *Charge) (result string, err error) {
	amount := decimal.NewFromInt(charge.MoneyFee).DivRound(decimal.NewFromInt(1), 2).IntPart()
	expire := time.Now().Add(10 * time.Minute).Format(time.RFC3339)
	bm := make(gopay.BodyMap)
	bm.Set("appid", w.config.Appid).
		Set("mchid", w.config.MchId).
		Set("description", charge.Describe).
		Set("out_trade_no", charge.TradeNum).
		Set("time_expire", expire).
		Set("notify_url", w.config.NotifyUrl).
		SetBodyMap("amount", func(bm gopay.BodyMap) {
			bm.Set("total", amount).
				Set("currency", "CNY")
		})

	rsp, err := w.wechatPay.V3TransactionNative(w.ctx, bm)
	if err != nil {
		return
	}
	result = rsp.Response.CodeUrl
	return
}

Android端支付

func (w *WechatPayService) GetNotifyResult(r *http.Request) (res *wechat.V3DecryptResult, err error) {
	notifyReq, err := wechat.V3ParseNotify(r)    // 解析回调参数
	if err != nil {
		fmt.Println(err)
		return
	}
	if notifyReq == nil {
		return
	}
	return notifyReq.DecryptCipherText(w.config.ApiV3Key)  // 解密回调内容
}

  • APP支付跟JSAPI支付很像。主要区别在于app与商户服务后台的交互。app会从商户服务后台获取签名信息,根据签名信息,app直接调用微信支付服务下单。

3. 解析支付回调

当用户完成支付后,微信会向我们的服务器发送支付成功的回调通知。我们需要解析这个通知并验证其合法性。

通过V3ParseNotify方法,解析支付通知,并使用API v3密钥解密支付结果。

四、实现退款功能

退款时序图

发起退款

除了支付,退款也是微信支付中常用的功能。接下来,我们来看如何使用Go语言实现退款功能。

当需要对已支付的订单进行退款时,可以调用Refund方法。

func (w *WechatPayService) Refund(charge *RefundCharge) (err error) {
	amount := decimal.NewFromInt(charge.MoneyFee).DivRound(decimal.NewFromInt(1), 2).IntPart()
	bm := make(gopay.BodyMap)
	bm.Set("out_trade_no", charge.TradeNum).
		Set("out_refund_no", charge.OutRefundNo).
		Set("reason", charge.RefundReason).
		Set("notify_url", w.config.RefundUrl).
		SetBodyMap("amount", func(bm gopay.BodyMap) {
			bm.Set("total", amount).
				Set("refund", amount).
				Set("currency", "CNY")
		})

	rsp, err := w.wechatPay.V3Refund(w.ctx, bm)  // 发起退款请求
	if err != nil {
		return
	}

	if rsp == nil || rsp.Response == nil || rsp.Error != "" {
        // 处理退款错误
		err = errors.New(rsp.Error) 
		return
	}
	return
}

解析退款回调

func (w *WechatPayService) GetRefundNotifyResult(r *http.Request) (res *wechat.V3DecryptRefundResult, err error) {
	notifyReq, err := wechat.V3ParseNotify(r)
	if err != nil {
		return
	}
	return notifyReq.DecryptRefundCipherText(w.config.ApiV3Key)
}

五、总结

通过本文的介绍,相信你已经掌握了如何使用Go语言对接微信支付,并实现了支付和退款功能。这些功能不仅能够提升用户体验,还能帮助你在实际项目中更加高效地处理支付相关的业务逻辑。希望本文对你有所帮助!

文章转载自:tatasix

原文链接:https://www.cnblogs.com/crazytata/p/18452145

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2199704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习干货IF=93.6!开发临床预测模型:分步指南

预测患者未来结果对临床实践至关重要,有助于医生做出明智决策。尽管每年发布大量预测模型,但许多研究存在方法学局限,如样本量不足和模型验证不充分,这削弱了模型的实际应用价值。因此,必须深入探讨并改进这些局限性&a…

电力央企数智化转型中的大模型构建及智能巡检机器人的应用

在全球经济数字化转型的大背景下,电力行业面临着多重挑战,包括能源结构的转型、市场竞争的加剧以及环境保护的压力。电力央企作为国家能源供应的中坚力量,亟需通过数智化转型提升竞争力和服务水平。 随着今年年初我国首次将“开展‘人工智能行…

第十四届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)

一.题目分析 (1).题目 (2).题目分析 1.PWM输出分析 模式切换时,占空比要不变, 在五秒之内就要变化成目标频率,同时要求频率的步进值要小于200hz 为了使步进值小于200hz,那么在五秒的时间之内…

AI绘画:人工智能颠覆艺术创作的新时代

*AI绘画的震撼与魅力* 你是否曾幻想过,手握画笔便能创造出前所未有的艺术作品?当我们谈及艺术,总会联想到那份独特的创意和灵感。而如今,随着人工智能的迅猛发展,AI绘画正以其独特的方式,颠覆着传统的艺术…

XTR115电流环电路原理研究【文献】

作者:昝 勇,罗永红,王沛莹 中航工业 摘要: 针对各种数据采集与监控中抗恶劣电磁干扰环境的需求,给出一种基于XTB115的低功耗两线4~20 mA电流环数据传输电路,首先讨论了XTR115的性能特点和工作原…

RabbitMQ简介及安装类

RabbitMQ概述-MQ介绍 RabbitMQ是一个开源的消息代理和队列服务器,它支持多种消息协议,并且可以轻松地与多种编程语言和框架集成。RabbitMQ是使用Erlang语言编写的,因此它具有高并发和高可用性的特点。以下是RabbitMQ的一些关键特性和概念 消息…

两文读懂DDD领域驱动设计,举例说明,通俗易懂【值得收藏】

最近对架构莫名的感兴趣,慢慢觉得架构本身是为了提供方便,定制规范,目标一致并更好的协作,它的变动也并不是像变形金刚一样,而是像幼苗一样按规律成长起来的 DDD是一种方法也是一种思想,大家前面个别概念看…

C++-再探构造函数(进阶)

个人主页:Jason_from_China-CSDN博客 所属栏目:C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目:C知识点的补充_Jason_from_China的博客-CSDN博客 前言 来到类和对象最后一个章节,这里的难度已经极大程度的降低了 再探构造…

FFMpeg源码分析,关键结构体分析(一)

http://lazybing.github.io/blog/categories/ffmpegyuan-ma-fen-xi/ 一、下载FFmpeg的编译源码 进入网站:http://ffmpeg.org/download.html二、编译源码 执行下述命令: ./configure --prefix/usr/local/ffmpeg --enable-debug3 --enable-ffplay sudo …

22年408数据结构

第一题&#xff1a; 解析&#xff1a; 观察一下这个程序&#xff1a;我们注意到最外层的循环是从i1开始的&#xff0c;每次ii*2&#xff0c;直到i<n为止&#xff0c;假设程序总共执行k次执行&#xff0c;则有2^(k1)>n。则k1>log(2)n这里是以2为底n的对数, k>log(2)…

Oracle11g服务器linux 安装

一&#xff0e;安装前准备 1.检查硬件&#xff08;内存&#xff0c;交换分区&#xff0c;tmp分区&#xff0c;cpu信息&#xff0c;内核版本&#xff09; # grep MemTotal /proc/meminfo # grep SwapTotal /proc/meminfo # df -k /tmp&#xff08;>400M&#xff09; # grep …

汽车氛围灯行业分析:未来几年年复合增长率CAGR为7.15%

汽车氛围灯是一种起到装饰和指示作用的照明灯&#xff0c;它属于装饰类的照明灯。通常是红色、蓝色、绿色等&#xff0c;主要是为了使车厢更加绚丽&#xff0c;烘托气氛&#xff0c;营造室内情调。氛围灯能够具有以下特性&#xff1a;功能性、舒适性、设计感、豪华感、个性化、…

【C++】——继承

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

深入解析MySQL事务管理:ACID特性与基本操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

自动猫砂盆是养猫新型智商税吗?测评2024年热门款智能猫砂盆分享

铲屎官们只要一察觉到猫主子拉屎&#xff0c;就要马上去铲掉&#xff0c;这不仅是为了猫砂盆中其他干净的猫砂&#xff0c;更是为了防止猫屎残留发臭&#xff0c;特别是便便这种东西&#xff0c;一旦放久了就很招虫子&#xff0c;家里出现这些虫子又要大扫除消杀&#xff0c;特…

2024 年顶级智能文档处理解决方案

在当今的数字时代&#xff0c;智能文档处理(IDP) 对于提高业务效率和降低成本至关重要。IDP 可实现文档处理的自动化&#xff0c;最大限度地减少人工劳动和错误。由于有众多 IDP 解决方案可供选择&#xff0c;因此选择合适的解决方案可能具有挑战性。 本指南回顾了 10 款最…

Android Handler消息机制完全解析-同步屏障(三)

Android 消息机制Handler完全解析(一) Android 消息机制Handler完全解析(二) 前面两篇我们主要讲了Handler消息机制的一些基础&#xff0c;今天来看下消息屏障&#xff0c;通过本篇文章你将学到如下知识点 (1)什么是同步屏障 (2)为什么要有同步屏障 (3)同步屏障的原理 (4…

获取时隔半个钟的三天

摘要&#xff1a; 今天遇到需求是配送时间&#xff0c;时隔半个钟的排线&#xff01;所以需要拼接时间&#xff01;例如2024-10-08 14&#xff1a;30&#xff0c;2024-10-08 15&#xff1a;00&#xff0c;2024-10-08 15&#xff1a;30 <el-form-item label"配送时间&a…

24下软考中级系统集成项目管理工程师怎么备考?

备考资料&#xff1a; 1.教材 教材可以准备由清华大学出版社出版的系统集成项目管理工程师教材&#xff0c;这也是官方所推荐的教材&#xff0c;准备这本书是绝对没错的。 2.真题 真题也是在备考过程中少不了的资料之一&#xff0c;而且系统集成项目管理工程师考试就是需要多…

初始项目托管到gitee教程,开箱即用

0.本地仓库与远程仓库关联&#xff08;需先在gitee创建仓库&#xff09; ①打开powershell生成ssh key ssh-keygen -t ed25519 -C "Gitee SSH Key"-t key 类型-C 注释 生成成功如下&#xff0c;并按下三次回车 ②查看公私钥文件 ls ~/.ssh/输出&#xff1a; id_…