WeChat Pay ist eine sehr verbreitete Online-Zahlungsmethode und viele Websites/Anwendungen müssen diese Funktion integrieren. In diesem Artikel wird erläutert, wie Sie mit Golang die WeChat-Zahlungsfunktion implementieren. In diesem Artikel werden wir das Gin-Framework verwenden, um eine einfache Webanwendung zu erstellen und das go-wechat WeChat SDK verwenden, um die WeChat-Zahlung schnell zu implementieren.
In diesem Tutorial erstellen wir eine einfache E-Commerce-Website. Die Website muss die folgenden Funktionen implementieren:
Bevor Sie beginnen, stellen Sie bitte sicher, dass Sie die folgenden Anforderungen erfüllen:
appid
, mch_id
, key
und andere Parameter. 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>
Rufen Sie die folgenden Parameter aus dem WeChat-Zahlungskonto ab und fügen Sie sie den Systemumgebungsvariablen hinzu:
APP_ID
: WeChat APP_ID MCH_ID
: HändlernummerAPI_KEY
: Händler-API-Schlüsseltype Order struct { OrderNumber string Amount float64 }
Erstellen Sie die Anwendung
main.go< /code>, wir werden das Gin-Paket verwenden, um die Anwendung zu initialisieren. <li><div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="contentsignin">Nach dem Login kopieren</div></div><h3>WeChat-Login zur App hinzufügen</h3></li>Auf der vorherigen Seite haben wir die grundlegende Gin-App eingerichtet. Wir werden jetzt die WeChat-Anmeldefunktion hinzufügen. </ol><p></p>Konfigurationsdatei hinzufügen<p></p><ul>Sie können wählen, ob Sie die Konfiguration im JSON-, YAML- oder TOML-Format definieren möchten. Hier erstellen wir eine <code>config.json
-Datei, um die Konfiguration zu definieren. 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
zu initialisieren und den oauth2
-Anfragecode zu verwenden, um das Zugriffstoken zu erhalten. rrreeeoauth2
-Anfrage in WeChatClient
erhält. /wechat/callback
-Handler aufgerufen, wenn der Benutzer unsere App zur Ausführung unter seinem Konto autorisiert. Dieser Handler speichert die WeChat-ID, den Spitznamen und andere öffentliche Daten des Benutzers in der Sitzung des Benutzers. 🎜rrreeeAdd(productID, amount int)
, Remove(productID int)
, Total() float64
enthält > Warenkorbstruktur mit mehreren Methoden. Wir speichern und laden Warenkorbdaten aus der Sitzung (cartFromSession()
und syncCartToSession()
) und berechnen die Artikel über CartItem.Subtotal()
Methode der Zwischensumme. 🎜🎜Warenkorbstatus unten auf der Seite anzeigen: 🎜rrreee🎜WeChat-Zahlung🎜🎜Um die WeChat-Zahlung zu implementieren, müssen wir eine Bestellstruktur definieren, die Bestellung generieren und an die WeChat-Zahlung senden und die Zahlungsbenachrichtigung verarbeiten . Nachfolgend finden Sie eine einfache Implementierung. 🎜🎜🎜Bestellstruktur definieren🎜🎜rrreee🎜🎜Bestellung generieren und an WeChat senden🎜🎜🎜In diesem Schritt generieren wir eine Bestellung und erstellen eine Bestellnummer über die WeChat-Zahlung. Lesen Sie die Zahlungsdokumentation von go-wechat, um mehr zu erfahren. 🎜rrreee🎜🎜Bearbeitung von WeChat-Zahlungsbenachrichtigungen🎜🎜🎜Nachdem WeChat uns mitgeteilt hat, dass wir die Zahlung des Benutzers erhalten haben, speichern wir im Rückruf den Bestellstatus für eine spätere Abfrage. 🎜rrreee🎜Wir müssen die Abfragefunktion aufrufen, um die Transaktion von WeChat zu überprüfen und eine Änderung des Bestellstatus zu erzwingen. Das WeChat SDK gibt einen der folgenden Status zurück. 🎜🎜🎜TradeStateSuccess: Die Zahlung des Benutzers war erfolgreich. 🎜🎜TradeStateClosed: Die Bestellung wurde geschlossen. 🎜🎜TradeStateRefund: Die Transaktion wurde erstattet. 🎜🎜🎜Zusammenfassung🎜🎜In diesem Artikel haben wir gelernt, wie man mit dem Golang- und Gin-Framework eine E-Commerce-Website erstellt und mit dem Go-Wechat SDK schnell WeChat-Anmelde- und Zahlungsfunktionen implementiert. Wir haben gelernt, wie man die Benutzerauthentifizierung und -autorisierung über WeChatClient handhabt und wie man WeChat-Benutzerdaten in der Sitzung des Benutzers speichert. Wir haben auch gelernt, wie man mit dem go-wechat SDK einen einfachen Warenkorb definiert und bestellt und in WeChat Pay integriert. 🎜Das obige ist der detaillierte Inhalt vonSo implementieren Sie WeChat-Zahlungen für Webanwendungen mit Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!