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

緣起

今年公司某個項目需要全面接入微信支付 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 = "//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。

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。

Tags: