目录
- 三方聚合支付
- 商户开通
- 使用 go 对接蓝兔支付
- 实现签名算法
- 支付接口参数序列化
- 支付接口调用
- 总结
支付宝、微信的网上支付需要营业执照个人无法直接使用。
如果个人需要实现网上支付功能,目前大部分应该是都是依赖第三方聚合支付来实现。
三方聚合支付
我是在做一个电商网站(ps:极简风格)的 demo 所以并不会有太多的流水,经过一番检索我发现大部分三方支付都会收取一些费用比如开户费、接口服务服务费。
咱也能理解毕竟靠爱发电不是长久的事情,有时候支付一些费用获取比较好的体验也是可以接受的。
矮个子里挑高个我找到了蓝兔支付-猛击访问官网 开户费用 50
,相对来说比较优惠了。
接口服务费感觉有那么一点高,不过我是用来做个人网站的支付不会有太大的流水倒也没那么在意。
产品对比
从这张图大概可以了解到与微信官方的一些区别。
商户开通
蓝兔支付的开通还是比较简单的进入个人中心、点击微信支付申请签约。
然后你会看到一个弹窗,小伙子你很刚啊!
然后按照要求填写一些信息即可,身份信息需要上传身份证照片。
友情提示记得加水印养成好习惯!
都做完以后一般很快就会审核完成,我大概半个小时左右就可以了。
然后在商户管理这里可以看到商户号、商户密钥后边调用接口要用!
使用 go 对接蓝兔支付
蓝兔支付提供了对接文档文档地址这非常好,一个好的文档可以让我少走很多弯路。
实现签名算法
这里文档说明了签名算法的实现,说明了和微信支付www.devze.com的签名算法一致可以使用微信支付的校验工具进行测试。
可以测试就会简单很多,让我们来实现一下这个签名。
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 生成蓝兔支付签名 func LTZFGenerateSignature(sinObj map[string]string) string { // 按照参数名进行字典序排序 keys := make([]string, 0, len(sinObj)) for k := range sinObj { keys = append(keys, k) } sort.Strings(keys) // 拼接参数键值对 var builder strings.Builder for _, key := range keys { value := sinObj[key] if value != "" { builder.WriteString(key + "=" + value + "&") } } // 拼接密钥 也就上边说的商户密钥 builder.WriteString("key=" + global.LTZFConfig.SecretKey) // 计算MD5并转换为大写 signature := calculateMD5(builder.String()) return s编程trings.ToUpper(signature) }
支付接口参数序列化
接口的调用比较简单但是没有接口参数的示例,参考文档实现下参数的封装。
// 获取微信支付签名对象 func getLTZFWeChatPayApiSinObj(params map[string]string) string { // 只有必填参数才参与签名! 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) } // 获取蓝兔支付微信 api 参数 func getLTZFWeChatPayApiReq(payReq pay.WeChatPayReq) url.Values { // 请求支付接口参数 opts := map[string]string{ "mch_id": global.LTZFConfig.MchId, // 上边说的商户id "out_trade_no": payReq.OrderId, "total_fee": "0.01", // 为了测试设置为 0.01 防止误支付 "body": payReq.Info, "timestamp": strconv.FormatInt(time.Now().Unix(), 10), "notify_url": "xxxxx", // 这里填写支付成功的回调地址 "attach": payReq.OrderId, // 附加数据,在支付通知中原样返回 "time_expire": "15m", // 支付超时时间 "sign": "", } // 设置接口签名 opts["sign"] = getLTZFWeChatPayApiSinObj(opts) // 格式化参数 req := url.Values{} js for key, value := range opts { req.Add(key, value) } return req }
支付接口调用
支付接口的调用官网文档有示例,记得先设置白名单地址。
咱就借鉴官网的调用示例然后完善一下,这里使用了 gin。
func WeChatPay编程客栈(ctx *gin.Context) { payReq := pay.WeChatPayReq{} if err := ctx.ShouldBind(&payReq); err != nil { utils.HandleValidatorError(ctx, err) return } // 调用蓝兔支付接口 获取支付二维码 res, err := http.PostForm("https://api.ltzf.cn/api/wxpay/native", getLTZFWeChatPayApiReq(payReq)) if err != nil {编程客栈 // 处理请求错误 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 { // 处理读取响应体错误 utils.ResponseResultsError(ctx, err.Error()) return } // 解析接口响应数据 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数据 var resp Response if err := json.Unmarshal(body, &resp); err != nil { // 处理解析JSON错误 utils.ResponseResultsError(ctx, err.Error()) return } if resp.Code != 0 { utils.ResponseResultsError(ctx, resp.Msg) return } utils.ResponseResultsSuccess(ctx, resp.Data) }
然后也提供了一个交易记录的管理。
总结
文章介绍了使用 go + 蓝兔支付 来实现的个人的网上支付,从蓝兔支付的开通到对接这个过程做了一个讲解说明。
重点说明:蓝兔支付客服态度不是很友好!
以上就是golang调用蓝兔支付实现网上支付功能的详细内容,更多关于go支付的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论