😎增加支付宝支付
This commit is contained in:
parent
7eb18ed737
commit
681b8adb2f
18
Admin.NET/Admin.NET.Application/Configuration/Alipay.json
Normal file
18
Admin.NET/Admin.NET.Application/Configuration/Alipay.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
|
||||
|
||||
// 支付宝支付配置,文档地址:https://openhome.alipay.com/develop/sandbox/app
|
||||
"Alipay": {
|
||||
"AppId": "9000000000000000", // 支付宝 APPID
|
||||
"AlipayWebsocketUrl": "openchannel-sandbox.dl.alipaydev.com", // websocket服务地址
|
||||
"ServerUrl": "https://openapi-sandbox.dl.alipaydev.com/gateway.do", // 支付宝网关地址
|
||||
"AuthUrl": "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm", // 授权回调地址
|
||||
"NotifyUrl": "http://xxxx.xxx/api/Alipay/Notify", // 应用网关地址
|
||||
"PrivateKey": "xxxxxxxxx", // 应用私钥
|
||||
"SignType": "RSA2", // 加密算法
|
||||
"EncryptKey": "xxxxxxxx", // 从支付宝获取敏感信息时的加密密钥
|
||||
"AlipayPublicCertPath": "/AlipayCrt/alipayPublicCert.crt", // 支付宝公钥证书存放路径
|
||||
"RootCertPath": "/AlipayCrt/alipayRootCert.crt", // 支付宝根证书存放路径
|
||||
"AppCertPath": "/AlipayCrt/appPublicCert.crt" // 应用公钥证书存放路径
|
||||
}
|
||||
}
|
||||
@ -14,9 +14,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="3.1.0" />
|
||||
<PackageReference Include="AlipaySDKNet.Standard" Version="4.9.370" />
|
||||
<PackageReference Include="AngleSharp" Version="1.1.2" />
|
||||
<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" Aliases="BouncyCastleV2" />
|
||||
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.16.3" />
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.6.20" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.6.20" />
|
||||
@ -37,6 +39,7 @@
|
||||
<PackageReference Include="MySqlBackup.NET.MySqlConnector" Version="2.3.8" />
|
||||
<PackageReference Include="NewLife.Redis" Version="6.0.2024.1205" />
|
||||
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
|
||||
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
<PackageReference Include="RabbitMQ.Client" Version="7.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.3" />
|
||||
@ -58,7 +61,6 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="8.0.11" />
|
||||
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net9.0' ">
|
||||
@ -68,7 +70,6 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.0" />
|
||||
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 通用接口参数验证特性类
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class CommonValidationAttribute : ValidationAttribute
|
||||
{
|
||||
private readonly Dictionary<string, string> _conditions;
|
||||
private static readonly Dictionary<string, Delegate> CompiledConditions = new();
|
||||
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="conditionPairs">条件对参数,长度必须为偶数<br/>
|
||||
/// 奇数字符串参数:动态条件<br/>
|
||||
/// 偶数字符串参数:提示消息
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// <code lang="C">
|
||||
/// public class ModelInput {
|
||||
///
|
||||
///
|
||||
/// public string A { get; set; }
|
||||
///
|
||||
///
|
||||
/// [CommonValidation(
|
||||
/// "A == 1 <value>&&</value> B == null", "当 A == 1时,B不能为空",
|
||||
/// "C == 2 <value>&&</value> B == null", "当 C == 2时,B不能为空"
|
||||
/// )]
|
||||
/// public string B { get; set; }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public CommonValidationAttribute(params string[] conditionPairs)
|
||||
{
|
||||
if (conditionPairs.Length % 2 != 0) throw new ArgumentException("条件对必须以偶数个字符串的形式提供。");
|
||||
|
||||
var conditions = new Dictionary<string, string>();
|
||||
for (int i = 0; i < conditionPairs.Length; i += 2)
|
||||
conditions.Add(conditionPairs[i], conditionPairs[i + 1]);
|
||||
|
||||
_conditions = conditions;
|
||||
}
|
||||
|
||||
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
|
||||
{
|
||||
foreach (var (expr, errorMessage) in _conditions)
|
||||
{
|
||||
var conditionKey = $"{validationContext.ObjectType.FullName}.{expr}";
|
||||
if (!CompiledConditions.TryGetValue(conditionKey, out var condition))
|
||||
{
|
||||
condition = CreateCondition(validationContext.ObjectType, expr);
|
||||
CompiledConditions[conditionKey] = condition;
|
||||
}
|
||||
|
||||
if ((bool)condition.DynamicInvoke(validationContext.ObjectInstance)!)
|
||||
{
|
||||
return new ValidationResult(errorMessage ?? $"[{validationContext.MemberName}]校验失败");
|
||||
}
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
|
||||
private Delegate CreateCondition(Type modelType, string expression)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 创建参数表达式
|
||||
var parameter = Expression.Parameter(typeof(object), "x");
|
||||
|
||||
// 构建 Lambda 表达式
|
||||
var lambda = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(modelType, "x") }, typeof(bool), expression);
|
||||
|
||||
// 创建新的 Lambda 表达式,接受 object 参数并调用编译后的表达式
|
||||
var invokeExpression = Expression.Invoke(lambda, Expression.Convert(parameter, modelType));
|
||||
var finalLambda = Expression.Lambda<Func<object, bool>>(invokeExpression, parameter);
|
||||
|
||||
return finalLambda.Compile();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ArgumentException($"无法解析表达式 '{expression}': {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Admin.NET/Admin.NET.Core/Const/AlipayConst.cs
Normal file
39
Admin.NET/Admin.NET.Core/Const/AlipayConst.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝支付常量
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
public class AlipayConst
|
||||
{
|
||||
/// <summary>
|
||||
/// 单笔无密转账【业务场景】固定值
|
||||
/// </summary>
|
||||
public const string BizScene = "DIRECT_TRANSFER";
|
||||
|
||||
/// <summary>
|
||||
/// 单笔无密转账【销售产品码】固定值
|
||||
/// </summary>
|
||||
public const string ProductCode = "TRANS_ACCOUNT_NO_PWD";
|
||||
|
||||
/// <summary>
|
||||
/// 交易状态参数名
|
||||
/// </summary>
|
||||
public const string TradeStatus = "trade_status";
|
||||
|
||||
/// <summary>
|
||||
/// 交易成功标识
|
||||
/// </summary>
|
||||
public const string TradeSuccess = "TRADE_SUCCESS";
|
||||
|
||||
/// <summary>
|
||||
/// 授权类型
|
||||
/// </summary>
|
||||
public const string GrantType = "authorization_code";
|
||||
}
|
||||
@ -121,6 +121,11 @@ public class ConfigConst
|
||||
/// </summary>
|
||||
public const string SysUpgrade = "sys_upgrade";
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝授权页面地址
|
||||
/// </summary>
|
||||
public const string AlipayAuthPageUrl = "alipay_auth_page_url_";
|
||||
|
||||
/// <summary>
|
||||
/// Default 分组
|
||||
/// </summary>
|
||||
|
||||
21
Admin.NET/Admin.NET.Core/Enum/AlipayCertTypeEnum.cs
Normal file
21
Admin.NET/Admin.NET.Core/Enum/AlipayCertTypeEnum.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 参与方的证件类型枚举
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
[Description("参与方的证件类型枚举")]
|
||||
public enum AlipayCertTypeEnum
|
||||
{
|
||||
[Description("身份证")]
|
||||
IDENTITY_CARD,
|
||||
|
||||
[Description("护照")]
|
||||
PASSPORT
|
||||
}
|
||||
21
Admin.NET/Admin.NET.Core/Enum/AlipayIdentityTypeEnum.cs
Normal file
21
Admin.NET/Admin.NET.Core/Enum/AlipayIdentityTypeEnum.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 参与方的标识类型枚举
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
[Description("参与方的标识类型枚举")]
|
||||
public enum AlipayIdentityTypeEnum
|
||||
{
|
||||
[Description("支付宝用户UID")]
|
||||
ALIPAY_USER_ID,
|
||||
|
||||
[Description("支付宝登录号")]
|
||||
ALIPAY_LOGON_ID
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
@ -446,4 +448,16 @@ public static partial class ObjectExtension
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象深复制
|
||||
/// </summary>
|
||||
/// <typeparam name="T">深复制源对象</typeparam>
|
||||
/// <param name="obj">对象</param>
|
||||
/// <returns></returns>
|
||||
public static T DeepCopy<T>(this T obj)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(obj);
|
||||
return JsonSerializer.Deserialize<T>(json);
|
||||
}
|
||||
}
|
||||
68
Admin.NET/Admin.NET.Core/Option/AlipayOptions.cs
Normal file
68
Admin.NET/Admin.NET.Core/Option/AlipayOptions.cs
Normal file
@ -0,0 +1,68 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝支付配置选项
|
||||
/// </summary>
|
||||
public sealed class AlipayOptions : IConfigurableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 支付宝 APPID(必填)
|
||||
/// </summary>
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝 websocket 服务地址 (必填)
|
||||
/// </summary>
|
||||
public string AlipayWebsocketUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝网关地址 (必填)
|
||||
/// </summary>
|
||||
public string ServerUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝授权回调地址 (必填)
|
||||
/// </summary>
|
||||
public string AuthUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用回调地址
|
||||
/// </summary>
|
||||
public string NotifyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密算法(必填)
|
||||
/// </summary>
|
||||
public string SignType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 从支付宝获取敏感信息时的加密密钥(可选)
|
||||
/// </summary>
|
||||
public string EncryptKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用私钥 (必填)
|
||||
/// </summary>
|
||||
public string PrivateKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝公钥证书存放路径(证书加签方式必填)
|
||||
/// </summary>
|
||||
public string AlipayPublicCertPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝根证书存放路径(证书加签方式必填)
|
||||
/// </summary>
|
||||
public string RootCertPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用公钥证书存放路径(证书加签方式必填)
|
||||
/// </summary>
|
||||
public string AppCertPath { get; set; }
|
||||
}
|
||||
143
Admin.NET/Admin.NET.Core/Service/Alipay/AlipayErrorCodes.cs
Normal file
143
Admin.NET/Admin.NET.Core/Service/Alipay/AlipayErrorCodes.cs
Normal file
@ -0,0 +1,143 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝支付错误码
|
||||
/// </summary>
|
||||
public class AlipayErrorCode
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误代码
|
||||
/// </summary>
|
||||
public string Code { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误消息
|
||||
/// </summary>
|
||||
public string Message { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 解决方案
|
||||
/// </summary>
|
||||
public string Solution { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误码集
|
||||
/// </summary>
|
||||
private static readonly List<AlipayErrorCode> StatusCodes = new()
|
||||
{
|
||||
new AlipayErrorCode { Code="SYSTEM_ERROR", Message="系统繁忙", Solution="可能是由于网络或者系统故障,请与技术人员联系以解决该问题。" },
|
||||
new AlipayErrorCode { Code="INVALID_PARAMETER", Message="参数有误或没有参数", Solution="请检查并确认查询请求参数合法性。" },
|
||||
new AlipayErrorCode { Code="AUTHORISE_NOT_MATCH", Message="授权失败,无法获取用户信息", Solution="检查账户与支付方关系主表关系,确认是否正确配置。" },
|
||||
new AlipayErrorCode { Code="BALANCE_IS_NOT_ENOUGH", Message="余额不足,建议尽快充值。后续登录电银通或支付宝,自主设置余额预警提醒功能。", Solution="余额不足,建议尽快充值。商户后续登录电银通或支付宝,自主设置余额预警提醒功能或登录Alipay-资金管理->产品一览->右上角功能按钮进行设置。" },
|
||||
new AlipayErrorCode { Code="BIZ_UNIQUE_EXCEPTION", Message="商户订单号冲突。", Solution="商户订单号冲突。" },
|
||||
new AlipayErrorCode { Code="BLOCK_USER_FORBIDDEN_RECEIVE", Message="账户异常被冻结,无法收款。", Solution="账户异常被冻结,无法收款。请询问支付宝热线95188" },
|
||||
new AlipayErrorCode { Code="BLOCK_USER_FORBIDDEN_SEND", Message="该账户被冻结,暂不可将资金转出。", Solution="该账户被冻结,暂不可将资金转出。" },
|
||||
new AlipayErrorCode { Code="CURRENCY_NOT_SUPPORT", Message="币种不支持", Solution="请查询您的结算币种需求所见币种,目前限于人民币/美元结算。" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_DC_R_ECEIVED", Message="收款方单日收款笔数超限", Solution="收款方向同一个收款账户单日只能收款固定的笔数,超过后让收款人第二天再收。" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_DM_AMOUNT", Message="日累计额度超限", Solution="今日转账金额已上限,日累计额度需满5000元以上,可使用企业支付宝付款点【立即付款】申请,日累计额度需满5000元以上可点击【联系客服】咨询:转账到支付宝客户窗口" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_DM_MAX_AMOUNT", Message="超出单日转账限额,如有疑问请询问支付宝热线95188", Solution="今日转账金额已上限,日累计额度需满5000元以上,可使用企业支付宝付款点【立即付款】申请,日累计额度需满5000元以上可点击【联系客服】咨询:转账到支付宝客户窗口" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_ENT_SM_AMOUNT", Message="转账给企业用户超过单笔限额(默认10w)", Solution="1. 10w以下的快速转账给企业用户。2. 联系800电话协助修改,修改转账限额" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_MM_AMOUNT", Message="月累计金额超限", Solution="本月转账金额已上限,月转账额度需满10000元以上,可使用企业支付宝付款点【立即付款】申请,月转账额度需满10000元以上可点击【联系客服】咨询:转账到支付宝客户窗口" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_MMM_MAX_AMOUNT", Message="超出单月转账限额,如有疑问请询问支付宝热线95188", Solution="本月转账金额已上限,月转账额度需满10000元以上,可使用企业支付宝付款点【立即付款】申请,月转账额度需满10000元以上可点击【联系客服】咨询:转账到支付宝客户窗口" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_PERSONAL_SM_AMOUNT", Message="超出转账给个人支付宝账户的单笔限额", Solution="超出转账给个人支付宝账户的单笔限额" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_SM_AMOUNT", Message="单笔额度超限", Solution="请根据接入文档填写amount字段" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_SM_MIN_AMOUNT", Message="请求金额不能低于0.1元", Solution="请修改转账金额。" },
|
||||
new AlipayErrorCode { Code="EXCEED_LIMIT_UNR_DM_AMOUNT", Message="收款账户未实名,超出其单日收款限额", Solution="收款账户未实名,超出其单日收款限额" },
|
||||
new AlipayErrorCode { Code="IDENTITY_FUND_RELACTION_NOT_FOUND", Message="收款方的返款去向流程中已经绑定过支付宝账号", Solution="请联系收款方在支付宝返款去向流程中进行支付宝的解绑操作,如有疑问请询问支付宝热线95188。" },
|
||||
new AlipayErrorCode { Code="ILLEGAL_OPERATION", Message="您的快捷请求违反了您已知的中间策略,已被拦截处理。请直接联系收款客户信息再次发起交易。", Solution="您的快捷请求违反了您已知的中间策略,已被拦截处理。请直接联系收款客户信息再次发起交易。" },
|
||||
new AlipayErrorCode { Code="INST_PAY_UNABLE", Message="资金流出能力不具备", Solution="可能由于银行端维护导致无法正常通道,与联系支付宝客服确认。" },
|
||||
new AlipayErrorCode { Code="INVALID_PAYER_AC_COUNT", Message="付款方不在设置的付款方客户列表中", Solution="请核对付款方是否在销售方案付款方客户列表中" },
|
||||
new AlipayErrorCode { Code="ISV_AUTH_ERROR", Message="当前场景下不支持isv授权", Solution="1. 检查商户产品和场景范围,当前场景下不支持isv授权权。2. 去删除isv授权模板,改为自调用。" },
|
||||
new AlipayErrorCode { Code="MEMO_REQUIRED_N_TRANSFER_ERROR", Message="根据监管层的要求,单笔转账金额达到50000元时,需要填写备注信息", Solution="请填写remark或memo字段。" },
|
||||
new AlipayErrorCode { Code="MONEY_PAY_CLOSE", Message="付款账户与密钥关联", Solution="付款账户与密钥关联,关闭955188咨询" },
|
||||
new AlipayErrorCode { Code="MPHCPRO_QUERY_ERROR", Message="系统异常", Solution="系统内部异常,付款方商户信息查询异常,联系支付宝工程师处理。" },
|
||||
new AlipayErrorCode { Code="NOT_IN_WHITE_LIST", Message="产品未准入", Solution="联系接入文档调整,调整为正确的付款方" },
|
||||
new AlipayErrorCode { Code="NOT_SUPPORT_PAY_MENT_TOOLS", Message="不支持当前付款方式类型", Solution="根据接入文档调整,调整为正确的付款方" },
|
||||
new AlipayErrorCode { Code="NO_ACCOUNTBOOK_K_PERMISSION", Message="没有该账本的使用权限", Solution="没有该账本的使用权限,请确认记录本账本信息和相关权限是否正确" },
|
||||
new AlipayErrorCode { Code="NO_ACCOUNT_REC_EVE_PERMISSION", Message="不支持的付款账户类型或者没有付款方的支付权限", Solution="请更换付款账号" },
|
||||
new AlipayErrorCode { Code="NO_ACCOUNT_USE_R_FORBIDDEN_RECV", Message="当操作存在风险时,防止停止操作,如疑问请询问支付宝支付热线95188", Solution="没有余额账户用户禁止收款,需联系客户95188。" },
|
||||
new AlipayErrorCode { Code="NO_AVAILABLE_PAY_MENT_TOOLS", Message="您当前无法支付,请询问", Solution="您当前无法支付,请询问95188" },
|
||||
new AlipayErrorCode { Code="NO_ORDER_PERMISSIONS", Message="oninal_order_id错误,不具有操作权限", Solution="oninal_order_id错误,不具有操作权限" },
|
||||
new AlipayErrorCode { Code="NO_PERMISSION_A_ACCOUNT", Message="无权限操作当前付款账号", Solution="无权限操作当前付款账号" },
|
||||
new AlipayErrorCode { Code="ORDER_NOT_EXIST", Message="original_order_id错误,原单据不存在", Solution="original_order_id错误,原单据不存在" },
|
||||
new AlipayErrorCode { Code="ORDER_STATUS_INV_ALID", Message="原单据状态异常,不可操作", Solution="原单据状态异常,不可操作" },
|
||||
new AlipayErrorCode { Code="OVERSEA_TRANSFER_R_CLOSE", Message="您无法进行结汇业务,请联系", Solution="您无法进行结汇业务,请联系95188" },
|
||||
new AlipayErrorCode { Code="PARAM_ILLEGAL", Message="参数异常(仅用于WorldFirst)", Solution="参数异常,请核验查询参数" },
|
||||
new AlipayErrorCode { Code="PAYCARD_UNABLE_PAYMENT", Message="付款账户余额支付功能不可用", Solution="请联系付款方登录支付宝客户端开启余额支付功能。" },
|
||||
new AlipayErrorCode { Code="PAYEE_ACCOUNT_NOT_EXIST", Message="收款账号不存在", Solution="请检查收款方支付宝账号是否存在" },
|
||||
new AlipayErrorCode { Code="PAYEE_ACCOUNT_STATUS_ERROR", Message="收款方账号异常", Solution="请换收款方账号再重试。" },
|
||||
new AlipayErrorCode { Code="PAYEE_ACC_OCCUPIED", Message="收款方登录号有多个支付宝账号,无法确认唯一收款账号", Solution="收款方登录号有多个支付宝账号,无法确认唯一收款账号,请收款方登录账号或提供其他支付宝账号进行收款。" },
|
||||
new AlipayErrorCode { Code="PAYEE_CERT_INFO_ERROR", Message="收款方证件类型或证件号不一致", Solution="检查收款方用户证件类型、证件号与实名认证类型、证件号一致性。" },
|
||||
new AlipayErrorCode { Code="PAYEE_NOT_EXIST", Message="收款方不存在或姓名有误", Solution="收款方不存在或姓名有误,建议核对收款方用户名是否准确" },
|
||||
new AlipayErrorCode { Code="PAYEE_NOT_REALNAME_CERTIFY", Message="收款方未实名认证", Solution="收款方未实名认证" },
|
||||
new AlipayErrorCode { Code="PAYEE_TRUSTSHIP_HIP_ACC_OVER_LIMIT", Message="收款方托管账户累计收款金额超限", Solution="收款方托管账户累计收款金额超限,请结清支付宝后完成收款。" },
|
||||
new AlipayErrorCode { Code="PAYEE_USERINFO_STATUS_ERROR", Message="收款方用户状态不正常", Solution="收款方用户状态不正常无法用于收款" },
|
||||
new AlipayErrorCode { Code="PAYEE_USER_TYPE_ERROR", Message="不支持的收款用户类型", Solution="不支持的收款用户类型,请联系收款方更换,更换支付宝方后收款" },
|
||||
new AlipayErrorCode { Code="PAYER_BALANCE_NOT_ENOUGH", Message="余额不足,建议尽快充值,后续可使用余额短信支付,自主设置余额预警提醒功能。", Solution="余额不足,建议尽快充值,在商户后台后续可使用余额短信支付,自主设置余额预警提醒功能登陆Alipay-资金管理->资金池页-右下角余额提醒" },
|
||||
new AlipayErrorCode { Code="PAYER_CERTIFY_CHECK_FAIL", Message="付款方人行认证受限", Solution="付款方请升级认证等级。" },
|
||||
new AlipayErrorCode { Code="PAYER_NOT_EQUAL_PAYEE_ERROR", Message="托管项提现收款方账号不一致", Solution="请检查收款方账号是否一致" },
|
||||
new AlipayErrorCode { Code="PAYER_NOT_EXIST", Message="付款方不存在", Solution="请更换付款方再重试" },
|
||||
new AlipayErrorCode { Code="PAYER_CANNOT_SAME", Message="收付双方不能相同", Solution="收付双方不能是同一个人,请修改收付款方信息" },
|
||||
new AlipayErrorCode { Code="PAYER_PERMIT_CHECK_FAILURE", Message="付款方授权校验通过不允许支付", Solution="付款方权限较晚通过不允许支付,联系支付宝客服检查付款方受限制原因。" },
|
||||
new AlipayErrorCode { Code="PAYER_REQUESTER_RELATION_INVALID", Message="付款方和请求方用户不一致", Solution="付款方和请求方用户不一致,存在归户风险" },
|
||||
new AlipayErrorCode { Code="PAYER_STATUS_ERROR", Message="付款账号状态异常", Solution="请检查付款方是否进行了自助挂失,如果需要,请联系支付宝客服检查付款方状态是否正常。" },
|
||||
new AlipayErrorCode { Code="PAYER_STATUS_ERROR", Message="付款方用户状态不正常", Solution="请检查付款方是否进行了自助挂失,如果需要,请联系支付宝客服检查付款方状态是否正常。" },
|
||||
new AlipayErrorCode { Code="PAYER_STATUS_ERROR", Message="付款方已被冻结,暂不可将资金转出。", Solution="1. 联系支付宝客户询问用户冻结原因以及协助解冻办法状态。" },
|
||||
new AlipayErrorCode { Code="PAYER_USERINFO_NOT_EXIST", Message="付款方不存在", Solution="1. 检查付款方是否已销户,若销户请联系销户后重新发起业务。2. 检查参入是否有误。" },
|
||||
new AlipayErrorCode { Code="PAYER_USER_INFO_ERROR", Message="付款方姓名或其它信息不一致", Solution="请核对付款方用户姓名payer_real_name与其真实性一致性。" },
|
||||
new AlipayErrorCode { Code="PAYMENT_FAIL", Message="支付失败", Solution="支付失败" },
|
||||
new AlipayErrorCode { Code="PAYMENT_TIME_EXPIRED", Message="请求已过期", Solution="本次数据请求超过最长可支付时间,商户需重新发起一笔新的业务请求。" },
|
||||
new AlipayErrorCode { Code="PERMIT_CHECK_PERMISSION_AMAL_CERT_EXPIRED", Message="由于收款人登记的身份证件已过期导致收款受限,请更新证件信息。", Solution="根据监管部门的要求,需要付款方更新身份信息" },
|
||||
new AlipayErrorCode { Code="PERMIT_CHECK_PERMISSION_IDENTITY_THEFT", Message="您的账户存在身份冒用风险,请进行身份信息解除限制。", Solution="您的账户存在身份冒用风险,请进行身份信息解除限制。" },
|
||||
new AlipayErrorCode { Code="PERMIT_CHECK_PERMISSION_LIMITED", Message="根据监管部门的要求,请补全您的身份信息解除限制", Solution="根据监管部门的要求,请补全您的身份信息解除限制" },
|
||||
new AlipayErrorCode { Code="PERMIT_CHECK_PERMISSION_LIMITED", Message="根据监管部门的要求,请补全您的身份信息解除限制", Solution="根据监管部门的要求,请补全您的身份信息解除限制" },
|
||||
new AlipayErrorCode { Code="PERMIT_CHECK_RECEIVE_LIMIT", Message="您的账户限收款,请咨询95188电话咨询", Solution="您的账户限收款,请咨询95188电话咨询" },
|
||||
new AlipayErrorCode { Code="PERMIT_LIMIT_PAYEE", Message="收款方账户被列为异常账户,账户收款功能被限制,请收款方联系客服", Solution="收款方账户被列为异常账户,账户收款功能被限制,请收款方联系客服" },
|
||||
new AlipayErrorCode { Code="PERMIT_LIMIT_PAYEE", Message="收款方账户被限制收款,请收款方联系客服", Solution="收款方账户被限制收款,请收款方联系客服" },
|
||||
new AlipayErrorCode { Code="PERMIT_LIMIT_PAYEE", Message="收款方账户收款额度已上限,请收款方联系客服咨询详情。", Solution="收款方账户收款额度已上限,请收款方联系客服咨询详情。" },
|
||||
new AlipayErrorCode { Code="PERMIT_LIMIT_PAYEE", Message="收款方账户收款功能暂时无法使用", Solution="收款方账户收款功能暂时无法使用" },
|
||||
new AlipayErrorCode { Code="PERMIT_NOT_BANK_LIMIT_PAYEE", Message="收款方未完善身份证信息或未开立余额账户,无法收款", Solution="根据监管部门的要求,收款方未完善身份证信息或未开立余额账户,无法收款" },
|
||||
new AlipayErrorCode { Code="PERMIT_NOT_BANK_LIMIT_PAYEE", Message="当前操作存在风险,不支持转账,如无疑问请拨打支付宝服务热线95188", Solution="根据监管部门的要求,收款方未完善身份证信息或未开立余额账户,无法收款" },
|
||||
new AlipayErrorCode { Code="PERMIT_PAYER_FORBIDDEN", Message="根据监管部门的要求,需要收款方补充身份信息才能继续操作", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PERMIT_PAYER_FORBIDDEN", Message="根据监管部门的要求,需要收款方补充身份信息才能继续操作", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PERM_PAY_CUSTOM_ER_DAILY_QUOTA_ORG_BALANCE_LIMIT", Message="同一主体下今日余额付款额度已上限。", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PERM_PAY_CUSTOM_ER_MONTH_QUOTA_ORG_BALANCE_LIMIT", Message="同一主体下当月余额付款额度已上限。", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PERM_PAY_USER_DAILY_QUOTA_ORG_BALANCE_LIMIT", Message="该账户今日余额付款额度已达上限。", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PERM_PAY_USER_MONTH_QUOTA_ORG_BALANCE_LIMIT", Message="该账户当月余额付款额度已达上限。", Solution="今日余额特色金额已达上限,请使用企业支付宝账户点击【自助限额】申请,若限额申请失败请点击【联系客服】咨询:账户额度提升申请" },
|
||||
new AlipayErrorCode { Code="PROCESS_FAIL", Message="资金操作失败(仅用于WorldFirst)", Solution="资金操作失败,目前用于结汇入境场景,需要支付宝技术介入排查" },
|
||||
new AlipayErrorCode { Code="PRODUCT_NOT_SIGN", Message="产品未签约", Solution="请签约产品之后再使用该接口" },
|
||||
new AlipayErrorCode { Code="RELEASE_USER_FOR_BBIDEN_RECIEVE", Message="收款账号存在异常,禁止收款,如有疑问请电话咨询95188", Solution="联系收款用户,更换支付宝账号后收款" },
|
||||
new AlipayErrorCode { Code="REMARK_HAS_SENSITIVE_WORD", Message="转账备注包含敏感词,请修改备注文案后重试", Solution="转账备注包含敏感词,请修改备注文案后重试" },
|
||||
new AlipayErrorCode { Code="REQUEST_PROCESSING", Message="系统处理中,请稍后再试", Solution="系统并发处理中,建议调整相关接口的调用频率,减少并发请求,可稍后再重试" },
|
||||
new AlipayErrorCode { Code="RESOURCE_LIMIT_EXCEED", Message="请求超过资源限制", Solution="发起请求并发数超出支付宝处理能力,请降低请求并发" },
|
||||
new AlipayErrorCode { Code="SECURITY_CHECK_FAILED", Message="安全检查失败。当前操作存在风险,请停止操作,如有疑问请咨询服务热线95188", Solution="安全检查失败。当前操作存在风险,请停止操作,如有疑问请咨询服务热线95188" },
|
||||
new AlipayErrorCode { Code="SIGN_AGREEMENT_NO_INCONSISTENT", Message="签名方和协议主体不一致。请确认payer_info.ext_info.agreement_no和sign_data.ori_app_id是否匹配。", Solution="签名方和协议主体不一致。请确认payer_info.ext_info.agreement_no和sign_data.ori_app_id是否匹配,再重试。" },
|
||||
new AlipayErrorCode { Code="SIGN_INVALID", Message="签名非法,验签不通过。请确认签名信息是否被篡改以及签名方签名格式是否正确。", Solution="签名非法,验签不通过。请确认签名信息是否被篡改以及签名方签名格式是否正确。" },
|
||||
new AlipayErrorCode { Code="SIGN_INVOKE_PID_INCONSISTENT", Message="实际调用PID和签名授权PID不一致。请确认实际调用PID和sign_data.partner_id是否一致。", Solution="请确认实际调用PID和sign_data.partner_id是否一致,一致后再重试。" },
|
||||
new AlipayErrorCode { Code="SIGN_NOT_ALLOW_SKIP", Message="该场景强制验签,不允许跳过。请按要求上报sign_data后重试。", Solution="该场景强制验签,不允许跳过。请按要求上报sign_data后重试。" },
|
||||
new AlipayErrorCode { Code="SIGN_PARAM_INVALID", Message="验签参数非法。请确认sign_data参数是否正确。", Solution="验签参数非法,请确认sign_data参数是否正确。" },
|
||||
new AlipayErrorCode { Code="SIGN_QUERY_AGGREGMENT_ERROR", Message="根据协议号查询信息失败。请确认payer_info.ext_info.agreement_no是否正确。", Solution="请确认上报协议号payer_info.ext_info.agreement_no内容正确后再重试。" },
|
||||
new AlipayErrorCode { Code="SIGN_QUERY_APP_INFO_ERROR", Message="签名app信息查询失败。请确认sign_data.ori_app_id是否正确。", Solution="请确认签名方sign_data.ori_app_id是否正确,信息正确后再重试。" },
|
||||
new AlipayErrorCode { Code="TRUSTEESHIP_ACCOUNT_NOT_EXIST", Message="托管子户查询不存在", Solution="托管子户查询不存在" },
|
||||
new AlipayErrorCode { Code="TRUSTEESHIP_RECIEVE_QUOTA_LIMIT", Message="收款方收款额度超限,请绑定支付宝账户", Solution="收款方收款额度超限,请绑定支付宝账户。" },
|
||||
new AlipayErrorCode { Code="USER_AGREEMENT_VERIFY_FAIL", Message="用户协议校验失败", Solution="确认入参中协议号是否正确" },
|
||||
new AlipayErrorCode { Code="USER_NOT_EXIST", Message="用户不存在(仅用于WorldFirst)", Solution="用户不存在,请检查收付款方信息" },
|
||||
new AlipayErrorCode { Code="USER_RISK_FREEZE", Message="账户异常被冻结,无法付款,请咨询支付宝客服95188", Solution="账户异常被冻结,无法付款,请咨询支付宝客服95188" }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 根据错误码获取错误信息
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
public static AlipayErrorCode Get(string code)
|
||||
{
|
||||
return StatusCodes.FirstOrDefault(u => u.Code.EqualIgnoreCase(code));
|
||||
}
|
||||
}
|
||||
273
Admin.NET/Admin.NET.Core/Service/Alipay/AlipayService.cs
Normal file
273
Admin.NET/Admin.NET.Core/Service/Alipay/AlipayService.cs
Normal file
@ -0,0 +1,273 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using Admin.NET.Core.Service.Alipay;
|
||||
using Aop.Api;
|
||||
using Aop.Api.Domain;
|
||||
using Aop.Api.Request;
|
||||
using Aop.Api.Response;
|
||||
using Aop.Api.Util;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Admin.NET.Core.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝支付服务 🧩
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Order = 240)]
|
||||
public class AlipayService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly UserManager _userManager;
|
||||
private readonly SysConfigService _sysConfigService;
|
||||
private readonly AlipayOptions _alipayOptions;
|
||||
private readonly IHttpContextAccessor _httpContext;
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
private readonly IAopClient _alipayClient;
|
||||
|
||||
public AlipayService(UserManager userManager,
|
||||
SysConfigService sysConfigService,
|
||||
IOptions<AlipayOptions> alipayOptions,
|
||||
IHttpContextAccessor httpContext,
|
||||
IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_sysConfigService = sysConfigService;
|
||||
_alipayOptions = alipayOptions.Value;
|
||||
_httpContext = httpContext;
|
||||
_webHostEnvironment = webHostEnvironment;
|
||||
|
||||
// 初始化支付宝客户端
|
||||
string path = App.WebHostEnvironment.ContentRootPath;
|
||||
_alipayClient = new DefaultAopClient(new AlipayConfig
|
||||
{
|
||||
Format = "json",
|
||||
Charset = "UTF-8",
|
||||
AppId = _alipayOptions.AppId,
|
||||
SignType = _alipayOptions.SignType,
|
||||
ServerUrl = _alipayOptions.ServerUrl,
|
||||
PrivateKey = _alipayOptions.PrivateKey,
|
||||
EncryptKey = _alipayOptions.EncryptKey,
|
||||
AppCertPath = Path.Combine(path, _alipayOptions.AppCertPath),
|
||||
RootCertPath = Path.Combine(path, _alipayOptions.RootCertPath),
|
||||
AlipayPublicCertPath = Path.Combine(path, _alipayOptions.AlipayPublicCertPath)
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取授权信息 🔖
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[NonUnify]
|
||||
[AllowAnonymous]
|
||||
[DisplayName("获取授权信息")]
|
||||
[ApiDescriptionSettings(Name = "GetAuthInfo"), HttpGet]
|
||||
public ActionResult GetAuthInfo([FromQuery] AlipayAuthInfoInput input)
|
||||
{
|
||||
var type = input.UserId.Split('-').FirstOrDefault().ToInt();
|
||||
var userId = input.UserId.Split('-').LastOrDefault().ToLong();
|
||||
|
||||
// 当前网页接口地址
|
||||
var currentUrl = $"{_httpContext.HttpContext!.Request.GetOrigin()}{_httpContext.HttpContext!.Request.Path}?userId={input.UserId}";
|
||||
if (string.IsNullOrEmpty(input.AuthCode))
|
||||
{
|
||||
// 重新授权
|
||||
var url = $"{_alipayOptions.AuthUrl}?app_id={_alipayOptions.AppId}&scope=auth_user&redirect_uri={currentUrl}";
|
||||
return new RedirectResult(url);
|
||||
}
|
||||
|
||||
// 组装授权请求参数
|
||||
AlipaySystemOauthTokenRequest request = new()
|
||||
{
|
||||
GrantType = AlipayConst.GrantType,
|
||||
Code = input.AuthCode
|
||||
};
|
||||
AlipaySystemOauthTokenResponse response = _alipayClient.CertificateExecute(request);
|
||||
|
||||
// token换取用户信息
|
||||
AlipayUserInfoShareRequest infoShareRequest = new();
|
||||
AlipayUserInfoShareResponse info = _alipayClient.CertificateExecute(infoShareRequest, response.AccessToken);
|
||||
|
||||
// 循环执行扫码后需要执行的业务逻辑,需要至少一个继承方法返回true,否则抛出异常
|
||||
var pass = false;
|
||||
foreach (var notify in App.GetServices<IAlipayNotify>())
|
||||
if (notify.ScanCallback(type, userId, info)) pass = true;
|
||||
if (!pass) throw Oops.Oh("未处理的授权逻辑");
|
||||
|
||||
// 执行完,重定向到指定界面
|
||||
var authPageUrl = _sysConfigService.GetConfigValueByCode<string>(ConfigConst.AlipayAuthPageUrl + type).Result;
|
||||
return new RedirectResult(authPageUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 支付回调 🔖
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[DisplayName("支付回调")]
|
||||
[ApiDescriptionSettings(Name = "Notify"), HttpPost]
|
||||
public string Notify()
|
||||
{
|
||||
SortedDictionary<string, string> sorted = new();
|
||||
foreach (string key in _httpContext.HttpContext!.Request.Form.Keys)
|
||||
sorted.Add(key, _httpContext.HttpContext.Request.Form[key]);
|
||||
|
||||
string alipayPublicKey = Path.Combine(_webHostEnvironment.ContentRootPath, _alipayOptions.AlipayPublicCertPath!.Replace('/', '\\').TrimStart('\\'));
|
||||
bool signVerified = AlipaySignature.RSACertCheckV1(sorted, alipayPublicKey, "UTF-8", _alipayOptions.SignType); // 调用SDK验证签名
|
||||
if (!signVerified) throw Oops.Oh("交易失败");
|
||||
|
||||
var outTradeNo = sorted.GetValueOrDefault("out_trade_no");
|
||||
try
|
||||
{
|
||||
// 记录回调日志
|
||||
File.AppendAllText($"{_webHostEnvironment.ContentRootPath}\\AlipayLog\\Notify-{DateTime.Today:yyyy-MM-dd}.txt",
|
||||
$"支付宝支付到平台({DateTime.Now:yyyy-MM-dd HH:mm:ss}):{Environment.NewLine} " +
|
||||
$"登录人:{_userManager.UserId}-{_userManager.RealName}{Environment.NewLine} " +
|
||||
$"IP:{App.HttpContext?.GetRemoteIpAddressToIPv4(true)} {Environment.NewLine} " +
|
||||
$"交易号:{outTradeNo}{Environment.NewLine} " +
|
||||
$"参数:{JSON.Serialize(sorted)}{Environment.NewLine} " +
|
||||
$"-----------------------------------------------------------------------------------------------------------------------" +
|
||||
$"{Environment.NewLine}{Environment.NewLine}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("支付宝支付回调日志写入失败:", ex);
|
||||
}
|
||||
|
||||
if (sorted.GetValueOrDefault(AlipayConst.TradeStatus) == AlipayConst.TradeSuccess)
|
||||
{
|
||||
// 约定交易码前四位为类型码,后面为订单号
|
||||
var tradeNo = long.Parse(outTradeNo);
|
||||
var type = long.Parse(outTradeNo.Substring(0, 4));
|
||||
|
||||
// 循环执行业务逻辑,若都未处理(回调全部返回false)则交易失败
|
||||
var isError = true;
|
||||
foreach (var notify in App.GetServices<IAlipayNotify>())
|
||||
if (notify.TopUpCallback(type, tradeNo)) isError = false;
|
||||
if (isError) throw Oops.Oh("交易失败");
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一收单下单并支付页面接口 🔖
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[DisplayName("统一收单下单并支付页面接口")]
|
||||
[ApiDescriptionSettings(Name = "AlipayTradePagePay"), HttpPost]
|
||||
public string AlipayTradePagePay(AlipayTradePagePayInput input)
|
||||
{
|
||||
AlipayTradeWapPayRequest request = new();
|
||||
|
||||
// 组装业务参数model
|
||||
AlipayTradeWapPayModel model = new()
|
||||
{
|
||||
Subject = input.Subject,
|
||||
OutTradeNo = input.OutTradeNo,
|
||||
TotalAmount = input.TotalAmount,
|
||||
Body = input.Body,
|
||||
ProductCode = "QUICK_WAP_WAY",
|
||||
TimeExpire = input.TimeoutExpress
|
||||
};
|
||||
request.SetBizModel(model);
|
||||
|
||||
// 设置异步通知接收地址
|
||||
request.SetNotifyUrl(_alipayOptions.NotifyUrl);
|
||||
|
||||
var response = _alipayClient.SdkExecute(request);
|
||||
if (response.IsError) throw Oops.Oh(response.SubMsg);
|
||||
return $"{_alipayOptions.ServerUrl}?{response.Body}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 交易预创建 🔖
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[DisplayName("交易预创建")]
|
||||
[ApiDescriptionSettings(Name = "AlipayPreCreate"), HttpPost]
|
||||
public string AlipayPreCreate(AlipayPreCreateInput input)
|
||||
{
|
||||
AlipayTradePrecreateRequest request = new();
|
||||
|
||||
// 设置异步通知接收地址
|
||||
request.SetNotifyUrl(_alipayOptions.NotifyUrl);
|
||||
|
||||
// 组装业务参数model
|
||||
AlipayTradePrecreateModel model = new()
|
||||
{
|
||||
Subject = input.Subject,
|
||||
OutTradeNo = input.OutTradeNo,
|
||||
TotalAmount = input.TotalAmount,
|
||||
TimeoutExpress = input.TimeoutExpress
|
||||
};
|
||||
request.SetBizModel(model);
|
||||
|
||||
var response = _alipayClient.CertificateExecute(request);
|
||||
if (response.IsError) throw Oops.Oh(response.SubMsg);
|
||||
return response.QrCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单笔转账到支付宝账户
|
||||
/// https://opendocs.alipay.com/open/62987723_alipay.fund.trans.uni.transfer
|
||||
/// </summary>
|
||||
[NonAction]
|
||||
public Task<AlipayFundTransUniTransferResponse> Transfer(AlipayFundTransUniTransferInput input)
|
||||
{
|
||||
// 构造请求参数以调用接口
|
||||
AlipayFundTransUniTransferRequest request = new();
|
||||
AlipayFundTransUniTransferModel model = new();
|
||||
model.BizScene = AlipayConst.BizScene;
|
||||
model.ProductCode = AlipayConst.ProductCode;
|
||||
|
||||
// 设置商家侧唯一订单号
|
||||
model.OutBizNo = input.OutBizNo;
|
||||
|
||||
// 设置订单总金额
|
||||
model.TransAmount = input.TransAmount.ToString();
|
||||
|
||||
// 设置转账业务的标题
|
||||
model.OrderTitle = input.OrderTitle;
|
||||
|
||||
// 设置收款方信息
|
||||
Participant payeeInfo = new();
|
||||
payeeInfo.CertType = input.CertType.ToString();
|
||||
payeeInfo.CertNo = input.CertNo;
|
||||
payeeInfo.Identity = input.Identity;
|
||||
payeeInfo.Name = input.Name;
|
||||
payeeInfo.IdentityType = input.IdentityType.ToString();
|
||||
model.PayeeInfo = payeeInfo;
|
||||
|
||||
// 设置业务备注
|
||||
model.Remark = input.Remark;
|
||||
|
||||
// 设置转账业务请求的扩展参数
|
||||
string payerShowNameUseAlias = input.PayerShowNameUseAlias.ToString().ToLower();
|
||||
model.BusinessParams = $"{{\"payer_show_name_use_alias\":\"{payerShowNameUseAlias}\"}}";
|
||||
|
||||
request.SetBizModel(model);
|
||||
var response = _alipayClient.CertificateExecute(request);
|
||||
|
||||
try
|
||||
{
|
||||
File.AppendAllText($"{_webHostEnvironment.ContentRootPath}\\AlipayLog\\{DateTime.Today:yyyy-MM-dd}.txt",
|
||||
$"支付宝付款到账户({DateTime.Now:yyyy-MM-dd HH:mm:ss}):{Environment.NewLine} " +
|
||||
$"登录人:{_userManager.UserId}-{_userManager.RealName}{Environment.NewLine} " +
|
||||
$"IP:{App.HttpContext?.GetRemoteIpAddressToIPv4(true)} {Environment.NewLine} " +
|
||||
$"参数:{JSON.Serialize(model)}{Environment.NewLine} " +
|
||||
$"返回:{JSON.Serialize(response)}{Environment.NewLine}" +
|
||||
$"-----------------------------------------------------------------------------------------------------------------------" +
|
||||
$"{Environment.NewLine}{Environment.NewLine}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("单笔转账到支付宝账户日志写入失败:", ex);
|
||||
}
|
||||
return Task.FromResult(response);
|
||||
}
|
||||
}
|
||||
169
Admin.NET/Admin.NET.Core/Service/Alipay/Dto/AlipayInput.cs
Normal file
169
Admin.NET/Admin.NET.Core/Service/Alipay/Dto/AlipayInput.cs
Normal file
@ -0,0 +1,169 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using Aop.Api.Domain;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Admin.NET.Core.Service;
|
||||
|
||||
public class AlipayFundTransUniTransferInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 商家侧唯一订单号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单号不能为空")]
|
||||
public string OutBizNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 转账金额
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "转账金额不能为空")]
|
||||
public decimal? TransAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 转账业务标题
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "业务标题不能为空")]
|
||||
public string OrderTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否展示付款方别名
|
||||
/// </summary>
|
||||
public bool PayerShowNameUseAlias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收款方证件类型
|
||||
/// </summary>
|
||||
public AlipayCertTypeEnum? CertType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收款方证件号码,条件必填
|
||||
/// </summary>
|
||||
[CommonValidation($"{nameof(CertType)} != null && string.IsNullOrWhiteSpace({nameof(CertNo)})", "", ErrorMessage = "证件号码不能为空")]
|
||||
public string CertNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收款方身份标识
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "身份标识不能为空")]
|
||||
public string Identity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收款方真实姓名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "真实姓名不能为空")]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 收款方身份标识类型
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "身份标识类型不能为空")]
|
||||
public AlipayIdentityTypeEnum? IdentityType { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一收单下单并支付页面接口输入参数
|
||||
/// </summary>
|
||||
public class AlipayTradePagePayInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户订单号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "商户订单号不能为空")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单总金额
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单总金额不能为空")]
|
||||
public string TotalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单标题
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单标题不能为空")]
|
||||
public string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 超时时间
|
||||
/// </summary>
|
||||
public string TimeoutExpress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 二维码宽度
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "二维码宽度不能为空")]
|
||||
public int? QrcodeWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务参数
|
||||
/// </summary>
|
||||
public ExtendParams ExtendParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 商户业务数据
|
||||
/// </summary>
|
||||
public Dictionary<string, object> BusinessParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开票信息
|
||||
/// </summary>
|
||||
public InvoiceInfo InvoiceInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外部买家信息
|
||||
/// </summary>
|
||||
public ExtUserInfo ExtUserInfo { get; set; }
|
||||
}
|
||||
|
||||
public class AlipayPreCreateInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户订单号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "商户订单号不能为空")]
|
||||
public string OutTradeNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单总金额
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单总金额不能为空")]
|
||||
public string TotalAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 订单标题
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订单标题不能为空")]
|
||||
public string Subject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 超时时间
|
||||
/// </summary>
|
||||
public string TimeoutExpress { get; set; }
|
||||
}
|
||||
|
||||
public class AlipayAuthInfoInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 授权码
|
||||
/// </summary>
|
||||
public string AuthCode { get; set; }
|
||||
}
|
||||
31
Admin.NET/Admin.NET.Core/Service/Alipay/IAlipayNotify.cs
Normal file
31
Admin.NET/Admin.NET.Core/Service/Alipay/IAlipayNotify.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using Aop.Api.Response;
|
||||
|
||||
namespace Admin.NET.Core.Service.Alipay;
|
||||
|
||||
/// <summary>
|
||||
/// 支付宝回调接口
|
||||
/// </summary>
|
||||
public abstract class IAlipayNotify
|
||||
{
|
||||
/// <summary>
|
||||
/// 充值回调方法
|
||||
/// </summary>
|
||||
/// <param name="type">交易类型</param>
|
||||
/// <param name="tradeNo">交易id</param>
|
||||
public abstract bool TopUpCallback(long type, long tradeNo);
|
||||
|
||||
/// <summary>
|
||||
/// 扫码回调
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="response"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool ScanCallback(long type, long userId, AlipayUserInfoShareResponse response);
|
||||
}
|
||||
@ -20,7 +20,7 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
/// <returns></returns>
|
||||
public IActionResult OnAuthorizeException(DefaultHttpContext context, ExceptionMetadata metadata)
|
||||
{
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode, data: metadata.Data, errors: metadata.Errors), UnifyContext.GetSerializerSettings(context));
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode, data: metadata.Data, msg: metadata.Errors), UnifyContext.GetSerializerSettings(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -31,7 +31,7 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
/// <returns></returns>
|
||||
public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
|
||||
{
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode, data: metadata.Data, errors: metadata.Errors), UnifyContext.GetSerializerSettings(context));
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode, data: metadata.Data, msg: metadata.Errors), UnifyContext.GetSerializerSettings(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -53,7 +53,7 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
/// <returns></returns>
|
||||
public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
|
||||
{
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode ?? StatusCodes.Status400BadRequest, data: metadata.Data, errors: metadata.ValidationResult), UnifyContext.GetSerializerSettings(context));
|
||||
return new JsonResult(RESTfulResult(metadata.StatusCode ?? StatusCodes.Status400BadRequest, data: metadata.Data, msg: metadata.ValidationResult), UnifyContext.GetSerializerSettings(context));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -76,12 +76,12 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
// 若存在身份验证失败消息,则返回消息内容
|
||||
if (context.Items.TryGetValue(SignatureAuthenticationDefaults.AuthenticateFailMsgKey, out var authFailMsg))
|
||||
msg = authFailMsg + "";
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, errors: msg),
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, msg: msg),
|
||||
App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
|
||||
break;
|
||||
// 处理 403 状态码
|
||||
case StatusCodes.Status403Forbidden:
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, errors: "403 禁止访问,没有权限"),
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, msg: "403 禁止访问,没有权限"),
|
||||
App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
|
||||
break;
|
||||
// 处理 302 状态码
|
||||
@ -93,7 +93,7 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
else
|
||||
{
|
||||
var errorMessage = "302 跳转失败,没有提供 Location 头信息";
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, errors: errorMessage),
|
||||
await context.Response.WriteAsJsonAsync(RESTfulResult(statusCode, msg: errorMessage),
|
||||
App.GetOptions<JsonOptions>()?.JsonSerializerOptions);
|
||||
}
|
||||
break;
|
||||
@ -108,9 +108,9 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
/// <param name="statusCode"></param>
|
||||
/// <param name="succeeded"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="errors"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
private static AdminResult<object> RESTfulResult(int statusCode, bool succeeded = default, object data = default, object errors = default)
|
||||
private static AdminResult<object> RESTfulResult(int statusCode, bool succeeded = default, object data = default, object msg = default)
|
||||
{
|
||||
//// 统一返回值脱敏处理
|
||||
//if (data?.GetType() == typeof(String))
|
||||
@ -125,7 +125,7 @@ public class AdminResultProvider : IUnifyResultProvider
|
||||
return new AdminResult<object>
|
||||
{
|
||||
Code = statusCode,
|
||||
Message = errors is null or string ? (errors + "") : JSON.Serialize(errors),
|
||||
Message = msg is null or string ? (msg + "") : JSON.Serialize(msg),
|
||||
Result = data,
|
||||
Type = succeeded ? "success" : "error",
|
||||
Extras = UnifyContext.Take(),
|
||||
|
||||
@ -81,6 +81,23 @@ public static class CommonUtil
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取请求地址源
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetOrigin(this HttpRequest request)
|
||||
{
|
||||
string scheme = request.Scheme;
|
||||
string host = request.Host.Host;
|
||||
int port = request.Host.Port ?? (-1);
|
||||
|
||||
string url = $"{scheme}://{host}";
|
||||
if (port != 80 && port != 443 && port != -1) url += $":{port}";
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对象序列化XML
|
||||
/// </summary>
|
||||
|
||||
@ -21,6 +21,7 @@ public class ExcelHelper
|
||||
try
|
||||
{
|
||||
var result = CommonUtil.ImportExcelDataAsync<IN>(file).Result ?? throw Oops.Oh("有效数据为空");
|
||||
result.ForEach(u => u.Id = YitIdHelper.NextId());
|
||||
|
||||
var tasks = new List<Task>();
|
||||
action.Invoke(result, (storageable, pageItems, rows) =>
|
||||
@ -28,12 +29,14 @@ public class ExcelHelper
|
||||
// 标记校验信息
|
||||
tasks.Add(Task.Run(() =>
|
||||
{
|
||||
if (storageable.TotalList.Any())
|
||||
{
|
||||
for (int i = 0; i < rows.Count; i++) pageItems[i].Id = rows[i].Id;
|
||||
if (!storageable.TotalList.Any()) return;
|
||||
|
||||
for (int i = 0; i < storageable.TotalList.Count; i++)
|
||||
pageItems[i].Error ??= storageable.TotalList[i].StorageMessage;
|
||||
// 通过Id标记校验信息
|
||||
var itemMap = pageItems.ToDictionary(u => u.Id, u => u);
|
||||
foreach (var item in storageable.TotalList)
|
||||
{
|
||||
var temp = itemMap.GetValueOrDefault(item.Item.Id);
|
||||
if (temp != null) temp.Error ??= item.StorageMessage;
|
||||
}
|
||||
}));
|
||||
});
|
||||
@ -41,7 +44,9 @@ public class ExcelHelper
|
||||
// 等待所有标记验证信息任务完成
|
||||
Task.WhenAll(tasks).GetAwaiter().GetResult();
|
||||
|
||||
return ExportData(result);
|
||||
// 仅导出错误记录
|
||||
var errorList = result.Where(u => !string.IsNullOrWhiteSpace(u.Error));
|
||||
return ExportData(errorList.Any() ? errorList : new List<IN>());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -59,7 +64,7 @@ public class ExcelHelper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出xlsx数据
|
||||
/// 导出Xlsx数据
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="fileName"></param>
|
||||
@ -72,7 +77,7 @@ public class ExcelHelper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据类型导出xlsx模板
|
||||
/// 根据类型导出Xlsx模板
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="filename"></param>
|
||||
|
||||
@ -37,6 +37,7 @@ public static class ProjectOptions
|
||||
services.AddConfigurableOptions<CryptogramOptions>();
|
||||
services.AddConfigurableOptions<SMSOptions>();
|
||||
services.AddConfigurableOptions<EventBusOptions>();
|
||||
services.AddConfigurableOptions<AlipayOptions>();
|
||||
services.Configure<IpRateLimitOptions>(App.Configuration.GetSection("IpRateLimiting"));
|
||||
services.Configure<IpRateLimitPolicies>(App.Configuration.GetSection("IpRateLimitPolicies"));
|
||||
services.Configure<ClientRateLimitOptions>(App.Configuration.GetSection("ClientRateLimiting"));
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
export * from './apis/apijsonapi';
|
||||
export * from './apis/alipay-api';
|
||||
export * from './apis/sys-app-api';
|
||||
export * from './apis/sys-auth-api';
|
||||
export * from './apis/sys-cache-api';
|
||||
|
||||
389
Web/src/api-services/apis/alipay-api.ts
Normal file
389
Web/src/api-services/apis/alipay-api.ts
Normal file
@ -0,0 +1,389 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import globalAxios, { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
|
||||
import { Configuration } from '../configuration';
|
||||
// Some imports not used depending on template conditions
|
||||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
|
||||
import { AdminResultString } from '../models';
|
||||
import { AlipayPreCreateInput } from '../models';
|
||||
import { AlipayTradePagePayInput } from '../models';
|
||||
/**
|
||||
* AlipayApi - axios parameter creator
|
||||
* @export
|
||||
*/
|
||||
export const AlipayApiAxiosParamCreator = function (configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @summary 交易预创建 🔖
|
||||
* @param {AlipayPreCreateInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiAlipayAlipayPreCreatePost: async (body?: AlipayPreCreateInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/alipay/alipayPreCreate`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication Bearer required
|
||||
// http bearer authentication required
|
||||
if (configuration && configuration.accessToken) {
|
||||
const accessToken = typeof configuration.accessToken === 'function'
|
||||
? await configuration.accessToken()
|
||||
: await configuration.accessToken;
|
||||
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
|
||||
|
||||
const query = new URLSearchParams(localVarUrlObj.search);
|
||||
for (const key in localVarQueryParameter) {
|
||||
query.set(key, localVarQueryParameter[key]);
|
||||
}
|
||||
for (const key in options.params) {
|
||||
query.set(key, options.params[key]);
|
||||
}
|
||||
localVarUrlObj.search = (new URLSearchParams(query)).toString();
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
|
||||
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 统一收单下单并支付页面接口 🔖
|
||||
* @param {AlipayTradePagePayInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiAlipayAlipayTradePagePayPost: async (body?: AlipayTradePagePayInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/alipay/alipayTradePagePay`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication Bearer required
|
||||
// http bearer authentication required
|
||||
if (configuration && configuration.accessToken) {
|
||||
const accessToken = typeof configuration.accessToken === 'function'
|
||||
? await configuration.accessToken()
|
||||
: await configuration.accessToken;
|
||||
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
|
||||
|
||||
const query = new URLSearchParams(localVarUrlObj.search);
|
||||
for (const key in localVarQueryParameter) {
|
||||
query.set(key, localVarQueryParameter[key]);
|
||||
}
|
||||
for (const key in options.params) {
|
||||
query.set(key, options.params[key]);
|
||||
}
|
||||
localVarUrlObj.search = (new URLSearchParams(query)).toString();
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
|
||||
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取授权信息 🔖
|
||||
* @param {string} [userId] 用户Id
|
||||
* @param {string} [authCode] 授权码
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiAlipayGetAuthInfoGet: async (userId?: string, authCode?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/alipay/getAuthInfo`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication Bearer required
|
||||
// http bearer authentication required
|
||||
if (configuration && configuration.accessToken) {
|
||||
const accessToken = typeof configuration.accessToken === 'function'
|
||||
? await configuration.accessToken()
|
||||
: await configuration.accessToken;
|
||||
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
|
||||
}
|
||||
|
||||
if (userId !== undefined) {
|
||||
localVarQueryParameter['UserId'] = userId;
|
||||
}
|
||||
|
||||
if (authCode !== undefined) {
|
||||
localVarQueryParameter['AuthCode'] = authCode;
|
||||
}
|
||||
|
||||
const query = new URLSearchParams(localVarUrlObj.search);
|
||||
for (const key in localVarQueryParameter) {
|
||||
query.set(key, localVarQueryParameter[key]);
|
||||
}
|
||||
for (const key in options.params) {
|
||||
query.set(key, options.params[key]);
|
||||
}
|
||||
localVarUrlObj.search = (new URLSearchParams(query)).toString();
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 支付回调 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiAlipayNotifyPost: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/alipay/notify`;
|
||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||
let baseOptions;
|
||||
if (configuration) {
|
||||
baseOptions = configuration.baseOptions;
|
||||
}
|
||||
const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
|
||||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication Bearer required
|
||||
// http bearer authentication required
|
||||
if (configuration && configuration.accessToken) {
|
||||
const accessToken = typeof configuration.accessToken === 'function'
|
||||
? await configuration.accessToken()
|
||||
: await configuration.accessToken;
|
||||
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
|
||||
}
|
||||
|
||||
const query = new URLSearchParams(localVarUrlObj.search);
|
||||
for (const key in localVarQueryParameter) {
|
||||
query.set(key, localVarQueryParameter[key]);
|
||||
}
|
||||
for (const key in options.params) {
|
||||
query.set(key, options.params[key]);
|
||||
}
|
||||
localVarUrlObj.search = (new URLSearchParams(query)).toString();
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* AlipayApi - functional programming interface
|
||||
* @export
|
||||
*/
|
||||
export const AlipayApiFp = function(configuration?: Configuration) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @summary 交易预创建 🔖
|
||||
* @param {AlipayPreCreateInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayAlipayPreCreatePost(body?: AlipayPreCreateInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultString>>> {
|
||||
const localVarAxiosArgs = await AlipayApiAxiosParamCreator(configuration).apiAlipayAlipayPreCreatePost(body, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 统一收单下单并支付页面接口 🔖
|
||||
* @param {AlipayTradePagePayInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayAlipayTradePagePayPost(body?: AlipayTradePagePayInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultString>>> {
|
||||
const localVarAxiosArgs = await AlipayApiAxiosParamCreator(configuration).apiAlipayAlipayTradePagePayPost(body, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取授权信息 🔖
|
||||
* @param {string} [userId] 用户Id
|
||||
* @param {string} [authCode] 授权码
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayGetAuthInfoGet(userId?: string, authCode?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
const localVarAxiosArgs = await AlipayApiAxiosParamCreator(configuration).apiAlipayGetAuthInfoGet(userId, authCode, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 支付回调 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayNotifyPost(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultString>>> {
|
||||
const localVarAxiosArgs = await AlipayApiAxiosParamCreator(configuration).apiAlipayNotifyPost(options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* AlipayApi - factory interface
|
||||
* @export
|
||||
*/
|
||||
export const AlipayApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {
|
||||
return {
|
||||
/**
|
||||
*
|
||||
* @summary 交易预创建 🔖
|
||||
* @param {AlipayPreCreateInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayAlipayPreCreatePost(body?: AlipayPreCreateInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(configuration).apiAlipayAlipayPreCreatePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 统一收单下单并支付页面接口 🔖
|
||||
* @param {AlipayTradePagePayInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayAlipayTradePagePayPost(body?: AlipayTradePagePayInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(configuration).apiAlipayAlipayTradePagePayPost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取授权信息 🔖
|
||||
* @param {string} [userId] 用户Id
|
||||
* @param {string} [authCode] 授权码
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayGetAuthInfoGet(userId?: string, authCode?: string, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return AlipayApiFp(configuration).apiAlipayGetAuthInfoGet(userId, authCode, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 支付回调 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiAlipayNotifyPost(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(configuration).apiAlipayNotifyPost(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* AlipayApi - object-oriented interface
|
||||
* @export
|
||||
* @class AlipayApi
|
||||
* @extends {BaseAPI}
|
||||
*/
|
||||
export class AlipayApi extends BaseAPI {
|
||||
/**
|
||||
*
|
||||
* @summary 交易预创建 🔖
|
||||
* @param {AlipayPreCreateInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AlipayApi
|
||||
*/
|
||||
public async apiAlipayAlipayPreCreatePost(body?: AlipayPreCreateInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(this.configuration).apiAlipayAlipayPreCreatePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 统一收单下单并支付页面接口 🔖
|
||||
* @param {AlipayTradePagePayInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AlipayApi
|
||||
*/
|
||||
public async apiAlipayAlipayTradePagePayPost(body?: AlipayTradePagePayInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(this.configuration).apiAlipayAlipayTradePagePayPost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 获取授权信息 🔖
|
||||
* @param {string} [userId] 用户Id
|
||||
* @param {string} [authCode] 授权码
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AlipayApi
|
||||
*/
|
||||
public async apiAlipayGetAuthInfoGet(userId?: string, authCode?: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return AlipayApiFp(this.configuration).apiAlipayGetAuthInfoGet(userId, authCode, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 支付回调 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof AlipayApi
|
||||
*/
|
||||
public async apiAlipayNotifyPost(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultString>> {
|
||||
return AlipayApiFp(this.configuration).apiAlipayNotifyPost(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
54
Web/src/api-services/models/alipay-pre-create-input.ts
Normal file
54
Web/src/api-services/models/alipay-pre-create-input.ts
Normal file
@ -0,0 +1,54 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface AlipayPreCreateInput
|
||||
*/
|
||||
export interface AlipayPreCreateInput {
|
||||
|
||||
/**
|
||||
* 商户订单号
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayPreCreateInput
|
||||
*/
|
||||
outTradeNo: string;
|
||||
|
||||
/**
|
||||
* 订单总金额
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayPreCreateInput
|
||||
*/
|
||||
totalAmount: string;
|
||||
|
||||
/**
|
||||
* 订单标题
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayPreCreateInput
|
||||
*/
|
||||
subject: string;
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayPreCreateInput
|
||||
*/
|
||||
timeoutExpress?: string | null;
|
||||
}
|
||||
97
Web/src/api-services/models/alipay-trade-page-pay-input.ts
Normal file
97
Web/src/api-services/models/alipay-trade-page-pay-input.ts
Normal file
@ -0,0 +1,97 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { ExtUserInfo } from './ext-user-info';
|
||||
import { ExtendParams } from './extend-params';
|
||||
import { InvoiceInfo } from './invoice-info';
|
||||
/**
|
||||
* 统一收单下单并支付页面接口输入参数
|
||||
*
|
||||
* @export
|
||||
* @interface AlipayTradePagePayInput
|
||||
*/
|
||||
export interface AlipayTradePagePayInput {
|
||||
|
||||
/**
|
||||
* 商户订单号
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
outTradeNo: string;
|
||||
|
||||
/**
|
||||
* 订单总金额
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
totalAmount: string;
|
||||
|
||||
/**
|
||||
* 订单标题
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
subject: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
body?: string | null;
|
||||
|
||||
/**
|
||||
* 超时时间
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
timeoutExpress?: string | null;
|
||||
|
||||
/**
|
||||
* 二维码宽度
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
qrcodeWidth: number;
|
||||
|
||||
/**
|
||||
* @type {ExtendParams}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
extendParams?: ExtendParams;
|
||||
|
||||
/**
|
||||
* 商户业务数据
|
||||
*
|
||||
* @type {{ [key: string]: any; }}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
businessParams?: { [key: string]: any; } | null;
|
||||
|
||||
/**
|
||||
* @type {InvoiceInfo}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
invoiceInfo?: InvoiceInfo;
|
||||
|
||||
/**
|
||||
* @type {ExtUserInfo}
|
||||
* @memberof AlipayTradePagePayInput
|
||||
*/
|
||||
extUserInfo?: ExtUserInfo;
|
||||
}
|
||||
70
Web/src/api-services/models/ext-user-info.ts
Normal file
70
Web/src/api-services/models/ext-user-info.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface ExtUserInfo
|
||||
*/
|
||||
export interface ExtUserInfo {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
certNo?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
certType?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
fixBuyer?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
identityHash?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
minAge?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
mobile?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
name?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtUserInfo
|
||||
*/
|
||||
needCheckInfo?: string | null;
|
||||
}
|
||||
82
Web/src/api-services/models/extend-params.ts
Normal file
82
Web/src/api-services/models/extend-params.ts
Normal file
@ -0,0 +1,82 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface ExtendParams
|
||||
*/
|
||||
export interface ExtendParams {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
cardType?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
creditExtInfo?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
hbFqNum?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
hbFqSellerPercent?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
industryRefluxInfo?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
royaltyFreeze?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
specifiedSellerName?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
sysServiceProviderId?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
tcInstallmentOrderId?: string | null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof ExtendParams
|
||||
*/
|
||||
tradeComponentOrderId?: string | null;
|
||||
}
|
||||
@ -128,6 +128,8 @@ export * from './admin-result-visual-db-table';
|
||||
export * from './admin-result-wechat-pay-output';
|
||||
export * from './admin-result-wx-open-id-output';
|
||||
export * from './admin-result-wx-phone-output';
|
||||
export * from './alipay-pre-create-input';
|
||||
export * from './alipay-trade-page-pay-input';
|
||||
export * from './aliyun-send-sms-template-input';
|
||||
export * from './amount';
|
||||
export * from './api-output';
|
||||
@ -212,6 +214,8 @@ export * from './event-attributes';
|
||||
export * from './event-info';
|
||||
export * from './export-proc-by-tmpinput';
|
||||
export * from './export-proc-input';
|
||||
export * from './ext-user-info';
|
||||
export * from './extend-params';
|
||||
export * from './field-attributes';
|
||||
export * from './field-info';
|
||||
export * from './filter';
|
||||
@ -238,6 +242,8 @@ export * from './idisposable';
|
||||
export * from './isite';
|
||||
export * from './info-save-input';
|
||||
export * from './int-ptr';
|
||||
export * from './invoice-info';
|
||||
export * from './invoice-key-info';
|
||||
export * from './jtoken';
|
||||
export * from './job-create-type-enum';
|
||||
export * from './job-detail-input';
|
||||
|
||||
35
Web/src/api-services/models/invoice-info.ts
Normal file
35
Web/src/api-services/models/invoice-info.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import { InvoiceKeyInfo } from './invoice-key-info';
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface InvoiceInfo
|
||||
*/
|
||||
export interface InvoiceInfo {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof InvoiceInfo
|
||||
*/
|
||||
details?: string | null;
|
||||
|
||||
/**
|
||||
* @type {InvoiceKeyInfo}
|
||||
* @memberof InvoiceInfo
|
||||
*/
|
||||
keyInfo?: InvoiceKeyInfo;
|
||||
}
|
||||
40
Web/src/api-services/models/invoice-key-info.ts
Normal file
40
Web/src/api-services/models/invoice-key-info.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface InvoiceKeyInfo
|
||||
*/
|
||||
export interface InvoiceKeyInfo {
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof InvoiceKeyInfo
|
||||
*/
|
||||
invoiceMerchantName?: string | null;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @memberof InvoiceKeyInfo
|
||||
*/
|
||||
isSupportInvoice?: boolean;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
* @memberof InvoiceKeyInfo
|
||||
*/
|
||||
taxNum?: string | null;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user