Skip to content

Commit

Permalink
Merge pull request #99 from EasyAbp/wechatpay-v3-jspayment
Browse files Browse the repository at this point in the history
Implemented all request interfaces for JS API payment. (Excludes notification interfaces)
  • Loading branch information
real-zony authored Jan 6, 2024
2 parents 27e3162 + 9d45015 commit 038abf3
Show file tree
Hide file tree
Showing 26 changed files with 1,247 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Extensions;
Expand Down Expand Up @@ -37,6 +35,22 @@ public DefaultWeChatPayApiRequester(IAbpWeChatPayHttpClientFactory httpClientFac
}

public async Task<string> RequestAsync(HttpMethod method, string url, string body, string mchId = null)
{
var response = await RequestRawAsync(method, url, body, mchId);
await ValidateResponseAsync(response);

return await response.Content.ReadAsStringAsync();
}

public async Task<TResponse> RequestAsync<TResponse>(HttpMethod method, string url, string body,
string mchId = null)
{
var responseString = await RequestAsync(method, url, body, mchId);

return JsonConvert.DeserializeObject<TResponse>(responseString);
}

public async Task<HttpResponseMessage> RequestRawAsync(HttpMethod method, string url, string body = null, string mchId = null)
{
var request = CreateRequest(method, url, body);

Expand All @@ -51,19 +65,7 @@ public async Task<string> RequestAsync(HttpMethod method, string url, string bod

// Sending the request.
var client = await _httpClientFactory.CreateAsync(mchId);
var response = await client.SendAsync(request);

await ValidateResponseAsync(response);

return await response.Content.ReadAsStringAsync();
}

public async Task<TResponse> RequestAsync<TResponse>(HttpMethod method, string url, string body,
string mchId = null)
{
var responseString = await RequestAsync(method, url, body, mchId);

return JsonConvert.DeserializeObject<TResponse>(responseString);
return await client.SendAsync(request);
}

public Task<string> RequestAsync(HttpMethod method, string url, object body, string mchId = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public interface IWeChatPayApiRequester
Task<string> RequestAsync(HttpMethod method, string url, [CanBeNull] string body = null, [CanBeNull] string mchId = null);

Task<TResponse> RequestAsync<TResponse>(HttpMethod method, string url, [CanBeNull] string body = null, [CanBeNull] string mchId = null);

Task<HttpResponseMessage> RequestRawAsync(HttpMethod method, string url, [CanBeNull] string body = null, [CanBeNull] string mchId = null);

Task<string> RequestAsync(HttpMethod method, string url, [NotNull] object body, [CanBeNull] string mchId = null);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment;
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 优惠类型的枚举值定义
/// 代金券的枚举值定义
/// </summary>
public static class PromotionTypeEnum
public static class CouponTypeEnum
{
/// <summary>
/// 充值型代金券。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 资金账户类型枚举。
/// </summary>
public static class FundAccountTypeEnum
{
/// <summary>
/// 基本账户。
/// </summary>
public const string Basic = "BASIC";

/// <summary>
/// 运营账户。
/// </summary>
public const string Operation = "OPERATION";

/// <summary>
/// 手续费账户。
/// </summary>
public const string Fees = "FEES";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment;
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 优惠范围的枚举值定义。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 优惠类型的枚举值定义。
/// </summary>
public static class PromotionTypeEnum
{
/// <summary>
/// 代金券,需要走结算资金的充值型代金券。
/// </summary>
public const string Coupon = "COUPON";

/// <summary>
/// 优惠券,不走结算资金的免充值型优惠券。
/// </summary>
public const string Discount = "DISCOUNT";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 退款渠道枚举。
/// </summary>
public static class RefundChannelEnum
{
/// <summary>
/// 原路退款。
/// </summary>
public const string Original = "ORIGINAL";

/// <summary>
/// 退回到余额。
/// </summary>
public const string Balance = "BALANCE";

/// <summary>
/// 原账户异常退到其他余额账户。
/// </summary>
public const string OtherBalance = "OTHER_BALANCE";

/// <summary>
/// 原银行卡异常退到其他银行卡。
/// </summary>
public const string OtherBankCard = "OTHER_BANKCARD";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 退款资金来源枚举。
/// </summary>
public static class RefundFundsAccountEnum
{
/// <summary>
/// 可用余额账户。
/// </summary>
public const string Available = "AVAILABLE";

/// <summary>
/// 不可用余额账户。
/// </summary>
public const string Unavailable = "UNAVAILABLE";

/// <summary>
/// 未结算资金账户。
/// </summary>
public const string Unsettled = "UNSETTLED";

/// <summary>
/// 运营账户。
/// </summary>
public const string Operation = "OPERATION";

/// <summary>
/// 基本账户。
/// </summary>
public const string Basic= "BASIC";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 退款状态枚举。
/// </summary>
public static class RefundStatusEnum
{
/// <summary>
/// 退款成功。
/// </summary>
public const string Success = "SUCCESS";

/// <summary>
/// 退款关闭。
/// </summary>
public const string Closed = "CLOSED";

/// <summary>
/// 退款处理中。
/// </summary>
public const string Processing = "PROCESSING";

/// <summary>
/// 退款异常。
/// </summary>
public const string Abnormal = "ABNORMAL";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment;
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 交易状态的枚举值定义。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment;
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 交易类型的枚举值定义。
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Enums;

/// <summary>
/// 账单类型枚举。
/// </summary>
public static class TransactionBillTypeEnum
{
/// <summary>
/// 回当日所有订单信息 (不含充值退款订单)。
/// </summary>
public const string All = "ALL";

/// <summary>
/// 返回当日成功支付的订单 (不含充值退款订单)。
/// </summary>
public const string Success = "SUCCESS";

/// <summary>
/// 返回当日退款订单 (不含充值退款订单)。
/// </summary>
public const string Refund = "REFUND";
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Net.Http;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Pay.Options;
using EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.JSPayment.Models;
using EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Models;
using EasyAbp.Abp.WeChat.Pay.Services.ParametersModel;
using Volo.Abp.DependencyInjection;
using CreateOrderRequest = EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.JSPayment.Models.CreateOrderRequest;

Expand All @@ -11,12 +13,13 @@ namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.JSPayment;
public class JsPaymentService : WeChatPayServiceBase
{
public const string CreateOrderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";

public const string QueryOrderByWechatNumberUrl =
"https://api.mch.weixin.qq.com/v3/pay/transactions/{transaction_id}";

public const string QueryOrderByOutTradeNumberUrl =
"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}";
public const string QueryOrderByWechatNumberUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/{transaction_id}";
public const string QueryOrderByOutTradeNumberUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}";
public const string CloseOrderUrl = "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}/close";
public const string RefundUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
public const string QueryRefundOrderUrl = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/{out_refund_no}";
public const string GetTransactionBillUrl = "https://api.mch.weixin.qq.com/v3/bill/tradebill";
public const string GetFundFlowBillUrl = "https://api.mch.weixin.qq.com/v3/bill/fundflowbill";

public JsPaymentService(AbpWeChatPayOptions options,
IAbpLazyServiceProvider lazyServiceProvider) : base(options,
Expand All @@ -40,4 +43,36 @@ public Task<QueryOrderResponse> QueryOrderByOutTradeNumberAsync(QueryOrderByOutT
var requestUrl = QueryOrderByOutTradeNumberUrl.Replace("{out_trade_no}", request.OutTradeNo);
return ApiRequester.RequestAsync<QueryOrderResponse>(HttpMethod.Get, requestUrl, request);
}

public Task<WeChatPayCommonErrorResponse> CloseOrderAsync(CloseOrderRequest request)
{
var requestUrl = CloseOrderUrl.Replace("{out_trade_no}", request.OutTradeNo);
return ApiRequester.RequestAsync<WeChatPayCommonErrorResponse>(HttpMethod.Post, requestUrl, request);
}

public Task<RefundOrderResponse> RefundAsync(RefundOrderRequest orderRequest)
{
return ApiRequester.RequestAsync<RefundOrderResponse>(HttpMethod.Post, RefundUrl, orderRequest);
}

public Task<RefundOrderResponse> QueryRefundOrderAsync(QueryRefundOrderRequest request)
{
var requestUrl = QueryRefundOrderUrl.Replace("{out_refund_no}", request.OutRefundNo);
return ApiRequester.RequestAsync<RefundOrderResponse>(HttpMethod.Get, requestUrl);
}

public Task<GetBillResponse> GetTransactionBillAsync(GetTransactionBillRequest request)
{
return ApiRequester.RequestAsync<GetBillResponse>(HttpMethod.Get, GetTransactionBillUrl, request);
}

public Task<GetBillResponse> GetFundFlowBillAsync(GetFundFlowBillRequest request)
{
return ApiRequester.RequestAsync<GetBillResponse>(HttpMethod.Get, GetFundFlowBillUrl, request);
}

public async Task<Stream> DownloadBillFileAsync(string billDownloadUrl)
{
return await (await ApiRequester.RequestRawAsync(HttpMethod.Get, billDownloadUrl)).Content.ReadAsStreamAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;

namespace EasyAbp.Abp.WeChat.Pay.Services.BasicPayment.Models;

public class CloseOrderRequest
{
/// <summary>
/// 直连商户号。
/// </summary>
/// <remarks>
/// 直连商户的商户号,由微信支付生成并下发。
/// </remarks>
/// <example>
/// 示例值: 1230000109
/// </example>
[Required]
[StringLength(32, MinimumLength = 1)]
[JsonProperty("mchid")]
public string MchId { get; set; }

/// <summary>
/// 商户订单号。
/// </summary>
/// <remarks>
/// 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。
/// </remarks>
/// <example>
/// 示例值: 1217752501201407033233368018
/// </example>
[Required]
[StringLength(32,MinimumLength = 6)]
[JsonProperty("out_trade_no")]
public string OutTradeNo { get; set; }
}
Loading

0 comments on commit 038abf3

Please sign in to comment.