【开源】这可能是封装微信 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 等算法工具类。
- 完整、完善、完全的微信 API 封装,同时可灵活自行扩展。
现有以下模块:
- 公众平台(公众号、小程序、小游戏、小商店) & 开放平台模块:`SKIT.FlurlHttpClient.Wechat.Api`
- 商户平台(微信支付)模块:`SKIT.FlurlHttpClient.Wechat.TenpayV3`
- 企业微信(企业号)模块:`SKIT.FlurlHttpClient.Wechat.Work`
- 广告平台(广点通)模块:`SKIT.FlurlHttpClient.Wechat.Ads`
---
## 快速开始
以接入微信支付为例,其他模块的开发流程与之十分类似。
### 安装:
```shell
dotnet add package SKIT.FlurlHttpClient.Wechat.TenpayV3
```
### 初始化:
```csharp
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);
```
### 发送请求:
```csharp
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);
}
```
### 验证响应签名:
```csharp
/* 一般情况下可以跳过验证响应的签名 */
bool valid = client.VerifyResponseSignature(response);
```
### 生成客户端 JS-SDK 调起支付所需参数:
```csharp
/* 字典结构,包含客户端 JS-SDK 调起支付所需的完整参数 */
var paramMap = client.GenerateParametersForJsapiPayRequest(request.AppId, response.PrepayId);
```
### 验签、解析并解密微信回调通知中的敏感信息:
```csharp
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`](https://flurl.dev/) 是一个轻量级 HTTP 库,是 .NET 中最受欢迎扩展库之一,在 NuGet 上的累计下载量超过 1700 万、日均下载量超过 6 千、GitHub 2.6k Stars(数据统计截至 2021-06-01)。
与另一个流行的 HTTP 库 [`RestSharp`](https://restsharp.dev/) 相比,`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 以下版本的技术支持。也就是说,微软已经不再为此提供安全更新,在大部分技术合规要求中这一点都是扣分项,所以建议各位开发者目标框架能升级就升级。
---
## 仓库
- GitHub:https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat
- Gitee:https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat
以上仓库地址同步更新,均可接受 Issue 或 Pull Request。
【开源】这可能是封装微信 API 最全的 .NET SDK 了的更多相关文章
- 面向对象的全套“企业微信”api接口的代码实现,网上太多“面向过程”微信api接口的代码,这个开源给需要的人用
有段时间没有写文章了. 一直以来,微信的热门是看得到的,很多人都需要与微信的api对接. 今天我这里就分享全套的企业微信api接口的代码. 关于微信api,网上已经有很多实现的了. 但是我今天之所以还 ...
- 使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始
在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作 首先需要明确的是,微信的API都是通过https调用实现的,分为p ...
- GitHub开源:升讯威微信营销系统(第三方微信平台)完整源代码
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction 升讯威微信营销系统开发实践系列升讯威微信营销系统开发实践:(1)功能设计与架构设 ...
- 详解封装微信小程序组件及小程序坑(附带解决方案)
一.序 上一篇介绍了如何从零开发微信小程序,博客园审核变智障了,每次代码都不算篇幅,好好滴一篇原创,不到3分钟从首页移出来了.这篇介绍一下组件封装和我的踩坑历程. 二.封装微信小程序可复用组件 首先模 ...
- 【转】【完全开源】百度地图Web service API C#.NET版,带地图显示控件、导航控件、POI查找控件
[转][完全开源]百度地图Web service API C#.NET版,带地图显示控件.导航控件.POI查找控件 目录 概述 功能 如何使用 参考帮助 概述 源代码主要包含三个项目,BMap.NET ...
- 简单封装微信小程序
一.不同环境配置封装 新建config文件夹,根据自己有不同环境设置不同的js文件 具体js文件内容: exports.config = { requestHost: 'https://******. ...
- 总结的一些微信API接口
本文给大家介绍的是个人总结的一些微信API接口,包括微信支付.微信红包.微信卡券.微信小店等,十分的全面,有需要的小伙伴可以参考下. 1. [代码]index.php <?php include ...
- 微信api退款操作
状况:证书加载进去,本地调试退款成功,然而发不到iis上却是不成功. 分析:定然是iis配置问题. 问题一:证书加载不进去,出现“内部错误” 解决:在iis中找到对应的应用连接池,右键高级设置,找到“ ...
- C# 数字证书微信API调用使用参考事例
X.509 v.3 证书的方法.一个比较完整的调用 微信 API的示例: private stringGetResponseResult() { string strRespons ...
随机推荐
- 详解 CDN 加速
背景 本来是为了深入了解 CDN 的,结果发现前置知识:IP.域名.DNS 都还不算特别熟,所以先写了他们 现在终于来聊一聊 CDN 啦 本文素材均出自:https://www.bilibili.co ...
- dev下拉框选择不同值显示不同控件
单列的ASPxFormLayout直接前台控制就可以了,多列的前台控制后会出现空白 <dx:LayoutItem Caption="内容类型" Height="40 ...
- 一次性讲清楚spring中bean的生命周期之一:getSingleton方法
要想讲清楚spring中bean的生命周期,真的是不容易,以AnnotationConfigApplicationContext上下文为基础来讲解bean的生命周期,AnnotationConfigA ...
- Unity 消消乐开发思路
以简单的方式讲述游戏开发思路,暂时没有实践,如有错误,欢迎各位大佬指错 关卡数据保存方式 数据保存我选用json,可读性强,解析快 消消乐物体处理方式 消消乐物体我将以预制体的方式使用(把物品拖到As ...
- 二维动态规划&&二分查找的动态规划&&最长递增子序列&&最长连续递增子序列
题目描述与背景介绍 背景题目: [674. 最长连续递增序列]https://leetcode-cn.com/problems/longest-continuous-increasing-subseq ...
- Java 设置PDF跨页表格重复显示表头行
在创建表格时,如果表格内容出现跨页显示的时候,默认情况下该表格的表头不会在下一页显示,在阅读体验上不是很好.下面分享一个方法如何在表格跨页是显示表格的表头内容,这里只需要简单使用方法 grid.set ...
- 单点登录(SSO)实现原理(转)
简介 单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源,像一些知名的大型网站,如:淘 ...
- Linux | 配置主机名称
配置主机名称 为了便于在局域 网中查找某台特定的主机,或者对主机进行区分,除了要有 IP 地址外,还要为主机配置一个主机名,主机之间可以通过这个类似于域名的名称来相互访问. 在 Linux 系统中,主 ...
- 章节1-Grafana Dashboard的简单应用(2)
目录 使用Grafana创建可视化Dashboard 1. Add data sources - Prometheus 2. 导入 Dashboard 模板 2.1 Node Exporter for ...
- 求数组的子数组之和的最大值III(循环数组)
新的要求:一维数组改成循环数组,只是涉及简单算法,只是拿了小数做测试 想法:从文件读取数组,然后新建数组,将文件读取的数组在新数组中做一下连接,成为二倍长度的数组,然后再遍历,将每次遍历的子数组的和存 ...