diff --git a/docs/WechatTenpayV2/Advanced_ModelDefinition.md b/docs/WechatTenpayV2/Advanced_ModelDefinition.md index f6d15fe8..d567258b 100644 --- a/docs/WechatTenpayV2/Advanced_ModelDefinition.md +++ b/docs/WechatTenpayV2/Advanced_ModelDefinition.md @@ -43,9 +43,9 @@ | √ | 特约商户配置 | 银行服务商 | | | × | 风控数据同步 | 银行服务商 | 请升级至 v3 API | | × | 事中风险服务接口 | 银行服务商 | 请升级至 v3 API | -| √ | 境外子商户进件 | 跨境支付 | | -| × | 微信支付报关 | 跨境支付 | 请升级至 v3 API | -| × | 融合钱包 | 跨境支付 | 请升级至 v3 API | +| √ | 境外支付:子商户进件 | 跨境支付 | | +| × | 境外支付:融合钱包 | 跨境支付 | 请升级至 v3 API | +| × | 境外支付:报关 | 跨境支付 | 请升级至 v3 API | diff --git a/docs/WechatTenpayV3/Advanced_ModelDefinition.md b/docs/WechatTenpayV3/Advanced_ModelDefinition.md index 24a06b54..2e501db3 100644 --- a/docs/WechatTenpayV3/Advanced_ModelDefinition.md +++ b/docs/WechatTenpayV3/Advanced_ModelDefinition.md @@ -54,7 +54,7 @@ | √ | 其他能力:视频上传 | 直连商户 & 服务商 | | | √ | 境外支付:子商户进件 | 服务商 | | | √ | 境外支付:融合钱包 | 服务商 | | -| √ | 境外支付:微信支付报关 | 服务商 | | +| √ | 境外支付:报关 | 服务商 | | @@ -1070,15 +1070,15 @@ - Customs Declaration - - Customs Declaration:`` + - Customs Declaration:`CreateCustomsOrder` - - Identity Information Verification:`` + - Identity Information Verification:`VerifyCustomsCertificate` - - Query Customs Declaration:`` + - Query Customs Declaration:`QueryCustomsOrders` - - Repush Customs Declaration:`` + - Repush Customs Declaration:`RedeclareCustomsOrder` - - Modify Customs Declaration Info:`` + - Modify Customs Declaration Info:`ModifyCustomsOrder` - Functional APIs diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteCustomsExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteCustomsExtensions.cs new file mode 100644 index 00000000..609c42c3 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteCustomsExtensions.cs @@ -0,0 +1,135 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 +{ + /// + /// 为 提供境外支付报关相关的 API 扩展方法。 + /// + public static class WechatTenpayClientExecuteCustomsExtensions + { + /// + /// 异步调用 [POST] /customs/orders 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/declarecustom/chapter3_1.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteCreateCustomsOrderAsync(this WechatTenpayClient client, Models.CreateCustomsOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.MerchantId == null) + request.MerchantId = client.Credentials.MerchantId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "customs", "orders"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /customs/orders 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/declarecustom/chapter3_1.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteQueryCustomsOrdersAsync(this WechatTenpayClient client, Models.QueryCustomsOrdersRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.MerchantId == null) + request.MerchantId = client.Credentials.MerchantId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Get, "customs", "orders") + .SetQueryParam("mchid", request.MerchantId) + .SetQueryParam("appid", request.AppId) + .SetQueryParam("order_type", request.OrderType) + .SetQueryParam("order_no", request.OrderNumber) + .SetQueryParam("customs", request.Customs); + + if (request.Offset != null) + flurlReq.SetQueryParam("offset", request.Offset); + + if (request.Limit != null) + flurlReq.SetQueryParam("limit", request.Limit); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /customs/redeclare 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/declarecustom/chapter3_4.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteRedeclareCustomsOrderAsync(this WechatTenpayClient client, Models.RedeclareCustomsOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.MerchantId == null) + request.MerchantId = client.Credentials.MerchantId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "customs", "redeclare"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [PATCH] /customs/orders 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/declarecustom/chapter3_5.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteModifyCustomsOrderAsync(this WechatTenpayClient client, Models.ModifyCustomsOrderRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.MerchantId == null) + request.MerchantId = client.Credentials.MerchantId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, new HttpMethod("PATCH"), "customs", "orders"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /customs/verify-certificate 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/api/wxpay/en/declarecustom/chapter3_2.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteVerifyCustomsCertificateAsync(this WechatTenpayClient client, Models.VerifyCustomsCertificateRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.MerchantId == null) + request.MerchantId = client.Credentials.MerchantId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "customs", "verify-certificate"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderRequest.cs new file mode 100644 index 00000000..f0ac9a9c --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderRequest.cs @@ -0,0 +1,92 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/orders 接口的请求。 + /// + public class CreateCustomsOrderRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信商户号。如果不指定将使用构造 时的 参数。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string? MerchantId { get; set; } + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string AppId { get; set; } = string.Empty; + + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("out_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string OutTradeNumber { get; set; } = string.Empty; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } = string.Empty; + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置海关代码。 + /// + [Newtonsoft.Json.JsonProperty("customs")] + [System.Text.Json.Serialization.JsonPropertyName("customs")] + public string Customs { get; set; } = string.Empty; + + /// + /// 获取或设置商户海关备案号。 + /// + [Newtonsoft.Json.JsonProperty("merchant_customs_no")] + [System.Text.Json.Serialization.JsonPropertyName("merchant_customs_no")] + public string MerchantCustomsNumber { get; set; } = string.Empty; + + /// + /// 获取或设置关税(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("duty")] + [System.Text.Json.Serialization.JsonPropertyName("duty")] + public int? Duty { get; set; } + + /// + /// 获取或设置币种。 + /// + [Newtonsoft.Json.JsonProperty("fee_type")] + [System.Text.Json.Serialization.JsonPropertyName("fee_type")] + public string? FeeType { get; set; } + + /// + /// 获取或设置应付金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("order_fee")] + [System.Text.Json.Serialization.JsonPropertyName("order_fee")] + public int? OrderFee { get; set; } + + /// + /// 获取或设置物流费(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("transport_fee")] + [System.Text.Json.Serialization.JsonPropertyName("transport_fee")] + public int? TransportFee { get; set; } + + /// + /// 获取或设置商品价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("product_fee")] + [System.Text.Json.Serialization.JsonPropertyName("product_fee")] + public int? ProductFee { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderResponse.cs new file mode 100644 index 00000000..d6f89cfb --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/CreateCustomsOrderResponse.cs @@ -0,0 +1,71 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/orders 接口的响应。 + /// + public class CreateCustomsOrderResponse : WechatTenpayResponse + { + /// + /// 获取或设置微信商户号。 + /// + [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("state")] + [System.Text.Json.Serialization.JsonPropertyName("state")] + public string State { get; set; } = default!; + + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("out_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string OutTradeNumber { get; set; } = default!; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置微信子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_id")] + public string? SubOrderId { get; set; } + + /// + /// 获取或设置验核机构。 + /// + [Newtonsoft.Json.JsonProperty("verify_department")] + [System.Text.Json.Serialization.JsonPropertyName("verify_department")] + public string? VerifyDepartment { get; set; } + + /// + /// 获取或设置验核机构交易流水号。 + /// + [Newtonsoft.Json.JsonProperty("verify_department_trade_id")] + [System.Text.Json.Serialization.JsonPropertyName("verify_department_trade_id")] + public string? VerifyDepartmentTradeId { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderRequest.cs new file mode 100644 index 00000000..6649ef6e --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderRequest.cs @@ -0,0 +1,9 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [PATCH] /customs/orders 接口的请求。 + /// + public class ModifyCustomsOrderRequest : CreateCustomsOrderRequest + { + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderResponse.cs new file mode 100644 index 00000000..af623571 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/ModifyCustomsOrderResponse.cs @@ -0,0 +1,19 @@ +using System; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [PATCH] /customs/orders 接口的响应。 + /// + public class ModifyCustomsOrderResponse : CreateCustomsOrderResponse + { + /// + /// 获取或设置最后更新时间。 + /// + [Newtonsoft.Json.JsonProperty("modify_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("modify_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset ModifyTime { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersRequest.cs new file mode 100644 index 00000000..8afd183b --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersRequest.cs @@ -0,0 +1,57 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /customs/orders 接口的请求。 + /// + public class QueryCustomsOrdersRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信商户号。如果不指定将使用构造 时的 参数。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? MerchantId { get; set; } + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string AppId { get; set; } = string.Empty; + + /// + /// 获取或设置订单类型。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OrderType { get; set; } = string.Empty; + + /// + /// 获取或设置订单编号。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string OrderNumber { get; set; } = string.Empty; + + /// + /// 获取或设置海关。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string Customs { get; set; } = string.Empty; + + /// + /// 获取或设置分页大小。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Limit { get; set; } + + /// + /// 获取或设置分页开始位置。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Offset { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersResponse.cs new file mode 100644 index 00000000..5e66d534 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/QueryCustomsOrdersResponse.cs @@ -0,0 +1,169 @@ +using System; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [GET] /customs/orders 接口的响应。 + /// + public class QueryCustomsOrdersResponse : WechatTenpayResponse + { + public static class Types + { + public class Record + { + /// + /// 获取或设置状态码。 + /// + [Newtonsoft.Json.JsonProperty("state")] + [System.Text.Json.Serialization.JsonPropertyName("state")] + public string State { get; set; } = default!; + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置微信子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_id")] + public string? SubOrderId { get; set; } + + /// + /// 获取或设置海关。 + /// + [Newtonsoft.Json.JsonProperty("customs")] + [System.Text.Json.Serialization.JsonPropertyName("customs")] + public string Customs { get; set; } = default!; + + /// + /// 获取或设置商户海关备案号。 + /// + [Newtonsoft.Json.JsonProperty("mch_customs_no")] + [System.Text.Json.Serialization.JsonPropertyName("mch_customs_no")] + public string MerchantCustomsNumber { get; set; } = default!; + + /// + /// 获取或设置关税(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("duty")] + [System.Text.Json.Serialization.JsonPropertyName("duty")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public int? Duty { get; set; } + + /// + /// 获取或设置币种。 + /// + [Newtonsoft.Json.JsonProperty("fee_type")] + [System.Text.Json.Serialization.JsonPropertyName("fee_type")] + public string? FeeType { get; set; } + + /// + /// 获取或设置应付金额(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("order_fee")] + [System.Text.Json.Serialization.JsonPropertyName("order_fee")] + public int? OrderFee { get; set; } + + /// + /// 获取或设置物流费(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("transport_fee")] + [System.Text.Json.Serialization.JsonPropertyName("transport_fee")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public int? TransportFee { get; set; } + + /// + /// 获取或设置商品价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("product_fee")] + [System.Text.Json.Serialization.JsonPropertyName("product_fee")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public int? ProductFee { get; set; } + + /// + /// 获取或设置最后更新时间。 + /// + [Newtonsoft.Json.JsonProperty("modify_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("modify_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset ModifyTime { get; set; } + + /// + /// 获取或设置申报结果说明。 + /// + [Newtonsoft.Json.JsonProperty("explanation")] + [System.Text.Json.Serialization.JsonPropertyName("explanation")] + public string? Explanation { get; set; } + } + } + + /// + /// 获取或设置微信商户号。 + /// + [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("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置记录列表。 + /// + [Newtonsoft.Json.JsonProperty("data")] + [System.Text.Json.Serialization.JsonPropertyName("data")] + public Types.Record[] RecordList { get; set; } = default!; + + /// + /// 获取或设置记录总数。 + /// + [Newtonsoft.Json.JsonProperty("total_count")] + [System.Text.Json.Serialization.JsonPropertyName("total_count")] + [System.Text.Json.Serialization.JsonNumberHandling(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString)] + public int TotalCount { 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("verify_department")] + [System.Text.Json.Serialization.JsonPropertyName("verify_department")] + public string? VerifyDepartment { get; set; } + + /// + /// 获取或设置验核机构交易流水号。 + /// + [Newtonsoft.Json.JsonProperty("verify_department_trade_id")] + [System.Text.Json.Serialization.JsonPropertyName("verify_department_trade_id")] + public string? VerifyDepartmentTradeId { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderRequest.cs new file mode 100644 index 00000000..e5e12d2f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderRequest.cs @@ -0,0 +1,64 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/redeclare 接口的请求。 + /// + public class RedeclareCustomsOrderRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信商户号。如果不指定将使用构造 时的 参数。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string? MerchantId { get; set; } + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string AppId { get; set; } = string.Empty; + + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("out_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string? OutTradeNumber { get; set; } + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string? TransactionId { get; set; } + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置微信子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_id")] + public string? SubOrderId { get; set; } + + /// + /// 获取或设置海关代码。 + /// + [Newtonsoft.Json.JsonProperty("customs")] + [System.Text.Json.Serialization.JsonPropertyName("customs")] + public string Customs { get; set; } = string.Empty; + + /// + /// 获取或设置商户海关备案号。 + /// + [Newtonsoft.Json.JsonProperty("merchant_customs_no")] + [System.Text.Json.Serialization.JsonPropertyName("merchant_customs_no")] + public string MerchantCustomsNumber { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderResponse.cs new file mode 100644 index 00000000..e3ff3fce --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/RedeclareCustomsOrderResponse.cs @@ -0,0 +1,75 @@ +using System; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/redeclare 接口的响应。 + /// + public class RedeclareCustomsOrderResponse : WechatTenpayResponse + { + /// + /// 获取或设置微信商户号。 + /// + [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("state")] + [System.Text.Json.Serialization.JsonPropertyName("state")] + public string State { get; set; } = default!; + + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("out_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string OutTradeNumber { get; set; } = default!; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置微信子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_id")] + public string? SubOrderId { get; set; } + + /// + /// 获取或设置最后更新时间。 + /// + [Newtonsoft.Json.JsonProperty("modify_time")] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.RFC3339DateTimeOffsetConverter))] + [System.Text.Json.Serialization.JsonPropertyName("modify_time")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.RFC3339DateTimeOffsetConverter))] + public DateTimeOffset ModifyTime { get; set; } + + /// + /// 获取或设置申报结果说明。 + /// + [Newtonsoft.Json.JsonProperty("explanation")] + [System.Text.Json.Serialization.JsonPropertyName("explanation")] + public string? Explanation { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateRequest.cs new file mode 100644 index 00000000..7f327202 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateRequest.cs @@ -0,0 +1,81 @@ +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/verify-certificate 接口的请求。 + /// + [WechatTenpaySensitive] + public class VerifyCustomsCertificateRequest : WechatTenpayRequest + { + /// + /// 获取或设置微信商户号。如果不指定将使用构造 时的 参数。 + /// + [Newtonsoft.Json.JsonProperty("mchid")] + [System.Text.Json.Serialization.JsonPropertyName("mchid")] + public string? MerchantId { get; set; } + + /// + /// 获取或设置微信 AppId。 + /// + [Newtonsoft.Json.JsonProperty("appid")] + [System.Text.Json.Serialization.JsonPropertyName("appid")] + public string AppId { get; set; } = string.Empty; + + /// + /// 获取或设置商户订单号。 + /// + [Newtonsoft.Json.JsonProperty("out_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string? OutTradeNumber { get; set; } + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string? TransactionId { get; set; } + + /// + /// 获取或设置商户子订单号。 + /// + [Newtonsoft.Json.JsonProperty("sub_order_no")] + [System.Text.Json.Serialization.JsonPropertyName("sub_order_no")] + public string? SubOrderNumber { get; set; } + + /// + /// 获取或设置海关代码。 + /// + [Newtonsoft.Json.JsonProperty("customs")] + [System.Text.Json.Serialization.JsonPropertyName("customs")] + public string Customs { get; set; } = string.Empty; + + /// + /// 获取或设置商户海关备案号。 + /// + [Newtonsoft.Json.JsonProperty("merchant_customs_no")] + [System.Text.Json.Serialization.JsonPropertyName("merchant_customs_no")] + public string MerchantCustomsNumber { get; set; } = string.Empty; + + /// + /// 获取或设置证件类型。 + /// + [Newtonsoft.Json.JsonProperty("certificate_type")] + [System.Text.Json.Serialization.JsonPropertyName("certificate_type")] + public string CertificateType { get; set; } = string.Empty; + + /// + /// 获取或设置证件号码(需使用平台公钥/证书加密)。 + /// + [Newtonsoft.Json.JsonProperty("certificate_id")] + [System.Text.Json.Serialization.JsonPropertyName("certificate_id")] + [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)] + public string CertificateId { get; set; } = string.Empty; + + /// + /// 获取或设置证件姓名(需使用平台公钥/证书加密)。 + /// + [Newtonsoft.Json.JsonProperty("certificate_name")] + [System.Text.Json.Serialization.JsonPropertyName("certificate_name")] + [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)] + public string CertificateName { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateResponse.cs new file mode 100644 index 00000000..c2c98418 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Customs/VerifyCustomsCertificateResponse.cs @@ -0,0 +1,45 @@ +using System; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models +{ + /// + /// 表示 [POST] /customs/verify-certificate 接口的响应。 + /// + public class VerifyCustomsCertificateResponse : WechatTenpayResponse + { + /// + /// 获取或设置微信商户号。 + /// + [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_trade_no")] + [System.Text.Json.Serialization.JsonPropertyName("out_trade_no")] + public string OutTradeNumber { get; set; } = default!; + + /// + /// 获取或设置微信支付订单号。 + /// + [Newtonsoft.Json.JsonProperty("transaction_id")] + [System.Text.Json.Serialization.JsonPropertyName("transaction_id")] + public string TransactionId { get; set; } = default!; + + /// + /// 获取或设置身份核验结果。 + /// + [Newtonsoft.Json.JsonProperty("certificate_check_result")] + [System.Text.Json.Serialization.JsonPropertyName("certificate_check_result")] + public string CertificateCheckResult { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayEndpoints.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayEndpoints.cs index 4491be70..33bc346b 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayEndpoints.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayEndpoints.cs @@ -23,7 +23,7 @@ /// /// 全球域名。 /// - public const string REGION_GLOBAL = "https://api.mch.weixin.qq.com/global/v3"; + public const string REGION_HONGKONG_GLOBAL = "https://apihk.mch.weixin.qq.com/global/v3"; /// /// 沙箱域名。 diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderRequest.json new file mode 100644 index 00000000..b254c4a2 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderRequest.json @@ -0,0 +1,14 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "customs": "SHANGHAI_ZS", + "merchant_customs_no": "123456", + "duty": 888, + "sub_order_no": "20150806125346", + "fee_type": "CNY", + "order_fee": 888, + "transport_fee": 888, + "product_fee": 888 +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderResponse.json new file mode 100644 index 00000000..19a5704a --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/CreateCustomsOrderResponse.json @@ -0,0 +1,11 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "state": "PROCESSING", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "sub_order_id": "20150806125346", + "verify_department": "UNIONPAY", + "verify_department_trade_id": "2018112288340107038204310100000" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderRequest.json new file mode 100644 index 00000000..9c3b5723 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderRequest.json @@ -0,0 +1,13 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "customs": "SHANGHAI_ZS", + "merchant_customs_no": "123456", + "duty": 888, + "order_fee": 888, + "transport_fee": 888, + "product_fee": 888 +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderResponse.json new file mode 100644 index 00000000..484857cf --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/ModifyCustomsOrderResponse.json @@ -0,0 +1,12 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "state": "SUBMITTED", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "sub_order_id": "20150806125346", + "modify_time": "2015-09-01T10:00:00+08:00", + "verify_department": "UNIONPAY", + "verify_department_trade_id": "2018112288340107038204310100000" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/QueryCustomsOrdersResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/QueryCustomsOrdersResponse.json new file mode 100644 index 00000000..e9d8168f --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/QueryCustomsOrdersResponse.json @@ -0,0 +1,26 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "transaction_id": "1000320306201511078440737890", + "verify_department": "UNIONPAY", + "verify_department_trade_id": "2018112288340107038204310100000", + "offset": 0, + "limit": 20, + "total_count": 1, + "data": [ + { + "sub_order_no": "20150806125346", + "sub_order_id": "20150806125346", + "mch_customs_no": "1234567", + "customs": "SHANGHAI_ZS", + "fee_type": "CNY", + "order_fee": 888, + "duty": 888, + "transport_fee": 888, + "product_fee": 888, + "state": "PROCESSING", + "explanation": "支付单已存在并且为非退单状态", + "modify_time": "2015-09-01T10:00:00+08:00" + } + ] +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderRequest.json new file mode 100644 index 00000000..1643a4aa --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderRequest.json @@ -0,0 +1,10 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "sub_order_id": "1000320306201511078440737891", + "customs": "SHANGHAI_ZS", + "merchant_customs_no": "123456" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderResponse.json new file mode 100644 index 00000000..7e2d4224 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/RedeclareCustomsOrderResponse.json @@ -0,0 +1,11 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "state": "PROCESSING", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "sub_order_id": "20150806125346", + "modify_time": "2015-09-01T10:00:00+08:00", + "explanation": "支付单已存在并且为非退单状态" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateRequest.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateRequest.json new file mode 100644 index 00000000..a0061719 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateRequest.json @@ -0,0 +1,12 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "sub_order_no": "20150806125346", + "customs": "SHANGHAI_ZS", + "merchant_customs_no": "123456", + "certificate_type": "IDCARD", + "certificate_id": "330821198809085211", + "certificate_name": "张三" +} \ No newline at end of file diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateResponse.json b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateResponse.json new file mode 100644 index 00000000..cf565407 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/ModelSamples/Customs/VerifyCustomsCertificateResponse.json @@ -0,0 +1,7 @@ +{ + "appid": "wxd678efh567hg6787", + "mchid": "1230000109", + "out_trade_no": "20150806125346", + "transaction_id": "1000320306201511078440737890", + "certificate_check_result": "UNchECKED" +} \ No newline at end of file