頁 JSAPI 支付接入實(shí)戰(zhàn):基于 Senparc.Weixin SDK 微信支付 V3 全流程解析)
后端即時(shí)通訊金融科技【免費(fèi)下載鏈接】WeiXinMPSDK微信全平臺 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公眾號、小程序、小游戲、微信支付、企業(yè)微信/企業(yè)號、開放平臺、JSSDK、微信周邊等全平臺。 WeChat SDK for C#.項(xiàng)目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK點(diǎn)擊查看免費(fèi)下載導(dǎo)讀本文以 Senparc.WeixinWeiXinMPSDK倉庫中微信支付 V3 的官方指南 docs/en/guide/tenpayv3/jssdk.md及其中文對照版 docs/zh/guide/tenpayv3/jssdk.md為骨架圍繞“在微信公眾號網(wǎng)頁中使用 JSAPI 完成微信支付”這一核心場景展開。文章將帶你走完從商品列表、商品詳情到預(yù)支付下單、前端喚起支付、后端支付結(jié)果通知的完整鏈路并結(jié)合倉庫內(nèi)TenPayApiV3Controller控制器、JsApi.cshtml視圖與TenPaySignHelper簽名工具的真實(shí)源碼講透prepay_id、JsApiUiPackage信息包與 RSA/國密簽名等底層原理。讀完你可以直接照著示例項(xiàng)目在自己的公眾號網(wǎng)頁中落地 JSAPI 支付。在微信公眾號網(wǎng)頁中使用微信支付必須借助 JSAPI 完成支付流程。官方示例在 Samples/TenPayV3/Senparc.Weixin.Sample.TenPayV3 中提供了 3 個(gè)關(guān)鍵頁面頁面作用ProductList商品列表展示商品提供下單入口如“一鍵購買”ProductItem商品詳情展示商品詳情根據(jù)運(yùn)行環(huán)境分流到 JSAPI 支付或掃碼支付JsApiJSAPI 訂單支付生成預(yù)支付訂單并喚起微信支付三個(gè)頁面對應(yīng)的后端邏輯全部集中在 Controllers/TenPayApiV3Controller.cs注意倉庫文件名是TenPayApiV3Controller.cs與文檔中略寫的TenPayApiV3Controller.cs對應(yīng)前端視圖位于 Views/TenPayApiV3 目錄。一、商品列表頁P(yáng)roductList提供下單入口JSAPI 支付的第一步是讓用戶找到一個(gè)“下訂單”的入口。示例項(xiàng)目用內(nèi)存模擬了一份商品數(shù)據(jù)見 Models/ProductModel.cs 中的GetFakeProductList()后端僅需一行代碼即可渲染商品列表public IActionResult ProductList() { var products ProductModel.GetFakeProductList(); return View(products); }對應(yīng)源碼位置TenPayApiV3Controller.cs#L113-L117。ProductList()從內(nèi)存獲取商品集合交給ProductList.cshtml視圖渲染每個(gè)商品上提供進(jìn)入詳情的鏈接同時(shí)把productId與hc商品信息的 HashCode作為參數(shù)傳遞用于后續(xù)校驗(yàn)。視圖商品列表的前端展示請參考Views/TenPayApiV3下的對應(yīng)視圖文件。文檔對應(yīng)小節(jié)見 docs/en/guide/tenpayv3/jssdk.md#productlist-productlist。在實(shí)際項(xiàng)目中商品列表通常來自數(shù)據(jù)庫GetFakeProductList()僅作為演示。二、商品詳情頁P(yáng)roductItem按運(yùn)行環(huán)境分流商品詳情頁的職責(zé)不止是展示商品還要判斷“當(dāng)前頁面是在微信內(nèi)打開還是在 PC 瀏覽器打開”從而決定走哪條支付路徑public ActionResult ProductItem(int productId, int hc) { var products ProductModel.GetFakeProductList(); var product products.FirstOrDefault(z z.Id productId); if (product null || product.GetHashCode() ! hc) { return Content(商品信息不存在或非法進(jìn)入2003); } //判斷是否正在微信端 if (Senparc.Weixin.BrowserUtility.BrowserUtility.SideInWeixinBrowser(HttpContext)) { //正在微信端直接跳轉(zhuǎn)到微信支付頁面 return RedirectToAction(JsApi, new { productId productId, hc hc }); } else { //在PC端打開提供二維碼掃描進(jìn)行支付 return View(product); } }對應(yīng)源碼位置TenPayApiV3Controller.cs#L124-L144。關(guān)鍵點(diǎn) 1productId與hc雙參數(shù)校驗(yàn)productId是商品編號示例中從內(nèi)存列表查詢真實(shí)項(xiàng)目中通常以數(shù)據(jù)庫為準(zhǔn)。hc是商品信息對應(yīng)的GetHashCode()值用來防止非法或過期參數(shù)直接進(jìn)入下單流程如價(jià)格被篡改。文檔明確說明hc僅用于保證示例內(nèi)存數(shù)據(jù)的有效性實(shí)際開發(fā)項(xiàng)目中可以忽略。關(guān)鍵點(diǎn) 2SideInWeixinBrowser()環(huán)境判斷方法Senparc.Weixin.BrowserUtility.BrowserUtility.SideInWeixinBrowser(HttpContext)用于判斷當(dāng)前請求是否來自微信內(nèi)置瀏覽器在微信內(nèi)打開直接RedirectToAction(JsApi, ...)進(jìn)入 JSAPI 訂單支付頁此時(shí)拿不到手機(jī)掃碼環(huán)節(jié)直接喚起支付。在 PC 端打開渲染商品詳情頁并提供多種支付方式選擇其中“掃一掃”支付會在頁面底部根據(jù)所選商品自動生成二維碼用戶用手機(jī)微信掃碼后即可進(jìn)入對應(yīng)的 JsApi 訂單頁面對應(yīng)控制器中的NativePayCode與ProductPayCode方法見 TenPayApiV3Controller.cs#L152-L206二者分別生成 Native 支付碼與跳轉(zhuǎn)手機(jī)詳情頁的二維碼。前端視圖參考 Views/TenPayApiV3/ProductItem.cshtml。三、JSAPI 訂單支付頁JsApi預(yù)支付下單與喚起支付這是整個(gè)流程的核心頁面。用戶點(diǎn)擊下單按鈕后后端需要生成預(yù)支付訂單拿到prepay_id前端再憑借它喚起微信支付。文檔對應(yīng)的代碼參考TenPayApiV3Controller.JsApi()倉庫中的完整實(shí)現(xiàn)如下//需要OAuth登錄 [CustomOAuth(null, /TenpayApiV3/OAuthCallback)] public async TaskIActionResult JsApi(int productId, int hc) { try { //獲取產(chǎn)品信息 var products ProductModel.GetFakeProductList(); var product products.FirstOrDefault(z z.Id productId); if (product null || product.GetHashCode() ! hc) { return Content(商品信息不存在或非法進(jìn)入1002); } ViewData[product] product; var openId HttpContext.Session.GetString(OpenId); string sp_billno Request.Query[order_no];//out_trade_no if (string.IsNullOrEmpty(sp_billno)) { //生成訂單10位序列號此處用時(shí)間和隨機(jī)數(shù)生成商戶根據(jù)自己調(diào)整保證唯一 sp_billno string.Format({0}{1}{2}, TenPayV3Info.MchId/*10位*/, SystemTime.Now.ToString(yyyyMMddHHmmss), TenPayV3Util.BuildRandomStr(6)); } else { sp_billno Request.Query[order_no]; } //調(diào)用下單接口下單 var name product null ? test : product.Name; var price product null ? 100 : (int)(product.Price * 100);//單位分 var notifyUrl TenPayV3Info.TenPayV3Notify; //請求信息 TransactionsRequestData jsApiRequestData new(TenPayV3Info.AppId, TenPayV3Info.MchId, name - 微信支付 V3, sp_billno, new TenpayDateTime(DateTime.Now.AddHours(1), false), null, notifyUrl, null, new() { currency CNY, total price }, new(openId), null, null, null); //請求接口 var basePayApis2 new Senparc.Weixin.TenPayV3.TenPayHttpClient.BasePayApis2(_httpClient, _tenpayV3Setting); var result await basePayApis2.JsApiAsync(jsApiRequestData); if (result.VerifySignSuccess ! true) { throw new WeixinException(獲取 prepay_id 結(jié)果校驗(yàn)出錯(cuò)); } //獲取 UI 信息包 var jsApiUiPackage TenPaySignHelper.GetJsApiUiPackage(TenPayV3Info.AppId, result.prepay_id, Senparc.Weixin.Config.SenparcWeixinSetting); ViewData[jsApiUiPackage] jsApiUiPackage; //臨時(shí)記錄訂單信息留給退款申請接口測試使用分布式情況下請注意數(shù)據(jù)同步 HttpContext.Session.SetString(BillNo, sp_billno); HttpContext.Session.SetString(BillFee, price.ToString()); return View(); } catch (Exception ex) { Senparc.Weixin.WeixinTrace.BaseExceptionLog(ex); throw; } }對應(yīng)源碼位置TenPayApiV3Controller.cs#L254-L315。文檔中的代碼片段保留了更早期的寫法如var result TenPayOldV3.Unifiedorder(xmlDataInfo)或直接以TenPayV3Info.AppId調(diào)用GetJsApiUiPackage倉庫當(dāng)前版本已演進(jìn)為TenPayHttpClient.BasePayApis2.JsApiAsync()與帶TenPayV3Info的新重載但核心語義完全一致result.prepay_id即“預(yù)支付 ID”前端必須憑借它才能在手機(jī)端喚起微信支付此時(shí)當(dāng)前訂單編號已在微信支付后臺注冊。3.1[CustomOAuth]特性自動完成用戶身份識別JsApi()方法上標(biāo)注了[CustomOAuth(null, /TenpayApiV3/OAuthCallback)]該特性實(shí)現(xiàn)見 Filters/CustomOAuthAttribute.cs用于自動使用微信公眾號 OAuth 能力識別用戶身份回調(diào)地址指向OAuthCallbackTenPayApiV3Controller.cs#L213-L247拿到openid后存入 Session。JSAPI 支付要求payer.openid與當(dāng)前公眾號用戶一致因此該步驟不能省略。文檔特別說明OAuth 屬于公眾號功能范疇本文不展開。3.2 下單請求參數(shù)TransactionsRequestDataTransactionsRequestData是微信支付 V3 下單接口的請求數(shù)據(jù)實(shí)體構(gòu)造參數(shù)順序?qū)?yīng)如下語義示例中按位置傳參位置參數(shù)含義示例值/說明appid公眾號 AppIdTenPayV3Info.AppIdmchid商戶號TenPayV3Info.MchIddescription商品描述name - 微信支付 V3out_trade_no商戶訂單號必唯一sp_billno商戶號時(shí)間6 位隨機(jī)數(shù)time_expire訂單失效時(shí)間new TenpayDateTime(DateTime.Now.AddHours(1), false)1 小時(shí)后過期attach附加數(shù)據(jù)nullnotify_url支付結(jié)果回調(diào)地址TenPayV3Info.TenPayV3Notifygoods_tag商品標(biāo)記nullamount金額對象new() { currency CNY, total price }單位分payer支付者信息new(openId)detail/scene_info等擴(kuò)展信息null金額單位是分示例中(int)(product.Price * 100)正是把元換算成分。訂單號生成邏輯在 TenPayApiV3Controller.cs#L269-L281代碼注釋提醒高訪問量場景下應(yīng)增加訂單流水號去重檢查。3.3 發(fā)起下單請求與驗(yàn)簽var basePayApis2 new Senparc.Weixin.TenPayV3.TenPayHttpClient.BasePayApis2(_httpClient, _tenpayV3Setting); var result await basePayApis2.JsApiAsync(jsApiRequestData); if (result.VerifySignSuccess ! true) { throw new WeixinException(獲取 prepay_id 結(jié)果校驗(yàn)出錯(cuò)); }BasePayApis2是 SDK 基于TenPayHttpClient實(shí)現(xiàn)的支付基礎(chǔ)能力封裝JsApiAsync()定義于 TenPayHttpClient/TenPayHttpClient.cspublic async TaskJsApiReturnJson JsApiAsync(TransactionsRequestData data, int timeOut Config.TIME_OUT)。返回結(jié)果JsApiReturnJson中的prepay_id是喚起支付的憑證SDK 還內(nèi)置了VerifySignSuccess響應(yīng)驗(yàn)簽這是安全鏈路的重要一環(huán)——驗(yàn)簽失敗直接拋WeixinException避免把偽造的prepay_id交給前端。3.4 生成前端 UI 信息包GetJsApiUiPackage拿到prepay_id后還需要為前端組裝調(diào)起支付所需的全部簽名信息var jsApiUiPackage TenPaySignHelper.GetJsApiUiPackage(TenPayV3Info.AppId, result.prepay_id, Senparc.Weixin.Config.SenparcWeixinSetting); ViewData[jsApiUiPackage] jsApiUiPackage;JsApiUiPackage實(shí)體定義在 Entities/JsApiUiPackage.cs包含 5 個(gè)字段屬性含義AppId公眾號 AppIdTimestamp時(shí)間戳NonceStr隨機(jī)串PrepayIdPackage打包后的預(yù)支付標(biāo)識形如prepay_idxxxSignature微信支付簽名SignType簽名類型固定返回RSA見 JsApiUiPackage.cs#L65GetJsApiUiPackage()的底層實(shí)現(xiàn)Helpers/TenPaySignHelper.cs#L311-L325依次完成生成時(shí)間戳TenPayV3Util.GetTimestamp()與隨機(jī)串TenPayV3Util.GetNoncestr()將prepay_id打包為prepay_id{0}格式GetPrepayIdPackage若傳入時(shí)已帶前綴會自動歸一化調(diào)用CreatePaySign(timeStamp, nonceStr, prepayIdPackage, tenPayV3Info)計(jì)算簽名組裝并返回JsApiUiPackage。其中CreatePaySign的簽名串格式為見 TenPaySignHelper.cs#L158-L162{appId}\n{timeStamp}\n{nonceStr}\n{package}\n簽名算法由商戶證書類型CertType決定RSA 模式下使用 SHA256withRSAPKCS#1 填充國密SM模式下使用 SM3withSM2密鑰從TenPayV3_PrivateKey配置讀取TenPaySignHelper.cs#L73-L112。SDK 同時(shí)支持“微信平臺證書”與“微信支付公鑰”兩種驗(yàn)簽方式VerifyTenpaySign見 TenPaySignHelper.cs#L176-L266。3.5 前端WeixinJSBridge喚起支付文檔指出前端的關(guān)鍵操作是“當(dāng)用戶點(diǎn)擊支付按鈕后執(zhí)行 JS 代碼”。倉庫中的視圖 Views/TenPayApiV3/JsApi.cshtml 給出了完整實(shí)現(xiàn)// 當(dāng)微信內(nèi)置瀏覽器完成內(nèi)部初始化后會觸發(fā)WeixinJSBridgeReady事件。 document.addEventListener(WeixinJSBridgeReady, function onBridgeReady() { //公眾號支付 jQuery(#getBrandWCPayRequest).click(function (e) { WeixinJSBridge.invoke(getBrandWCPayRequest, { appId: jsApiUiPackage.AppId, timeStamp: jsApiUiPackage.Timestamp, nonceStr: jsApiUiPackage.NonceStr, package: Html.Raw(jsApiUiPackage.PrepayIdPackage), signType: Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting.EncryptionType, paySign: Html.Raw(jsApiUiPackage.Signature) }, function (res) { if (res.err_msg get_brand_wcpay_request:ok) { setTimeout(function() { if (confirm(支付成功點(diǎn)擊確定進(jìn)入退款流程測試。)) { location.href Url.Action(Refund, TenPayApiV3); } }, 300); } else { alert(JSON.stringify(res)); } }); }); WeixinJSBridge.log(WeixinJSBridge ready); }, false);調(diào)起支付參數(shù)說明WeixinJSBridge.invoke(getBrandWCPayRequest, ...)參數(shù)來源說明appIdjsApiUiPackage.AppId公眾號名稱AppId由商戶傳入timeStampjsApiUiPackage.Timestamp時(shí)間戳nonceStrjsApiUiPackage.NonceStr隨機(jī)串packagejsApiUiPackage.PrepayIdPackage擴(kuò)展包即prepay_idxxx使用Html.Raw輸出避免轉(zhuǎn)義signType配置項(xiàng)EncryptionType微信 V3 簽名類型RSA文檔示例中直接寫死為RSA倉庫視圖則從配置讀取可兼容國密 SM 模式paySignjsApiUiPackage.Signature微信支付簽名同樣用Html.Raw輸出回調(diào)res.err_msg處理當(dāng)res.err_msg get_brand_wcpay_request:ok時(shí)代表用戶已調(diào)起支付。文檔引用微信官方團(tuán)隊(duì)的鄭重提示res.err_msg在用戶支付成功后返回ok但并不保證它絕對可靠。建議當(dāng)收到ok返回時(shí)向商戶后臺詢問是否收到“交易成功”的通知若已收到通知前端展示交易成功界面若未收到商戶后臺應(yīng)主動調(diào)用“查詢訂單”接口核對訂單狀態(tài)再反饋給前端展示對應(yīng)界面。示例頁面在支付成功后還會彈窗引導(dǎo)進(jìn)入退款流程測試Refund方法見 TenPayApiV3Controller.cs#L497-L542并演示了通過TradeNumberToTransactionId對照表記錄transaction_id供退款使用。四、支付結(jié)果通知PayNotifyUrl真正的成功依據(jù)JSAPI 支付的“成功”必須以微信服務(wù)器異步回調(diào)為準(zhǔn)而不是前端res.err_msg。示例中的回調(diào)地址由下單時(shí)的notifyUrlTenPayV3Info.TenPayV3Notify指定處理邏輯在 TenPayApiV3Controller.cs#L322-L387//獲取微信服務(wù)器異步發(fā)送的支付通知信息 var resHandler new TenPayNotifyHandler(HttpContext); var orderReturnJson await resHandler.DecryptGetObjectAsyncOrderReturnJson(_isPublicKey); //演示記錄 transaction_id實(shí)際開發(fā)中需要記錄到數(shù)據(jù)庫以便退款和后續(xù)跟蹤 TradeNumberToTransactionId[orderReturnJson.out_trade_no] orderReturnJson.transaction_id; string trade_state orderReturnJson.trade_state; //驗(yàn)證可靠的支付狀態(tài) if (orderReturnJson.VerifySignSuccess true trade_state SUCCESS) { returnData.code SUCCESS;//正確的訂單處理 /* 提示 * 1、直到這里才能認(rèn)為交易真正成功了可以進(jìn)行數(shù)據(jù)庫操作但是別忘了返回規(guī)定格式的消息 * 2、上述判斷已經(jīng)具有比較高的安全性以外還可以對訪問 IP 進(jìn)行判斷進(jìn)一步加強(qiáng)安全性。 */ } else { returnData.code FAILD;//錯(cuò)誤的訂單處理 returnData.message 驗(yàn)證失敗; }要點(diǎn)總結(jié)TenPayNotifyHandler負(fù)責(zé)解密微信回調(diào)報(bào)文V3 回調(diào)為 AES-256-GCM 加密DecryptGetObjectAsyncOrderReturnJson()直接得到結(jié)構(gòu)化結(jié)果判斷邏輯是VerifySignSuccess true且trade_state SUCCESS兩者同時(shí)滿足才認(rèn)定為支付成功否則返回FAILD處理完業(yè)務(wù)后必須返回固定格式的 JSON 應(yīng)答{code:SUCCESS,message:成功}等微信側(cè)才會停止重推回調(diào)中還演示了將通知原文落盤到App_Data/TenPayNotify/目錄進(jìn)行審計(jì)生產(chǎn)環(huán)境建議入庫。五、升級注意ApiV2 與 ApiV3 的差異文檔末尾特別強(qiáng)調(diào)了一條升級提醒值得在接入時(shí)反復(fù)確認(rèn)微信支付 ApiV2 和 ApiV3 在訂單接口有完全不同的區(qū)別如果升級請留意具體差異體現(xiàn)在多個(gè)層面簽名機(jī)制V2 使用 MD5/HMAC-SHA256 商戶 API KeyV3 使用商戶私鑰 RSASHA256withRSA或國密 SM2 簽名并引入平臺證書/微信支付公鑰驗(yàn)簽請求數(shù)據(jù)實(shí)體V2 的TenPayV3RefundRequestData、xmlDataInfo等 XML 風(fēng)格實(shí)體在 V3 中已被TransactionsRequestData、RefundRequestData、QueryRequestData、CloseRequestData等強(qiáng)類型 JSON 實(shí)體取代Apis/BasePay 目錄調(diào)用方式舊式靜態(tài)入口如文檔示例中的TenPayOldV3.Unifiedorder已演進(jìn)為BasePayApis/BasePayApis2的實(shí)例方法JsApiAsync、NativeAsync、H5Async等。因此從 V2 升級到 V3 時(shí)不能簡單替換請求地址而應(yīng)整體遷移到新的數(shù)據(jù)實(shí)體與調(diào)用鏈。六、JSAPI 支付接入清單與最佳實(shí)踐把上文內(nèi)容收斂為一份可直接照做的接入清單環(huán)境識別在商品詳情頁用BrowserUtility.SideInWeixinBrowser(HttpContext)分流——微信內(nèi)直接進(jìn)JsApiPC 端展示詳情并提供二維碼掃碼入口OAuth 取 openidJsApi方法標(biāo)注[CustomOAuth]通過公眾號 OAuth 獲取用戶openid回調(diào)方法參考OAuthCallback并妥善保存Session/緩存均可分布式環(huán)境注意共享存儲下單組裝TransactionsRequestData注意金額單位是分、訂單號保證唯一、time_expire建議設(shè)置失效時(shí)間調(diào)用BasePayApis2.JsApiAsync()獲取prepay_id驗(yàn)簽檢查result.VerifySignSuccess未通過必須中斷流程組裝 UI 信息包調(diào)用TenPaySignHelper.GetJsApiUiPackage(prepayId, tenPayV3Info)得到JsApiUiPackage傳入視圖前端喚起監(jiān)聽WeixinJSBridgeReady用WeixinJSBridge.invoke(getBrandWCPayRequest, ...)調(diào)起支付注意package與paySign需Html.Raw輸出可靠判定前端res.err_msg get_brand_wcpay_request:ok僅作參考最終以PayNotifyUrl回調(diào)中VerifySignSuccess trade_state SUCCESS為準(zhǔn)必要時(shí)主動調(diào)用訂單查詢接口兜底OrderQuery見 TenPayApiV3Controller.cs#L602-L629。安全性提示均來自文檔與源碼注釋訂單號需去重hc僅限演示回調(diào)應(yīng)對返回 IP 做校驗(yàn)簽名驗(yàn)簽不可跳過退款、賬單等接口的完整示例可繼續(xù)翻閱 TenPayApiV3Controller.cs 的其余區(qū)域以及倉庫中 docs/zh/guide/tenpayv3 與 docs/en/guide/tenpayv3 目錄下的配套指南。贊分享后端即時(shí)通訊金融科技【免費(fèi)下載鏈接】WeiXinMPSDK微信全平臺 .NET SDK Senparc.Weixin for C#支持 .NET Framework 及 .NET Core、.NET 10.0。已支持微信公眾號、小程序、小游戲、微信支付、企業(yè)微信/企業(yè)號、開放平臺、JSSDK、微信周邊等全平臺。 WeChat SDK for C#.項(xiàng)目地址https://gitcode.com/gh_mirrors/we/WeiXinMPSDK點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Senparc.Weixin 微信支付 V3 JSAPI 公眾號網(wǎng)頁支付實(shí)戰(zhàn)從商品頁到 prepay_id 簽名喚起Senparc.Weixin 微信支付 V3 JSAPI 公眾號網(wǎng)頁支付實(shí)戰(zhàn)從商品頁到 prepay_id 簽名喚起 本文基于當(dāng)前倉庫的 TenPay V3后端即時(shí)通訊金融科技Senparc.WeixinWeiXinMPSDK微信支付 V2 JSAPI 支付實(shí)戰(zhàn)商品頁、預(yù)支付訂單與 WeixinJSBridge 喚起全流程Senparc.WeixinWeiXinMPSDK微信支付 V2 JSAPI 支付實(shí)戰(zhàn)商品頁、預(yù)支付訂單與 WeixinJSBridge 喚起全流程 本文后端即時(shí)通訊金融科技Senparc.Weixin 微信支付V2接入實(shí)戰(zhàn)全局注冊、公眾號與支付模塊注冊及 appsettings.json 配置全解Senparc.Weixin 微信支付V2接入實(shí)戰(zhàn)全局注冊、公眾號與支付模塊注冊及 appsettings.json 配置全解 本文基于 Senparc.后端即時(shí)通訊金融科技上一篇telebot核心功能揭秘自動回復(fù)、圖片生成與Webhook設(shè)置實(shí)戰(zhàn)下一篇toto文章管理技巧Markdown與YAML元數(shù)據(jù)完美結(jié)合創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考