Merge pull request 'refactor: 😀重构支付宝支付模块' (#249) from jasondom/Admin.NET.Pro:v2 into v2
Reviewed-on: http://101.43.53.74:3000/Admin.NET/Admin.NET.Pro/pulls/249
This commit is contained in:
commit
a502e5c59a
@ -3,16 +3,33 @@
|
|||||||
|
|
||||||
// 支付宝支付配置,文档地址:https://openhome.alipay.com/develop/sandbox/app
|
// 支付宝支付配置,文档地址:https://openhome.alipay.com/develop/sandbox/app
|
||||||
"Alipay": {
|
"Alipay": {
|
||||||
"AppId": "9000000000000000", // 支付宝 APPID
|
|
||||||
"AlipayWebsocketUrl": "openchannel-sandbox.dl.alipaydev.com", // websocket服务地址
|
|
||||||
"ServerUrl": "https://openapi-sandbox.dl.alipaydev.com/gateway.do", // 支付宝网关地址
|
"ServerUrl": "https://openapi-sandbox.dl.alipaydev.com/gateway.do", // 支付宝网关地址
|
||||||
"AuthUrl": "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm", // 授权回调地址
|
"WebsocketUrl": "openchannel-sandbox.dl.alipaydev.com", // websocket服务地址
|
||||||
"NotifyUrl": "http://xxxx.xxx/api/Alipay/Notify", // 应用网关地址
|
//"AuthUrl": "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm", // 正式环境授权回调地址
|
||||||
"PrivateKey": "xxxxxxxxx", // 应用私钥
|
"AuthUrl": "https://openauth-sandbox.dl.alipaydev.com/oauth2/publicAppAuthorize.htm", // 沙箱环境授权回调地址
|
||||||
"SignType": "RSA2", // 加密算法
|
"AppAuthUrl": "http://xxxxxxxxxx", // 应用授权回调地址
|
||||||
"EncryptKey": "xxxxxxxx", // 从支付宝获取敏感信息时的加密密钥
|
"NotifyUrl": "http://xxxxxxxxx/api/sysAlipay/Notify", // 应用网关地址
|
||||||
"AlipayPublicCertPath": "/AlipayCrt/alipayPublicCert.crt", // 支付宝公钥证书存放路径
|
"RootCertPath": "Alipaycrt/alipayRootCert.crt", // 支付宝根证书存放路径
|
||||||
"RootCertPath": "/AlipayCrt/alipayRootCert.crt", // 支付宝根证书存放路径
|
"AccountList": [
|
||||||
"AppCertPath": "/AlipayCrt/appPublicCert.crt" // 应用公钥证书存放路径
|
{
|
||||||
|
"Name": "sandbox 默认应用",
|
||||||
|
"AppId": "xxxxxxxxxxxxxx",
|
||||||
|
"SignType": "RSA2",
|
||||||
|
"PrivateKey": "xxxxxxxxxxxxxxxxx",
|
||||||
|
"EncryptKey": "xxxxxxxxxxxxxxxxxxxx",
|
||||||
|
"AppCertPath": "Alipaycrt/appPublicCert.crt", // 应用公钥证书存放路径
|
||||||
|
"AlipayPublicCertPath": "Alipaycrt/alipayPublicCert.crt" // 支付宝公钥证书存放路径
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "sandbox 默认应用2",
|
||||||
|
"AppId": "xxxxxxxxxxxxxx",
|
||||||
|
"SignType": "RSA2",
|
||||||
|
"PrivateKey": "xxxxxxxxxxxxxxxxx",
|
||||||
|
"EncryptKey": "xxxxxxxxxxxxxxxxxxxx",
|
||||||
|
"AppCertPath": "Alipaycrt/appPublicCert.crt", // 应用公钥证书存放路径
|
||||||
|
"AlipayPublicCertPath": "Alipaycrt/alipayPublicCert.crt" // 支付宝公钥证书存放路径
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
149
Admin.NET/Admin.NET.Core/Entity/SysAlipayAuthInfo.cs
Normal file
149
Admin.NET/Admin.NET.Core/Entity/SysAlipayAuthInfo.cs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||||
|
//
|
||||||
|
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||||
|
//
|
||||||
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝授权记录表
|
||||||
|
/// </summary>
|
||||||
|
[SysTable]
|
||||||
|
[SugarTable(null, "支付宝授权记录表")]
|
||||||
|
[SugarIndex("index_{table}_U", nameof(UserId), OrderByType.Asc)]
|
||||||
|
[SugarIndex("index_{table}_T", nameof(OpenId), OrderByType.Asc)]
|
||||||
|
public class SysAlipayAuthInfo : EntityBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 商户AppId
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "商户AppId", Length = 64)]
|
||||||
|
public string? AppId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开放ID
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "开放ID", Length = 64)]
|
||||||
|
public string? OpenId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户ID
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户ID", Length = 64)]
|
||||||
|
public string? UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 性别
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "性别", Length = 8)]
|
||||||
|
public GenderEnum Gender { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 年龄
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "年龄", Length = 16)]
|
||||||
|
public int Age { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "手机号", Length = 32)]
|
||||||
|
public string Mobile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示名称
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "显示名称", Length = 128)]
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 昵称
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "昵称", Length = 64)]
|
||||||
|
public string NickName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户名", Length = 64)]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 头像
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "头像", Length = 512)]
|
||||||
|
public string? Avatar { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邮箱
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "邮箱", Length = 128)]
|
||||||
|
public string? Email { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户民族
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户民族", Length = 32)]
|
||||||
|
public string? UserNation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 淘宝ID
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "淘宝ID", Length = 64)]
|
||||||
|
public string? TaobaoId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 电话
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "电话", Length = 32)]
|
||||||
|
public string? Phone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生日
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "生日", Length = 32)]
|
||||||
|
public string? PersonBirthday { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职业
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "职业", Length = 64)]
|
||||||
|
public string? Profession { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 省份
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "省份", Length = 64)]
|
||||||
|
public string? Province { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户状态
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户状态", Length = 32)]
|
||||||
|
public string? UserStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 学历
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "学历", Length = 32)]
|
||||||
|
public string? Degree { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户类型
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户类型", Length = 32)]
|
||||||
|
public string? UserType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 邮编
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "邮编", Length = 16)]
|
||||||
|
public string? Zip { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地址
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "地址", Length = 256)]
|
||||||
|
public string? Address { get; set; }
|
||||||
|
}
|
||||||
108
Admin.NET/Admin.NET.Core/Entity/SysAlipayTransaction.cs
Normal file
108
Admin.NET/Admin.NET.Core/Entity/SysAlipayTransaction.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||||
|
//
|
||||||
|
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||||
|
//
|
||||||
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝交易记录表
|
||||||
|
/// </summary>
|
||||||
|
[SysTable]
|
||||||
|
[SugarTable(null, "支付宝交易记录表")]
|
||||||
|
[SugarIndex("index_{table}_U", nameof(UserId), OrderByType.Asc)]
|
||||||
|
[SugarIndex("index_{table}_T", nameof(TradeNo), OrderByType.Asc)]
|
||||||
|
[SugarIndex("index_{table}_O", nameof(OutTradeNo), OrderByType.Asc)]
|
||||||
|
public class SysAlipayTransaction : EntityBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户Id
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "用户Id", Length = 64)]
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易号", Length = 64)]
|
||||||
|
public string? TradeNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商户订单号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "商户订单号", Length = 64)]
|
||||||
|
public string OutTradeNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易金额
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易金额", Length = 20)]
|
||||||
|
public decimal TotalAmount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易状态
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易状态", Length = 32)]
|
||||||
|
public string TradeStatus { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易完成时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易完成时间")]
|
||||||
|
public DateTime? FinishTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易标题
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易标题", Length = 256)]
|
||||||
|
public string Subject { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易描述
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易描述", Length = 512)]
|
||||||
|
public string? Body { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 买家支付宝账号
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "买家支付宝账号", Length = 128)]
|
||||||
|
public string? BuyerLogonId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 买家支付宝用户ID
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "买家支付宝用户ID", Length = 32)]
|
||||||
|
public string? BuyerUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 卖家支付宝用户ID
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "卖家支付宝用户ID", Length = 32)]
|
||||||
|
public string? SellerUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商户AppId
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "商户AppId", Length = 64)]
|
||||||
|
public string? AppId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易扩展信息
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易扩展信息", Length = 1024)]
|
||||||
|
public string? ExtendInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易异常信息
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易扩展信息", Length = 1024)]
|
||||||
|
public string? ErrorInfo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易备注
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(ColumnDescription = "交易备注", Length = 512)]
|
||||||
|
public string? Remark { get; set; }
|
||||||
|
}
|
||||||
@ -4,6 +4,8 @@
|
|||||||
//
|
//
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
using Aop.Api;
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
namespace Admin.NET.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -12,57 +14,106 @@ namespace Admin.NET.Core;
|
|||||||
public sealed class AlipayOptions : IConfigurableOptions
|
public sealed class AlipayOptions : IConfigurableOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝 APPID(必填)
|
/// 支付宝网关地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AppId { get; set; }
|
public string ServerUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝 websocket 服务地址 (必填)
|
/// 支付宝授权回调地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AlipayWebsocketUrl { get; set; }
|
public string AuthUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝网关地址 (必填)
|
/// 应用授权回调地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ServerUrl { get; set; }
|
public string AppAuthUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝授权回调地址 (必填)
|
/// 支付宝 websocket 服务地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AuthUrl { get; set; }
|
public string WebsocketUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用回调地址
|
/// 应用回调地址
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string NotifyUrl { get; set; }
|
public string NotifyUrl { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 加密算法(必填)
|
/// 支付宝根证书存放路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SignType { get; set; }
|
public string RootCertPath { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝商户账号列表
|
||||||
|
/// </summary>
|
||||||
|
public List<AlipayMerchantAccount> AccountList { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取支付宝客户端
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="account"></param>
|
||||||
|
public DefaultAopClient GetClient(AlipayMerchantAccount account)
|
||||||
|
{
|
||||||
|
account = account ?? throw new Exception("未找到支付宝商户账号");
|
||||||
|
string path = App.WebHostEnvironment.ContentRootPath;
|
||||||
|
return new DefaultAopClient(new AlipayConfig
|
||||||
|
{
|
||||||
|
Format = "json",
|
||||||
|
Charset = "UTF-8",
|
||||||
|
ServerUrl = ServerUrl,
|
||||||
|
AppId = account.AppId,
|
||||||
|
SignType = account.SignType,
|
||||||
|
PrivateKey = account.PrivateKey,
|
||||||
|
EncryptKey = account.EncryptKey,
|
||||||
|
RootCertPath = Path.Combine(path, RootCertPath),
|
||||||
|
AppCertPath = Path.Combine(path, account.AppCertPath),
|
||||||
|
AlipayPublicCertPath = Path.Combine(path, account.AlipayPublicCertPath)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝商户账号信息
|
||||||
|
/// </summary>
|
||||||
|
public class AlipayMerchantAccount
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 配置Id
|
||||||
|
/// </summary>
|
||||||
|
public long Id { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商户名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商户AppId
|
||||||
|
/// </summary>
|
||||||
|
public string AppId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 应用私钥
|
||||||
|
/// </summary>
|
||||||
|
public string PrivateKey { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 从支付宝获取敏感信息时的加密密钥(可选)
|
/// 从支付宝获取敏感信息时的加密密钥(可选)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string EncryptKey { get; set; }
|
public string EncryptKey { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用私钥 (必填)
|
/// 加密算法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PrivateKey { get; set; }
|
public string SignType { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝公钥证书存放路径(证书加签方式必填)
|
/// 应用公钥证书路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AlipayPublicCertPath { get; set; }
|
public string AppCertPath { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 支付宝根证书存放路径(证书加签方式必填)
|
/// 支付宝公钥证书路径
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RootCertPath { get; set; }
|
public string AlipayPublicCertPath { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用公钥证书存放路径(证书加签方式必填)
|
|
||||||
/// </summary>
|
|
||||||
public string AppCertPath { get; set; }
|
|
||||||
}
|
}
|
||||||
@ -1,279 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
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 IEnumerable<IAlipayNotify> _alipayNotifyList;
|
|
||||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
|
||||||
private readonly SysConfigService _sysConfigService;
|
|
||||||
private readonly IHttpContextAccessor _httpContext;
|
|
||||||
private readonly AlipayOptions _alipayOptions;
|
|
||||||
private readonly IAopClient _alipayClient;
|
|
||||||
private readonly UserManager _userManager;
|
|
||||||
|
|
||||||
public AlipayService(
|
|
||||||
UserManager userManager,
|
|
||||||
IHttpContextAccessor httpContext,
|
|
||||||
SysConfigService sysConfigService,
|
|
||||||
IWebHostEnvironment webHostEnvironment,
|
|
||||||
IOptions<AlipayOptions> alipayOptions)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_httpContext = httpContext;
|
|
||||||
_sysConfigService = sysConfigService;
|
|
||||||
_alipayOptions = alipayOptions.Value;
|
|
||||||
_webHostEnvironment = webHostEnvironment;
|
|
||||||
_alipayNotifyList = App.GetServices<IAlipayNotify>();
|
|
||||||
|
|
||||||
// 初始化支付宝客户端
|
|
||||||
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 _alipayNotifyList)
|
|
||||||
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 = [];
|
|
||||||
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[..4]);
|
|
||||||
|
|
||||||
// 循环执行业务逻辑,若都未处理(回调全部返回false)则交易失败
|
|
||||||
var isError = true;
|
|
||||||
foreach (var notify in _alipayNotifyList)
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
BizScene = AlipayConst.BizScene,
|
|
||||||
ProductCode = AlipayConst.ProductCode,
|
|
||||||
|
|
||||||
// 设置商家侧唯一订单号
|
|
||||||
OutBizNo = input.OutBizNo,
|
|
||||||
|
|
||||||
// 设置订单总金额
|
|
||||||
TransAmount = input.TransAmount.ToString(),
|
|
||||||
|
|
||||||
// 设置转账业务的标题
|
|
||||||
OrderTitle = input.OrderTitle
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置收款方信息
|
|
||||||
Participant payeeInfo = new()
|
|
||||||
{
|
|
||||||
CertType = input.CertType.ToString(),
|
|
||||||
CertNo = input.CertNo,
|
|
||||||
Identity = input.Identity,
|
|
||||||
Name = input.Name,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,28 +4,37 @@
|
|||||||
//
|
//
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using Aop.Api.Domain;
|
using Aop.Api.Domain;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Admin.NET.Core.Service;
|
namespace Admin.NET.Core.Service;
|
||||||
|
|
||||||
public class AlipayFundTransUniTransferInput
|
public class AlipayFundTransUniTransferInput
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 商家侧唯一订单号
|
/// 用户ID
|
||||||
|
/// </summary>
|
||||||
|
public long UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商户AppId
|
||||||
|
/// </summary>
|
||||||
|
public string AppId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 商家订单号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "订单号不能为空")]
|
|
||||||
public string OutBizNo { get; set; }
|
public string OutBizNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转账金额
|
/// 转账金额
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "转账金额不能为空")]
|
public decimal TransAmount { get; set; }
|
||||||
public decimal? TransAmount { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转账业务标题
|
/// 业务标题
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "业务标题不能为空")]
|
|
||||||
public string OrderTitle { get; set; }
|
public string OrderTitle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -46,25 +55,21 @@ public class AlipayFundTransUniTransferInput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 收款方证件号码,条件必填
|
/// 收款方证件号码,条件必填
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CommonValidation($"{nameof(CertType)} != null && string.IsNullOrWhiteSpace({nameof(CertNo)})", "", ErrorMessage = "证件号码不能为空")]
|
|
||||||
public string CertNo { get; set; }
|
public string CertNo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 收款方身份标识
|
/// 收款方身份标识
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "身份标识不能为空")]
|
|
||||||
public string Identity { get; set; }
|
public string Identity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 收款方真实姓名
|
/// 收款方真实姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "真实姓名不能为空")]
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 收款方身份标识类型
|
/// 收款方身份标识类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Required(ErrorMessage = "身份标识类型不能为空")]
|
|
||||||
public AlipayIdentityTypeEnum? IdentityType { get; set; }
|
public AlipayIdentityTypeEnum? IdentityType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +164,17 @@ public class AlipayAuthInfoInput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户Id
|
/// 用户Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
|
[JsonProperty("user_id")]
|
||||||
|
[JsonPropertyName("user_id")]
|
||||||
|
[FromQuery(Name = "user_id")]
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 授权码
|
/// 授权码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonProperty("auth_code")]
|
||||||
|
[JsonPropertyName("auth_code")]
|
||||||
|
[FromQuery(Name = "auth_code")]
|
||||||
public string AuthCode { get; set; }
|
public string AuthCode { get; set; }
|
||||||
}
|
}
|
||||||
271
Admin.NET/Admin.NET.Core/Service/Alipay/SysAlipayService.cs
Normal file
271
Admin.NET/Admin.NET.Core/Service/Alipay/SysAlipayService.cs
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||||
|
//
|
||||||
|
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||||
|
//
|
||||||
|
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||||
|
|
||||||
|
using Aop.Api;
|
||||||
|
using Aop.Api.Domain;
|
||||||
|
using Aop.Api.Request;
|
||||||
|
using Aop.Api.Response;
|
||||||
|
using Aop.Api.Util;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using NewLife.Reflection;
|
||||||
|
|
||||||
|
namespace Admin.NET.Core.Service;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付宝支付服务 🧩
|
||||||
|
/// </summary>
|
||||||
|
[ApiDescriptionSettings(Order = 240)]
|
||||||
|
public class SysAlipayService : IDynamicApiController, ITransient
|
||||||
|
{
|
||||||
|
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||||
|
private readonly SysConfigService _sysConfigService;
|
||||||
|
private readonly List<IAopClient> _alipayClientList;
|
||||||
|
private readonly IHttpContextAccessor _httpContext;
|
||||||
|
private readonly AlipayOptions _option;
|
||||||
|
private readonly ISqlSugarClient _db;
|
||||||
|
|
||||||
|
public SysAlipayService(
|
||||||
|
ISqlSugarClient db,
|
||||||
|
IHttpContextAccessor httpContext,
|
||||||
|
SysConfigService sysConfigService,
|
||||||
|
IWebHostEnvironment webHostEnvironment,
|
||||||
|
IOptions<AlipayOptions> alipayOptions)
|
||||||
|
{
|
||||||
|
_db = db;
|
||||||
|
_httpContext = httpContext;
|
||||||
|
_sysConfigService = sysConfigService;
|
||||||
|
_option = alipayOptions.Value;
|
||||||
|
_webHostEnvironment = webHostEnvironment;
|
||||||
|
|
||||||
|
// 初始化支付宝客户端列表
|
||||||
|
_alipayClientList = [];
|
||||||
|
foreach (var account in _option.AccountList) _alipayClientList.Add(_option.GetClient(account));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取授权信息 🔖
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[NonUnify]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[DisplayName("获取授权信息")]
|
||||||
|
[ApiDescriptionSettings(Name = "AuthInfo"), HttpGet]
|
||||||
|
public ActionResult GetAuthInfo([FromQuery] AlipayAuthInfoInput input)
|
||||||
|
{
|
||||||
|
var type = input.UserId?.Split('-').FirstOrDefault().ToInt();
|
||||||
|
var userId = input.UserId?.Split('-').LastOrDefault().ToLong();
|
||||||
|
var account = _option.AccountList.FirstOrDefault();
|
||||||
|
var alipayClient = _alipayClientList.First();
|
||||||
|
|
||||||
|
// 当前网页接口地址
|
||||||
|
var currentUrl = $"{_option.AppAuthUrl}{_httpContext.HttpContext!.Request.Path}?userId={input.UserId}";
|
||||||
|
if (string.IsNullOrEmpty(input.AuthCode))
|
||||||
|
{
|
||||||
|
// 重新授权
|
||||||
|
var url = $"{_option.AuthUrl}?app_id={account!.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);
|
||||||
|
|
||||||
|
// 记录授权信息
|
||||||
|
var entity = _db.Queryable<SysAlipayAuthInfo>().First(u =>
|
||||||
|
(!string.IsNullOrWhiteSpace(u.UserId) && u.UserId == info.UserId) ||
|
||||||
|
(!string.IsNullOrWhiteSpace(u.OpenId) && u.OpenId == info.OpenId)) ?? new ();
|
||||||
|
entity.Copy(info, excludes: [nameof(SysAlipayAuthInfo.Gender), nameof(SysAlipayAuthInfo.Age)]);
|
||||||
|
entity.Age = int.Parse(info.Age);
|
||||||
|
entity.Gender = info.Gender switch
|
||||||
|
{
|
||||||
|
"m" => GenderEnum.Male,
|
||||||
|
"f" => GenderEnum.Female,
|
||||||
|
_ => GenderEnum.Unknown
|
||||||
|
};
|
||||||
|
entity.AppId = account!.AppId;
|
||||||
|
if (entity.Id <= 0) _db.Insertable(entity).ExecuteCommand();
|
||||||
|
else _db.Updateable(entity).ExecuteCommand();
|
||||||
|
|
||||||
|
// 执行完,重定向到指定界面
|
||||||
|
//var authPageUrl = _sysConfigService.GetConfigValueByCode<string>(ConfigConst.AlipayAuthPageUrl + type).Result;
|
||||||
|
//return new RedirectResult(authPageUrl);
|
||||||
|
return new RedirectResult(_option.AppAuthUrl + "/index.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付回调 🔖
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[AllowAnonymous]
|
||||||
|
[DisplayName("支付回调")]
|
||||||
|
[ApiDescriptionSettings(Name = "Notify"), HttpPost]
|
||||||
|
public string Notify()
|
||||||
|
{
|
||||||
|
SortedDictionary<string, string> sorted = [];
|
||||||
|
foreach (string key in _httpContext.HttpContext!.Request.Form.Keys)
|
||||||
|
sorted.Add(key, _httpContext.HttpContext.Request.Form[key]);
|
||||||
|
|
||||||
|
var account = _option.AccountList.FirstOrDefault();
|
||||||
|
string alipayPublicKey = Path.Combine(_webHostEnvironment.ContentRootPath, account!.AlipayPublicCertPath!.Replace('/', '\\').TrimStart('\\'));
|
||||||
|
bool signVerified = AlipaySignature.RSACertCheckV1(sorted, alipayPublicKey, "UTF-8", account.SignType); // 调用SDK验证签名
|
||||||
|
if (!signVerified) throw Oops.Oh("交易失败");
|
||||||
|
|
||||||
|
// 更新交易记录
|
||||||
|
var outTradeNo = sorted.GetValueOrDefault("out_trade_no");
|
||||||
|
var transaction = _db.Queryable<SysAlipayTransaction>().First(x => x.OutTradeNo == outTradeNo) ?? throw Oops.Oh("交易记录不存在");
|
||||||
|
transaction.TradeNo = sorted.GetValueOrDefault("trade_no");
|
||||||
|
transaction.TradeStatus = sorted.GetValueOrDefault("trade_status");
|
||||||
|
transaction.FinishTime = sorted.ContainsKey("gmt_payment") ? DateTime.Parse(sorted.GetValueOrDefault("gmt_payment")) : null;
|
||||||
|
transaction.BuyerLogonId = sorted.GetValueOrDefault("buyer_logon_id");
|
||||||
|
transaction.BuyerUserId = sorted.GetValueOrDefault("buyer_user_id");
|
||||||
|
transaction.SellerUserId = sorted.GetValueOrDefault("seller_id");
|
||||||
|
transaction.Remark = sorted.GetValueOrDefault("remark");
|
||||||
|
_db.Updateable(transaction).ExecuteCommand();
|
||||||
|
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 统一收单下单并支付页面接口 🔖
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[DisplayName("统一收单下单并支付页面接口")]
|
||||||
|
[ApiDescriptionSettings(Name = "AlipayTradePagePay"), HttpPost]
|
||||||
|
public string AlipayTradePagePay(AlipayTradePagePayInput input)
|
||||||
|
{
|
||||||
|
// 创建交易记录,状态为等待支付
|
||||||
|
var transactionRecord = new SysAlipayTransaction
|
||||||
|
{
|
||||||
|
AppId = _option.AccountList.First().AppId,
|
||||||
|
OutTradeNo = input.OutTradeNo,
|
||||||
|
TotalAmount = input.TotalAmount.ToDecimal(),
|
||||||
|
TradeStatus = "WAIT_PAY", // 等待支付
|
||||||
|
CreateTime = DateTime.Now,
|
||||||
|
Subject = input.Subject,
|
||||||
|
Body = input.Body,
|
||||||
|
Remark = "等待用户支付"
|
||||||
|
};
|
||||||
|
_db.Insertable(transactionRecord).ExecuteCommand();
|
||||||
|
|
||||||
|
// 设置支付页面请求,并组装业务参数model,设置异步通知接收地址
|
||||||
|
AlipayTradeWapPayRequest request = new();
|
||||||
|
request.SetBizModel(new AlipayTradeWapPayModel()
|
||||||
|
{
|
||||||
|
Subject = input.Subject,
|
||||||
|
OutTradeNo = input.OutTradeNo,
|
||||||
|
TotalAmount = input.TotalAmount,
|
||||||
|
Body = input.Body,
|
||||||
|
ProductCode = "QUICK_WAP_WAY",
|
||||||
|
TimeExpire = input.TimeoutExpress
|
||||||
|
});
|
||||||
|
request.SetNotifyUrl(_option.NotifyUrl);
|
||||||
|
|
||||||
|
var alipayClient = _alipayClientList.First();
|
||||||
|
var response = alipayClient.SdkExecute(request);
|
||||||
|
if (response.IsError) throw Oops.Oh(response.SubMsg);
|
||||||
|
return $"{_option.ServerUrl}?{response.Body}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 交易预创建 🔖
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[DisplayName("交易预创建")]
|
||||||
|
[ApiDescriptionSettings(Name = "AlipayPreCreate"), HttpPost]
|
||||||
|
public string AlipayPreCreate(AlipayPreCreateInput input)
|
||||||
|
{
|
||||||
|
// 创建交易记录,状态为等待支付
|
||||||
|
var transactionRecord = new SysAlipayTransaction
|
||||||
|
{
|
||||||
|
AppId = _option.AccountList.First().AppId,
|
||||||
|
OutTradeNo = input.OutTradeNo,
|
||||||
|
TotalAmount = input.TotalAmount.ToDecimal(),
|
||||||
|
TradeStatus = "WAIT_PAY", // 等待支付
|
||||||
|
CreateTime = DateTime.Now,
|
||||||
|
Subject = input.Subject,
|
||||||
|
Remark = "等待用户支付"
|
||||||
|
};
|
||||||
|
_db.Insertable(transactionRecord).ExecuteCommand();
|
||||||
|
|
||||||
|
// 设置异步通知接收地址,并组装业务参数model
|
||||||
|
AlipayTradePrecreateRequest request = new();
|
||||||
|
request.SetNotifyUrl(_option.NotifyUrl);
|
||||||
|
request.SetBizModel(new AlipayTradePrecreateModel()
|
||||||
|
{
|
||||||
|
Subject = input.Subject,
|
||||||
|
OutTradeNo = input.OutTradeNo,
|
||||||
|
TotalAmount = input.TotalAmount,
|
||||||
|
TimeoutExpress = input.TimeoutExpress
|
||||||
|
});
|
||||||
|
|
||||||
|
var alipayClient = _alipayClientList.First();
|
||||||
|
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 async Task<AlipayFundTransUniTransferResponse> Transfer(AlipayFundTransUniTransferInput input)
|
||||||
|
{
|
||||||
|
var account = _option.AccountList.FirstOrDefault(u => u.AppId == input.AppId) ?? throw Oops.Oh("未找到商户支付宝账号");
|
||||||
|
var alipayClient = _option.GetClient(account);
|
||||||
|
|
||||||
|
// 构造请求参数以调用接口
|
||||||
|
AlipayFundTransUniTransferRequest request = new();
|
||||||
|
AlipayFundTransUniTransferModel model = new()
|
||||||
|
{
|
||||||
|
BizScene = AlipayConst.BizScene,
|
||||||
|
ProductCode = AlipayConst.ProductCode,
|
||||||
|
OutBizNo = input.OutBizNo, // 商家订单
|
||||||
|
TransAmount = $"{input.TransAmount}:F2", // 订单总金额
|
||||||
|
OrderTitle = input.OrderTitle, // 业务标题
|
||||||
|
Remark = input.Remark, // 业务备注
|
||||||
|
PayeeInfo = new() // 收款方信息
|
||||||
|
{
|
||||||
|
CertType = input.CertType?.ToString(),
|
||||||
|
CertNo = input.CertNo,
|
||||||
|
Identity = input.Identity,
|
||||||
|
Name = input.Name,
|
||||||
|
IdentityType = input.IdentityType.ToString()
|
||||||
|
},
|
||||||
|
BusinessParams = input.PayerShowNameUseAlias ? "{\"payer_show_name_use_alias\":\"true\"}" : null
|
||||||
|
};
|
||||||
|
|
||||||
|
request.SetBizModel(model);
|
||||||
|
var response = alipayClient.CertificateExecute(request);
|
||||||
|
|
||||||
|
// 保存转账记录
|
||||||
|
await _db.Insertable(new SysAlipayTransaction
|
||||||
|
{
|
||||||
|
UserId = input.UserId,
|
||||||
|
AppId = input.AppId,
|
||||||
|
TradeNo = response.OrderId,
|
||||||
|
OutTradeNo = input.OutBizNo,
|
||||||
|
TotalAmount = response.Amount.ToDecimal(),
|
||||||
|
TradeStatus = response.Code == "10000" ? "SUCCESS" : "FAILED",
|
||||||
|
Subject = input.OrderTitle,
|
||||||
|
ErrorInfo = response.SubMsg,
|
||||||
|
Remark = input.Remark
|
||||||
|
}).ExecuteCommandAsync();
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/alipayPublicCert.crt
Normal file
38
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/alipayPublicCert.crt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDszCCApugAwIBAgIQICQSIl9wqwjbcsS1A/zPajANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE
|
||||||
|
BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv
|
||||||
|
biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1
|
||||||
|
dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMjQxMjIyMTE0NzAzWhcNMjUxMjIyMTE0NzAzWjCB
|
||||||
|
hDELMAkGA1UEBhMCQ04xHzAdBgNVBAoMFm10cXdudzEyODlAc2FuZGJveC5jb20xDzANBgNVBAsM
|
||||||
|
BkFsaXBheTFDMEEGA1UEAww65pSv5LuY5a6dKOS4reWbvSnnvZHnu5zmioDmnK/mnInpmZDlhazl
|
||||||
|
j7gtMjA4ODcyMTA1MzI1NzEzMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIPs9UeN
|
||||||
|
0Hhp0qFTXE51E/a2EQ7YmMI8dJdBLWP17Irzo1I1Zxw3BIsrxEsdPJSGr76oQlunEyWYNyiVsOaL
|
||||||
|
6KE8V1FK6uPSJr5BK5W9o3wKg3XX7BKdflyB4964uRNJOOPpqNi4vwY1ZZFVpSHrZJ0ZAthDHGYo
|
||||||
|
o3/zdEEIwEWRkVAtMC6pJa8K0qk3qyaqHRMzwO3r13Ex8q/7+kO1iOsQ5UFQwKeV/g6/NuyEW9BZ
|
||||||
|
6y59BehHQBqf51ZJcPa91Dc6va/C6McKe/OWd+km9EFwjab0L2GvwdRtrxUAikR0tghgvx3fAfJw
|
||||||
|
nkfdjTzYUi/umDuVJlyW6xg0p9cJwLcCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgTwMA0GCSqGSIb3
|
||||||
|
DQEBCwUAA4IBAQAoaQR/LYaBNMQ9pjEAHNaLdheebL6TbDNI8thKYAhMKFfeJ4ZNZPwqg2FnCfhf
|
||||||
|
eVJctLqJtxgzzl0vazVGeFJRwrMvJXkZsU9veRjLP1s4QUOO5NqjxkDNuQnFnQZBsySLWkM/+0f3
|
||||||
|
AcFImbXVUDuod/KnPZ6i2gbYNmaADAvYM8M87aqbvrfbLHBk6wtHR21l9MMu1BXyAlJn29k47xYj
|
||||||
|
XNRJo6292M4Y4fyGFxT7tC+kt+MA6WUTl4hB+PvuXJh26tUOEo6EcXAZekcDJNOLCioNTW9/ck4P
|
||||||
|
bj2Qxvouztndmd3zsT+flLiImEtGgRaClveKuUwrd9rzWLNkl2lw
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDszCCApugAwIBAgIQIBkIGbgVxq210KxLJ+YA/TANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UE
|
||||||
|
BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxJTAjBgNVBAsMHENlcnRpZmljYXRpb24gQXV0
|
||||||
|
aG9yaXR5IHRlc3QxNjA0BgNVBAMMLUFudCBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
|
||||||
|
dHkgUjEgdGVzdDAeFw0xOTA4MTkxMTE2MDBaFw0yNDA4MDExMTE2MDBaMIGRMQswCQYDVQQGEwJD
|
||||||
|
TjEbMBkGA1UECgwSQW50IEZpbmFuY2lhbCB0ZXN0MSUwIwYDVQQLDBxDZXJ0aWZpY2F0aW9uIEF1
|
||||||
|
dGhvcml0eSB0ZXN0MT4wPAYDVQQDDDVBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
|
||||||
|
aXR5IENsYXNzIDIgUjEgdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMh4FKYO
|
||||||
|
ZyRQHD6eFbPKZeSAnrfjfU7xmS9Yoozuu+iuqZlb6Z0SPLUqqTZAFZejOcmr07ln/pwZxluqplxC
|
||||||
|
5+B48End4nclDMlT5HPrDr3W0frs6Xsa2ZNcyil/iKNB5MbGll8LRAxntsKvZZj6vUTMb705gYgm
|
||||||
|
VUMILwi/ZxKTQqBtkT/kQQ5y6nOZsj7XI5rYdz6qqOROrpvS/d7iypdHOMIM9Iz9DlL1mrCykbBi
|
||||||
|
t25y+gTeXmuisHUwqaRpwtCGK4BayCqxRGbNipe6W73EK9lBrrzNtTr9NaysesT/v+l25JHCL9tG
|
||||||
|
wpNr1oWFzk4IHVOg0ORiQ6SUgxZUTYcCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgTwMA0GCSqGSIb3
|
||||||
|
DQEBCwUAA4IBAQBWThEoIaQoBX2YeRY/I8gu6TYnFXtyuCljANnXnM38ft+ikhE5mMNgKmJYLHvT
|
||||||
|
yWWWgwHoSAWEuml7EGbE/2AK2h3k0MdfiWLzdmpPCRG/RJHk6UB1pMHPilI+c0MVu16OPpKbg5Vf
|
||||||
|
LTv7dsAB40AzKsvyYw88/Ezi1osTXo6QQwda7uefvudirtb8FcQM9R66cJxl3kt1FXbpYwheIm/p
|
||||||
|
j1mq64swCoIYu4NrsUYtn6CV542DTQMI5QdXkn+PzUUly8F6kDp+KpMNd0avfWNL5+O++z+F5Szy
|
||||||
|
1CPta1D7EQ/eYmMP+mOQ35oifWIoFCpN6qQVBS/Hob1J/UUyg7BW
|
||||||
|
-----END CERTIFICATE-----
|
||||||
88
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/alipayRootCert.crt
Normal file
88
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/alipayRootCert.crt
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG
|
||||||
|
EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw
|
||||||
|
MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO
|
||||||
|
UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE
|
||||||
|
MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT
|
||||||
|
V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti
|
||||||
|
W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ
|
||||||
|
MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b
|
||||||
|
53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI
|
||||||
|
pDoiVhsLwg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE
|
||||||
|
BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj
|
||||||
|
YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj
|
||||||
|
YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0
|
||||||
|
MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV
|
||||||
|
BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j
|
||||||
|
aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF
|
||||||
|
AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk
|
||||||
|
rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2
|
||||||
|
xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp
|
||||||
|
dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6
|
||||||
|
vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl
|
||||||
|
YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1
|
||||||
|
Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H
|
||||||
|
DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98
|
||||||
|
SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG
|
||||||
|
PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe
|
||||||
|
9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC
|
||||||
|
AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90
|
||||||
|
tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy
|
||||||
|
nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf
|
||||||
|
tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq
|
||||||
|
JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3
|
||||||
|
IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW
|
||||||
|
05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41
|
||||||
|
T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI
|
||||||
|
kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop
|
||||||
|
PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N
|
||||||
|
1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y
|
||||||
|
jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02
|
||||||
|
77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi
|
||||||
|
kT9qhqn+lw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG
|
||||||
|
EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh
|
||||||
|
dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh
|
||||||
|
dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0
|
||||||
|
WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE
|
||||||
|
CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp
|
||||||
|
YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||||
|
IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU
|
||||||
|
WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt
|
||||||
|
rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ
|
||||||
|
4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2
|
||||||
|
zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg
|
||||||
|
wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH
|
||||||
|
Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF
|
||||||
|
BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM
|
||||||
|
E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg
|
||||||
|
MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq
|
||||||
|
MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp
|
||||||
|
bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv
|
||||||
|
b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV
|
||||||
|
nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5
|
||||||
|
4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg
|
||||||
|
wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw
|
||||||
|
WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN
|
||||||
|
z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g
|
||||||
|
KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA
|
||||||
|
uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF
|
||||||
|
MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp
|
||||||
|
emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3
|
||||||
|
U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I
|
||||||
|
UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn
|
||||||
|
DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU
|
||||||
|
1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX
|
||||||
|
Yf4Zr0fJsGuv
|
||||||
|
-----END CERTIFICATE-----
|
||||||
19
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/appPublicCert.crt
Normal file
19
Admin.NET/Admin.NET.Web.Entry/Alipaycrt/appPublicCert.crt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDmTCCAoGgAwIBAgIQICQSIV6QZN2y3Knbwe6r9TANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE
|
||||||
|
BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv
|
||||||
|
biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1
|
||||||
|
dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMjQxMjIxMTEzOTMzWhcNMjUxMjI2MTEzOTMzWjBr
|
||||||
|
MQswCQYDVQQGEwJDTjEfMB0GA1UECgwWbXRxd253MTI4OUBzYW5kYm94LmNvbTEPMA0GA1UECwwG
|
||||||
|
QWxpcGF5MSowKAYDVQQDDCEyMDg4NzIxMDUzMjU3MTMyLTkwMjEwMDAxNDI2ODYzOTUwggEiMA0G
|
||||||
|
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCxJhoamnjWZGQp+1kHXTyQgA2va0rTQv8ZvFggERZv
|
||||||
|
fOg2i5RYTBFLB0J1l3hj+23iBqzRTgzPxCLUTZUrj6WgwdDbXi11eE2wltVwmDHI1r3YdLC6KCQN
|
||||||
|
Jpv6SKSHs9JV6UDpzsHaJbsoi6NymYpkbFClLCh3MOcyha9Ju4B9n5mKze1GEDTNcAs1nGfSsH1E
|
||||||
|
wAWoe65iVM8pbTXTzjbEW/jJc2xbFT9RPRTihflkEf6p3kOpaPtgFmcUqdJ4BsldL6iWqbdR5JhT
|
||||||
|
mVKT8hDmsbW9KpPnCXWedxBZHmNiuOOCOeDhHGV3zFrZvIPJa7umAL+eweg0egN5RHP9tDAnAgMB
|
||||||
|
AAGjEjAQMA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQsFAAOCAQEANPJelQG99aAZb+KXUE3Z
|
||||||
|
ES+ZjPD9WwCBWpfcjyDq6duEQc9Qo0B2vW6EunbOi2qhS0dJ3pgJFaRrbi72BqQavT1eVYHcfXeC
|
||||||
|
y8I3dI7oxn5BS944oiGTzaYTx6dJ8lXDmlQO8ULz+6/wBCkhr6TgKbjIOh7p3/B9NPcfL5z6OrbQ
|
||||||
|
fXRk439uRfjWlzohE9q4cAY5AYnHLZCgbHwRX+YusDmJCu+LS9hioNHjwJ9t/jXsjzEQ09sfzEHF
|
||||||
|
uPGKS4JGmzwqGp2Ly68MCzp7WOgEFBexYUio4suzKlZUcv1+HDi6fEosZ6Fr7Z3CEMwKelq8m2l7
|
||||||
|
jg83G0PECp5unR1Hcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
Loading…
Reference in New Issue
Block a user