WeChat Pay は非常に一般的なオンライン支払い方法であり、多くの Web サイト/アプリケーションはこの機能を統合する必要があります。この記事では、Golangを使ってWeChatの決済機能を実装する方法を紹介します。この記事では、Gin フレームワークを使用して単純な Web アプリケーションを構築し、go-wechat WeChat SDK を使用して WeChat 支払いを迅速に実装します。
このチュートリアルでは、単純な電子商取引 Web サイトを構築します。 Web サイトには次の機能を実装する必要があります。
開始する前に、次の要件を満たしていることを確認してください:
appid を持っていること
、mch_id
、key
およびその他のパラメーター。 次に進む前に、go-wechat の Github リポジトリから WeChat SDK をインストールしてください。
go get github.com/silenceper/wechat/v2
WeChat 支払いアカウントから次のパラメーターを取得し、システム環境変数に追加します:
APP_ID
: WeChat APP_IDMCH_ID
: マーチャント IDAPI_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") }
前のページで、基本的な Jin アプリケーションをセットアップしました。ここで、WeChat ログイン機能を追加します。
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 を定義します。また、リダイレクト URL を設定し、WeChatClient
の oauth2
リクエストを使用してアクセス トークンを取得する Jin ハンドラーも定義します。
ユーザーが自分のアカウントでアプリケーションを実行することを承認すると、リダイレクト URL で /wechat/callback# が呼び出されます。 # ハンドラー。このハンドラーは、ユーザーの WeChat 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, "/") }
func main() { ... router.GET("/wechat/login", weChatLoginHandler) router.GET("/wechat/callback", callbackHandler) ... }
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,数量 int)、
Remove(productID int)、
Total() float64# を含む関数を実装しました。 ##カート構造体のいくつかのメソッド。セッション (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>
WeChat 支払い
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. } } }() }
クエリ関数を呼び出して、WeChat が注文ステータスを強制的に変更するトランザクションを確認する必要があります。 WeChat SDK は次のいずれかのステータスを返します。
TradeStateSuccess: ユーザーの支払いは成功しました。以上がGolang を使用して Web アプリケーションに WeChat 支払いを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。