diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinExpressExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinExpressExtensions.cs index 5cf514fd..2fa84f7d 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinExpressExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinExpressExtensions.cs @@ -352,6 +352,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); } + #region Delivery/OpenMessage /// /// 异步调用 [POST] /cgi-bin/express/delivery/open_msg/follow_waybill 接口。 /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/express_open_msg.html#_4-1%E3%80%81%E4%BC%A0%E8%BF%90%E5%8D%95%E6%8E%A5%E5%8F%A3-follow-waybill @@ -432,6 +433,28 @@ namespace SKIT.FlurlHttpClient.Wechat.Api return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); } + /// + /// 异步调用 [POST] /cgi-bin/express/delivery/open_msg/open_query_plugin 接口。 + /// REF: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/logistics-service/applyQueryPlugin.html + /// + /// + /// + /// + /// + public static async Task ExecuteCgibinExpressDeliveryOpenMessageOpenQueryPluginAsync(this WechatApiClient client, Models.CgibinExpressDeliveryOpenMessageOpenQueryPluginRequest 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, "cgi-bin", "express", "delivery", "open_msg", "open_query_plugin") + .SetQueryParam("access_token", request.AccessToken); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + + #region Delivery/Return /// /// 异步调用 [POST] /cgi-bin/express/delivery/return/open_return 接口。 /// REF: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/logistics-service/applyReturnPlugin.html @@ -453,25 +476,66 @@ namespace SKIT.FlurlHttpClient.Wechat.Api } /// - /// 异步调用 [POST] /cgi-bin/express/delivery/open_msg/open_query_plugin 接口。 - /// REF: https://developers.weixin.qq.com/doc/oplatform/openApi/OpenApiDoc/miniprogram-management/logistics-service/applyQueryPlugin.html + /// 异步调用 [POST] /cgi-bin/express/delivery/return/add 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_sale_return.html /// /// /// /// /// - public static async Task ExecuteCgibinExpressDeliveryOpenMessageOpenQueryPluginAsync(this WechatApiClient client, Models.CgibinExpressDeliveryOpenMessageOpenQueryPluginRequest request, CancellationToken cancellationToken = default) + public static async Task ExecuteCgibinExpressDeliveryReturnAddAsync(this WechatApiClient client, Models.CgibinExpressDeliveryReturnAddRequest 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, "cgi-bin", "express", "delivery", "open_msg", "open_query_plugin") + .CreateRequest(request, HttpMethod.Post, "cgi-bin", "express", "delivery", "return", "add") .SetQueryParam("access_token", request.AccessToken); - return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); } + /// + /// 异步调用 [POST] /cgi-bin/express/delivery/return/get 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_sale_return.html + /// + /// + /// + /// + /// + public static async Task ExecuteCgibinExpressDeliveryReturnGetAsync(this WechatApiClient client, Models.CgibinExpressDeliveryReturnGetRequest 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, "cgi-bin", "express", "delivery", "return", "get") + .SetQueryParam("access_token", request.AccessToken); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [POST] /cgi-bin/express/delivery/return/unbind 接口。 + /// REF: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_sale_return.html + /// + /// + /// + /// + /// + public static async Task ExecuteCgibinExpressDeliveryReturnUnbindAsync(this WechatApiClient client, Models.CgibinExpressDeliveryReturnUnbindRequest 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, "cgi-bin", "express", "delivery", "return", "unbind") + .SetQueryParam("access_token", request.AccessToken); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + #endregion + #region Delivery/SingleWaybill /// /// 异步调用 [POST] /cgi-bin/express/delivery/single_waybill/update 接口。 diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.cs new file mode 100644 index 00000000..93bd4964 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.cs @@ -0,0 +1,135 @@ +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/add 接口的请求。 + /// + public class CgibinExpressDeliveryReturnAddRequest : WechatApiRequest, IInferable + { + public static class Types + { + public class ShopAddress + { + /// + /// 获取或设置国家。 + /// + [Newtonsoft.Json.JsonProperty("country")] + [System.Text.Json.Serialization.JsonPropertyName("country")] + public string Country { get; set; } = string.Empty; + + /// + /// 获取或设置省份。 + /// + [Newtonsoft.Json.JsonProperty("province")] + [System.Text.Json.Serialization.JsonPropertyName("province")] + public string Province { get; set; } = string.Empty; + + /// + /// 获取或设置城市。 + /// + [Newtonsoft.Json.JsonProperty("city")] + [System.Text.Json.Serialization.JsonPropertyName("city")] + public string City { get; set; } = string.Empty; + + /// + /// 获取或设置区县。 + /// + [Newtonsoft.Json.JsonProperty("area")] + [System.Text.Json.Serialization.JsonPropertyName("area")] + public string District { get; set; } = string.Empty; + + /// + /// 获取或设置详细地址。 + /// + [Newtonsoft.Json.JsonProperty("address")] + [System.Text.Json.Serialization.JsonPropertyName("address")] + public string Address { get; set; } = string.Empty; + + /// + /// 获取或设置联系人。 + /// + [Newtonsoft.Json.JsonProperty("name")] + [System.Text.Json.Serialization.JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// + /// 获取或设置联系电话。 + /// + [Newtonsoft.Json.JsonProperty("mobile")] + [System.Text.Json.Serialization.JsonPropertyName("mobile")] + public string MobileNumber { get; set; } = string.Empty; + } + + public class UserAddress : ShopAddress + { + } + + public class Goods + { + /// + /// 获取或设置商品名称。 + /// + [Newtonsoft.Json.JsonProperty("name")] + [System.Text.Json.Serialization.JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// + /// 获取或设置商品图片 URL。 + /// + [Newtonsoft.Json.JsonProperty("url")] + [System.Text.Json.Serialization.JsonPropertyName("url")] + public string ImageUrl { get; set; } = string.Empty; + } + } + + /// + /// 获取或设置商家退货单号。 + /// + [Newtonsoft.Json.JsonProperty("shop_order_id")] + [System.Text.Json.Serialization.JsonPropertyName("shop_order_id")] + public string ShopOrderId { get; set; } = string.Empty; + + /// + /// 获取或设置商家退货地址信息。 + /// + [Newtonsoft.Json.JsonProperty("biz_addr")] + [System.Text.Json.Serialization.JsonPropertyName("biz_addr")] + public Types.ShopAddress ShopAddress { get; set; } = new Types.ShopAddress(); + + /// + /// 获取或设置用户收货地址信息。 + /// + [Newtonsoft.Json.JsonProperty("user_addr")] + [System.Text.Json.Serialization.JsonPropertyName("user_addr")] + public Types.UserAddress? UserAddress { get; set; } + + /// + /// 获取或设置退货用户的 OpenId。 + /// + [Newtonsoft.Json.JsonProperty("openid")] + [System.Text.Json.Serialization.JsonPropertyName("openid")] + public string OpenId { get; set; } = string.Empty; + + /// + /// 获取或设置订单中心页面路径。 + /// + [Newtonsoft.Json.JsonProperty("order_path")] + [System.Text.Json.Serialization.JsonPropertyName("order_path")] + public string OrderPagePath { get; set; } = string.Empty; + + /// + /// 获取或设置退货商品列表。 + /// + [Newtonsoft.Json.JsonProperty("goods_list")] + [System.Text.Json.Serialization.JsonPropertyName("goods_list")] + public IList GoodsList { get; set; } = new List(); + + /// + /// 获取或设置退货订单价格(单位:分)。 + /// + [Newtonsoft.Json.JsonProperty("order_price")] + [System.Text.Json.Serialization.JsonPropertyName("order_price")] + public int OrderPrice { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.cs new file mode 100644 index 00000000..5ea03658 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.cs @@ -0,0 +1,16 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/add 接口的响应。 + /// + public class CgibinExpressDeliveryReturnAddResponse : WechatApiResponse + { + /// + /// 获取或设置退货单 ID。 + /// + [Newtonsoft.Json.JsonProperty("return_id")] + [System.Text.Json.Serialization.JsonPropertyName("return_id")] + [System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.NumericalStringReadOnlyConverter))] + public string ReturnId { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.cs new file mode 100644 index 00000000..3392968a --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.cs @@ -0,0 +1,15 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/get 接口的请求。 + /// + public class CgibinExpressDeliveryReturnGetRequest : WechatApiRequest, IInferable + { + /// + /// 获取或设置退货单 ID。 + /// + [Newtonsoft.Json.JsonProperty("return_id")] + [System.Text.Json.Serialization.JsonPropertyName("return_id")] + public string ReturnId { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.cs new file mode 100644 index 00000000..fda98265 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.cs @@ -0,0 +1,43 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/get 接口的响应。 + /// + public class CgibinExpressDeliveryReturnGetResponse : WechatApiResponse + { + /// + /// 获取或设置退货状态。 + /// + [Newtonsoft.Json.JsonProperty("status")] + [System.Text.Json.Serialization.JsonPropertyName("status")] + public int Status { get; set; } + + /// + /// 获取或设置运单号。 + /// + [Newtonsoft.Json.JsonProperty("waybill_id")] + [System.Text.Json.Serialization.JsonPropertyName("waybill_id")] + public string WaybillId { get; set; } = default!; + + /// + /// 获取或设置运单状态。 + /// + [Newtonsoft.Json.JsonProperty("order_status")] + [System.Text.Json.Serialization.JsonPropertyName("order_status")] + public int OrderStatus { get; set; } + + /// + /// 获取或设置快递公司 ID。 + /// + [Newtonsoft.Json.JsonProperty("delivery_id")] + [System.Text.Json.Serialization.JsonPropertyName("delivery_id")] + public string DeliveryId { get; set; } = default!; + + /// + /// 获取或设置快递公司名称。 + /// + [Newtonsoft.Json.JsonProperty("delivery_name")] + [System.Text.Json.Serialization.JsonPropertyName("delivery_name")] + public string DeliveryName { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.cs new file mode 100644 index 00000000..d824e5e3 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.cs @@ -0,0 +1,15 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/unbind 接口的请求。 + /// + public class CgibinExpressDeliveryReturnUnbindRequest : WechatApiRequest, IInferable + { + /// + /// 获取或设置退货单 ID。 + /// + [Newtonsoft.Json.JsonProperty("return_id")] + [System.Text.Json.Serialization.JsonPropertyName("return_id")] + public string ReturnId { get; set; } = string.Empty; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindResponse.cs new file mode 100644 index 00000000..037c6edd --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindResponse.cs @@ -0,0 +1,9 @@ +namespace SKIT.FlurlHttpClient.Wechat.Api.Models +{ + /// + /// 表示 [POST] /cgi-bin/express/delivery/return/unbind 接口的响应。 + /// + public class CgibinExpressDeliveryReturnUnbindResponse : WechatApiResponse + { + } +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.json new file mode 100644 index 00000000..7d216ec4 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddRequest.json @@ -0,0 +1,30 @@ +{ + "shop_order_id": "xxx", + "biz_addr": { + "name": "张三", + "mobile": "13600000000", + "country": "中国", + "province": "广东省", + "city": "广州市", + "area": "海珠区", + "address": "xx路xx号" + }, + "user_addr": { + "name": "李四", + "mobile": "13600000000", + "country": "中国", + "province": "广东省", + "city": "广州市", + "area": "海珠区", + "address": "xx路xx号" + }, + "openid": "xxx", + "order_path": "xxx", + "goods_list": [ + { + "name": "xxx", + "url": "xxx" + } + ], + "order_price": 1 +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.json new file mode 100644 index 00000000..b3a799c1 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnAddResponse.json @@ -0,0 +1,5 @@ +{ + "errcode": 0, + "errmsg": "OK", + "return_id": "1935761508265738242" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.json new file mode 100644 index 00000000..31a6f74d --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetRequest.json @@ -0,0 +1,3 @@ +{ + "return_id": "1935761508265738242" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.json new file mode 100644 index 00000000..de9acf55 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnGetResponse.json @@ -0,0 +1,9 @@ +{ + "errcode": 0, + "errmsg": "OK", + "status": "2", + "waybill_id": "JDxxxxxx", + "order_status": 0, + "delivery_name": "申通快递", + "delivery_id": "SF" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.json new file mode 100644 index 00000000..31a6f74d --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Api.UnitTests/ModelSamples/CgibinExpress/Delivery/Return/CgibinExpressDeliveryReturnUnbindRequest.json @@ -0,0 +1,3 @@ +{ + "return_id": "1935761508265738242" +}