【開源】這可能是封裝微信 API 最全的 .NET SDK 了

RHQYZ發表於2021-08-08

緣起

今年公司某個專案需要全面接入微信支付 V3 版 API。起初覺得,2014 年微信支付就已上線了 V3 版 API,這都 2021 年了,就算官方不給力,怎麼著社群也該有幾個造好的 .NET 的輪子了吧?於是興沖沖地到 NuGet 上開始搜尋“微信支付”四個大字,結果……

倒不是沒有現成的輪子,但基本都是隻包含一些簡單 API(如下單、查單、退款等等),與需求不符;偶爾有一些看似封裝全的,點進去一看卻是基於 V2 版 API 的。

沒辦法,自己動手,豐衣足食!

接入了微信支付後想著,既然微信支付都有了,為啥不把公眾號、小程式、企業微信之類的也接入了呢?

於是乎 SKIT.FlurlHttpClient.Wechat 這個專案就誕生了。


 

專案介紹

SKIT.FlurlHttpClient.Wechat 是一個基於 Flurl.Http 的微信 API HTTP 客戶端。

包含以下特性:

  • 支援 .NET Framework 4.6.1+、.NET Standard 2.0+、.NET Core 2.0+、.NET 5。
  • 支援 Windows / Linux / macOS 多平臺部署。
  • 支援 System.Text.Json(預設)和 Newtonsoft.Json 兩種序列化方式。
  • 非同步式程式設計。
  • 強型別介面模型。
  • 提供攔截器功能。
  • 提供微信 API 所需的 MD5、SHA-1、SHA-256、AES、RSA 等演算法工具類。
  • 提供 SourceLink,方便專案無原始碼除錯。
  • 完整、完善、完全的微信 API 封裝,同時可靈活自行擴充套件。

現有以下模組:

  • 公眾平臺(公眾號、小程式、小遊戲、小商店) & 開放平臺模組:SKIT.FlurlHttpClient.Wechat.Api
  • 商戶平臺(微信支付)模組:SKIT.FlurlHttpClient.Wechat.TenpayV3
  • 企業微信(企業號)模組:SKIT.FlurlHttpClient.Wechat.Work
  • 廣告平臺(廣點通)模組:SKIT.FlurlHttpClient.Wechat.Ads

 

快速開始

以接入微信支付為例,其他模組的開發流程與之十分類似。完整開發文件請前往倉庫(連結在最下方)閱讀。

安裝:

dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayV3

初始化:

using SKIT.FlurlHttpClient.Wechat;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;

/* 平臺證書管理器,具體用法請參見文件 */
var certManager = new InMemoryCertificateManager();
/* 僅列出必須配置項。也包含一些諸如超時時間、UserAgent 等的配置項 */
var options = new WechatTenpayClientOptions()
{
    MerchantId = "微信商戶號",
    MerchantV3Secret = "微信商戶 v3 API 金鑰",
    MerchantCertSerialNumber = "微信商戶證書序列號",
    MerchantCertPrivateKey = "-----BEGIN PRIVATE KEY-----微信商戶證書私鑰-----END PRIVATE KEY-----",
    CertificateManager = certManager
};
var client = new WechatTenpayClient(options);

傳送請求:

using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;

/* 以 JSAPI 統一下單介面為例 */
var request = new CreatePayTransactionJsapiRequest()
{
    OutTradeNumber = "商戶訂單號",
    AppId = "微信 AppId",
    Description = "訂單描述",
    ExpireTime = DateTimeOffset.Now.AddMinutes(15),
    NotifyUrl = "https://example.com",
    Amount = new CreatePayTransactionJsapiRequest.Types.Amount()
    {
        Total = 100
    },
    Payer = new CreatePayTransactionJsapiRequest.Types.Payer()
    {
        OpenId = "微信 OpenId"
    }
};
var response = await client.ExecuteCreatePayTransactionJsapiAsync(request);
if (response.IsSuccessful())
{
    Console.WriteLine("PrepayId:" + response.PrepayId);
}
else
{
    Console.WriteLine("HTTP 狀態:" + response.RawStatus);
    Console.WriteLine("錯誤程式碼:" + response.ErrorCode);
    Console.WriteLine("錯誤描述:" + response.ErrorMessage);
}

驗證響應簽名:

/* 一般情況下可以跳過驗證響應的簽名 */
bool valid = client.VerifyResponseSignature(response);

生成客戶端 JS-SDK 調起支付所需引數:

/* 字典結構,包含客戶端 JS-SDK 調起支付所需的完整引數 */
var paramMap = client.GenerateParametersForJsapiPayRequest(request.AppId, response.PrepayId);

驗籤、解析並解密微信回撥通知中的敏感資訊:

string callbackJson = "{ 微信商戶平臺發來的 JSON 格式的通知內容 }";
string callbackTimestamp = "微信回撥通知中的 Wechatpay-Timestamp 標頭";
string callbackNonce = "微信回撥通知中的 Wechatpay-Nonce 標頭";
string callbackSignature = "微信回撥通知中的 Wechatpay-Signature 標頭";
string callbackSerialNumber = "微信回撥通知中的 Wechatpay-Serial 標頭";

bool valid = client.VerifyEventSignature(callbackTimestamp, callbackNonce, callbackJson, callbackSignature, callbackSerialNumber);
if (valid)
{
    /* 將 JSON 反序列化得到通知物件 */
    /* 你也可以將 WechatTenpayEvent 型別直接繫結到 MVC 模型上,這樣就不再需要手動反序列化 */
    var callbackModel = client.DeserializeEvent(callbackJson);
    if ("TRANSACTION.SUCCESS".Equals(callbackModel.EventType))
    {
        /* 根據事件型別,解密得到支付通知敏感資料 */
        var callbackResource = client.DecryptEventResource<Events.TransactionResource>(callbackModel);
        string outTradeNumber = callbackResource.OutTradeNumber;
        string transactionId = callbackResource.TransactionId;
        Console.WriteLine("訂單 {0} 已完成支付,交易單號為 {1}", outTradeNumber, transactionId);
    }
}

更多使用說明請閱讀專案倉庫中的開發文件。

專案倉庫中還包含了一個示例專案,以供開發者快速掌握本庫的使用方法。


 

FAQ

1. Flurl.Http 是什麼?

Flurl.Http 是一個輕量級 HTTP 庫,是 .NET 中最受歡迎擴充套件庫之一,在 NuGet 上的累計下載量超過 1700 萬、日均下載量超過 6 千、GitHub 2.6k Stars(資料統計截至 2021-06-01)。

與另一個流行的 HTTP 庫 RestSharp 相比,Flurl.Http 底層基於 System.Net.Http.HttpClient,而 RestSharp 底層則基於 System.Net.HttpWebRequest,前者在多核多執行緒環境下的效能基準測試中表現要遠優於後者,同時也是微軟官方目前推薦的 HTTP 客戶端方案。

2. 本庫與盛派微信 SDK(Senparc.Weixin)有什麼區別?

  • 本庫專注於 API 本身的封裝,捎帶提供了一些用於加解密、序列化的工具類,使用更靈活;盛派微信 SDK 提供了大而全的功能,可與 MVC / WebAPI 深度整合。
  • 本庫遵循微軟官方推薦的 C# 屬性命名方式(大駝峰命名法)對介面模型進行定義;盛派微信 SDK 提供的是微信介面本身的命名方式(蛇形命名法和小駝峰命名法混雜)。
  • 本庫封裝了目前微信官方提供的所有 API;盛派微信 SDK 只提供了常用的 API。
  • 本庫只支援微信支付 v3 版 API;盛派微信 SDK 只支援微信支付 v2 版 API(作者開了新坑似乎是想提供 v3 版支援,不過目前只封裝了部分介面,進展還比較緩慢)。原則上微信官方已經停止更新 v2 版 API,現在介面只做日常維護,所以有條件的話還是應該儘快升級。如果你有使用 v2 版 API 的需求(比如企業提現、紅包等幾個尚未提供 v3 版 API 的介面),建議使用盛派微信 SDK。

3. 為什麼不支援 .NET Framework 4.0 / .NET Framework 4.5?

直接原因是本庫的依賴庫最低支援到 .NET Framework 4.6.1。

間接原因是為了支援跨平臺的 .NET Standard 2.0,只能相容到 .NET Framework 4.6.1。

根本原因是微軟官方已於 2016 年 1 月 12 日終止了對 .NET Framework 4.6.1 以下版本的技術支援。也就是說,微軟已經不再為此提供安全更新,在大部分技術合規要求中這一點都是扣分項,所以建議各位開發者目標框架能升級就升級。


 

倉庫

以上倉庫地址同步更新,均可接受 Issue 或 Pull Request。

相關文章