首页 - 新闻 - 如何使用Golang实现Web应用的微信支付

如何使用Golang实现Web应用的微信支付

2023-10-03 08:18

微信支付是一种非常常见的在线支付方式,很多网站/应用程序都需要集成这个功能。本文将介绍如何使用Golang实现微信支付功能。在本文中,我们将使用Gin框架构建一个简单的Web应用程序,并使用go-wechat微信SDK快速实现微信支付。

要求

在本教程中,我们将构建一个简单的电子商务网站。网站需要实现以下功能:

  1. 用户通过微信登录网站。
  2. 用户浏览产品并将商品添加到购物车。
  3. 用户可以使用微信支付购买商品。

准备工作

在开始之前,请确保您具备以下要求:

  • 已注册微信支付账号,参数有appidmch_idkey等参数。
  • 安装了Golang和Gin框架。

安装go-wechat SDK

在继续之前,请从go-wechat的Github存储库安装微信SDK。

前往www.gsm-guard.net/silenceper/wechat/v2
登录后,复制

配置环境变量

从微信支付账号中获取以下参数,添加到系统环境变量中:

  • APP_ID:微信APP_ID
  • MCH_ID:商户编号
  • API_KEY:商户API密钥
导出APP_ID=your_appid
导出 MCH_ID=your_mchid
export API_KEY=your_api_key
登录后复制

构建应用程序

初始化Gin

在文件main.go中,我们将使用gin包来初始化应用程序。

套餐主

进口 (
    “网络/http”

    “www.gsm-guard.net/gin-gonic/gin”
)

函数主() {
    路由器 := gin.Default()

    router.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "Hello World!")
    })

    路由器.运行(“:8080”)
}
登录后复制

将微信登录添加到应用程序中

在上一页中,我们设置了基本的Gin应用程序。我们现在将添加微信登录功能。

  1. 添加配置文件

您可以选择通过 JSON、YAML 或 TOML 格式定义配置。在这里,我们将创建一个 config.json 文件来定义配置。

{
    “微信”: {
        “appid”:“你的appid”,
        “秘密”:“你的应用程序秘密”
    }
}
登录副本后
  1. 初始化微信

下一步是初始化微信客户端并使用oauth2请求码获取访问令牌。

导入(
    “编码/json”
    “io/ioutil”
    “网络/http”
    “操作系统”

    “www.gsm-guard.net/silenceper/wechat/v2”
)

func loadConfig() 映射[字符串]字符串 {
    文件, err := www.gsm-guard.net("config.json")
    如果错误!= nil {
        恐慌(“无法加载配置文件。”)
    }
    延迟文件.Close()

    数据,错误:= ioutil.ReadAll(文件)
    如果错误!= nil {
        恐慌(“无法读取配置文件。”)
    }

    var config 映射[字符串]映射[字符串]字符串
    err = json.Unmarshal(数据, &config)
    如果错误!= nil {恐慌(“无法解析配置文件。”)
    }

    返回配置[“微信”]
}

funcinitializeWeChat() *wechat.WeChat {
    配置 := 加载配置()
    客户端 := wechat.NewWechat(&wechat.Config{
        应用程序ID:配置[“appid”],
        应用程序秘密:配置[“秘密”],
        代币:“”,
        编码 AESKey: "",
    })

    返回客户
}

func weChatLoginHandler(c *gin.Context) {
    客户端 := 初始化微信()

    重定向URL := ""
    url := client.Oauth2.GetRedirectURL(redirectURL, "snsapi_userinfo", "")
    c.Redirect(http.StatusTemporaryRedirect, url)
}
登录后复制

本质上,我们定义了一个包含应用程序身份验证的WeChatClient。我们还定义了一个 Gin 处理程序,用于设置重定向 URL 并使用 WeChatClient 中的 oauth2 请求获取访问令牌。

  1. 处理微信授权

在重定向URL中,当用户授权我们的应用程序在其帐户下运行时,会调用/wechat/callback处理程序。该处理程序在用户会话中存储用户的微信 ID、昵称和其他公共数据。

funccallbackHandler(c *gin.Context) {
    代码 := c.Request.URL.Query().Get("代码")客户端 := 初始化微信()
    accessToken, err := client.Oauth2.GetUserAccessToken(code)
    如果错误!= nil {
        panic("微信获取访问token失败。")
    }

    userInfo, err := client.Oauth2.GetUserInfo(accessToken.AccessToken, accessToken.Openid)
    如果错误!= nil {
        panic("微信获取用户信息失败。")
    }

    会话 := 会话.Default(c)
    session.Set("wechat_openid", userInfo.Openid)
    session.Set("wechat_nickname", userInfo.Nickname)
    会话.保存()

    c.Redirect(http.StatusTemporaryRedirect, "/")
}
登录后复制
  1. 集成微信登录

我们应该将微信登录集成到我们的应用程序中。过程比较简单。只需将处理程序添加到 Gin 路由器即可。

func main() {
    ...
    router.GET("/wechat/login", weChatLoginHandler)
    router.GET("/微信/callback",callbackHandler)
    ...
}
登录后复制

实施购物车

我们将向应用程序添加基本的购物车状态。只需在用户会话中添加购物车信息即可。

类型 CartItem 结构 {
    产品 ID 整数
    数量整数
}

func (c *CartItem) 小计() float64 {// TODO:实施。
}

类型购物车结构体{
    内容 []*购物车项目
}

func (c *Cart) Add(产品ID, 数量 int) {
    项目 := &CartItem{
        产品ID:产品ID,
        数量: 数量,
    }

    发现:=假
    对于 _,现有项目 := 范围 c.Contents {
        如果现有Item.ProductID == ProductID {
            现有商品数量 += 数量
            发现=真
            休息
        }
    }

    如果!发现{
        c.Contents = 附加(c.Contents, item)
    }
}

func (c *Cart) 删除(productID int) {
    对于 i,item := range c.Contents {
        if item.ProductID == ProductID {
            c.Contents = 追加(c.Contents[:i], c.Contents[i+1:]...)
            休息
        }
    }
}

func (c *Cart) Total() float64 {
    总计 := 0.0
    对于 _, item := 范围 c.Contents {
        总计 += item.Subtotal()
    }
    返回总计
}

func cartFromSession(会话sessions.Session) *购物车{
    值 := session.Get("购物车")如果值 == nil {
        返回购物车(&C){}
    }

    cartBytes := []byte(值.(字符串))
    var 购物车 购物车
    json.Unmarshal(cartBytes, &cart)
    退货&购物车
}

funcsyncCartToSession(会话sessions.Session,购物车*购物车){
    cartBytes, err := json.Marshal(cart)
    如果错误!= nil {
        恐慌(“无法将购物车与会话数据存储同步。”)
    }

    session.Set(“购物车”,字符串(cartBytes))
    会话.保存()
}
登录后复制

如上所示,我们实现了一个函数,包含Add(productID, amount int), Remove(productID int), 合计( ) float64 购物车结构有多种方法。我们从会话(cartFromSession()

syncCartToSession()) 存储和加载购物车数据,并通过 CartItem.Subtotal() 方法小计进行计算。

在页面底部显示购物车状态:

登录后复制

微信支付

为了实现微信支付,我们需要定义一个订单结构体,生成订单并发送给微信支付,并处理支付通知。下面是一个简单的实现。

  1. 定义订单结构
type 订单结构 {
    订单号字符串
    金额 float64
}
登录后复制
  1. 生成订单并发送订单到微信

这一步我们将通过微信支付生成订单并创建订单号。阅读 go-wechat 的支付文档以了解更多信息。

funcgenerateOutTradeNo()字符串{
    // TODO:实施。
}

func createOrder(购物车 *购物车) *订单 {
    订单 := &订单{
        订单编号:generateOutTradeNo(),
        金额:购物车.Total(),
    }

    客户端 := 初始化微信()
    付款 := &wechat.Payment{
        应用程序ID:APP_ID,
        MchID:MCH_ID,
        NotifyURL: "",
        交易类型:“JSAPI”,
        Body:“购物车结账”,
        OutTradeNo: 订单.订单编号,总费用: int(订单.金额 * 100),
        SpbillCreateIP:“127.0.0.1”,
        OpenID: "",
        密钥:API_KEY,
    }
    结果,err := client.Pay.SubmitPayment(付款)
    如果错误!= nil {
        恐慌(“提交付款失败。”)
    }

    // 保存订单状态并返回。
    退货订单
}
登录后复制
  1. 处理微信付款通知

微信通知我们收到用户付款后,我们会在回调中存储订单状态以供后续查询。

func setupCheckOrderStatus() {
    去函数(){
        为了 {
            // 检查前等待 10 秒(如果您想更频繁地检查,则等待 10 秒)。
            时间.睡眠(10 * 时间.秒)

            客户端 := 初始化微信()
            // TODO: 检索需要检查的订单。
            对于_,订单:=范围ordersToCheck {
                queryOrderResult, err := client.Pay.QueryOrder(&wechat.QueryOrderParams{
                    OutTradeNo: 订单.订单编号,
                })
                如果错误!= nil {panic("查询订单失败。")
                }

                切换 queryOrderResult.TradeState {
                案例wechat.TradeStateSuccess:
                    // 在您的应用程序中处理订单付款。
                    订单.已付款 = true
                    // TODO: 更新数据库中的订单状态。
                案例 wechat.TradeStateClosed:
                    // 在您的应用程序中处理订单付款。
                    订单.已付款= false
                    // TODO: 更新数据库中的订单状态。
                案例微信.TradeStateRefund:
                    // 在您的应用程序中处理订单付款。
                    订单.已付款= false
                    // TODO: 更新数据库中的订单状态。
                默认:
                    休息
                }

                // TODO: 从缓存中删除已检查的订单。
            }
        }
    }()
}
登录后复制

我们需要调用查询函数来查看微信强制改变订单状态的交易。微信SDK将返回以下状态之一。

  • TradeStateSuccess:用户支付成功。
  • TradeStateClosed:订单已关闭。
  • TradeStateRefund:交易已退款。

总结

在这篇文章中,我们学习了如何使用Golang和Gin框架搭建一个电商网站,并使用go-wechat SDK快速实现微信登录和支付功能。我们学习了如何通过WeChatClient处理用户认证和授权,以及如何在用户会话中存储微信用户数据。我们还学习了如何定义简单的购物车和订单,并使用 go-wechat SDK 与微信支付集成。

以上就是如何在Web应用中使用Golang实现微信支付的详细介绍。更多相关内容请关注其他相关文章!