当前位置: 代码网 > it编程>前端脚本>Golang > Go语言对接微信支付与退款指南(示例详解)

Go语言对接微信支付与退款指南(示例详解)

2024年11月03日 Golang 我要评论
在互联网技术日益发展的今天,线上支付已成为不可或缺的一部分。作为一门简洁高效的编程语言,go(又称golang)凭借其强大的并发处理能力和高效性能,在后端开发领域越来越受到开发者的青睐。本文将详细介绍

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

一、准备工作

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

  • 注册成为微信支付商户:如果你还没有微信支付商户账号,需要先前往微信支付商户平台完成注册。
  • 获取必要的配置信息
    • 商户号 (mchid)
    • appid (appid)
    • api v3 密钥 (apiv3key)
    • 商户证书序列号 (mchserialno)
    • 私钥 (privatekey)
    • 支付通知地址 (notifyurl)
    • 退款通知地址 (refundurl)

安装第三方库:为了简化微信支付接口的调用,推荐使用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) androidpay(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.appid1).
		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.v3transactionapp(w.ctx, bm) 
	if err != nil {
		return
	}
	jsapiinfo, err := w.wechatpay.paysignofapp(w.config.appid1, rsp.response.prepayid)
	str, _ := json.marshal(jsapiinfo)
	result = string(str)
	return
}
  • app支付跟jsapi支付很像。主要区别在于app与商户服务后台的交互。app会从商户服务后台获取签名信息,根据签名信息,app直接调用微信支付服务下单。

3. 解析支付回调

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

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)  // 解密回调内容
}

通过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语言对接微信支付,并实现了支付和退款功能。这些功能不仅能够提升用户体验,还能帮助你在实际项目中更加高效地处理支付相关的业务逻辑。希望本文对你有所帮助!

到此这篇关于go语言对接微信支付与退款全流程指南的文章就介绍到这了,更多相关go语言对接微信支付与退款内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com