最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言對接微信支付與退款指南(示例詳解)

 更新時間:2024年10月09日 08:57:33   作者:tatasix  
在互聯(lián)網(wǎng)技術(shù)日益發(fā)展的背景下,Go語言憑借并發(fā)處理能力,在后端開發(fā)中大放異彩,本文詳細介紹如何使用Go語言對接微信支付,完成支付和退款功能,包括準備工作、初始化微信支付客戶端、實現(xiàn)支付功能,以及處理支付回調(diào)和退款等

在互聯(lián)網(wǎng)技術(shù)日益發(fā)展的今天,線上支付已成為不可或缺的一部分。作為一門簡潔高效的編程語言,Go(又稱Golang)憑借其強大的并發(fā)處理能力和高效性能,在后端開發(fā)領(lǐng)域越來越受到開發(fā)者的青睞。本文將詳細介紹如何使用Go語言對接微信支付,并實現(xiàn)支付和退款功能,幫助開發(fā)者快速上手。

一、準備工作

在開始編寫代碼之前,你需要先準備好以下幾項工作:

  • 注冊成為微信支付商戶:如果你還沒有微信支付商戶賬號,需要先前往微信支付商戶平臺完成注冊。
  • 獲取必要的配置信息
    • 商戶號 (MchId)
    • AppID (Appid)
    • API v3 密鑰 (ApiV3Key)
    • 商戶證書序列號 (MchSerialNo)
    • 私鑰 (PrivateKey)
    • 支付通知地址 (NotifyUrl)
    • 退款通知地址 (RefundUrl)

安裝第三方庫:為了簡化微信支付接口的調(diào)用,推薦使用github.com/go-pay/gopay這個庫。可以通過go get命令安裝:

go get github.com/go-pay/gopay

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

首先,我們需要創(chuàng)建一個WechatPayService結(jié)構(gòu)體來封裝微信支付的相關(guān)操作。該結(jié)構(gòu)體包含上下文、配置信息和微信支付客戶端實例。

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函數(shù)來初始化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密鑰和私鑰等關(guān)鍵參數(shù)。為了保障支付的安全性,開啟了自動驗簽功能。

三、實現(xiàn)支付功能

1. 付款時序圖

2. 實現(xiàn)不同場景下的支付

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支付很像。主要區(qū)別在于app與商戶服務(wù)后臺的交互。app會從商戶服務(wù)后臺獲取簽名信息,根據(jù)簽名信息,app直接調(diào)用微信支付服務(wù)下單。

3. 解析支付回調(diào)

當用戶完成支付后,微信會向我們的服務(wù)器發(fā)送支付成功的回調(diào)通知。我們需要解析這個通知并驗證其合法性。

func (w *WechatPayService) GetNotifyResult(r *http.Request) (res *wechat.V3DecryptResult, err error) {
	notifyReq, err := wechat.V3ParseNotify(r)    // 解析回調(diào)參數(shù)
	if err != nil {
		fmt.Println(err)
		return
	}
	if notifyReq == nil {
		return
	}
	return notifyReq.DecryptCipherText(w.config.ApiV3Key)  // 解密回調(diào)內(nèi)容
}

通過V3ParseNotify方法,解析支付通知,并使用API v3密鑰解密支付結(jié)果。

四、實現(xiàn)退款功能

退款時序圖

發(fā)起退款

除了支付,退款也是微信支付中常用的功能。接下來,我們來看如何使用Go語言實現(xiàn)退款功能。

當需要對已支付的訂單進行退款時,可以調(diào)用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)  // 發(fā)起退款請求
	if err != nil {
		return
	}
	if rsp == nil || rsp.Response == nil || rsp.Error != "" {
        // 處理退款錯誤
		err = errors.New(rsp.Error) 
		return
	}
	return
}

解析退款回調(diào)

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)
}

五、總結(jié)

通過本文的介紹,相信你已經(jīng)掌握了如何使用Go語言對接微信支付,并實現(xiàn)了支付和退款功能。這些功能不僅能夠提升用戶體驗,還能幫助你在實際項目中更加高效地處理支付相關(guān)的業(yè)務(wù)邏輯。希望本文對你有所幫助!

到此這篇關(guān)于Go語言對接微信支付與退款全流程指南的文章就介紹到這了,更多相關(guān)Go語言對接微信支付與退款內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口

    Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口

    這篇文章主要介紹了Go語言學(xué)習(xí)函數(shù)+結(jié)構(gòu)體+方法+接口,文章圍繞主題的相關(guān)資料展開詳細的文章說明,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Go日志管理庫zap安裝及使用過程

    Go日志管理庫zap安裝及使用過程

    Zap是Go語言中一個高性能的日志記錄庫,它支持日志切割、多級別日志記錄等功能,zap還支持使用Lumberjack進行日志文件的自動切割和歸檔,適用于需要高效日志管理的Go項目開發(fā),本文介紹Go日志管理庫zap安裝及使用過程,感興趣的朋友一起看看吧
    2024-09-09
  • 使用Golang開發(fā)一個簡易版shell

    使用Golang開發(fā)一個簡易版shell

    這篇文章主要為大家詳細介紹了如何使用Golang開發(fā)一個簡易版shell,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • Go底層之string和[]byte相互轉(zhuǎn)換原理分析

    Go底層之string和[]byte相互轉(zhuǎn)換原理分析

    這篇文章主要介紹了Go底層之string和[]byte相互轉(zhuǎn)換原理,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • 深入理解Go語言的Type-Value Pair(類型-值對)的使用

    深入理解Go語言的Type-Value Pair(類型-值對)的使用

    本文主要介紹了深入理解Go語言的Type-Value Pair(類型-值對)的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • 詳解golang 定時任務(wù)time.Sleep和time.Tick實現(xiàn)結(jié)果比較

    詳解golang 定時任務(wù)time.Sleep和time.Tick實現(xiàn)結(jié)果比較

    本文主要介紹了golang 定時任務(wù)time.Sleep和time.Tick實現(xiàn)結(jié)果比較,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • golang gorm多條件篩選查詢操作

    golang gorm多條件篩選查詢操作

    這篇文章主要介紹了golang gorm多條件篩選查詢操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go 語言中的 Struct Tag 的用法詳解

    Go 語言中的 Struct Tag 的用法詳解

    在 Go 語言中,結(jié)構(gòu)體字段標簽(Struct Tag) 是一種用于給字段添加元信息(metadata)的機制,常用于序列化(如 JSON、XML)、ORM 映射、驗證等場景,本文給大家介紹Go 語言中的 Struct Tag 的用法,感興趣的朋友一起看看吧
    2025-05-05
  • Golang中堆排序的實現(xiàn)

    Golang中堆排序的實現(xiàn)

    堆是一棵基于數(shù)組實現(xiàn)的特殊的完全二叉樹,本文主要介紹了Golang中堆排序的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • GO workPool的線程池實現(xiàn)

    GO workPool的線程池實現(xiàn)

    本文主要介紹了GO workPool的線程池實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03

最新評論

平原县| 龙江县| 焦作市| 巴林右旗| 和平县| 库尔勒市| 大英县| 历史| 黄山市| 招远市| 綦江县| 青浦区| 辉县市| 滨州市| 封开县| 焦作市| 凤阳县| 清河县| 曲周县| 洮南市| 大同市| 孝义市| 马公市| 阿拉善左旗| 沽源县| 邢台县| 甘孜县| 滕州市| 涿鹿县| 大竹县| 巢湖市| 乌兰浩特市| 长汀县| 米泉市| 墨竹工卡县| 哈尔滨市| 分宜县| 海伦市| 五指山市| 黄浦区| 临桂县|