golang調(diào)用藍(lán)兔支付實(shí)現(xiàn)網(wǎng)上支付功能
支付寶、微信的網(wǎng)上支付需要營業(yè)執(zhí)照個(gè)人無法直接使用。
如果個(gè)人需要實(shí)現(xiàn)網(wǎng)上支付功能,目前大部分應(yīng)該是都是依賴第三方聚合支付來實(shí)現(xiàn)。
三方聚合支付
我是在做一個(gè)電商網(wǎng)站(ps:極簡風(fēng)格)的 demo 所以并不會(huì)有太多的流水,經(jīng)過一番檢索我發(fā)現(xiàn)大部分三方支付都會(huì)收取一些費(fèi)用比如開戶費(fèi)、接口服務(wù)服務(wù)費(fèi)。
咱也能理解畢竟靠愛發(fā)電不是長久的事情,有時(shí)候支付一些費(fèi)用獲取比較好的體驗(yàn)也是可以接受的。
矮個(gè)子里挑高個(gè)我找到了藍(lán)兔支付-猛擊訪問官網(wǎng) 開戶費(fèi)用 50
,相對來說比較優(yōu)惠了。
接口服務(wù)費(fèi)感覺有那么一點(diǎn)高,不過我是用來做個(gè)人網(wǎng)站的支付不會(huì)有太大的流水倒也沒那么在意。
產(chǎn)品對比
從這張圖大概可以了解到與微信官方的一些區(qū)別。
商戶開通
藍(lán)兔支付的開通還是比較簡單的進(jìn)入個(gè)人中心、點(diǎn)擊微信支付申請簽約。
然后你會(huì)看到一個(gè)彈窗,小伙子你很剛??!
然后按照要求填寫一些信息即可,身份信息需要上傳身份證照片。
友情提示記得加水印養(yǎng)成好習(xí)慣!
都做完以后一般很快就會(huì)審核完成,我大概半個(gè)小時(shí)左右就可以了。
然后在商戶管理這里可以看到商戶號(hào)、商戶密鑰后邊調(diào)用接口要用!
使用 go 對接藍(lán)兔支付
藍(lán)兔支付提供了對接文檔文檔地址這非常好,一個(gè)好的文檔可以讓我少走很多彎路。
實(shí)現(xiàn)簽名算法
這里文檔說明了簽名算法的實(shí)現(xiàn),說明了和微信支付的簽名算法一致可以使用微信支付的校驗(yàn)工具進(jìn)行測試。
可以測試就會(huì)簡單很多,讓我們來實(shí)現(xiàn)一下這個(gè)簽名。
package pay import ( "crypto/md5" "encoding/hex" "simple-mall/global" "sort" "strings" ) func calculateMD5(data string) string { hash := md5.Sum([]byte(data)) return hex.EncodeToString(hash[:]) } // LTZFGenerateSignature 生成藍(lán)兔支付簽名 func LTZFGenerateSignature(sinObj map[string]string) string { // 按照參數(shù)名進(jìn)行字典序排序 keys := make([]string, 0, len(sinObj)) for k := range sinObj { keys = append(keys, k) } sort.Strings(keys) // 拼接參數(shù)鍵值對 var builder strings.Builder for _, key := range keys { value := sinObj[key] if value != "" { builder.WriteString(key + "=" + value + "&") } } // 拼接密鑰 也就上邊說的商戶密鑰 builder.WriteString("key=" + global.LTZFConfig.SecretKey) // 計(jì)算MD5并轉(zhuǎn)換為大寫 signature := calculateMD5(builder.String()) return strings.ToUpper(signature) }
支付接口參數(shù)序列化
接口的調(diào)用比較簡單但是沒有接口參數(shù)的示例,參考文檔實(shí)現(xiàn)下參數(shù)的封裝。
// 獲取微信支付簽名對象 func getLTZFWeChatPayApiSinObj(params map[string]string) string { // 只有必填參數(shù)才參與簽名! sinObj := map[string]string{ "mch_id": params["mch_id"], "out_trade_no": params["out_trade_no"], "total_fee": params["total_fee"], "body": params["body"], "timestamp": params["timestamp"], "notify_url": params["notify_url"], } return LTZFGenerateSignature(sinObj) } // 獲取藍(lán)兔支付微信 api 參數(shù) func getLTZFWeChatPayApiReq(payReq pay.WeChatPayReq) url.Values { // 請求支付接口參數(shù) opts := map[string]string{ "mch_id": global.LTZFConfig.MchId, // 上邊說的商戶id "out_trade_no": payReq.OrderId, "total_fee": "0.01", // 為了測試設(shè)置為 0.01 防止誤支付 "body": payReq.Info, "timestamp": strconv.FormatInt(time.Now().Unix(), 10), "notify_url": "xxxxx", // 這里填寫支付成功的回調(diào)地址 "attach": payReq.OrderId, // 附加數(shù)據(jù),在支付通知中原樣返回 "time_expire": "15m", // 支付超時(shí)時(shí)間 "sign": "", } // 設(shè)置接口簽名 opts["sign"] = getLTZFWeChatPayApiSinObj(opts) // 格式化參數(shù) req := url.Values{} for key, value := range opts { req.Add(key, value) } return req }
支付接口調(diào)用
支付接口的調(diào)用官網(wǎng)文檔有示例,記得先設(shè)置白名單地址。
咱就借鑒官網(wǎng)的調(diào)用示例然后完善一下,這里使用了 gin。
func WeChatPay(ctx *gin.Context) { payReq := pay.WeChatPayReq{} if err := ctx.ShouldBind(&payReq); err != nil { utils.HandleValidatorError(ctx, err) return } // 調(diào)用藍(lán)兔支付接口 獲取支付二維碼 res, err := http.PostForm("https://api.ltzf.cn/api/wxpay/native", getLTZFWeChatPayApiReq(payReq)) if err != nil { // 處理請求錯(cuò)誤 utils.ResponseResultsError(ctx, err.Error()) return } defer func(Body io.ReadCloser) { err := Body.Close() if err != nil { utils.ResponseResultsError(ctx, err.Error()) } }(res.Body) body, err := io.ReadAll(res.Body) if err != nil { // 處理讀取響應(yīng)體錯(cuò)誤 utils.ResponseResultsError(ctx, err.Error()) return } // 解析接口響應(yīng)數(shù)據(jù) type Data struct { CodeURL string `json:"code_url"` QRCodeURL string `json:"QRcode_url"` } type Response struct { Code int `json:"code"` Data Data `json:"data"` Msg string `json:"msg"` RequestID string `json:"request_id"` } // 解析JSON數(shù)據(jù) var resp Response if err := json.Unmarshal(body, &resp); err != nil { // 處理解析JSON錯(cuò)誤 utils.ResponseResultsError(ctx, err.Error()) return } if resp.Code != 0 { utils.ResponseResultsError(ctx, resp.Msg) return } utils.ResponseResultsSuccess(ctx, resp.Data) }
然后也提供了一個(gè)交易記錄的管理。
總結(jié)
文章介紹了使用 go + 藍(lán)兔支付 來實(shí)現(xiàn)的個(gè)人的網(wǎng)上支付,從藍(lán)兔支付的開通到對接這個(gè)過程做了一個(gè)講解說明。
重點(diǎn)說明:藍(lán)兔支付客服態(tài)度不是很友好!
以上就是golang調(diào)用藍(lán)兔支付實(shí)現(xiàn)網(wǎng)上支付功能的詳細(xì)內(nèi)容,更多關(guān)于go支付的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換
這篇文章主要介紹了Go語言strconv包實(shí)現(xiàn)字符串和數(shù)值類型的相互轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03使用go實(shí)現(xiàn)常見的數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了使用go實(shí)現(xiàn)常見的數(shù)據(jù)結(jié)構(gòu),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03go語言for循環(huán)中嵌套defer的執(zhí)行順序
在Go語言中,defer語句用于延遲函數(shù)調(diào)用的執(zhí)行,本文主要介紹了go語言for循環(huán)中嵌套defer的執(zhí)行順序,具有一定的參考價(jià)值,感興趣的可以了解一下2025-03-03golang jwt+token驗(yàn)證的實(shí)現(xiàn)
這篇文章主要介紹了golang jwt+token驗(yàn)證的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Go語言實(shí)現(xiàn)請求超時(shí)處理的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了Go語言中實(shí)現(xiàn)請求的超時(shí)控制的方法,主要是通過timer和timerCtx來實(shí)現(xiàn)請求的超時(shí)控制,希望對大家有所幫助2023-05-05