diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/FormDataFields.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/Internal/FormDataFields.cs similarity index 100% rename from src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/FormDataFields.cs rename to src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/Internal/FormDataFields.cs diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/SignAlgorithms.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/SignAlgorithms.cs new file mode 100644 index 00000000..56ffe932 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Constants/SignAlgorithms.cs @@ -0,0 +1,12 @@ +using System; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants +{ + public static class SignAlgorithms + { + /// + /// WECHATPAY2-SHA256-RSA2048。 + /// + public const string WECHATPAY2_SHA256_RSA2048 = "WECHATPAY2-SHA256-RSA2048"; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventDecryptionExtensions.cs similarity index 96% rename from src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventExtensions.cs rename to src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventDecryptionExtensions.cs index 73afbc90..fdc60163 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventDecryptionExtensions.cs @@ -3,9 +3,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 { /// - /// 为 提供回调通知事件的扩展方法。 + /// 为 提供回调通知事件敏感数据解密的扩展方法。 /// - public static class WechatTenpayClientEventExtensions + public static class WechatTenpayClientEventDecryptionExtensions { /// /// 反序列化得到 对象。 diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs new file mode 100644 index 00000000..8c51113a --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs @@ -0,0 +1,80 @@ +using System; +using System.Text; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供回调通知事件签名验证的扩展方法。 + /// + public static class WechatTenpayClientEventVerificationExtensions + { + /// + /// 验证回调通知事件签名。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml + /// + /// + /// + /// 微信回调通知中的 Wechatpay-Timestamp 字段。 + /// 微信回调通知中的 Wechatpay-Nonce 字段。 + /// 微信回调通知中请求正文。 + /// 微信回调通知中的 Wechatpay-Signature 字段。 + /// 微信回调通知中的 Wechatpay-Serial 字段。 + /// + public static bool VerifyEventSignature( + this WechatTenpayClient client, + string callbackTimestamp, + string callbackNonce, + string callbackBody, + string callbackSignature, + string callbackSerialNumber) + where TResponse : WechatTenpayResponse + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (callbackTimestamp == null) throw new ArgumentNullException(nameof(callbackTimestamp)); + if (callbackNonce == null) throw new ArgumentNullException(nameof(callbackNonce)); + if (callbackBody == null) throw new ArgumentNullException(nameof(callbackBody)); + if (callbackSignature == null) throw new ArgumentNullException(nameof(callbackSignature)); + if (callbackSerialNumber == null) throw new ArgumentNullException(nameof(callbackSerialNumber)); + + if (client.WechatCertificateStorer == null) + { + throw new Exceptions.WechatTenpayResponseVerificationException($"You must set an instance of `{nameof(Settings.ICertificateStorer)}` at first."); + } + else + { + string? certificate = client.WechatCertificateStorer.Get(callbackSerialNumber); + if (certificate == null) + throw new Exceptions.WechatTenpayResponseVerificationException("Cannot get certificate by the serial number, may not be stored."); + + string? publicKey = null; + try + { + publicKey = Utilities.RSAUtility.ExportPublicKey(certificate); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseVerificationException("Cannot get public key of the certificate, may not be a valid certificate data.", ex); + } + + try + { + return Utilities.RSAUtility.VerifyWithSHA256( + publicKey: publicKey, + plainText: GetPlainTextForSignature(timestamp: callbackTimestamp, nonce: callbackNonce, body: callbackBody), + signature: callbackSignature + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseVerificationException("Verify event signature failed.", ex); + } + } + } + + private static string GetPlainTextForSignature(string timestamp, string nonce, string body) + { + return $"{timestamp}\n{nonce}\n{body}\n"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteBillExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteBillExtensions.cs index ac377597..17b7fd17 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteBillExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteBillExtensions.cs @@ -108,6 +108,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_8.shtml /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter5_1_19.shtml /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_9_3.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_3.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_3.shtml /// /// /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundBalanceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundBalanceExtensions.cs index ed344dc7..2b0ac1bc 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundBalanceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundBalanceExtensions.cs @@ -18,6 +18,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// 异步调用 [GET] /ecommerce/fund/balance/{sub_mchid} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_7_1.shtml /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_1.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter5_1.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter5_2.shtml /// /// /// @@ -40,6 +42,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /ecommerce/fund/enddaybalance/{sub_mchid} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_7_2.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter5_3.shtml /// /// /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundWithdrawExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundWithdrawExtensions.cs index 23a4a707..11c5a77a 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundWithdrawExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteEcommerceFundWithdrawExtensions.cs @@ -17,6 +17,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [POST] /ecommerce/fund/withdraw 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_2.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter6_1.shtml /// /// /// @@ -37,6 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /ecommerce/fund/withdraw/out-request-no/{out_request_no} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_3.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter6_2.shtml /// /// /// @@ -57,6 +59,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /ecommerce/fund/withdraw/{withdraw_id} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_3.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter6_2.shtml /// /// /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundBalanceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundBalanceExtensions.cs index 74eceecc..cd6e0436 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundBalanceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundBalanceExtensions.cs @@ -17,6 +17,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /merchant/fund/balance/{account_type} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_7_3.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_1.shtml /// /// /// @@ -36,6 +37,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /merchant/fund/dayendbalance/{account_type} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_7_4.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_2.shtml /// /// /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundIncomeRecordsExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundIncomeRecordsExtensions.cs new file mode 100644 index 00000000..af509541 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundIncomeRecordsExtensions.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供来账识别相关的 API 扩展方法。 + /// + public static class WechatTenpayClientExecuteMerchantFundIncomeRecordsExtensions + { + /// + /// 异步调用 [GET] /merchantfund/merchant/income-records 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_7.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_7.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteQueryMerchantFundMerchantIncomeRecordsAsync(this WechatTenpayClient client, Models.QueryMerchantFundMerchantIncomeRecordsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "merchantfund", "merchant", "income-records") + .SetQueryParam("account_type", request.AccountType) + .SetQueryParam("date", request.DateString) + .SetQueryParam("limit", request.Limit); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset); + + return await client.SendRequestWithJsonAsync(flurlReq, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /merchantfund/partner/income-records 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_6.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteQueryMerchantFundPartnerIncomeRecordsAsync(this WechatTenpayClient client, Models.QueryMerchantFundPartnerIncomeRecordsRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "merchantfund", "partner", "income-records") + .SetQueryParam("sub_mchid", request.SubMerchantId) + .SetQueryParam("account_type", request.AccountType) + .SetQueryParam("date", request.DateString) + .SetQueryParam("limit", request.Limit); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset); + + return await client.SendRequestWithJsonAsync(flurlReq, cancellationToken: cancellationToken); + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundWithdrawExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundWithdrawExtensions.cs index ea437c37..0a392486 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundWithdrawExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantFundWithdrawExtensions.cs @@ -74,6 +74,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 异步调用 [GET] /merchant/fund/withdraw/bill-type/{bill_type} 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_4.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter6_3.shtml /// /// /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecutePartnerTransferExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecutePartnerTransferExtensions.cs new file mode 100644 index 00000000..9569caba --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecutePartnerTransferExtensions.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供服务商转账相关的 API 扩展方法。 + /// + public static class WechatTenpayClientExecutePartnerTransferExtensions + { + #region Batches + /// + /// 异步调用 [POST] /partner-transfer/batches 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_1.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteCreatePartnerTransferBatchAsync(this WechatTenpayClient client, Models.CreatePartnerTransferBatchRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "partner-transfer", "batches"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + /// + /// 异步调用 [GET] /partner-transfer/batches/batch-id/{batch_id} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_2.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetPartnerTransferBatchByBatchIdAsync(this WechatTenpayClient client, Models.GetPartnerTransferBatchByBatchIdRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "partner-transfer", "batches", "batch-id", request.BatchId) + .SetQueryParam("need_query_detail", request.RequireQueryDetail); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset.Value); + + if (request.Limit.HasValue) + flurlReq.SetQueryParam("limit", request.Limit.Value); + + if (!string.IsNullOrEmpty(request.DetailStatus)) + flurlReq.SetQueryParam("detail_status", request.DetailStatus); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_3.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetPartnerTransferBatchDetailByDetailIdAsync(this WechatTenpayClient client, Models.GetPartnerTransferBatchDetailByDetailIdRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "partner-transfer", "batches", "batch-id", request.BatchId, "details", "detail-id", request.DetailId); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_4.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetPartnerTransferBatchByOutBatchNumberAsync(this WechatTenpayClient client, Models.GetPartnerTransferBatchByOutBatchNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "partner-transfer", "batches", "out-batch-no", request.OutBatchNumber) + .SetQueryParam("need_query_detail", request.RequireQueryDetail); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset.Value); + + if (request.Limit.HasValue) + flurlReq.SetQueryParam("limit", request.Limit.Value); + + if (!string.IsNullOrEmpty(request.DetailStatus)) + flurlReq.SetQueryParam("detail_status", request.DetailStatus); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_5.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetPartnerTransferBatchDetailByOutDetailNumberAsync(this WechatTenpayClient client, Models.GetPartnerTransferBatchDetailByOutDetailNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "partner-transfer", "batches", "out-batch-no", request.OutBatchNumber, "details", "out-detail-no", request.OutDetailNumber); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteTransferExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteTransferExtensions.cs new file mode 100644 index 00000000..3ee45bee --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteTransferExtensions.cs @@ -0,0 +1,223 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供转账相关的 API 扩展方法。 + /// + public static class WechatTenpayClientExecuteTransferExtensions + { + #region Batches + /// + /// 异步调用 [POST] /transfer/batches 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_1.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteCreateTransferBatchAsync(this WechatTenpayClient client, Models.CreateTransferBatchRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "transfer", "batches"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer/batches/batch-id/{batch_id} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_2.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferBatchByBatchIdAsync(this WechatTenpayClient client, Models.GetTransferBatchByBatchIdRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer", "batches", "batch-id", request.BatchId) + .SetQueryParam("need_query_detail", request.RequireQueryDetail); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset.Value); + + if (request.Limit.HasValue) + flurlReq.SetQueryParam("limit", request.Limit.Value); + + if (!string.IsNullOrEmpty(request.DetailStatus)) + flurlReq.SetQueryParam("detail_status", request.DetailStatus); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_3.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferBatchDetailByDetailIdAsync(this WechatTenpayClient client, Models.GetTransferBatchDetailByDetailIdRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer", "batches", "batch-id", request.BatchId, "details", "detail-id", request.DetailId); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer/batches/out-batch-no/{out_batch_no} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_4.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferBatchByOutBatchNumberAsync(this WechatTenpayClient client, Models.GetTransferBatchByOutBatchNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer", "batches", "out-batch-no", request.OutBatchNumber) + .SetQueryParam("need_query_detail", request.RequireQueryDetail); + + if (request.Offset.HasValue) + flurlReq.SetQueryParam("offset", request.Offset.Value); + + if (request.Limit.HasValue) + flurlReq.SetQueryParam("limit", request.Limit.Value); + + if (!string.IsNullOrEmpty(request.DetailStatus)) + flurlReq.SetQueryParam("detail_status", request.DetailStatus); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_5.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferBatchDetailByOutDetailNumberAsync(this WechatTenpayClient client, Models.GetTransferBatchDetailByOutDetailNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer", "batches", "out-batch-no", request.OutBatchNumber, "details", "out-detail-no", request.OutDetailNumber); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + + #region BillReceipt + /// + /// 异步调用 [POST] /transfer/bill-receipt 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_1.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_1.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteCreateTransferBillReceiptAsync(this WechatTenpayClient client, Models.CreateTransferBillReceiptRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "transfer", "bill-receipt"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer/bill-receipt/{out_batch_no} 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_2.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_2.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferBillReceiptByOutBatchNumberAsync(this WechatTenpayClient client, Models.GetTransferBillReceiptByOutBatchNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer", "bill-receipt", request.OutBatchNumber); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + + #region Detail + /// + /// 异步调用 [POST] /transfer-detail/electronic-receipts 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_4.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_4.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteCreateTransferDetailElectronicReceiptAsync(this WechatTenpayClient client, Models.CreateTransferDetailElectronicReceiptRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "transfer-detail", "electronic-receipts"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /transfer-detail/electronic-receipts 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_5.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter4_5.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteGetTransferDetailElectronicReceiptByOutDetailNumberAsync(this WechatTenpayClient client, Models.GetTransferDetailElectronicReceiptByOutDetailNumberRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "transfer-detail", "electronic-receipts") + .SetQueryParam("accept_type", request.AcceptType) + .SetQueryParam("out_detail_no", request.OutDetailNumber); + + if (!string.IsNullOrEmpty(request.OutBatchNumber)) + flurlReq.SetQueryParam("out_batch_no", request.OutBatchNumber); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs index 3850c772..409a3dba 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs @@ -11,13 +11,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 { /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.GetEcommerceApplymentByOutRequestNumberResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.GetEcommerceApplymentByOutRequestNumberResponse response) + public static Models.GetEcommerceApplymentByOutRequestNumberResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetEcommerceApplymentByOutRequestNumberResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -73,13 +71,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.GetEcommerceBillFundflowBillResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.GetEcommerceBillFundflowBillResponse response) + public static Models.GetEcommerceBillFundflowBillResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetEcommerceBillFundflowBillResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -121,13 +117,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.GetMerchantServiceComplaintByComplaintIdResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.GetMerchantServiceComplaintByComplaintIdResponse response) + public static Models.GetMerchantServiceComplaintByComplaintIdResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetMerchantServiceComplaintByComplaintIdResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -161,13 +155,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.QueryCertificatesResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.QueryCertificatesResponse response) + public static Models.QueryCertificatesResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.QueryCertificatesResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -215,13 +207,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.QueryMerchantServiceComplaintsResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.QueryMerchantServiceComplaintsResponse response) + public static Models.QueryMerchantServiceComplaintsResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.QueryMerchantServiceComplaintsResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -263,13 +253,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml /// /// /// /// - public static Models.QuerySmartGuidesResponse DecryptResponseEncryptedData(this WechatTenpayClient client, Models.QuerySmartGuidesResponse response) + public static Models.QuerySmartGuidesResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.QuerySmartGuidesResponse response) { if (client == null) throw new ArgumentNullException(nameof(client)); if (response == null) throw new ArgumentNullException(nameof(response)); @@ -323,5 +311,145 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 return response; } + + /// + /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 + /// + /// + /// + /// + public static Models.GetTransferBatchDetailByOutDetailNumberResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetTransferBatchDetailByOutDetailNumberResponse response) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (response == null) throw new ArgumentNullException(nameof(response)); + + if (string.IsNullOrEmpty(client.WechatMerchantCertPrivateKey)) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of there is no merchant private key."); + + if (!response.IsSuccessful()) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of the response is not successful."); + + if (!string.IsNullOrEmpty(response.UserName)) + { + try + { + response.UserName = Utilities.RSAUtility.DecryptWithECB( + client.WechatMerchantCertPrivateKey, + response.UserName + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed.", ex); + } + } + + return response; + } + + /// + /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 + /// + /// + /// + /// + public static Models.GetTransferBatchDetailByDetailIdResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetTransferBatchDetailByDetailIdResponse response) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (response == null) throw new ArgumentNullException(nameof(response)); + + if (string.IsNullOrEmpty(client.WechatMerchantCertPrivateKey)) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of there is no merchant private key."); + + if (!response.IsSuccessful()) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of the response is not successful."); + + if (!string.IsNullOrEmpty(response.UserName)) + { + try + { + response.UserName = Utilities.RSAUtility.DecryptWithECB( + client.WechatMerchantCertPrivateKey, + response.UserName + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed.", ex); + } + } + + return response; + } + + /// + /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 + /// + /// + /// + /// + public static Models.GetPartnerTransferBatchDetailByOutDetailNumberResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetPartnerTransferBatchDetailByOutDetailNumberResponse response) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (response == null) throw new ArgumentNullException(nameof(response)); + + if (string.IsNullOrEmpty(client.WechatMerchantCertPrivateKey)) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of there is no merchant private key."); + + if (!response.IsSuccessful()) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of the response is not successful."); + + if (!string.IsNullOrEmpty(response.UserName)) + { + try + { + response.UserName = Utilities.RSAUtility.DecryptWithECB( + client.WechatMerchantCertPrivateKey, + response.UserName + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed.", ex); + } + } + + return response; + } + + /// + /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。 + /// + /// + /// + /// + public static Models.GetPartnerTransferBatchDetailByDetailIdResponse DecryptResponseEncryptedData(this WechatTenpayClient client, ref Models.GetPartnerTransferBatchDetailByDetailIdResponse response) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (response == null) throw new ArgumentNullException(nameof(response)); + + if (string.IsNullOrEmpty(client.WechatMerchantCertPrivateKey)) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of there is no merchant private key."); + + if (!response.IsSuccessful()) + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because of the response is not successful."); + + if (!string.IsNullOrEmpty(response.UserName)) + { + try + { + response.UserName = Utilities.RSAUtility.DecryptWithECB( + client.WechatMerchantCertPrivateKey, + response.UserName + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed.", ex); + } + } + + return response; + } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerificationExtensions.cs new file mode 100644 index 00000000..0b45bf7c --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerificationExtensions.cs @@ -0,0 +1,72 @@ +using System; +using System.Text; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供响应签名验证的扩展方法。 + /// + public static class WechatTenpayClientResponseVerificationExtensions + { + /// + /// 验证响应签名。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml + /// + /// + /// + /// + /// + public static bool VerifyResponseSignature(this WechatTenpayClient client, TResponse response) + where TResponse : WechatTenpayResponse + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (response == null) throw new ArgumentNullException(nameof(response)); + + if (client.WechatCertificateStorer == null) + { + throw new Exceptions.WechatTenpayResponseVerificationException($"You must set an instance of `{nameof(Settings.ICertificateStorer)}` at first."); + } + else + { + if (response.WechatpayCertSerialNumber == null) + throw new Exceptions.WechatTenpayResponseVerificationException("Cannot read the serial number in headers of this response."); + + string? certificate = client.WechatCertificateStorer.Get(response.WechatpayCertSerialNumber); + if (certificate == null) + throw new Exceptions.WechatTenpayResponseVerificationException("Cannot get certificate by the serial number, may not be stored."); + + string? publicKey = null; + try + { + publicKey = Utilities.RSAUtility.ExportPublicKey(certificate); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseVerificationException("Cannot get public key of the certificate, may not be a valid certificate data.", ex); + } + + try + { + return Utilities.RSAUtility.VerifyWithSHA256( + publicKey: publicKey, + plainText: GetPlainTextForSignature(response), + signature: response.WechatpaySignature + ); + } + catch (Exception ex) + { + throw new Exceptions.WechatTenpayResponseVerificationException("Verify response signature failed.", ex); + } + } + } + + private static string GetPlainTextForSignature(WechatTenpayResponse response) + { + string timestamp = response.WechatpayTimestamp; + string nonce = response.WechatpayNonce; + string body = Encoding.UTF8.GetString(response.RawBytes); + return $"{timestamp}\n{nonce}\n{body}\n"; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerifyExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerifyExtensions.cs deleted file mode 100644 index 2e86dd8d..00000000 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseVerifyExtensions.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Text; - -namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 -{ - /// - /// 为 提供响应签名验证的扩展方法。 - /// - public static class WechatTenpayClientResponseVerifyExtensions - { - /// - /// 验证响应签名(使用微信支付平台证书公钥)。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml - /// - /// - /// - /// - /// - /// - public static bool VerifyResponseSignature(this WechatTenpayClient client, TResponse response, string publicKey) - where TResponse : WechatTenpayResponse - { - if (client == null) throw new ArgumentNullException(nameof(client)); - if (response == null) throw new ArgumentNullException(nameof(response)); - if (string.IsNullOrEmpty(publicKey)) throw new ArgumentNullException(publicKey); - - try - { - return Utilities.RSAUtility.VerifyWithSHA256( - publicKey: publicKey, - plainText: GetPlainTextForSignature(response), - signature: response.WechatpaySignature - ); - } - catch (Exception ex) - { - throw new Exceptions.WechatTenpayResponseVerificationException("Verify response signature failed.", ex); - } - } - - /// - /// 验证响应签名(使用微信支付平台证书)。 - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml - /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml - /// - /// - /// - /// - /// - /// - public static bool VerifyResponseSignatureByCertificate(this WechatTenpayClient client, TResponse response, string certificate) - where TResponse : WechatTenpayResponse - { - if (client == null) throw new ArgumentNullException(nameof(client)); - if (response == null) throw new ArgumentNullException(nameof(response)); - if (string.IsNullOrEmpty(certificate)) throw new ArgumentNullException(certificate); - - try - { - return Utilities.RSAUtility.VerifyWithSHA256ByCertificate( - certificate: certificate, - plainText: GetPlainTextForSignature(response), - signature: response.WechatpaySignature - ); - } - catch (Exception ex) - { - throw new Exceptions.WechatTenpayResponseVerificationException("Verify response signature failed.", ex); - } - } - - private static string GetPlainTextForSignature(WechatTenpayResponse response) - { - string timestamp = response.WechatpayTimestamp; - string nonce = response.WechatpayNonce; - string body = Encoding.UTF8.GetString(response.RawBytes); - return $"{timestamp}\n{nonce}\n{body}\n"; - } - } -} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Interceptors/WechatTenpaySignInterceptor.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Interceptors/WechatTenpaySignInterceptor.cs index 6f8e101e..2d426685 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Interceptors/WechatTenpaySignInterceptor.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Interceptors/WechatTenpaySignInterceptor.cs @@ -53,7 +53,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors switch (_scheme) { - case WechatTenpayAuthSchemes.WECHATPAY2_SHA256_RSA2048: + case Constants.SignAlgorithms.WECHATPAY2_SHA256_RSA2048: { try { diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs index 12dee55a..4266e544 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs @@ -738,7 +738,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string? BankBranchId { get; set; } /// - /// 获取或设置开户开户银行全称(含支行)。与字段 二选一。 + /// 获取或设置开户银行全称(含支行)。与字段 二选一。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/GetApplyForSubMerchantSettlementResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/GetApplyForSubMerchantSettlementResponse.cs index 6616834c..25a66fbc 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/GetApplyForSubMerchantSettlementResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/GetApplyForSubMerchantSettlementResponse.cs @@ -44,7 +44,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string? BankBranchId { get; set; } /// - /// 获取或设置开户开户银行全称(含支行)。 + /// 获取或设置开户银行全称(含支行)。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs index cbaa80ff..a20b32c7 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs @@ -51,7 +51,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string? BankBranchId { get; set; } /// - /// 获取或设置开户开户银行全称(含支行)。与字段 二选一。 + /// 获取或设置开户银行全称(含支行)。与字段 二选一。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs index acea858f..3f040025 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs @@ -231,7 +231,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string? BankBranchId { get; set; } /// - /// 获取或设置开户开户银行全称(含支行)。与字段 二选一。 + /// 获取或设置开户银行全称(含支行)。与字段 二选一。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceFundWithdraw/GetEcommerceFundWithdrawByOutRequestNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceFundWithdraw/GetEcommerceFundWithdrawByOutRequestNumberResponse.cs index 5ec37381..4c39b128 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceFundWithdraw/GetEcommerceFundWithdrawByOutRequestNumberResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceFundWithdraw/GetEcommerceFundWithdrawByOutRequestNumberResponse.cs @@ -86,7 +86,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string AccountBank { get; set; } = default!; /// - /// 获取或设置开户开户银行全称(含支行)。 + /// 获取或设置开户银行全称(含支行)。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.cs new file mode 100644 index 00000000..687b151d --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /merchantfund/merchant/income-records 接口的请求。 + /// + public class QueryMerchantFundMerchantIncomeRecordsRequest : WechatTenpayRequest + { + /// + /// 获取或设置账户类型。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string AccountType { get; set; } = string.Empty; + + /// + /// 获取或设置日期(格式:yyyy-MM-dd)。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string DateString { get; set; } = string.Empty; + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Offset { get; set; } + + /// + /// 获取或设置分页每页数量。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int Limit { get; set; } = 10; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.cs new file mode 100644 index 00000000..2d2aea13 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /merchantfund/merchant/income-records 接口的响应。 + /// + public class QueryMerchantFundMerchantIncomeRecordsResponse : WechatTenpayResponse + { + public static class Types + { + public class IncomeRecord + { + /// + /// 获取或设置微信商户号。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string MerchantId { get; set; } = default!; + + /// + /// 获取或设置账户类型。 + /// + [Newtonsoft.Json.JsonProperty("account_type")] + [System.Text.Json.Serialization.JsonPropertyName("account_type")] + public string AccountType { get; set; } = default!; + + /// + /// 获取或设置银行来账类型。 + /// + [Newtonsoft.Json.JsonProperty("income_record_type")] + [System.Text.Json.Serialization.JsonPropertyName("income_record_type")] + public string IncomeRecordType { get; set; } = default!; + + /// + /// 获取或设置银行来账微信单号。 + /// + [Newtonsoft.Json.JsonProperty("income_record_id")] + [System.Text.Json.Serialization.JsonPropertyName("income_record_id")] + public string IncomeRecordId { get; set; } = default!; + + /// + /// 获取或设置银行来账金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("amount")] + [System.Text.Json.Serialization.JsonPropertyName("amount")] + public int Amount { get; set; } + + /// + /// 获取或设置企业微信的员工工号。 + /// + [Newtonsoft.Json.JsonProperty("success_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("success_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset SuccessTime { get; set; } + + /// + /// 获取或设置付款方银行名称。 + /// + [Newtonsoft.Json.JsonProperty("bank_name")] + [System.Text.Json.Serialization.JsonPropertyName("bank_name")] + public string BankName { get; set; } = default!; + + /// + /// 获取或设置付款方银行户名。 + /// + [Newtonsoft.Json.JsonProperty("bank_account_name")] + [System.Text.Json.Serialization.JsonPropertyName("bank_account_name")] + public string BankAccountName { get; set; } = default!; + + /// + /// 获取或设置付款方银行卡号。 + /// + [Newtonsoft.Json.JsonProperty("bank_account_number")] + [System.Text.Json.Serialization.JsonPropertyName("bank_account_number")] + public string BankAccountNumber { get; set; } = default!; + } + } + + /// + /// 获取或设置银行来账记录列表。 + /// + [Newtonsoft.Json.JsonProperty("data")] + [System.Text.Json.Serialization.JsonPropertyName("data")] + public Types.IncomeRecord[]? IncomeRecordList { get; set; } + + /// + /// 获取或设置分页大小。 + /// + [Newtonsoft.Json.JsonProperty("limit")] + [System.Text.Json.Serialization.JsonPropertyName("limit")] + public int Limit { get; set; } + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonProperty("offset")] + [System.Text.Json.Serialization.JsonPropertyName("offset")] + public int Offset { get; set; } + + /// + /// 获取或设置银行来账记录总数。 + /// + [Newtonsoft.Json.JsonProperty("total_count")] + [System.Text.Json.Serialization.JsonPropertyName("total_count")] + public int TotalCount { get; set; } + + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.cs new file mode 100644 index 00000000..21fa56c2 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /merchantfund/partner/income-records 接口的请求。 + /// + public class QueryMerchantFundPartnerIncomeRecordsRequest : QueryMerchantFundMerchantIncomeRecordsRequest + { + /// + /// 获取或设置特约商户号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string SubMerchantId { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.cs new file mode 100644 index 00000000..82665c0f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /merchantfund/partner/income-records 接口的响应。 + /// + public class QueryMerchantFundPartnerIncomeRecordsResponse : WechatTenpayResponse + { + public static class Types + { + public class IncomeRecord + { + /// + /// 获取或设置特约商户号。 + /// + [Newtonsoft.Json.JsonProperty("sub_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_mchid")] + public string SubMerchantId { get; set; } = default!; + + /// + /// 获取或设置账户类型。 + /// + [Newtonsoft.Json.JsonProperty("account_type")] + [System.Text.Json.Serialization.JsonPropertyName("account_type")] + public string AccountType { get; set; } = default!; + + /// + /// 获取或设置银行来账类型。 + /// + [Newtonsoft.Json.JsonProperty("income_record_type")] + [System.Text.Json.Serialization.JsonPropertyName("income_record_type")] + public string IncomeRecordType { get; set; } = default!; + + /// + /// 获取或设置银行来账微信单号。 + /// + [Newtonsoft.Json.JsonProperty("income_record_id")] + [System.Text.Json.Serialization.JsonPropertyName("income_record_id")] + public string IncomeRecordId { get; set; } = default!; + + /// + /// 获取或设置银行来账金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("amount")] + [System.Text.Json.Serialization.JsonPropertyName("amount")] + public int Amount { get; set; } + + /// + /// 获取或设置企业微信的员工工号。 + /// + [Newtonsoft.Json.JsonProperty("success_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("success_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset SuccessTime { get; set; } + + /// + /// 获取或设置付款方银行名称。 + /// + [Newtonsoft.Json.JsonProperty("bank_name")] + [System.Text.Json.Serialization.JsonPropertyName("bank_name")] + public string BankName { get; set; } = default!; + + /// + /// 获取或设置付款方银行户名。 + /// + [Newtonsoft.Json.JsonProperty("bank_account_name")] + [System.Text.Json.Serialization.JsonPropertyName("bank_account_name")] + public string BankAccountName { get; set; } = default!; + + /// + /// 获取或设置付款方银行卡号。 + /// + [Newtonsoft.Json.JsonProperty("bank_account_number")] + [System.Text.Json.Serialization.JsonPropertyName("bank_account_number")] + public string BankAccountNumber { get; set; } = default!; + } + } + + /// + /// 获取或设置银行来账记录列表。 + /// + [Newtonsoft.Json.JsonProperty("data")] + [System.Text.Json.Serialization.JsonPropertyName("data")] + public Types.IncomeRecord[]? IncomeRecordList { get; set; } + + /// + /// 获取或设置分页大小。 + /// + [Newtonsoft.Json.JsonProperty("limit")] + [System.Text.Json.Serialization.JsonPropertyName("limit")] + public int Limit { get; set; } + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonProperty("offset")] + [System.Text.Json.Serialization.JsonPropertyName("offset")] + public int Offset { get; set; } + + /// + /// 获取或设置银行来账记录总数。 + /// + [Newtonsoft.Json.JsonProperty("total_count")] + [System.Text.Json.Serialization.JsonPropertyName("total_count")] + public int TotalCount { get; set; } + + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundWithdraw/GetMerchantFundWithdrawByOutRequestNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundWithdraw/GetMerchantFundWithdrawByOutRequestNumberResponse.cs index 1568c539..03b7dc3f 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundWithdraw/GetMerchantFundWithdrawByOutRequestNumberResponse.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/MerchantFundWithdraw/GetMerchantFundWithdrawByOutRequestNumberResponse.cs @@ -72,7 +72,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public string AccountBank { get; set; } = default!; /// - /// 获取或设置开户开户银行全称(含支行)。 + /// 获取或设置开户银行全称(含支行)。 /// [Newtonsoft.Json.JsonProperty("bank_name")] [System.Text.Json.Serialization.JsonPropertyName("bank_name")] diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.cs new file mode 100644 index 00000000..82d43a87 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /partner-transfer/batches 接口的请求。 + /// + public class CreatePartnerTransferBatchRequest : WechatTenpayRequest + { + public static class Types + { + public class TransferDetail : CreateTransferBatchRequest.Types.TransferDetail + { + } + } + + /// + /// 获取或设置特约商户号。 + /// + [Newtonsoft.Json.JsonProperty("sub_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_mchid")] + public string SubMerchantId { get; set; } = string.Empty; + + /// + /// 获取或设置服务商 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sp_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_appid")] + public string? AppId { get; set; } + + /// + /// 获取或设置特约商户 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sub_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_appid")] + public string? SubAppId { get; set; } + + /// + /// 获取或设置特约商户授权类型。 + /// + [Newtonsoft.Json.JsonProperty("authorization_type")] + [System.Text.Json.Serialization.JsonPropertyName("authorization_type")] + public string AuthorizationType { get; set; } = string.Empty; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = string.Empty; + + /// + /// 获取或设置批次名称。 + /// + [Newtonsoft.Json.JsonProperty("batch_name")] + [System.Text.Json.Serialization.JsonPropertyName("batch_name")] + public string BatchName { get; set; } = string.Empty; + + /// + /// 获取或设置批次备注。 + /// + [Newtonsoft.Json.JsonProperty("batch_remark")] + [System.Text.Json.Serialization.JsonPropertyName("batch_remark")] + public string BatchRemark { get; set; } = string.Empty; + + /// + /// 获取或设置转账总金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("total_amount")] + [System.Text.Json.Serialization.JsonPropertyName("total_amount")] + public int TotalAmount { get; set; } + + /// + /// 获取或设置转账总笔数。 + /// + [Newtonsoft.Json.JsonProperty("total_num")] + [System.Text.Json.Serialization.JsonPropertyName("total_num")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置转账明细列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public IList TransferDetailList { get; set; } = new List(); + + /// + /// 获取或设置转账用途。 + /// + [Newtonsoft.Json.JsonProperty("transfer_purpose")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_purpose")] + public string? TransferPurpose { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.cs new file mode 100644 index 00000000..1e9b5574 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /partner-transfer/batches 接口的响应。 + /// + public class CreatePartnerTransferBatchResponse : CreateTransferBatchResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.cs new file mode 100644 index 00000000..6e8cce4d --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/batch-id/{batch_id} 接口的请求。 + /// + public class GetPartnerTransferBatchByBatchIdRequest : GetTransferBatchByBatchIdRequest + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.cs new file mode 100644 index 00000000..6dca7119 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/batch-id/{batch_id} 接口的响应。 + /// + public class GetPartnerTransferBatchByBatchIdResponse : WechatTenpayResponse + { + public static class Types + { + public class TransferDetail : GetPartnerTransferBatchByOutBatchNumberResponse.Types.TransferDetail + { + } + } + + /// + /// 获取或设置服务商商户号。 + /// + [Newtonsoft.Json.JsonProperty("sp_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_mchid")] + public string MerchantId { get; set; } = default!; + + /// + /// 获取或设置特约商户号。 + /// + [Newtonsoft.Json.JsonProperty("sub_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_mchid")] + public string SubMerchantId { get; set; } = default!; + + /// + /// 获取或设置服务商 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sp_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_appid")] + public string? AppId { get; set; } + + /// + /// 获取或设置特约商户 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sub_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_appid")] + public string? SubAppId { get; set; } + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonProperty("batch_id")] + [System.Text.Json.Serialization.JsonPropertyName("batch_id")] + public string BatchId { get; set; } = default!; + + /// + /// 获取或设置批次状态。 + /// + [Newtonsoft.Json.JsonProperty("batch_status")] + [System.Text.Json.Serialization.JsonPropertyName("batch_status")] + public string BatchStatus { get; set; } = default!; + + /// + /// 获取或设置批次类型。 + /// + [Newtonsoft.Json.JsonProperty("batch_type")] + [System.Text.Json.Serialization.JsonPropertyName("batch_type")] + public string BatchType { get; set; } = default!; + + /// + /// 获取或设置特约商户授权类型。 + /// + [Newtonsoft.Json.JsonProperty("authorization_type")] + [System.Text.Json.Serialization.JsonPropertyName("authorization_type")] + public string AuthorizationType { get; set; } = default!; + + /// + /// 获取或设置批次名称。 + /// + [Newtonsoft.Json.JsonProperty("batch_name")] + [System.Text.Json.Serialization.JsonPropertyName("batch_name")] + public string BatchName { get; set; } = default!; + + /// + /// 获取或设置批次备注。 + /// + [Newtonsoft.Json.JsonProperty("batch_remark")] + [System.Text.Json.Serialization.JsonPropertyName("batch_remark")] + public string BatchRemark { get; set; } = default!; + + /// + /// 获取或设置批次关闭原因。 + /// + [Newtonsoft.Json.JsonProperty("close_reason")] + [System.Text.Json.Serialization.JsonPropertyName("close_reason")] + public string? CloseReason { get; set; } + + /// + /// 获取或设置转账总金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("total_amount")] + [System.Text.Json.Serialization.JsonPropertyName("total_amount")] + public int TotalAmount { get; set; } + + /// + /// 获取或设置转账总笔数。 + /// + [Newtonsoft.Json.JsonProperty("total_num")] + [System.Text.Json.Serialization.JsonPropertyName("total_num")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置批次创建时间。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset CreateTime { get; set; } + + /// + /// 获取或设置批次更新时间。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + public DateTimeOffset? UpdateTime { get; set; } + + /// + /// 获取或设置转账成功金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("success_amount")] + [System.Text.Json.Serialization.JsonPropertyName("success_amount")] + public int SuccessAmount { get; set; } + + /// + /// 获取或设置转账成功笔数。 + /// + [Newtonsoft.Json.JsonProperty("success_num")] + [System.Text.Json.Serialization.JsonPropertyName("success_num")] + public int SuccessNumber { get; set; } + + /// + /// 获取或设置转账失败金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("fail_amount")] + [System.Text.Json.Serialization.JsonPropertyName("fail_amount")] + public int FailAmount { get; set; } + + /// + /// 获取或设置转账失败笔数。 + /// + [Newtonsoft.Json.JsonProperty("fail_num")] + [System.Text.Json.Serialization.JsonPropertyName("fail_num")] + public int FailNumber { get; set; } + + /// + /// 获取或设置转账用途。 + /// + [Newtonsoft.Json.JsonProperty("transfer_purpose")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_purpose")] + public string? TransferPurpose { get; set; } + + /// + /// 获取或设置转账明细单列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public Types.TransferDetail[]? TransferDetailList { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.cs new file mode 100644 index 00000000..5fca88fa --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no} 接口的请求。 + /// + public class GetPartnerTransferBatchByOutBatchNumberRequest : GetTransferBatchByOutBatchNumberRequest + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.cs new file mode 100644 index 00000000..66cd54a8 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no} 接口的响应。 + /// + public class GetPartnerTransferBatchByOutBatchNumberResponse : WechatTenpayResponse + { + public static class Types + { + public class TransferDetail : GetTransferBatchByOutBatchNumberResponse.Types.TransferDetail + { + } + } + + /// + /// 获取或设置服务商商户号。 + /// + [Newtonsoft.Json.JsonProperty("sp_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_mchid")] + public string MerchantId { get; set; } = default!; + + /// + /// 获取或设置特约商户号。 + /// + [Newtonsoft.Json.JsonProperty("sub_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_mchid")] + public string SubMerchantId { get; set; } = default!; + + /// + /// 获取或设置服务商 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sp_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_appid")] + public string? AppId { get; set; } + + /// + /// 获取或设置特约商户 AppId。 + /// + [Newtonsoft.Json.JsonProperty("sub_appid")] + [System.Text.Json.Serialization.JsonPropertyName("sub_appid")] + public string? SubAppId { get; set; } + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonProperty("batch_id")] + [System.Text.Json.Serialization.JsonPropertyName("batch_id")] + public string BatchId { get; set; } = default!; + + /// + /// 获取或设置批次状态。 + /// + [Newtonsoft.Json.JsonProperty("batch_status")] + [System.Text.Json.Serialization.JsonPropertyName("batch_status")] + public string BatchStatus { get; set; } = default!; + + /// + /// 获取或设置批次类型。 + /// + [Newtonsoft.Json.JsonProperty("batch_type")] + [System.Text.Json.Serialization.JsonPropertyName("batch_type")] + public string BatchType { get; set; } = default!; + + /// + /// 获取或设置特约商户授权类型。 + /// + [Newtonsoft.Json.JsonProperty("authorization_type")] + [System.Text.Json.Serialization.JsonPropertyName("authorization_type")] + public string AuthorizationType { get; set; } = default!; + + /// + /// 获取或设置批次名称。 + /// + [Newtonsoft.Json.JsonProperty("batch_name")] + [System.Text.Json.Serialization.JsonPropertyName("batch_name")] + public string BatchName { get; set; } = default!; + + /// + /// 获取或设置批次备注。 + /// + [Newtonsoft.Json.JsonProperty("batch_remark")] + [System.Text.Json.Serialization.JsonPropertyName("batch_remark")] + public string BatchRemark { get; set; } = default!; + + /// + /// 获取或设置批次关闭原因。 + /// + [Newtonsoft.Json.JsonProperty("close_reason")] + [System.Text.Json.Serialization.JsonPropertyName("close_reason")] + public string? CloseReason { get; set; } + + /// + /// 获取或设置转账总金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("total_amount")] + [System.Text.Json.Serialization.JsonPropertyName("total_amount")] + public int TotalAmount { get; set; } + + /// + /// 获取或设置转账总笔数。 + /// + [Newtonsoft.Json.JsonProperty("total_num")] + [System.Text.Json.Serialization.JsonPropertyName("total_num")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置批次创建时间。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset CreateTime { get; set; } + + /// + /// 获取或设置批次更新时间。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + public DateTimeOffset? UpdateTime { get; set; } + + /// + /// 获取或设置转账成功金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("success_amount")] + [System.Text.Json.Serialization.JsonPropertyName("success_amount")] + public int SuccessAmount { get; set; } + + /// + /// 获取或设置转账成功笔数。 + /// + [Newtonsoft.Json.JsonProperty("success_num")] + [System.Text.Json.Serialization.JsonPropertyName("success_num")] + public int SuccessNumber { get; set; } + + /// + /// 获取或设置转账失败金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("fail_amount")] + [System.Text.Json.Serialization.JsonPropertyName("fail_amount")] + public int FailAmount { get; set; } + + /// + /// 获取或设置转账失败笔数。 + /// + [Newtonsoft.Json.JsonProperty("fail_num")] + [System.Text.Json.Serialization.JsonPropertyName("fail_num")] + public int FailNumber { get; set; } + + /// + /// 获取或设置转账用途。 + /// + [Newtonsoft.Json.JsonProperty("transfer_purpose")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_purpose")] + public string? TransferPurpose { get; set; } + + /// + /// 获取或设置转账明细单列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public Types.TransferDetail[]? TransferDetailList { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.cs new file mode 100644 index 00000000..d2704d35 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口的请求。 + /// + public class GetPartnerTransferBatchDetailByDetailIdRequest : GetTransferBatchDetailByDetailIdRequest + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.cs new file mode 100644 index 00000000..c852614b --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口的响应。 + /// + public class GetPartnerTransferBatchDetailByDetailIdResponse : GetPartnerTransferBatchDetailByOutDetailNumberResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.cs new file mode 100644 index 00000000..b8fc89bf --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口的请求。 + /// + public class GetPartnerTransferBatchDetailByOutDetailNumberRequest : GetTransferBatchDetailByOutDetailNumberRequest + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.cs new file mode 100644 index 00000000..f0e993b8 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口的响应。 + /// + public class GetPartnerTransferBatchDetailByOutDetailNumberResponse : GetTransferBatchDetailByOutDetailNumberResponse + { + /// + /// 获取或设置服务商商户号。 + /// + [Newtonsoft.Json.JsonProperty("sp_mchid")] + [System.Text.Json.Serialization.JsonPropertyName("sp_mchid")] + public string MerchantId { get; set; } = default!; + + /// + /// 获取或设置收款用户姓名(需使用商户私钥解密)。 + /// + [Newtonsoft.Json.JsonProperty("username")] + [System.Text.Json.Serialization.JsonPropertyName("username")] + public override string UserName { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs new file mode 100644 index 00000000..52be9883 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer/batches 接口的请求。 + /// + public class CreateTransferBatchRequest : WechatTenpayRequest + { + public static class Types + { + public class TransferDetail + { + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonProperty("out_detail_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_detail_no")] + public string OutDetailNumber { get; set; } = string.Empty; + + /// + /// 获取或设置转账金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("transfer_amount")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_amount")] + public int TransferAmount { get; set; } + + /// + /// 获取或设置转账备注。 + /// + [Newtonsoft.Json.JsonProperty("transfer_remark")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_remark")] + public string TransferRemark { get; set; } = string.Empty; + + /// + /// 获取或设置收款用户 OpenId。 + /// + [Newtonsoft.Json.JsonProperty("openid")] + [System.Text.Json.Serialization.JsonPropertyName("openid")] + public string OpenId { get; set; } = string.Empty; + + /// + /// 获取或设置收款用户姓名(需使用微信支付平台公钥加密)。 + /// + [Newtonsoft.Json.JsonProperty("user_name")] + [System.Text.Json.Serialization.JsonPropertyName("user_name")] + public string UserName { get; set; } = string.Empty; + + /// + /// 获取或设置收款用户身份证号(需使用微信支付平台公钥加密)。 + /// + [Newtonsoft.Json.JsonProperty("user_id_card")] + [System.Text.Json.Serialization.JsonPropertyName("user_id_card")] + public string UserIdCardNumber { get; set; } = string.Empty; + } + } + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string AppId { get; set; } = string.Empty; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = string.Empty; + + /// + /// 获取或设置批次名称。 + /// + [Newtonsoft.Json.JsonProperty("batch_name")] + [System.Text.Json.Serialization.JsonPropertyName("batch_name")] + public string BatchName { get; set; } = string.Empty; + + /// + /// 获取或设置批次备注。 + /// + [Newtonsoft.Json.JsonProperty("batch_remark")] + [System.Text.Json.Serialization.JsonPropertyName("batch_remark")] + public string BatchRemark { get; set; } = string.Empty; + + /// + /// 获取或设置转账总金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("total_amount")] + [System.Text.Json.Serialization.JsonPropertyName("total_amount")] + public int TotalAmount { get; set; } + + /// + /// 获取或设置转账总笔数。 + /// + [Newtonsoft.Json.JsonProperty("total_num")] + [System.Text.Json.Serialization.JsonPropertyName("total_num")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置转账明细列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public IList TransferDetailList { get; set; } = new List(); + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchResponse.cs new file mode 100644 index 00000000..ed3cf0c8 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchResponse.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer/batches 接口的响应。 + /// + public class CreateTransferBatchResponse : WechatTenpayResponse + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonProperty("batch_id")] + [System.Text.Json.Serialization.JsonPropertyName("batch_id")] + public string BatchId { get; set; } = default!; + + /// + /// 获取或设置批次创建时间。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset CreateTime { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdRequest.cs new file mode 100644 index 00000000..762c6d6a --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdRequest.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/batch-id/{batch_id} 接口的请求。 + /// + public class GetTransferBatchByBatchIdRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string BatchId { get; set; } = string.Empty; + + /// + /// 获取或设置是否查询转账明细单。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public bool RequireQueryDetail { get; set; } + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Offset { get; set; } + + /// + /// 获取或设置分页每页数量。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Limit { get; set; } + + /// + /// 获取或设置明细状态。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? DetailStatus { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdResponse.cs new file mode 100644 index 00000000..17d273e2 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByBatchIdResponse.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/batch-id/{batch_id} 接口的响应。 + /// + public class GetTransferBatchByBatchIdResponse : WechatTenpayResponse + { + public static class Types + { + public class TransferBatch : GetTransferBatchByOutBatchNumberResponse.Types.TransferBatch + { + } + + public class TransferDetail : GetTransferBatchByOutBatchNumberResponse.Types.TransferDetail + { + } + } + + /// + /// 获取或设置转账批次单信息。 + /// + [Newtonsoft.Json.JsonProperty("transfer_batch")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_batch")] + public Types.TransferBatch TransferBatch { get; set; } = default!; + + /// + /// 获取或设置转账明细单列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public Types.TransferDetail[]? TransferDetailList { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.cs new file mode 100644 index 00000000..b2e8dace --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/out-batch-no/{out_batch_no} 接口的请求。 + /// + public class GetTransferBatchByOutBatchNumberRequest : WechatTenpayRequest + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OutBatchNumber { get; set; } = string.Empty; + + /// + /// 获取或设置是否查询转账明细单。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public bool RequireQueryDetail { get; set; } + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Offset { get; set; } + + /// + /// 获取或设置分页每页数量。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Limit { get; set; } + + /// + /// 获取或设置明细状态。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? DetailStatus { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.cs new file mode 100644 index 00000000..56c18134 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/out-batch-no/{out_batch_no} 接口的响应。 + /// + public class GetTransferBatchByOutBatchNumberResponse : WechatTenpayResponse + { + public static class Types + { + public class TransferBatch + { + /// + /// 获取或设置微信商户号。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string MerchantId { get; set; } = default!; + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string AppId { get; set; } = default!; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonProperty("batch_id")] + [System.Text.Json.Serialization.JsonPropertyName("batch_id")] + public string BatchId { get; set; } = default!; + + /// + /// 获取或设置批次状态。 + /// + [Newtonsoft.Json.JsonProperty("batch_status")] + [System.Text.Json.Serialization.JsonPropertyName("batch_status")] + public string BatchStatus { get; set; } = default!; + + /// + /// 获取或设置批次类型。 + /// + [Newtonsoft.Json.JsonProperty("batch_type")] + [System.Text.Json.Serialization.JsonPropertyName("batch_type")] + public string BatchType { get; set; } = default!; + + /// + /// 获取或设置批次名称。 + /// + [Newtonsoft.Json.JsonProperty("batch_name")] + [System.Text.Json.Serialization.JsonPropertyName("batch_name")] + public string BatchName { get; set; } = default!; + + /// + /// 获取或设置批次备注。 + /// + [Newtonsoft.Json.JsonProperty("batch_remark")] + [System.Text.Json.Serialization.JsonPropertyName("batch_remark")] + public string BatchRemark { get; set; } = default!; + + /// + /// 获取或设置批次关闭原因。 + /// + [Newtonsoft.Json.JsonProperty("close_reason")] + [System.Text.Json.Serialization.JsonPropertyName("close_reason")] + public string? CloseReason { get; set; } + + /// + /// 获取或设置转账总金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("total_amount")] + [System.Text.Json.Serialization.JsonPropertyName("total_amount")] + public int TotalAmount { get; set; } + + /// + /// 获取或设置转账总笔数。 + /// + [Newtonsoft.Json.JsonProperty("total_num")] + [System.Text.Json.Serialization.JsonPropertyName("total_num")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置批次创建时间。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset CreateTime { get; set; } + + /// + /// 获取或设置批次更新时间。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + public DateTimeOffset? UpdateTime { get; set; } + + /// + /// 获取或设置转账成功金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("success_amount")] + [System.Text.Json.Serialization.JsonPropertyName("success_amount")] + public int SuccessAmount { get; set; } + + /// + /// 获取或设置转账成功笔数。 + /// + [Newtonsoft.Json.JsonProperty("success_num")] + [System.Text.Json.Serialization.JsonPropertyName("success_num")] + public int SuccessNumber { get; set; } + + /// + /// 获取或设置转账失败金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("fail_amount")] + [System.Text.Json.Serialization.JsonPropertyName("fail_amount")] + public int FailAmount { get; set; } + + /// + /// 获取或设置转账失败笔数。 + /// + [Newtonsoft.Json.JsonProperty("fail_num")] + [System.Text.Json.Serialization.JsonPropertyName("fail_num")] + public int FailNumber { get; set; } + } + + public class TransferDetail + { + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonProperty("out_detail_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_detail_no")] + public string OutDetailNumber { get; set; } = default!; + + /// + /// 获取或设置微信明细单号。 + /// + [Newtonsoft.Json.JsonProperty("detail_id")] + [System.Text.Json.Serialization.JsonPropertyName("detail_id")] + public string DetailId { get; set; } = default!; + + /// + /// 获取或设置明细状态。 + /// + [Newtonsoft.Json.JsonProperty("detail_status")] + [System.Text.Json.Serialization.JsonPropertyName("detail_status")] + public string DetailStatus { get; set; } = default!; + } + } + + /// + /// 获取或设置转账批次单信息。 + /// + [Newtonsoft.Json.JsonProperty("transfer_batch")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_batch")] + public Types.TransferBatch TransferBatch { get; set; } = default!; + + /// + /// 获取或设置转账明细单列表。 + /// + [Newtonsoft.Json.JsonProperty("transfer_detail_list")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_detail_list")] + public Types.TransferDetail[]? TransferDetailList { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.cs new file mode 100644 index 00000000..47d5a035 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口的请求。 + /// + public class GetTransferBatchDetailByDetailIdRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string BatchId { get; set; } = string.Empty; + + /// + /// 获取或设置微信明细单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string DetailId { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.cs new file mode 100644 index 00000000..6b113033 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} 接口的响应。 + /// + public class GetTransferBatchDetailByDetailIdResponse : GetTransferBatchDetailByOutDetailNumberResponse + { + /// + /// 获取或设置微信商户号。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string MerchantId { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.cs new file mode 100644 index 00000000..83117adb --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口的请求。 + /// + public class GetTransferBatchDetailByOutDetailNumberRequest : WechatTenpayRequest + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OutBatchNumber { get; set; } = string.Empty; + + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OutDetailNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.cs new file mode 100644 index 00000000..12cae7b9 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口的响应。 + /// + public class GetTransferBatchDetailByOutDetailNumberResponse : WechatTenpayResponse + { + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string? AppId { get; set; } + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置微信批次单号。 + /// + [Newtonsoft.Json.JsonProperty("batch_id")] + [System.Text.Json.Serialization.JsonPropertyName("batch_id")] + public string BatchId { get; set; } = default!; + + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonProperty("out_detail_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_detail_no")] + public string OutDetailNumber { get; set; } = default!; + + /// + /// 获取或设置微信明细单号。 + /// + [Newtonsoft.Json.JsonProperty("detail_id")] + [System.Text.Json.Serialization.JsonPropertyName("detail_id")] + public string DetailId { get; set; } = default!; + + /// + /// 获取或设置明细状态。 + /// + [Newtonsoft.Json.JsonProperty("detail_status")] + [System.Text.Json.Serialization.JsonPropertyName("detail_status")] + public string DetailStatus { get; set; } = default!; + + /// + /// 获取或设置转账金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("transfer_amount")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_amount")] + public int TransferAmount { get; set; } + + /// + /// 获取或设置转账备注。 + /// + [Newtonsoft.Json.JsonProperty("transfer_remark")] + [System.Text.Json.Serialization.JsonPropertyName("transfer_remark")] + public string TransferRemark { get; set; } = default!; + + /// + /// 获取或设置失败原因。 + /// + [Newtonsoft.Json.JsonProperty("fail_reason")] + [System.Text.Json.Serialization.JsonPropertyName("fail_reason")] + public string? FailReason { get; set; } + + /// + /// 获取或设置收款用户 OpenId。 + /// + [Newtonsoft.Json.JsonProperty("openid")] + [System.Text.Json.Serialization.JsonPropertyName("openid")] + public string OpenId { get; set; } = default!; + + /// + /// 获取或设置收款用户姓名(需使用商户私钥解密)。 + /// + [Newtonsoft.Json.JsonProperty("user_name")] + [System.Text.Json.Serialization.JsonPropertyName("user_name")] + public virtual string UserName { get; set; } = default!; + + /// + /// 获取或设置转账发起时间。 + /// + [Newtonsoft.Json.JsonProperty("initiate_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("initiate_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset InitiateTime { get; set; } + + /// + /// 获取或设置明细更新时间。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset UpdateTime { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptRequest.cs new file mode 100644 index 00000000..b7fd860f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptRequest.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer/bill-receipt 接口的请求。 + /// + public class CreateTransferBillReceiptRequest : WechatTenpayRequest + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptResponse.cs new file mode 100644 index 00000000..0b9de23e --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/CreateTransferBillReceiptResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer/bill-receipt 接口的响应。 + /// + public class CreateTransferBillReceiptResponse : GetTransferBillReceiptByOutBatchNumberResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.cs new file mode 100644 index 00000000..444ad849 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/bill-receipt/{out_batch_no} 接口的请求。 + /// + public class GetTransferBillReceiptByOutBatchNumberRequest : WechatTenpayRequest + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OutBatchNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.cs new file mode 100644 index 00000000..f11e883b --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer/bill-receipt/{out_batch_no} 接口的响应。 + /// + public class GetTransferBillReceiptByOutBatchNumberResponse : WechatTenpayResponse + { + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置电子回单申请单号。 + /// + [Newtonsoft.Json.JsonProperty("signature_no")] + [System.Text.Json.Serialization.JsonPropertyName("signature_no")] + public string SignatureNumber { get; set; } = default!; + + /// + /// 获取或设置电子回单状态。 + /// + [Newtonsoft.Json.JsonProperty("signature_status")] + [System.Text.Json.Serialization.JsonPropertyName("signature_status")] + public string? SignatureStatus { get; set; } + + /// + /// 获取或设置电子回单文件的哈希方法。 + /// + [Newtonsoft.Json.JsonProperty("hash_type")] + [System.Text.Json.Serialization.JsonPropertyName("hash_type")] + public string? HashType { get; set; } + + /// + /// 获取或设置电子回单文件的哈希值。 + /// + [Newtonsoft.Json.JsonProperty("hash_value")] + [System.Text.Json.Serialization.JsonPropertyName("hash_value")] + public string? HashValue { get; set; } + + /// + /// 获取或设置电子回单文件的下载地址。 + /// + [Newtonsoft.Json.JsonProperty("download_url")] + [System.Text.Json.Serialization.JsonPropertyName("download_url")] + public string? DownloadUrl { get; set; } + + /// + /// 获取或设置创建时间。 + /// + [Newtonsoft.Json.JsonProperty("create_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("create_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + public DateTimeOffset? CreateTime { get; set; } + + /// + /// 获取或设置更新时间。 + /// + [Newtonsoft.Json.JsonProperty("update_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("update_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339NullableDateTimeOffsetConverter))] + public DateTimeOffset? UpdateTime { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.cs new file mode 100644 index 00000000..968c919c --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer-detail/electronic-receipts 接口的请求。 + /// + public class CreateTransferDetailElectronicReceiptRequest : WechatTenpayRequest + { + /// + /// 获取或设置受理类型。 + /// + [Newtonsoft.Json.JsonProperty("accept_type")] + [System.Text.Json.Serialization.JsonPropertyName("accept_type")] + public string AcceptType { get; set; } = string.Empty; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string? OutBatchNumber { get; set; } + + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonProperty("out_detail_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_detail_no")] + public string OutDetailNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.cs new file mode 100644 index 00000000..459d1e9c --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /transfer-detail/electronic-receipts 接口的响应。 + /// + public class CreateTransferDetailElectronicReceiptResponse : GetTransferDetailElectronicReceiptByOutDetailNumberResponse + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.cs new file mode 100644 index 00000000..26f954e4 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer-detail/electronic-receipts 接口的请求。 + /// + public class GetTransferDetailElectronicReceiptByOutDetailNumberRequest : WechatTenpayRequest + { + /// + /// 获取或设置受理类型。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string AcceptType { get; set; } = string.Empty; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? OutBatchNumber { get; set; } + + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OutDetailNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.cs new file mode 100644 index 00000000..bcaf988a --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /transfer-detail/electronic-receipts 接口的响应。 + /// + public class GetTransferDetailElectronicReceiptByOutDetailNumberResponse : WechatTenpayResponse + { + /// + /// 获取或设置受理类型。 + /// + [Newtonsoft.Json.JsonProperty("accept_type")] + [System.Text.Json.Serialization.JsonPropertyName("accept_type")] + public string AcceptType { get; set; } = default!; + + /// + /// 获取或设置商户批次单号。 + /// + [Newtonsoft.Json.JsonProperty("out_batch_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_batch_no")] + public string OutBatchNumber { get; set; } = default!; + + /// + /// 获取或设置商户明细单号。 + /// + [Newtonsoft.Json.JsonProperty("out_detail_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_detail_no")] + public string OutDetailNumber { get; set; } = default!; + + /// + /// 获取或设置电子回单申请单号。 + /// + [Newtonsoft.Json.JsonProperty("signature_no")] + [System.Text.Json.Serialization.JsonPropertyName("signature_no")] + public string SignatureNumber { get; set; } = default!; + + /// + /// 获取或设置电子回单状态。 + /// + [Newtonsoft.Json.JsonProperty("signature_status")] + [System.Text.Json.Serialization.JsonPropertyName("signature_status")] + public string? SignatureStatus { get; set; } + + /// + /// 获取或设置电子回单文件的哈希方法。 + /// + [Newtonsoft.Json.JsonProperty("hash_type")] + [System.Text.Json.Serialization.JsonPropertyName("hash_type")] + public string? HashType { get; set; } + + /// + /// 获取或设置电子回单文件的哈希值。 + /// + [Newtonsoft.Json.JsonProperty("hash_value")] + [System.Text.Json.Serialization.JsonPropertyName("hash_value")] + public string? HashValue { get; set; } + + /// + /// 获取或设置电子回单文件的下载地址。 + /// + [Newtonsoft.Json.JsonProperty("download_url")] + [System.Text.Json.Serialization.JsonPropertyName("download_url")] + public string? DownloadUrl { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj index 6bd92f8f..482f7c76 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj @@ -12,7 +12,7 @@ MIT https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat Flurl.Http Wechat Weixin MicroMessage Tenpay WechatPay WeixinPay Wxpay 微信 微信支付 微信商户 - 1.2.1 + 1.3.0 Flurl.Http client for Wechat Tenpay API. 基于 Flurl.Http 的微信支付 API v3 版客户端,支持直连商户、服务商模式,支持基础支付、代金券、商家券、委托营销、消费卡、支付有礼、微信支付分、微信先享卡、支付即服务、点金计划、智慧商圈、电商收付通、消费者投诉等功能。 Fu Diwei git diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/ICertificateStorer.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/ICertificateStorer.cs new file mode 100644 index 00000000..0c99f9ff --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/ICertificateStorer.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings +{ + /// + /// 微信商户平台证书存储器接口。 + /// + public interface ICertificateStorer + { + /// + /// 根据证书序列号获取证书(cer 格式)。 + /// + /// + /// + string? Get(string serialNumber); + + /// + /// 设置证书序列号与证书(cer 格式)的映射关系。 + /// + /// + /// + void Set(string serialNumber, string certificate); + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/InMemoryCertificateStorer.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/InMemoryCertificateStorer.cs new file mode 100644 index 00000000..37afe581 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Settings/InMemoryCertificateStorer.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings +{ + /// + /// 一个基于内存实现的 。 + /// + public class InMemoryCertificateStorer : ICertificateStorer + { + public IDictionary _dict; + + public InMemoryCertificateStorer() + { + _dict = new ConcurrentDictionary(); + } + + string? ICertificateStorer.Get(string serialNumber) + { + if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber)); + + return _dict[serialNumber]; + } + + void ICertificateStorer.Set(string serialNumber, string certificate) + { + if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber)); + if (certificate == null) throw new ArgumentNullException(nameof(certificate)); + + _dict[serialNumber] = certificate; + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayAuthSchemes.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayAuthSchemes.cs deleted file mode 100644 index 372fecdd..00000000 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayAuthSchemes.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 -{ - /// - /// 微信支付 API 接口签名认证方式。 - /// - public static class WechatTenpayAuthSchemes - { - /// - /// WECHATPAY2-SHA256-RSA2048(默认)。 - /// - public const string WECHATPAY2_SHA256_RSA2048 = "WECHATPAY2-SHA256-RSA2048"; - } -} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs index a7afc7a2..d2e084fb 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs @@ -39,6 +39,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// internal string WechatMerchantV3Secret { get; } + /// + /// 获取当前客户端使用的微信商户平台证书存储器。 + /// + internal Settings.ICertificateStorer? WechatCertificateStorer { get; } + /// /// 获取当前客户端使用的 JSON 序列化器。 /// @@ -59,6 +64,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 WechatMerchantCertSerialNumber = options.MerchantCertSerialNumber; WechatMerchantCertPrivateKey = options.MerchantCertPrivateKey; WechatMerchantV3Secret = options.MerchantV3Secret; + WechatCertificateStorer = options.CertificateStorer; FlurlClient.BaseUrl = options.Endpoints ?? WechatTenpayEndpoints.DEFAULT; FlurlClient.Headers.Remove("Accept"); diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClientOptions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClientOptions.cs index a73a442d..3c339680 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClientOptions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClientOptions.cs @@ -34,9 +34,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// /// 获取或设置微信支付 API 签名认证方式。 - /// 默认值: + /// 默认值: /// - public string AuthScheme { get; set; } = WechatTenpayAuthSchemes.WECHATPAY2_SHA256_RSA2048; + public string AuthScheme { get; set; } = Constants.SignAlgorithms.WECHATPAY2_SHA256_RSA2048; /// /// 获取或设置微信商户号。 @@ -57,5 +57,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 /// 获取或设置微信商户 API 证书私钥。 /// public string MerchantCertPrivateKey { get; set; } = default!; + + /// + /// 获取或设置微信商户平台证书存储器。 + /// 默认值: + /// + public Settings.ICertificateStorer? CertificateStorer { get; set; } = new Settings.InMemoryCertificateStorer(); } } diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.json new file mode 100644 index 00000000..6ebcaaa4 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundMerchantIncomeRecordsResponse.json @@ -0,0 +1,18 @@ +{ + "total_count": 100, + "offset": 0, + "limit": 100, + "data": [ + { + "mchid": "2480253391", + "account_type": "BASIC", + "income_record_type": "OFFLINERECHARGE", + "income_record_id": "4200000811202011056138519459", + "amount": 100, + "success_time": "2017-12-08T00:08:00.00+08:00", + "bank_name": "招商银行", + "bank_account_name": "财付通支付科技有限公司", + "bank_account_number": "****6473" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.json new file mode 100644 index 00000000..28f6a57f --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/MerchantFundIncomeRecords/QueryMerchantFundPartnerIncomeRecordsResponse.json @@ -0,0 +1,18 @@ +{ + "total_count": 0, + "offset": 0, + "limit": 0, + "data": [ + { + "sub_mchid": "2480253391", + "account_type": "BASIC", + "income_record_type": "OFFLINERECHARGE", + "income_record_id": "4200000811202011056138519459", + "amount": 2734921, + "success_time": "2017-12-08T00:08:00.00+08:00", + "bank_name": "招商银行", + "bank_account_name": "北京三快科技有限公司", + "bank_account_number": "****6473" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.json new file mode 100644 index 00000000..d7d3629e --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchRequest.json @@ -0,0 +1,22 @@ +{ + "sub_mchid": "1900000109", + "sub_appid": "wxf636efh567hg4356", + "authorization_type": "INFORMATION_AUTHORIZATION_TYPE", + "out_batch_no": "plfk2020042013", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "total_amount": 4000000, + "total_num": 200, + "transfer_detail_list": [ + { + "out_detail_no": "x23zy545Bd5436", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "user_name": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "user_id_card": "8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f" + } + ], + "sp_appid": "wxf636efh567hg4388", + "transfer_purpose": "COMMISSION" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.json new file mode 100644 index 00000000..57ba85e0 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/CreatePartnerTransferBatchResponse.json @@ -0,0 +1,5 @@ +{ + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "create_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.json new file mode 100644 index 00000000..195bae4c --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByBatchIdResponse.json @@ -0,0 +1,29 @@ +{ + "sp_mchid": "1900001109", + "sub_mchid": "1900000109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "sub_appid": "wxf636efh567hg4356", + "batch_status": "ACCEPTED", + "batch_type": "API", + "authorization_type": "INFORMATION_AUTHORIZATION_TYPE", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "close_reason": "OVERDUE_CLOSE", + "total_amount": 4000000, + "total_num": 200, + "create_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00", + "success_amount": 3900000, + "success_num": 199, + "fail_amount": 100000, + "fail_num": 1, + "transfer_detail_list": [ + { + "detail_id": "1040000071100999991182020050700019500100", + "out_detail_no": "x23zy545Bd5436", + "detail_status": "SUCCESS" + } + ], + "transfer_purpose": "COMMISSION" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.json new file mode 100644 index 00000000..195bae4c --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchByOutBatchNumberResponse.json @@ -0,0 +1,29 @@ +{ + "sp_mchid": "1900001109", + "sub_mchid": "1900000109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "sub_appid": "wxf636efh567hg4356", + "batch_status": "ACCEPTED", + "batch_type": "API", + "authorization_type": "INFORMATION_AUTHORIZATION_TYPE", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "close_reason": "OVERDUE_CLOSE", + "total_amount": 4000000, + "total_num": 200, + "create_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00", + "success_amount": 3900000, + "success_num": 199, + "fail_amount": 100000, + "fail_num": 1, + "transfer_detail_list": [ + { + "detail_id": "1040000071100999991182020050700019500100", + "out_detail_no": "x23zy545Bd5436", + "detail_status": "SUCCESS" + } + ], + "transfer_purpose": "COMMISSION" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.json new file mode 100644 index 00000000..9a221567 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByDetailIdResponse.json @@ -0,0 +1,16 @@ +{ + "sp_mchid": "1900001109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "out_detail_no": "x23zy545Bd5436", + "detail_id": "1040000071100999991182020050700019500100", + "detail_status": "SUCCESS", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "fail_reason": "ACCOUNT_FROZEN", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "username": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "initiate_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.json new file mode 100644 index 00000000..9a221567 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/PartnerTransfer/Batches/GetPartnerTransferBatchDetailByOutDetailNumberResponse.json @@ -0,0 +1,16 @@ +{ + "sp_mchid": "1900001109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "out_detail_no": "x23zy545Bd5436", + "detail_id": "1040000071100999991182020050700019500100", + "detail_status": "SUCCESS", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "fail_reason": "ACCOUNT_FROZEN", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "username": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "initiate_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchRequest.json new file mode 100644 index 00000000..763bb22e --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchRequest.json @@ -0,0 +1,18 @@ +{ + "appid": "wxf636efh567hg4356", + "out_batch_no": "plfk2020042013", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "total_amount": 4000000, + "total_num": 200, + "transfer_detail_list": [ + { + "out_detail_no": "x23zy545Bd5436", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "user_name": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "user_id_card": "8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchResponse.json new file mode 100644 index 00000000..57ba85e0 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/CreateTransferBatchResponse.json @@ -0,0 +1,5 @@ +{ + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "create_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdResponse.json new file mode 100644 index 00000000..47d00ef7 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByBatchIdResponse.json @@ -0,0 +1,28 @@ +{ + "transfer_batch": { + "mchid": "1900001109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "batch_status": "ACCEPTED", + "batch_type": "API", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "close_reason": "OVERDUE_CLOSE", + "total_amount": 4000000, + "total_num": 200, + "create_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00", + "success_amount": 3900000, + "success_num": 199, + "fail_amount": 100000, + "fail_num": 1 + }, + "transfer_detail_list": [ + { + "detail_id": "1040000071100999991182020050700019500100", + "out_detail_no": "x23zy545Bd5436", + "detail_status": "SUCCESS" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.json new file mode 100644 index 00000000..47d00ef7 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchByOutBatchNumberResponse.json @@ -0,0 +1,28 @@ +{ + "transfer_batch": { + "mchid": "1900001109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "batch_status": "ACCEPTED", + "batch_type": "API", + "batch_name": "2019年1月深圳分部报销单", + "batch_remark": "2019年1月深圳分部报销单", + "close_reason": "OVERDUE_CLOSE", + "total_amount": 4000000, + "total_num": 200, + "create_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00", + "success_amount": 3900000, + "success_num": 199, + "fail_amount": 100000, + "fail_num": 1 + }, + "transfer_detail_list": [ + { + "detail_id": "1040000071100999991182020050700019500100", + "out_detail_no": "x23zy545Bd5436", + "detail_status": "SUCCESS" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.json new file mode 100644 index 00000000..03610c54 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByDetailIdResponse.json @@ -0,0 +1,16 @@ +{ + "mchid": "1900001109", + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "out_detail_no": "x23zy545Bd5436", + "detail_id": "1040000071100999991182020050700019500100", + "detail_status": "SUCCESS", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "fail_reason": "ACCOUNT_FROZEN", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "user_name": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "initiate_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.json new file mode 100644 index 00000000..f98a9da7 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Batches/GetTransferBatchDetailByOutDetailNumberResponse.json @@ -0,0 +1,15 @@ +{ + "out_batch_no": "plfk2020042013", + "batch_id": "1030000071100999991182020050700019480001", + "appid": "wxf636efh567hg4356", + "out_detail_no": "x23zy545Bd5436", + "detail_id": "1040000071100999991182020050700019500100", + "detail_status": "SUCCESS", + "transfer_amount": 200000, + "transfer_remark": "2020年4月报销", + "fail_reason": "ACCOUNT_FROZEN", + "openid": "o-MYE42l80oelYMDE34nYD456Xoy", + "user_name": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", + "initiate_time": "2015-05-20T13:29:35.120+08:00", + "update_time": "2015-05-20T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptRequest.json new file mode 100644 index 00000000..aec1ac18 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptRequest.json @@ -0,0 +1,3 @@ +{ + "out_batch_no": "plfk2020042013" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptResponse.json new file mode 100644 index 00000000..8ead5382 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/CreateTransferBillReceiptResponse.json @@ -0,0 +1,10 @@ +{ + "out_batch_no": "plfk2020042013", + "signature_no": "1050000010509999485212020110200058820001", + "signature_status": "ACCEPTED", + "hash_type": "SHA256", + "hash_value": "DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529", + "download_url": "https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx", + "create_time": "2020-05-20T13:29:35.120+08:00", + "update_time": "2020-05-21T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.json new file mode 100644 index 00000000..8ead5382 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/BillReceipt/GetTransferBillReceiptByOutBatchNumberResponse.json @@ -0,0 +1,10 @@ +{ + "out_batch_no": "plfk2020042013", + "signature_no": "1050000010509999485212020110200058820001", + "signature_status": "ACCEPTED", + "hash_type": "SHA256", + "hash_value": "DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529", + "download_url": "https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx", + "create_time": "2020-05-20T13:29:35.120+08:00", + "update_time": "2020-05-21T13:29:35.120+08:00" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.json new file mode 100644 index 00000000..950ad60a --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptRequest.json @@ -0,0 +1,5 @@ +{ + "accept_type": "BATCH_TRANSFER", + "out_batch_no": "GD2021011610162610BBdkkIwcu3", + "out_detail_no": "mx0911231610162610v4CNkO4HAf" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.json new file mode 100644 index 00000000..bb8ce743 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/CreateTransferDetailElectronicReceiptResponse.json @@ -0,0 +1,10 @@ +{ + "accept_type": "BATCH_TRANSFER", + "out_batch_no": "GD2021011610162610BBdkkIwcu3", + "out_detail_no": "mx0911231610162610v4CNkO4HAf", + "signature_no": "1050000010509999485212020110200058820001", + "signature_status": "ACCEPTED", + "hash_type": "SHA256", + "hash_value": "DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529", + "download_url": "https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.json new file mode 100644 index 00000000..22fdca1b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberRequest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.json new file mode 100644 index 00000000..bb8ce743 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Transfer/Detail/GetTransferDetailElectronicReceiptByOutDetailNumberResponse.json @@ -0,0 +1,10 @@ +{ + "accept_type": "BATCH_TRANSFER", + "out_batch_no": "GD2021011610162610BBdkkIwcu3", + "out_detail_no": "mx0911231610162610v4CNkO4HAf", + "signature_no": "1050000010509999485212020110200058820001", + "signature_status": "ACCEPTED", + "hash_type": "SHA256", + "hash_value": "DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529", + "download_url": "https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayResponseVerificationTests.cs b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayResponseVerificationTests.cs index b331786d..12b3e907 100644 --- a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayResponseVerificationTests.cs +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayResponseVerificationTests.cs @@ -21,7 +21,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests Assert.NotNull(response.WechatpayCertSerialNumber); Assert.NotNull(response.WechatpaySignature); - TestClients.Instance.DecryptResponseEncryptedData(response); + TestClients.Instance.DecryptResponseEncryptedData(ref response); var certificateModel = response.CertificateList.SingleOrDefault(e => e.SerialNumber == response.WechatpayCertSerialNumber); Assert.NotNull(certificateModel);