Zxd.Core/code/Zxd.Core.WebApi/Controllers/CallbackController.cs

170 lines
5.4 KiB
C#

using DG.Redis;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Zxd.Core.Domain.Dto.Zxd.Callback;
using Zxd.Core.Shared.Helpers;
namespace Zxd.Core.WebApi.Controllers
{
/// <summary>
/// 回调管理
/// </summary>
[ApiSignatureFilterForbid]
public class CallbackController : BaseController
{
private readonly IRedisManager _redisManager;
private readonly IOrderDomain _orderDomain;
private readonly PayCallbackConfig _payCallbackConfig;
/// <summary>
///
/// </summary>
/// <param name="redisManager"></param>
/// <param name="orderDomain"></param>
/// <param name="configuration"></param>
public CallbackController(
IRedisManager redisManager,
IOrderDomain orderDomain,
IConfiguration configuration)
{
_redisManager = redisManager;
_orderDomain = orderDomain;
_payCallbackConfig = configuration.GetSection("PayCallbackConfig").Get<PayCallbackConfig>();
}
/// <summary>
/// 支付回调
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("Pay")]
[ApiResultFilterForbid]
public async Task<string> Pay(Dictionary<string, object> dto)
{
var authorization = default(string);
var timestamps = default(string);
var json = default(string);
var success = false;
try
{
authorization = Request.Headers["authorization"].FirstOrDefault();
if (string.IsNullOrEmpty(authorization))
{
throw new ApiException("authorization必填", 1);
}
var parts = authorization.Split(':');
if (parts.Length != 2)
{
throw new ApiException("authorization无效", 1);
}
var user = parts[0];
var sign = parts[1];
//var secret = await _redisManager.GetAsync<string>($"ZxdCore:Secret:{user}");
var secret = _payCallbackConfig.Secret;
if (string.IsNullOrEmpty(secret))
{
throw new ApiException("还未配置secret", 999);
}
timestamps = Request.Headers["timestamps"].FirstOrDefault();
if (string.IsNullOrEmpty(timestamps))
{
throw new ApiException("timestamps必填", 1);
}
json = GetSortedJson(dto);
Log.Information($"Callback,{authorization},{timestamps},{json}");
var args = new List<string> { user, json, secret, timestamps };
args.Sort(new ASCIIComparer());
var input = string.Join("", args);
var signData = Shared.Helpers.SecurityHelper.GetMD5String(input);
if (signData != sign)
{
throw new ApiException("签名不正确", 2);
}
var req = Dict2Model<BindOrderDto>(dto);
var invalids = ValidationHelper.Validate2<BindOrderDto>(req);
if (!string.IsNullOrEmpty(invalids))
{
throw new ApiException(invalids, 1);
}
await _orderDomain.BindAsync(req);
success = true;
}
catch (Exception ex)
{
Log.Information($"CallbackError,{authorization},{timestamps},{json},{ex}");
}
return success ? "支付回调成功" : "支付回调失败";
}
private string GetSortedJson(Dictionary<string, object> dto)
{
var items = new List<string>();
foreach (var p in dto.Keys)
{
items.Add(p);
}
items.Sort(new ASCIIComparer());
var dict = new Dictionary<string, object>();
foreach (var item in items)
{
var val = dto[item];
if (val!=null && val.ToString().Length>0)
{
dict[item]=val;
}
}
return JsonSerializer.Serialize(dict);
}
private T Dict2Model<T>(Dictionary<string, object> dict) where T : class, new()
{
var one = new T();
var t = typeof(T);
var ps = t.GetProperties();
foreach (var p in ps)
{
if (dict.ContainsKey(p.Name))
{
var val = dict[p.Name];
if (val != null)
{
var val_real = ConvertHelper.GetVal(p.PropertyType, val.ToString());
p.SetValue(one, val_real, null);
}
}
}
return one;
}
}
public class ASCIIComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var len = x.Length > y.Length ? y.Length : x.Length;
for (var i = 0; i < len; i++)
{
if (x[i] < y[i])
{
return -1;
}
if (x[i] > y[i])
{
return 1;
}
}
return 0;
}
}
}