Maison  >  Article  >  développement back-end  >  Comment utiliser Golang pour mettre en œuvre le paiement WeChat pour les applications Web

Comment utiliser Golang pour mettre en œuvre le paiement WeChat pour les applications Web

PHPz
PHPzoriginal
2023-06-24 09:12:052666parcourir

WeChat Pay est un moyen de paiement en ligne très courant, et de nombreux sites/applications doivent intégrer cette fonction. Cet article explique comment utiliser Golang pour implémenter la fonction de paiement WeChat. Dans cet article, nous utiliserons le framework Gin pour créer une application Web simple et utiliserons le SDK go-wechat WeChat pour implémenter rapidement le paiement WeChat.

Exigences

Dans ce tutoriel, nous allons créer un site Web de commerce électronique simple. Le site Web doit mettre en œuvre les fonctions suivantes :

  1. Les utilisateurs se connectent au site Web via WeChat.
  2. Les utilisateurs parcourent les produits et ajoutent des articles à leur panier.
  3. Les utilisateurs peuvent utiliser WeChat Pay pour acheter des biens.

Préparation

Avant de commencer, assurez-vous d'avoir les conditions suivantes :

  • Avoir enregistré un compte de paiement WeChat, avoir appid, mch_id, clé et autres paramètres. appidmch_idkey 等参数。
  • 安装了 Golang 和 Gin 框架。

安装 go-wechat SDK

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

go get github.com/silenceper/wechat/v2

配置环境变量

从微信支付账户中获得以下参数并将其添加到系统环境变量中:

  • APP_ID : 微信 APP_ID
  • MCH_ID: 商户号
  • API_KEY: 商户 API 密钥
export APP_ID=your_appid
export MCH_ID=your_mchid
export API_KEY=your_api_key

构建应用程序

初始化 Gin

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

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

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

    router.Run(":8080")
}

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

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

  1. 添加配置文件

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

{
    "wechat": {
        "appid": "your_appid",
        "secret": "your_app_secret"
    }
}
  1. 初始化 WeChat

下一步是初始化 WeChatClient 并使用 oauth2 请求代码来获取访问令牌。

import (
    "encoding/json"
    "io/ioutil"
    "net/http"
    "os"

    "github.com/silenceper/wechat/v2"
)

func loadConfig() map[string]string {
    file, err := os.Open("config.json")
    if err != nil {
        panic("Failed to load config file.")
    }
    defer file.Close()

    data, err := ioutil.ReadAll(file)
    if err != nil {
        panic("Failed to read config file.")
    }

    var config map[string]map[string]string
    err = json.Unmarshal(data, &config)
    if err != nil {
        panic("Failed to parse config file.")
    }

    return config["wechat"]
}

func initializeWeChat() *wechat.WeChat {
    config := loadConfig()
    client := wechat.NewWechat(&wechat.Config{
        AppID:          config["appid"],
        AppSecret:      config["secret"],
        Token:          "",
        EncodingAESKey: "",
    })

    return client
}

func weChatLoginHandler(c *gin.Context) {
    client := initializeWeChat()

    redirectURL := "<YOUR_REDIRECT_URL>"
    url := client.Oauth2.GetRedirectURL(redirectURL, "snsapi_userinfo", "")
    c.Redirect(http.StatusTemporaryRedirect, url)
}

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

  1. 处理微信授权

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

func callbackHandler(c *gin.Context) {
    code := c.Request.URL.Query().Get("code")

    client := initializeWeChat()
    accessToken, err := client.Oauth2.GetUserAccessToken(code)
    if err != nil {
        panic("Failed to get access token from WeChat.")
    }

    userInfo, err := client.Oauth2.GetUserInfo(accessToken.AccessToken, accessToken.Openid)
    if err != nil {
        panic("Failed to get user info from WeChat.")
    }

    session := sessions.Default(c)
    session.Set("wechat_openid", userInfo.Openid)
    session.Set("wechat_nickname", userInfo.Nickname)
    session.Save()

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

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

func main() {
    ...
    router.GET("/wechat/login", weChatLoginHandler)
    router.GET("/wechat/callback", callbackHandler)
    ...
}

实现购物车

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

type CartItem struct {
    ProductID int
    Quantity  int
}

func (c *CartItem) Subtotal() float64 {
    // TODO: Implement.
}

type Cart struct {
    Contents []*CartItem
}

func (c *Cart) Add(productID, quantity int) {
    item := &CartItem{
        ProductID: productID,
        Quantity:  quantity,
    }

    found := false
    for _, existingItem := range c.Contents {
        if existingItem.ProductID == productID {
            existingItem.Quantity += quantity
            found = true
            break
        }
    }

    if !found {
        c.Contents = append(c.Contents, item)
    }
}

func (c *Cart) Remove(productID int) {
    for i, item := range c.Contents {
        if item.ProductID == productID {
            c.Contents = append(c.Contents[:i], c.Contents[i+1:]...)
            break
        }
    }
}

func (c *Cart) Total() float64 {
    total := 0.0
    for _, item := range c.Contents {
        total += item.Subtotal()
    }
    return total
}

func cartFromSession(session sessions.Session) *Cart {
    value := session.Get("cart")
    if value == nil {
        return &Cart{}
    }

    cartBytes := []byte(value.(string))
    var cart Cart
    json.Unmarshal(cartBytes, &cart)
    return &cart
}

func syncCartToSession(session sessions.Session, cart *Cart) {
    cartBytes, err := json.Marshal(cart)
    if err != nil {
        panic("Failed to sync cart with session data store.")
    }

    session.Set("cart", string(cartBytes))
    session.Save()
}

如上所示,我们实现了一个包含 Add(productID, quantity int)Remove(productID int), Total() float64几个方法的 cart struct。我们从会话中存储和加载 cart 数据 (cartFromSession()syncCartToSession()),并通过 CartItem.Subtotal()

Framework Golang et Gin installé.

Installer le SDK go-wechat

Avant de continuer, veuillez installer le SDK WeChat à partir du référentiel Github de go-wechat.

<footer>
    <div class="container">
        <div class="row">
            <div class="col-sm-4">
                <a href="/">Back to home</a>
            </div>
            <div class="col-sm-4">
                <p id="cart-count"></p>
            </div>
            <div class="col-sm-4">
                <p id="cart-total"></p>
            </div>
        </div>
    </div>
</footer>
<script>
    document.getElementById("cart-count").innerText = "{{.CartItemCount}} items in cart";
    document.getElementById("cart-total").innerText = "Total: ${{.CartTotal}}";
</script>

Configurer les variables d'environnement

Récupérez les paramètres suivants à partir du compte de paiement WeChat et ajoutez-les aux variables d'environnement du système :

  1. APP_ID : WeChat APP_ID
MCH_ID : Numéro du marchand
  1. API_KEY : Clé API du marchand
type Order struct {
    OrderNumber string
    Amount      float64
}

Construire l'application

Initialiser Gin

    Dans le fichier main.go, nous utiliserons le package gin pour initialiser l’application. <li><pre class='brush:go;toolbar:false;'>func generateOutTradeNo() string { // TODO: Implement. } func createOrder(cart *Cart) *Order { order := &amp;Order{ OrderNumber: generateOutTradeNo(), Amount: cart.Total(), } client := initializeWeChat() payment := &amp;wechat.Payment{ AppID: APP_ID, MchID: MCH_ID, NotifyURL: &quot;&lt;YOUR_NOTIFY_URL&gt;&quot;, TradeType: &quot;JSAPI&quot;, Body: &quot;购物车结算&quot;, OutTradeNo: order.OrderNumber, TotalFee: int(order.Amount * 100), SpbillCreateIP: &quot;127.0.0.1&quot;, OpenID: &quot;&lt;USER_WECHAT_OPENID&gt;&quot;, Key: API_KEY, } result, err := client.Pay.SubmitPayment(payment) if err != nil { panic(&quot;Failed to submit payment.&quot;) } // Save order state and return it. return order }</pre><h3>Ajouter la connexion WeChat à l'application</h3> </li>Sur la page précédente, nous avons configuré l'application de base Gin. Nous allons maintenant ajouter la fonctionnalité de connexion WeChat.

Ajouter un fichier de configuration

    Vous pouvez choisir de définir la configuration via le format JSON, YAML ou TOML. Ici, nous allons créer un fichier config.json pour définir la configuration.
  • func setupCheckOrderStatus() {
        go func() {
            for {
                // Wait 10 seconds before checking (or less if you want to check more frequently).
                time.Sleep(10 * time.Second)
    
                client := initializeWeChat()
                // TODO: Retrieve orders that need to be checked.
                for _, order := range ordersToCheck {
                    queryOrderResult, err := client.Pay.QueryOrder(&wechat.QueryOrderParams{
                        OutTradeNo: order.OrderNumber,
                    })
                    if err != nil {
                        panic("Failed to query order.")
                    }
    
                    switch queryOrderResult.TradeState {
                    case wechat.TradeStateSuccess:
                        // Handle order payment in your app.
                        order.Paid = true
                        // TODO: Update order state in database.
                    case wechat.TradeStateClosed:
                        // Handle order payment in your app.
                        order.Paid = false
                        // TODO: Update order state in database.
                    case wechat.TradeStateRefund:
                        // Handle order payment in your app.
                        order.Paid = false
                        // TODO: Update order state in database.
                    default:
                        break
                    }
    
                    // TODO: Remove checked order from cache.
                }
            }
        }()
    }
  • Initialiser WeChat
  • L'étape suivante consiste à initialiser WeChatClient et à utiliser le code de requête oauth2 pour obtenir le jeton d'accès.
rrreee

Essentiellement, nous définissons un WeChatClient qui contient l'authentification de l'application. Nous définissons également un gestionnaire Gin qui définit l'URL de redirection et obtient le jeton d'accès à l'aide de la requête oauth2 dans WeChatClient.

Gestion de l'autorisation WeChat🎜🎜🎜Dans l'URL de redirection, le gestionnaire /wechat/callback est appelé lorsque l'utilisateur autorise notre application à s'exécuter sous son compte. Ce gestionnaire stocke l'identifiant WeChat, le surnom et d'autres données publiques de l'utilisateur dans la session de l'utilisateur. 🎜rrreee
    🎜Intégrer la connexion WeChat🎜🎜🎜Nous devrions intégrer la connexion WeChat dans notre application. Le processus est relativement simple. Ajoutez simplement le gestionnaire au routeur Gin. 🎜rrreee🎜Implémentation du panier🎜🎜Nous ajouterons un état de base du panier à l'application. Ajoutez simplement les informations du panier dans la session utilisateur. 🎜rrreee🎜Comme indiqué ci-dessus, nous avons implémenté une fonction comprenant Add(productID,Quantity int), Remove(productID int), Total() float64 Cart struct avec plusieurs méthodes. Nous stockons et chargeons les données du panier de la session (cartFromSession() et syncCartToSession()) et calculons les articles via CartItem.Subtotal() méthode de sous-total. 🎜🎜Affichez l'état du panier en bas de la page : 🎜rrreee🎜Paiement WeChat🎜🎜Afin de mettre en œuvre le paiement WeChat, nous devons définir une structure de commande, générer la commande et l'envoyer au paiement WeChat, et traiter le paiement. notification. Vous trouverez ci-dessous une implémentation simple. 🎜🎜🎜Définir la structure de la commande🎜🎜rrreee🎜🎜Générer la commande et envoyer la commande à WeChat🎜🎜🎜Dans cette étape, nous générerons la commande et créerons le numéro de commande via le paiement WeChat. Lisez la documentation sur les paiements de go-wechat pour en savoir plus. 🎜rrreee🎜🎜Traitement des notifications de paiement WeChat🎜🎜🎜Une fois que WeChat nous a informé que nous avons reçu le paiement de l'utilisateur, dans le rappel, nous stockerons le statut de la commande pour une requête ultérieure. 🎜rrreee🎜Nous devons appeler la fonction de requête pour vérifier la transaction où WeChat force le changement du statut de la commande. Le SDK WeChat renverra l'un des statuts suivants. 🎜🎜🎜TradeStateSuccess : le paiement de l'utilisateur a réussi. 🎜🎜TradeStateClosed : La commande a été clôturée. 🎜🎜TradeStateRefund : La transaction a été remboursée. 🎜🎜🎜Résumé🎜🎜Dans cet article, nous avons appris à utiliser le framework Golang et Gin pour créer un site Web de commerce électronique et à utiliser le SDK go-wechat pour implémenter rapidement les fonctions de connexion et de paiement WeChat. Nous avons appris comment gérer l'authentification et l'autorisation des utilisateurs via WeChatClient et comment stocker les données utilisateur WeChat dans la session de l'utilisateur. Nous avons également appris à définir un panier et une commande simples et à les intégrer à WeChat Pay à l'aide du SDK go-wechat. 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn