Rumah >pembangunan bahagian belakang >Golang >Cara menggunakan Golang untuk melaksanakan pembayaran WeChat untuk aplikasi web
WeChat Pay ialah kaedah pembayaran dalam talian yang sangat biasa, dan banyak tapak web/aplikasi perlu menyepadukan fungsi ini. Artikel ini akan memperkenalkan cara menggunakan Golang untuk melaksanakan fungsi pembayaran WeChat. Dalam artikel ini, kami akan menggunakan rangka kerja Gin untuk membina aplikasi web mudah dan menggunakan SDK WeChat go-wechat untuk melaksanakan pembayaran WeChat dengan cepat.
Dalam tutorial ini, kami akan membina laman web e-dagang yang ringkas. Laman web perlu melaksanakan fungsi berikut:
Sebelum anda mula, sila pastikan anda mempunyai keperluan berikut:
appid
, mch_id
, key
dan parameter lain. Sebelum meneruskan, sila pasang SDK WeChat daripada repositori Github go-wechat.
go get github.com/silenceper/wechat/v2
Dapatkan parameter berikut daripada akaun pembayaran WeChat dan tambahkannya pada pembolehubah persekitaran sistem:
APP_ID
: WeChat APP_IDMCH_ID
: ID PedagangAPI_KEY
: Kunci API Pedagangexport APP_ID=your_appid export MCH_ID=your_mchid export API_KEY=your_api_key
Dalam fail main.go
kami akan menggunakan pakej gin untuk memulakan aplikasi.
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") }
Pada halaman sebelumnya, kami menyediakan apl asas Gin. Kami kini akan menambah fungsi log masuk WeChat.
Anda boleh memilih untuk menentukan konfigurasi melalui format JSON, YAML atau TOML. Di sini, kami akan mencipta fail config.json
untuk menentukan konfigurasi.
{ "wechat": { "appid": "your_appid", "secret": "your_app_secret" } }
Langkah seterusnya ialah untuk memulakan WeChatClient
dan gunakan kod permintaan oauth2
untuk mendapatkan token akses.
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) }
Pada asasnya, kami mentakrifkan WeChatClient yang mengandungi pengesahan untuk aplikasi. Kami juga mentakrifkan pengendali Gin yang menetapkan URL ubah hala dan mendapatkan token akses menggunakan WeChatClient
dalam permintaan. oauth2
dipanggil apabila pengguna membenarkan apl kami untuk dijalankan di bawah akaun mereka. Pengendali ini menyimpan ID WeChat pengguna, nama panggilan dan data awam lain dalam sesi pengguna. /wechat/callback
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, "/") }
func main() { ... router.GET("/wechat/login", weChatLoginHandler) router.GET("/wechat/callback", callbackHandler) ... }Melaksanakan troli beli-belahKami akan menambah keadaan troli beli-belah asas pada aplikasi. Hanya tambah maklumat troli beli-belah dalam sesi pengguna.
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() }Seperti yang ditunjukkan di atas, kami melaksanakan struct troli yang mengandungi beberapa kaedah:
, Add(productID, quantity int)
, Remove(productID int)
. Kami menyimpan dan memuatkan data troli (Total() float64
dan cartFromSession()
) daripada sesi dan mengira jumlah kecil item melalui kaedah 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>WeChat PaymentUntuk melaksanakan pembayaran WeChat, kita perlu mentakrifkan struktur pesanan, menjana pesan dan hantar ke pembayaran WeChat , memproses pemberitahuan pembayaran. Di bawah adalah pelaksanaan mudah.
type Order struct { OrderNumber string Amount float64 }
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 }
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. } } }() }Kami perlu memanggil fungsi pertanyaan untuk menyemak transaksi di mana WeChat memaksa menukar status pesanan. SDK WeChat akan mengembalikan salah satu daripada status berikut.
Atas ialah kandungan terperinci Cara menggunakan Golang untuk melaksanakan pembayaran WeChat untuk aplikasi web. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!