feat(tenpayv2): 导入项目

This commit is contained in:
RHQYZ
2022-01-20 23:20:03 +08:00
committed by GitHub
parent 47575857b6
commit 7205686f71
72 changed files with 4092 additions and 45 deletions

View File

@@ -0,0 +1,14 @@
{
"appid": "wx2421b1c4370ec43b",
"customs": "ZHENGZHOU_BS",
"mch_customs_no": "D00411",
"mch_id": "1262544101",
"order_fee": "13110",
"out_trade_no": "15112496832609",
"product_fee": "13110",
"sign": "8FF6CEF879FB9555CD580222E671E9D4",
"transaction_id": "1006930610201511241751403478",
"transport_fee": "0",
"fee_type": "CNY",
"sub_order_no": "15112496832609001"
}

View File

@@ -0,0 +1,20 @@
{
"return_code": "",
"return_msg": "",
"sign_type": "",
"sign": "",
"appid": "",
"mch_id": "",
"result_code": "",
"err_code": "",
"err_code_des": "",
"state": "",
"transaction_id": "",
"out_trade_no": "",
"sub_order_no": "",
"sub_order_id": "",
"modify_time": "20091227091010",
"cert_check_result": "",
"verify_department": "",
"verify_department_trade_id": ""
}

View File

@@ -0,0 +1,11 @@
{
"sign_type": "",
"sign": "",
"appid": "",
"mch_id": "",
"out_trade_no": "",
"transaction_id": "",
"sub_order_no": "",
"sub_order_id": "",
"customs": ""
}

View File

@@ -0,0 +1,38 @@
{
"return_code": "SUCCESS",
"return_msg": "OK",
"sign": "C380BEC2BFD727A4B6845133519F3AD6",
"appid": "wxd678efh567hg6787",
"mch_id": "1230000109",
"result_code": "SUCCESS",
"err_code": "SUCCESS",
"err_code_des": "ERRCODE",
"transaction_id": "ERRMSG",
"count": 1,
"sub_order_no_0": "20150806125346",
"sub_order_id_0": "20150806125346",
"mch_customs_no_0": "mch_customs_no_0",
"customs_0": "SHANGHAI",
"duty_0": 888,
"fee_type_0": "CNY",
"order_fee_0": 888,
"transport_fee_0": 888,
"product_fee_0": 888,
"state_0": "UNDECLARED",
"explanation_0": "支付单已存在并且为非退单状态",
"modify_time_0": "20091227091010",
"cert_check_result_0": "UNCHECKED",
"sub_order_no_1": "201508061253461",
"sub_order_id_1": "201508061253461",
"mch_customs_no_1": "mch_customs_no_1",
"customs_1": "SHANGHAI1",
"duty_1": 8881,
"fee_type_1": "CNY1",
"order_fee_1": 8881,
"transport_fee_1": 8881,
"product_fee_1": 8881,
"state_1": "UNDECLARED1",
"explanation_1": "支付单已存在并且为非退单状态1",
"modify_time_1": "20091227091011",
"cert_check_result_1": "UNCHECKED1"
}

View File

@@ -0,0 +1,8 @@
{
"appid": "wxab8acb865bb16371",
"customs": "SHENZHEN",
"mch_customs_no": "440316T004",
"mch_id": "1900006511",
"transaction_id": "4200000027201712197200279161",
"sign": "5D98596798203B0B1D61445707F71F87"
}

View File

@@ -0,0 +1,18 @@
{
"return_code": "",
"return_msg": "",
"sign_type": "",
"sign": "",
"appid": "",
"mch_id": "",
"result_code": "",
"err_code": "",
"err_code_des": "",
"state": "",
"transaction_id": "",
"out_trade_no": "",
"sub_order_no": "",
"sub_order_id": "",
"modify_time": "20091227091010",
"explanation": ""
}

View File

@@ -0,0 +1,17 @@
{
"appid": "wxdace645e0bc2c424",
"attach": "test",
"auth_code": "130050378319653252",
"body": "被扫测试",
"detail": "{\"cost_price\":1,\"receipt_id\":\"wx123\",\"goods_detail\":[{\"goods_id\":\"商品编码\",\"wxpay_goods_id\":\"1001\",\"goods_name\":\"iPhone6s 16G\",\"quantity\":1,\"price\":1},{\"goods_id\":\"商品编码\",\"wxpay_goods_id\":\"1002\",\"goods_name\":\"iPhone6s 32G\",\"quantity\":1,\"price\":1}]}",
"device_info": "TEST01",
"goods_tag": "MEETING",
"mch_id": "1900009001",
"nonce_str": "4b4f6f692547affd2c8fadb39fed603a",
"out_trade_no": "19000090011489146530",
"spbill_create_ip": "14.23.150.211",
"sub_mch_id": "11383918",
"total_fee": "503",
"version": "1.0",
"sign": "144FF79B7391FE1BD0708470B7D8A2E3"
}

View File

@@ -0,0 +1,21 @@
{
"return_code": "SUCCESS",
"return_msg": "OK",
"appid": "wx2421b1c4370ec43b",
"mch_id": "10000100",
"device_info": "1000",
"nonce_str": "GOp3TRyMXzbMlkun",
"sign": "D6C76CB785F07992CDE05494BB7DF7FD",
"result_code": "SUCCESS",
"openid": "oUpF8uN95-Ptaags6E_roPHg7AG0",
"is_subscribe": "Y",
"trade_type": "MICROPAY",
"bank_type": "CCB_DEBIT",
"total_fee": "1",
"coupon_fee": "0",
"fee_type": "CNY",
"transaction_id": "1008450740201411110005820873",
"out_trade_no": "1415757673",
"attach": "订单额外描述",
"time_end": "20141111170043"
}

View File

@@ -0,0 +1,10 @@
{
"appid": "wx8888888888888888",
"mch_id": "1900000109",
"device_info": "013467007045764",
"nonce_str": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"sign": "C380BEC2BFD727A4B6845133519F3AD6",
"interface_url": "https://api.mch.weixin.qq.com/pay/batchreport/micropay/total",
"user_ip": "8.8.8.8",
"trades": "[{\n\t\t\"out_trade_no\": \"out_trade_no_test_1\",\n\t\t\"begin_time\": \"20160602203256\",\n\t\t\"end_time\": \"20160602203257\",\n\t\t\"state\": \"OK\",\n\t\t\"err_msg\": \"\"\n\t},\n\t{\n\t\t\"out_trade_no\": \"out_trade_no_test_2\",\n\t\t\"begin_time\": \"20160602203258\",\n\t\t\"end_time\": \"20160602203259\",\n\t\t\"state\": \"FAIL\",\n\t\t\"err_msg\": \"SYSTEMERROR\"\n\t}\n]"
}

View File

@@ -0,0 +1,5 @@
{
"return_code": "SUCCESS",
"return_msg": "OK",
"result_code": "SUCCESS"
}

View File

@@ -0,0 +1,9 @@
{
"appid": "",
"sub_appid": "",
"mch_id": "",
"sub_mch_id": "",
"auth_code": "",
"nonce_str": "",
"sign": ""
}

View File

@@ -0,0 +1,14 @@
{
"return_code": "",
"return_msg": "",
"appid": "",
"sub_appid": "",
"mch_id": "",
"sub_mch_id": "",
"nonce_str": "",
"sign": "",
"result_code": "",
"err_code": "",
"openid": "",
"sub_openid": ""
}

View File

@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472; netcoreapp3.1; net6.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<NullableReferenceTypes>true</NullableReferenceTypes>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<None Remove=".gitignore" />
<None Remove="appsettings.local.json" />
<Content Include="appsettings.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</Content>
<Content Include="appsettings.*.json" Condition="'$(Configuration)' == 'Debug'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="ModelSamples/**/*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SKIT.FlurlHttpClient.Wechat.TenpayV2\SKIT.FlurlHttpClient.Wechat.TenpayV2.csproj" />
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat.TestTools\SKIT.FlurlHttpClient.Wechat.TestTools.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,57 @@
using System.IO;
using System.Reflection;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests
{
public class TestCase_CodeReviewAnalyzer
{
private Assembly SourceAssembly { get; } = Assembly.Load("SKIT.FlurlHttpClient.Wechat.TenpayV2");
[Fact(DisplayName = "代码评审:分析 API 模型命名")]
public void TestApiModelsNaming()
{
CodeStyleUtil.VerifyApiModelsNaming(SourceAssembly, out var ex);
if (ex != null)
throw ex;
Assert.Null(ex);
}
[Fact(DisplayName = "代码评审:分析 API 模型定义")]
public void TestApiModelsDefinition()
{
string workdir = Path.Combine(TestConfigs.ProjectTestDirectory, "ModelSamples");
CodeStyleUtil.VerifyApiModelsDefinition(SourceAssembly, workdir, out var ex);
if (ex != null)
throw ex;
Assert.Null(ex);
}
[Fact(DisplayName = "代码评审:分析 API 接口命名")]
public void TestApiExtensionsNaming()
{
CodeStyleUtil.VerifyApiExtensionsNaming(SourceAssembly, out var ex);
if (ex != null)
throw ex;
Assert.Null(ex);
}
[Fact(DisplayName = "代码评审:分析代码规范")]
public void TestCodeStyle()
{
string workdir = Path.Combine(TestConfigs.ProjectSourceDirectory);
CodeStyleUtil.VerifySourceCodeStyle(workdir, out var ex);
if (ex != null)
throw ex;
Assert.Null(ex);
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests
{
public class TestCase_JsonConverterTest
{
[Fact(DisplayName = "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>֮ `FlattenNArrayObjectConverterBase`")]
public void TestFlattenNArrayObjectConverter()
{
var newtonsoftJsonSerializer = new FlurlNewtonsoftJsonSerializer();
var systemTextJsonSerializer = new FlurlSystemTextJsonSerializer();
string rawJson = "{\"return_code\":\"RETURN_CODE\",\"return_msg\":\"RETURN_MSG\",\"sign\":\"SIGN\",\"appid\":\"APPID\",\"mch_id\":\"MCH_ID\",\"result_code\":\"RESULT_CODE\",\"err_code\":\"ERR_CODE\",\"err_code_des\":\"ERR_CODE_DESC\",\"transaction_id\":\"TRANSACTION_ID\",\"count\":2,\"sub_order_no_0\":\"SUB_ORDER_NO_0\",\"sub_order_id_0\":\"SUB_ORDER_ID_0\",\"mch_customs_no_0\":\"MCH_CUSTOMS_NO_0\",\"customs_0\":\"CUSTOMS_0\",\"duty_0\":10,\"fee_type_0\":\"FEE_TYPE_0\",\"order_fee_0\":10,\"transport_fee_0\":10,\"product_fee_0\":10,\"state_0\":\"STATE_0\",\"explanation_0\":\"EXPLANATION_0\",\"modify_time_0\":\"20000101112233\",\"cert_check_result_0\":\"UNCHECKED\",\"sub_order_no_1\":\"SUB_ORDER_NO_1\",\"sub_order_id_1\":\"SUB_ORDER_ID_1\",\"mch_customs_no_1\":\"MCH_CUSTOMS_NO_1\",\"customs_1\":\"CUSTOMS_1\",\"duty_1\":11,\"fee_type_1\":\"FEE_TYPE_1\",\"order_fee_1\":11,\"transport_fee_1\":11,\"product_fee_1\":11,\"state_1\":\"STATE_1\",\"explanation_1\":\"EXPLANATION_1\",\"modify_time_1\":\"20010101112233\",\"cert_check_result_1\":\"UNCHECKED1\"}";
var parsedObjByNewtonsoftJson = newtonsoftJsonSerializer.Deserialize<Models.QueryMerchantCustomsCustomDeclarationResponse>(rawJson);
var parsedObjBySystemTextJson = systemTextJsonSerializer.Deserialize<Models.QueryMerchantCustomsCustomDeclarationResponse>(rawJson);
Assert.Equal("RETURN_CODE", parsedObjByNewtonsoftJson.ReturnCode);
Assert.Equal("RETURN_CODE", parsedObjBySystemTextJson.ReturnCode);
Assert.Equal("RETURN_MSG", parsedObjByNewtonsoftJson.ReturnMessage);
Assert.Equal("RETURN_MSG", parsedObjBySystemTextJson.ReturnMessage);
Assert.Equal("SIGN", parsedObjByNewtonsoftJson.Signature);
Assert.Equal("SIGN", parsedObjBySystemTextJson.Signature);
Assert.Equal("APPID", parsedObjByNewtonsoftJson.AppId);
Assert.Equal("APPID", parsedObjBySystemTextJson.AppId);
Assert.Equal("MCH_ID", parsedObjByNewtonsoftJson.MerchantId);
Assert.Equal("MCH_ID", parsedObjBySystemTextJson.MerchantId);
Assert.Equal("RESULT_CODE", parsedObjByNewtonsoftJson.ResultCode);
Assert.Equal("RESULT_CODE", parsedObjBySystemTextJson.ResultCode);
Assert.Equal("ERR_CODE", parsedObjByNewtonsoftJson.ErrorCode);
Assert.Equal("ERR_CODE", parsedObjBySystemTextJson.ErrorCode);
Assert.Equal("ERR_CODE_DESC", parsedObjByNewtonsoftJson.ErrorCodeDescription);
Assert.Equal("ERR_CODE_DESC", parsedObjBySystemTextJson.ErrorCodeDescription);
Assert.Equal("TRANSACTION_ID", parsedObjByNewtonsoftJson.TransactionId);
Assert.Equal("TRANSACTION_ID", parsedObjBySystemTextJson.TransactionId);
Assert.Equal(2, parsedObjByNewtonsoftJson.RecordCount);
Assert.Equal(2, parsedObjBySystemTextJson.RecordCount);
Assert.Equal("SUB_ORDER_NO_0", parsedObjByNewtonsoftJson.RecordList[0].SubOrderNumber);
Assert.Equal("SUB_ORDER_NO_0", parsedObjBySystemTextJson.RecordList[0].SubOrderNumber);
Assert.Equal("SUB_ORDER_ID_0", parsedObjByNewtonsoftJson.RecordList[0].SubOrderId);
Assert.Equal("SUB_ORDER_ID_0", parsedObjBySystemTextJson.RecordList[0].SubOrderId);
Assert.Equal("MCH_CUSTOMS_NO_0", parsedObjByNewtonsoftJson.RecordList[0].MerchantCustomsNumber);
Assert.Equal("MCH_CUSTOMS_NO_0", parsedObjBySystemTextJson.RecordList[0].MerchantCustomsNumber);
Assert.Equal("CUSTOMS_0", parsedObjByNewtonsoftJson.RecordList[0].Customs);
Assert.Equal("CUSTOMS_0", parsedObjBySystemTextJson.RecordList[0].Customs);
Assert.Equal(10, parsedObjByNewtonsoftJson.RecordList[0].Duty);
Assert.Equal(10, parsedObjBySystemTextJson.RecordList[0].Duty);
Assert.Equal("FEE_TYPE_0", parsedObjByNewtonsoftJson.RecordList[0].FeeType);
Assert.Equal("FEE_TYPE_0", parsedObjBySystemTextJson.RecordList[0].FeeType);
Assert.Equal(DateTimeOffset.Parse("2000-01-01 11:22:33"), parsedObjByNewtonsoftJson.RecordList[0].ModifyTime);
Assert.Equal(DateTimeOffset.Parse("2000-01-01 11:22:33"), parsedObjBySystemTextJson.RecordList[0].ModifyTime);
Assert.Equal("SUB_ORDER_NO_1", parsedObjByNewtonsoftJson.RecordList[1].SubOrderNumber);
Assert.Equal("SUB_ORDER_NO_1", parsedObjBySystemTextJson.RecordList[1].SubOrderNumber);
Assert.Equal("SUB_ORDER_ID_1", parsedObjByNewtonsoftJson.RecordList[1].SubOrderId);
Assert.Equal("SUB_ORDER_ID_1", parsedObjBySystemTextJson.RecordList[1].SubOrderId);
Assert.Equal("MCH_CUSTOMS_NO_1", parsedObjByNewtonsoftJson.RecordList[1].MerchantCustomsNumber);
Assert.Equal("MCH_CUSTOMS_NO_1", parsedObjBySystemTextJson.RecordList[1].MerchantCustomsNumber);
Assert.Equal("CUSTOMS_1", parsedObjByNewtonsoftJson.RecordList[1].Customs);
Assert.Equal("CUSTOMS_1", parsedObjBySystemTextJson.RecordList[1].Customs);
Assert.Equal(11, parsedObjByNewtonsoftJson.RecordList[1].Duty);
Assert.Equal(11, parsedObjBySystemTextJson.RecordList[1].Duty);
Assert.Equal("FEE_TYPE_1", parsedObjByNewtonsoftJson.RecordList[1].FeeType);
Assert.Equal("FEE_TYPE_1", parsedObjBySystemTextJson.RecordList[1].FeeType);
Assert.Equal(DateTimeOffset.Parse("2001-01-01 11:22:33"), parsedObjByNewtonsoftJson.RecordList[1].ModifyTime);
Assert.Equal(DateTimeOffset.Parse("2001-01-01 11:22:33"), parsedObjBySystemTextJson.RecordList[1].ModifyTime);
string unparsedJsonByNewtonsoftJson = newtonsoftJsonSerializer.Serialize(parsedObjByNewtonsoftJson);
string unparsedJsonBySystemTextJson = systemTextJsonSerializer.Serialize(parsedObjByNewtonsoftJson);
Assert.Contains("return_code", unparsedJsonByNewtonsoftJson);
Assert.Contains("return_code", unparsedJsonBySystemTextJson);
Assert.Contains("return_msg", unparsedJsonByNewtonsoftJson);
Assert.Contains("return_msg", unparsedJsonBySystemTextJson);
Assert.Contains("sub_order_no_0", unparsedJsonByNewtonsoftJson);
Assert.Contains("sub_order_no_0", unparsedJsonBySystemTextJson);
Assert.Contains("sub_order_id_0", unparsedJsonByNewtonsoftJson);
Assert.Contains("sub_order_id_0", unparsedJsonBySystemTextJson);
Assert.DoesNotContain("#n", unparsedJsonByNewtonsoftJson);
Assert.DoesNotContain("#n", unparsedJsonBySystemTextJson);
Assert.DoesNotContain("$n", unparsedJsonByNewtonsoftJson);
Assert.DoesNotContain("$n", unparsedJsonBySystemTextJson);
}
}
}

View File

@@ -0,0 +1,16 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests
{
class TestClients
{
static TestClients()
{
Instance = new WechatTenpayClient(new WechatTenpayClientOptions()
{
MerchantId = TestConfigs.WechatMerchantId,
MerchantSecret = TestConfigs.WechatMerchantSecret
});
}
public static readonly WechatTenpayClient Instance;
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.IO;
using System.Text.Json;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests
{
class TestConfigs
{
static TestConfigs()
{
// NOTICE: 请在项目根目录下按照 appsettings.json 的格式新建 appsettings.local.json 填入测试参数。
// WARNING: 请在 DEBUG 模式下运行测试用例。
// WARNING: 敏感信息请不要提交到 git
try
{
using var stream = File.OpenRead("appsettings.local.json");
using var jdoc = JsonDocument.Parse(stream);
var config = jdoc.RootElement.GetProperty("TestConfig");
WechatAppId = config.GetProperty("AppId").GetString()!;
WechatMerchantId = config.GetProperty("MerchantId").GetString()!;
WechatMerchantSecret = config.GetProperty("MerchantSecret").GetString()!;
WechatOpenId = config.GetProperty("OpenId").GetString()!;
ProjectSourceDirectory = jdoc.RootElement.GetProperty("ProjectSourceDirectory").GetString()!;
ProjectTestDirectory = jdoc.RootElement.GetProperty("ProjectTestDirectory").GetString()!;
}
catch (Exception ex)
{
throw new Exception("加载配置文件 appsettings.local.json 失败,请查看 `InnerException` 了解具体失败原因", ex);
}
}
public static readonly string WechatAppId;
public static readonly string WechatMerchantId;
public static readonly string WechatMerchantSecret;
public static readonly string WechatOpenId;
public static readonly string ProjectSourceDirectory;
public static readonly string ProjectTestDirectory;
}
}

View File

@@ -0,0 +1,10 @@
{
"TestConfig": {
"AppId": "请在此填写用于测试的微信 AppId",
"MerchantId": "请在此填写用于测试的微信商户号",
"MerchantSecret": "请在此填写用于测试的微信商户 API 密钥",
"OpenId": "请在此填写用于测试的微信用户唯一标识"
},
"ProjectSourceDirectory": "请输入当前 SDK 项目所在的目录完整路径,如 C:\\Project\\src\\SKIT.FlurlHttpClient.Wechat.TenpayV2\\",
"ProjectTestDirectory": "请输入当前测试项目所在的目录完整路径,如 C:\\Project\\test\\SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests\\"
}

View File

@@ -0,0 +1,10 @@
{
"TestConfig": {
"AppId": "wxd861802f8e303335",
"MerchantId": "1601103314",
"MerchantSecret": "f09b03a7a1902b5b4913856f1fd07ab1",
"OpenId": "owNIE0msADfoPjhpy2cz1qL4vImw"
},
"ProjectSourceDirectory": "D:\\Projects\\_SKIT\\stack-dotnet\\DotNetCore.SKIT.FlurlHttpClient.Wechat\\src\\SKIT.FlurlHttpClient.Wechat.TenpayV2",
"ProjectTestDirectory": "D:\\Projects\\_SKIT\\stack-dotnet\\DotNetCore.SKIT.FlurlHttpClient.Wechat\\test\\SKIT.FlurlHttpClient.Wechat.TenpayV2.UnitTests"
}