fix: 修复支付宝支付功能相关问题
- 修复支付接口参数顺序错误,调整商品名称和订单号参数位置 - 修复支付页面HTML返回格式,直接返回Body内容而非序列化字符串 - 添加支付相关接口的权限控制,支付回调接口允许匿名访问 - 优化支付宝回调验签逻辑,保持原始参数顺序避免验签失败 - 增加回调格式错误的异常处理 - 修复商品类型枚举显示名称为英文,新增测试商品类型 - 修正Token服务提示文案中的错别字 - 移除订单更新时不必要的时间字段设置
This commit is contained in:
@@ -18,5 +18,5 @@ public class CreateOrderOutput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付页面HTML内容
|
/// 支付页面HTML内容
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PaymentPageHtml { get; set; }
|
public object PaymentPageHtml { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
@@ -40,6 +41,7 @@ public class PayService : ApplicationService, IPayService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">创建订单输入</param>
|
/// <param name="input">创建订单输入</param>
|
||||||
/// <returns>订单创建结果</returns>
|
/// <returns>订单创建结果</returns>
|
||||||
|
[Authorize]
|
||||||
[HttpPost("pay/Order")]
|
[HttpPost("pay/Order")]
|
||||||
public async Task<CreateOrderOutput> CreateOrderAsync(CreateOrderInput input)
|
public async Task<CreateOrderOutput> CreateOrderAsync(CreateOrderInput input)
|
||||||
{
|
{
|
||||||
@@ -48,8 +50,8 @@ public class PayService : ApplicationService, IPayService
|
|||||||
|
|
||||||
// 2. 通过AlipayManager发起页面支付
|
// 2. 通过AlipayManager发起页面支付
|
||||||
var paymentPageHtml = await _alipayManager.PaymentPageAsync(
|
var paymentPageHtml = await _alipayManager.PaymentPageAsync(
|
||||||
order.OutTradeNo,
|
|
||||||
order.GoodsName,
|
order.GoodsName,
|
||||||
|
order.OutTradeNo,
|
||||||
order.TotalAmount);
|
order.TotalAmount);
|
||||||
|
|
||||||
// 3. 返回结果
|
// 3. 返回结果
|
||||||
@@ -57,7 +59,7 @@ public class PayService : ApplicationService, IPayService
|
|||||||
{
|
{
|
||||||
OrderId = order.Id,
|
OrderId = order.Id,
|
||||||
OutTradeNo = order.OutTradeNo,
|
OutTradeNo = order.OutTradeNo,
|
||||||
PaymentPageHtml = JsonConvert.SerializeObject(paymentPageHtml)
|
PaymentPageHtml = paymentPageHtml.Body
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,16 +69,17 @@ public class PayService : ApplicationService, IPayService
|
|||||||
/// <param name="form">表单数据</param>
|
/// <param name="form">表单数据</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("pay/AlipayNotify")]
|
[HttpPost("pay/AlipayNotify")]
|
||||||
|
[AllowAnonymous]
|
||||||
public async Task<string> AlipayNotifyAsync([FromForm] IFormCollection form)
|
public async Task<string> AlipayNotifyAsync([FromForm] IFormCollection form)
|
||||||
{
|
{
|
||||||
// 1. 将表单数据转换为字典
|
// 1. 将表单数据转换为字典,保持原始顺序
|
||||||
var notifyData = new Dictionary<string, string>();
|
var notifyData = new Dictionary<string, string>();
|
||||||
foreach (var item in form)
|
foreach (var item in form)
|
||||||
{
|
{
|
||||||
notifyData[item.Key] = item.Value.ToString();
|
notifyData[item.Key] = item.Value.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("收到支付宝回调通知:{NotifyData}", System.Text.Json.JsonSerializer.Serialize(notifyData));
|
_logger.LogInformation($"收到支付宝回调通知:{System.Text.Json.JsonSerializer.Serialize(notifyData)}");
|
||||||
|
|
||||||
// 2. 验证签名
|
// 2. 验证签名
|
||||||
await _alipayManager.VerifyNotifyAsync(notifyData);
|
await _alipayManager.VerifyNotifyAsync(notifyData);
|
||||||
@@ -97,6 +100,10 @@ public class PayService : ApplicationService, IPayService
|
|||||||
|
|
||||||
_logger.LogInformation("订单状态更新成功,订单号:{OutTradeNo},状态:{TradeStatus}", outTradeNo, tradeStatus);
|
_logger.LogInformation("订单状态更新成功,订单号:{OutTradeNo},状态:{TradeStatus}", outTradeNo, tradeStatus);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AlipayException($"回调格式错误");
|
||||||
|
}
|
||||||
|
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
@@ -107,6 +114,7 @@ public class PayService : ApplicationService, IPayService
|
|||||||
/// <param name="input">查询订单状态输入</param>
|
/// <param name="input">查询订单状态输入</param>
|
||||||
/// <returns>订单状态信息</returns>
|
/// <returns>订单状态信息</returns>
|
||||||
[HttpGet("pay/OrderStatus")]
|
[HttpGet("pay/OrderStatus")]
|
||||||
|
[Authorize]
|
||||||
public async Task<QueryOrderStatusOutput> QueryOrderStatusAsync([FromQuery] QueryOrderStatusInput input)
|
public async Task<QueryOrderStatusOutput> QueryOrderStatusAsync([FromQuery] QueryOrderStatusInput input)
|
||||||
{
|
{
|
||||||
// 通过PayManager查询订单
|
// 通过PayManager查询订单
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class TokenService : ApplicationService
|
|||||||
{
|
{
|
||||||
if (!CurrentUser.IsAiVip())
|
if (!CurrentUser.IsAiVip())
|
||||||
{
|
{
|
||||||
throw new UserFriendlyException("充值成为Vip,畅想第三方token服务");
|
throw new UserFriendlyException("充值成为Vip,畅享第三方token服务");
|
||||||
}
|
}
|
||||||
|
|
||||||
await _tokenManager.CreateAsync(CurrentUser.GetId());
|
await _tokenManager.CreateAsync(CurrentUser.GetId());
|
||||||
|
|||||||
@@ -36,20 +36,24 @@ public class DisplayNameAttribute : Attribute
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum GoodsTypeEnum
|
public enum GoodsTypeEnum
|
||||||
{
|
{
|
||||||
|
[Price(0.01)]
|
||||||
|
[DisplayName("YiXinVip Test")]
|
||||||
|
YiXinVipTest = 0,
|
||||||
|
|
||||||
[Price(29.9)]
|
[Price(29.9)]
|
||||||
[DisplayName("意心Vip会员1个月")]
|
[DisplayName("YiXinVip 1 month")]
|
||||||
YiXinVip1 = 1,
|
YiXinVip1 = 1,
|
||||||
|
|
||||||
[Price(80.7)]
|
[Price(80.7)]
|
||||||
[DisplayName("意心Vip会员3个月")]
|
[DisplayName("YiXinVip 3 month")]
|
||||||
YiXinVip3 = 3,
|
YiXinVip3 = 3,
|
||||||
|
|
||||||
[Price(143.9)]
|
[Price(143.9)]
|
||||||
[DisplayName("意心Vip会员6个月")]
|
[DisplayName("YiXinVip 6 month")]
|
||||||
YiXinVip6 = 6,
|
YiXinVip6 = 6,
|
||||||
|
|
||||||
[Price(199.9)]
|
[Price(199.9)]
|
||||||
[DisplayName("意心Vip会员10个月")]
|
[DisplayName("YiXinVip 10 month")]
|
||||||
YiXinVip10 = 10
|
YiXinVip10 = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public class AlipayManager : DomainService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="AlipayException"></exception>
|
/// <exception cref="AlipayException"></exception>
|
||||||
public Task<AlipayTradePagePayResponse> PaymentPageAsync(string productName, string orderNumber, decimal totalAmount)
|
public Task<AlipayTradePagePayResponse> PaymentPageAsync(string productName, string orderNumber,
|
||||||
|
decimal totalAmount)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -54,12 +55,16 @@ public class AlipayManager : DomainService
|
|||||||
/// <exception cref="AlipayException"></exception>
|
/// <exception cref="AlipayException"></exception>
|
||||||
public Task VerifyNotifyAsync(Dictionary<string, string> form)
|
public Task VerifyNotifyAsync(Dictionary<string, string> form)
|
||||||
{
|
{
|
||||||
|
// 注意:不要对参数进行排序,保持支付宝回调的原始参数顺序
|
||||||
|
// 支付宝的验签需要保持原始参数顺序,排序会导致验签失败
|
||||||
var result = Factory.Payment.Common().VerifyNotify(form);
|
var result = Factory.Payment.Common().VerifyNotify(form);
|
||||||
if (result == false)
|
if (result == false)
|
||||||
{
|
{
|
||||||
|
_logger.LogError($"支付宝支付验签失败,回调参数:{System.Text.Json.JsonSerializer.Serialize(form)}");
|
||||||
throw new AlipayException($"支付宝支付,验签失败");
|
throw new AlipayException($"支付宝支付,验签失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("支付宝回调验签成功");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,8 +82,6 @@ public class PayManager : DomainService
|
|||||||
{
|
{
|
||||||
order.TradeNo = tradeNo;
|
order.TradeNo = tradeNo;
|
||||||
}
|
}
|
||||||
order.LastModificationTime = DateTime.Now;
|
|
||||||
|
|
||||||
await _payOrderRepository.UpdateAsync(order);
|
await _payOrderRepository.UpdateAsync(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user