195 lines
7.7 KiB
C#
195 lines
7.7 KiB
C#
using Hncore.Infrastructure.Common;
|
||
using Hncore.Infrastructure.Extension;
|
||
using Hncore.Infrastructure.Serializer;
|
||
using Hncore.Infrastructure.WebApi;
|
||
using Hncore.Pass.PaymentCenter.Domain;
|
||
using Hncore.Pass.PaymentCenter.Pay.WxPay;
|
||
using Hncore.Pass.PaymentCenter.Request.WechatJsPay;
|
||
using Hncore.Pass.PaymentCenter.Service;
|
||
using Hncore.Pass.PaymentCenter.WxPay.WechatJsPay;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Configuration;
|
||
using System.Threading.Tasks;
|
||
using Aliyun.Acs.Core;
|
||
using Aliyun.Acs.Core.Exceptions;
|
||
using Aliyun.Acs.Core.Http;
|
||
using Aliyun.Acs.Core.Profile;
|
||
using Alipay.AopSdk.Core.Domain;
|
||
using Alipay.AopSdk.Core.Request;
|
||
using Alipay.AopSdk.Core;
|
||
using System.Collections.Generic;
|
||
using Alipay.AopSdk.Core.Util;
|
||
using System;
|
||
using Microsoft.AspNetCore.Http;
|
||
|
||
namespace Hncore.Pass.PaymentCenter.Controllers
|
||
{
|
||
/// <summary>
|
||
/// 微信小程序、公众号支付
|
||
/// </summary>
|
||
[ApiVersion("1.0")]
|
||
[Route("api/paymentcenter/v{version:apiVersion}/AliPay/[action]")]
|
||
public class AliPayController : PaymentControllerBase
|
||
{
|
||
private PaymentRecordService m_PaymentRecordService;
|
||
private WxPayClient m_WxPayClient;
|
||
DefaultAopClient _aopClient;
|
||
public AliPayController(PaymentRecordService paymentRecordService
|
||
, WxPayClient _WxPayClient, TenantService _TenantService, IConfiguration _Configuration):base(_TenantService, _Configuration)
|
||
{
|
||
m_PaymentRecordService = paymentRecordService;
|
||
m_WxPayClient = _WxPayClient;
|
||
}
|
||
[HttpPost, InternalApiAuth]
|
||
public async Task<ApiResult> CreateOrder([FromBody] CreateOrderRequest request)
|
||
{
|
||
|
||
LogHelper.Trace($"微信支付,收到支付请求", request.ToJson(true));
|
||
request.AppId = "wx18683d61ce7da361";
|
||
//增加支付记录
|
||
var entity = request.MapTo<PaymentRecord>();
|
||
entity.Openid = request.UserOpenId;
|
||
PaymentRecord paymentRecord = await m_PaymentRecordService.CreatePaymentRecord(entity);
|
||
paymentRecord.PaymentChannel = PaymentChannel.WxPay;
|
||
//todo
|
||
var mchInfo = await GetMchInfoAsync(paymentRecord.TenantId
|
||
, paymentRecord.StoreId
|
||
, paymentRecord.PaymentChannel);
|
||
|
||
//发起支付
|
||
|
||
var APP_ID = "";
|
||
var APP_PRIVATE_KEY = "";
|
||
var CHARSET = "";
|
||
var ALIPAY_PUBLIC_KEY = "";
|
||
|
||
// 组装业务参数model
|
||
AlipayTradePagePayModel model = new AlipayTradePagePayModel
|
||
{
|
||
Body = request.Body,
|
||
Subject = request.Body,
|
||
TotalAmount =request.TotalFee.ToString(),
|
||
OutTradeNo = request.OrderId,
|
||
ProductCode = "FAST_INSTANT_TRADE_PAY"//QUICK_WAP_PAY
|
||
};
|
||
|
||
AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();
|
||
// 设置同步回调地址
|
||
aliRequest.SetReturnUrl($"http://{Request.Host}/Pay/Callback");
|
||
// 设置异步通知接收地址
|
||
aliRequest.SetNotifyUrl("");
|
||
// 将业务model载入到request
|
||
aliRequest.SetBizModel(model);
|
||
|
||
var _aopClient = new DefaultAopClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY);
|
||
|
||
var response = _aopClient.PageExecute(aliRequest);
|
||
|
||
return Success();
|
||
}
|
||
|
||
#region 支付异步回调通知
|
||
|
||
/// <summary>
|
||
/// 支付异步回调通知 需配置域名 因为是支付宝主动post请求这个action 所以要通过域名访问或者公网ip
|
||
/// </summary>
|
||
public async void Notify()
|
||
{
|
||
/* 实际验证过程建议商户添加以下校验。
|
||
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
|
||
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
|
||
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
|
||
4、验证app_id是否为该商户本身。
|
||
*/
|
||
Dictionary<string, string> sArray = GetRequestPost();
|
||
if (sArray.Count != 0)
|
||
{
|
||
// bool flag = AlipaySignature.RSACheckV1(sArray, Options.AlipayPublicKey, Options.CharSet, Options.SignType, false);
|
||
bool flag = AlipaySignature.RSACheckV1(sArray, "", "", "", false);
|
||
if (flag)
|
||
{
|
||
//交易状态
|
||
//判断该笔订单是否在商户网站中已经做过处理
|
||
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
|
||
//请务必判断请求时的total_amount与通知时获取的total_fee为一致的
|
||
//如果有做过处理,不执行商户的业务程序
|
||
|
||
//注意:
|
||
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
|
||
Console.WriteLine(Request.Form["trade_status"]);
|
||
|
||
await Response.WriteAsync("success");
|
||
}
|
||
else
|
||
{
|
||
await Response.WriteAsync("fail");
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 支付同步回调
|
||
|
||
/// <summary>
|
||
/// 支付同步回调
|
||
/// </summary>
|
||
[HttpGet]
|
||
public IActionResult Callback()
|
||
{
|
||
/* 实际验证过程建议商户添加以下校验。
|
||
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
|
||
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
|
||
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
|
||
4、验证app_id是否为该商户本身。
|
||
*/
|
||
Dictionary<string, string> sArray = GetRequestGet();
|
||
if (sArray.Count != 0)
|
||
{
|
||
bool flag = AlipaySignature.RSACheckV1(sArray, "", "", "", false);
|
||
if (flag)
|
||
{
|
||
Console.WriteLine($"同步验证通过,订单号:{sArray["out_trade_no"]}");
|
||
// ViewData["PayResult"] = "同步验证通过";
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine($"同步验证失败,订单号:{sArray["out_trade_no"]}");
|
||
// ViewData["PayResult"] = "同步验证失败";
|
||
}
|
||
}
|
||
return Content("");
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
private Dictionary<string, string> GetRequestGet()
|
||
{
|
||
Dictionary<string, string> sArray = new Dictionary<string, string>();
|
||
|
||
ICollection<string> requestItem = Request.Query.Keys;
|
||
foreach (var item in requestItem)
|
||
{
|
||
sArray.Add(item, Request.Query[item]);
|
||
|
||
}
|
||
return sArray;
|
||
|
||
}
|
||
private Dictionary<string, string> GetRequestPost()
|
||
{
|
||
Dictionary<string, string> sArray = new Dictionary<string, string>();
|
||
|
||
ICollection<string> requestItem = Request.Form.Keys;
|
||
foreach (var item in requestItem)
|
||
{
|
||
sArray.Add(item, Request.Form[item]);
|
||
|
||
}
|
||
return sArray;
|
||
|
||
}
|
||
|
||
}
|
||
} |