Maison > Article > développement back-end > Comment utiliser Golang pour mettre en œuvre le paiement WeChat pour les applications Web
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.
Dans ce tutoriel, nous allons créer un site Web de commerce électronique simple. Le site Web doit mettre en œuvre les fonctions suivantes :
Avant de commencer, assurez-vous d'avoir les conditions suivantes :
appid
, mch_id
, clé
et autres paramètres. appid
、mch_id
、key
等参数。在继续之前,请从 go-wechat 的 Github 存储库中安装微信 SDK。
go get github.com/silenceper/wechat/v2
从微信支付账户中获得以下参数并将其添加到系统环境变量中:
APP_ID
: 微信 APP_IDMCH_ID
: 商户号API_KEY
: 商户 API 密钥export APP_ID=your_appid export MCH_ID=your_mchid export API_KEY=your_api_key
在文件 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 应用程序。我们现在将添加微信登录功能。
您可以选择通过 JSON 、YAML 或 TOML 格式定义配置。这里,我们将 创建一个 config.json
文件来定义配置。
{ "wechat": { "appid": "your_appid", "secret": "your_app_secret" } }
下一步是初始化 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
请求获取访问令牌。
在重定向 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, "/") }
我们应该将微信登录集成到我们的应用程序中。这个过程相对简单。仅需将处理程序添加到 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()
<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>
Récupérez les paramètres suivants à partir du compte de paiement WeChat et ajoutez-les aux variables d'environnement du système :
APP_ID
: WeChat APP_ID MCH_ID
: Numéro du marchandAPI_KEY
: Clé API du marchandtype Order struct { OrderNumber string Amount float64 }
Construire l'application
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 := &Order{
OrderNumber: generateOutTradeNo(),
Amount: cart.Total(),
}
client := initializeWeChat()
payment := &wechat.Payment{
AppID: APP_ID,
MchID: MCH_ID,
NotifyURL: "<YOUR_NOTIFY_URL>",
TradeType: "JSAPI",
Body: "购物车结算",
OutTradeNo: order.OrderNumber,
TotalFee: int(order.Amount * 100),
SpbillCreateIP: "127.0.0.1",
OpenID: "<USER_WECHAT_OPENID>",
Key: API_KEY,
}
result, err := client.Pay.SubmitPayment(payment)
if err != nil {
panic("Failed to submit payment.")
}
// 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.
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. } } }() }
WeChatClient
et à utiliser le code de requête oauth2
pour obtenir le jeton d'accès. oauth2
dans WeChatClient
. /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. 🎜rrreeeAdd(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!