|
|
|
@ -1,18 +1,197 @@
|
|
|
|
|
using GDZZ.Core.Service;
|
|
|
|
|
using GDZZ.Application.Entity;
|
|
|
|
|
using GDZZ.Core.Entity;
|
|
|
|
|
using GDZZ.Core;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using Senparc.Weixin;
|
|
|
|
|
using Senparc.Weixin.Exceptions;
|
|
|
|
|
using Senparc.Weixin.Helpers;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Furion.EventBus;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Senparc.CO2NET.Extensions;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Senparc.Weixin.TenPay.V3;
|
|
|
|
|
using Senparc.Weixin.TenPay;
|
|
|
|
|
|
|
|
|
|
namespace GDZZ.Application.Service.WXPay
|
|
|
|
|
{
|
|
|
|
|
public class WXPayService
|
|
|
|
|
public class WXPayService:IWXPayService
|
|
|
|
|
{
|
|
|
|
|
private readonly IAuthService _authService;
|
|
|
|
|
private readonly SqlSugarRepository<BaseUser> Baseuser; // wx用户仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
|
|
|
|
|
private readonly SqlSugarRepository<SysTenant> _sysTenantRep; //租户仓储
|
|
|
|
|
private readonly SqlSugarRepository<SeIF> Self; //职业仓储
|
|
|
|
|
|
|
|
|
|
private readonly SqlSugarRepository<MiniRecharge> rechargeRep; //充值仓储
|
|
|
|
|
private readonly SqlSugarRepository<MiniPayTake> payTakeRep; //支付仓储
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private readonly WechatOAuth _wechatOAuth; //微信权限服务
|
|
|
|
|
private readonly IEventPublisher _eventPublisher; //事件写入服务
|
|
|
|
|
private readonly IHttpContextAccessor _httpContextAccessor; //http服务
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static TenPayV3Info _tenPayV3Info;
|
|
|
|
|
public static TenPayV3Info TenPayV3Info
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (_tenPayV3Info == null)
|
|
|
|
|
{
|
|
|
|
|
var key = TenPayHelper.GetRegisterKey(Config.SenparcWeixinSetting);
|
|
|
|
|
|
|
|
|
|
_tenPayV3Info =
|
|
|
|
|
TenPayV3InfoCollection.Data[key];
|
|
|
|
|
}
|
|
|
|
|
return _tenPayV3Info;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取配置文件
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly ThirdParty _oauthConfig;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public WXPayService(
|
|
|
|
|
IOptions<OAuthOptions> options,
|
|
|
|
|
SqlSugarRepository<BaseUser> Baseuser,
|
|
|
|
|
SqlSugarRepository<SysTenant> sysTenantRep,
|
|
|
|
|
SqlSugarRepository<SysUser> sysUserRep,
|
|
|
|
|
SqlSugarRepository<SeIF> Self,
|
|
|
|
|
SqlSugarRepository<MiniRecharge> rechargeRep,
|
|
|
|
|
SqlSugarRepository<MiniPayTake> payTakeRep,
|
|
|
|
|
WechatOAuth wechatOAuth,
|
|
|
|
|
IHttpContextAccessor _httpContextAccessor,
|
|
|
|
|
IEventPublisher eventPublisher)
|
|
|
|
|
{
|
|
|
|
|
this.Baseuser= Baseuser;
|
|
|
|
|
this._sysUserRep= sysUserRep;
|
|
|
|
|
this._sysTenantRep= sysTenantRep;
|
|
|
|
|
this.Self= Self;
|
|
|
|
|
this.rechargeRep = rechargeRep;
|
|
|
|
|
this.payTakeRep= payTakeRep;
|
|
|
|
|
this._wechatOAuth= wechatOAuth;
|
|
|
|
|
this._oauthConfig =options.Value.Wechat;
|
|
|
|
|
this._httpContextAccessor = _httpContextAccessor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///微信小程序支付
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="productId">商品Id</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[Route("api/v1/wxpay/{productId}")]
|
|
|
|
|
public async Task<dynamic> WxPay(AuthUserInput authUserInput)
|
|
|
|
|
{
|
|
|
|
|
var recharge = await this.rechargeRep.InsertReturnEntityAsync(new MiniRecharge()
|
|
|
|
|
{
|
|
|
|
|
PaymentMoney = authUserInput.Money / authUserInput.Discount,
|
|
|
|
|
Status = (int)RechargeEnum.NoFinis,
|
|
|
|
|
TotalPrice = authUserInput.Money
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
var payTake = await this.payTakeRep.InsertReturnEntityAsync(new MiniPayTake()
|
|
|
|
|
{
|
|
|
|
|
PaymentMoney = authUserInput.Money / authUserInput.Discount,
|
|
|
|
|
OrderId = recharge.Id,
|
|
|
|
|
PaySn = "",
|
|
|
|
|
PayStatus = (int)PayStatusEnum.NotPaying
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//序列号
|
|
|
|
|
string sp_billno =
|
|
|
|
|
$"{Config.SenparcWeixinSetting.TenPayV3_MchId}{SystemTime.Now:yyyyMMddHHmmss}{TenPayV3Util.BuildRandomStr(6)}";
|
|
|
|
|
string timeStamp = TenPayV3Util.GetTimestamp();
|
|
|
|
|
string nonceStr = TenPayV3Util.GetNoncestr();
|
|
|
|
|
|
|
|
|
|
TenPayV3UnifiedorderRequestData xmlDataInfo = new TenPayV3UnifiedorderRequestData(this._oauthConfig.app_id,
|
|
|
|
|
Config.SenparcWeixinSetting.TenPayV3_MchId, "充值金额", sp_billno,
|
|
|
|
|
(int)authUserInput.Money * 100,
|
|
|
|
|
"127.0.0.1",
|
|
|
|
|
Config.SenparcWeixinSetting.TenPayV3_WxOpenTenpayNotify, TenPayV3Type.JSAPI, authUserInput.OpenID.ToString(),
|
|
|
|
|
Config.SenparcWeixinSetting.TenPayV3_Key, nonceStr, null, null, null, null, payTake.Id.ToString());
|
|
|
|
|
UnifiedorderResult result = await TenPayV3.UnifiedorderAsync(xmlDataInfo); //调用统一订单接口
|
|
|
|
|
string packageStr = "prepay_id=" + result.prepay_id;
|
|
|
|
|
|
|
|
|
|
return new
|
|
|
|
|
{
|
|
|
|
|
success = true,
|
|
|
|
|
result.prepay_id,
|
|
|
|
|
appId = Config.SenparcWeixinSetting.WxOpenAppId,
|
|
|
|
|
timeStamp,
|
|
|
|
|
nonceStr,
|
|
|
|
|
package = packageStr,
|
|
|
|
|
signType = "MD5",
|
|
|
|
|
paySign = TenPayV3.GetJsPaySign(Config.SenparcWeixinSetting.WxOpenAppId, timeStamp, nonceStr,
|
|
|
|
|
packageStr, Config.SenparcWeixinSetting.TenPayV3_Key)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 微信小程序支付回调
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
[Route("v1/wxpay/NotifyUrl")]
|
|
|
|
|
|
|
|
|
|
public async Task<string> NotifyUrl()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError("NotifyUrl");
|
|
|
|
|
ResponseHandler resHandler = new ResponseHandler(_httpContextAccessor.HttpContext);
|
|
|
|
|
string returnCode = resHandler.GetParameter("return_code");
|
|
|
|
|
resHandler.SetKey(TenPayKey);
|
|
|
|
|
if (resHandler.IsTenpaySign() && returnCode.ToUpper() == "SUCCESS")
|
|
|
|
|
{
|
|
|
|
|
//attach
|
|
|
|
|
string paymentId = resHandler.GetParameter("attach");
|
|
|
|
|
//业务处理
|
|
|
|
|
PaymentRecordEntity paymentRecord = await _paymentRecordRepository.GetAsync(paymentId.ToLong());
|
|
|
|
|
if (paymentRecord.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
paymentRecord.PayStatus = (int)PayStatusEnum.Paying;
|
|
|
|
|
await _paymentRecordRepository.UpdateAsync(paymentRecord);
|
|
|
|
|
//order
|
|
|
|
|
OrderEntity order = await _orderRepository.GetAsync(paymentRecord.OrderId);
|
|
|
|
|
if (order.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
order.OrderStatus = (int)OrderStatusEnum.Paying;
|
|
|
|
|
await _orderRepository.UpdateAsync(order);
|
|
|
|
|
//积分操作
|
|
|
|
|
OrderDetailEntity orderDetail = await _orderDetailRepository.Select.Where(x => x.OrderId == order.Id)
|
|
|
|
|
.ToOneAsync();
|
|
|
|
|
//ProductInfoEntity productInfo = await _productInfoRepository.GetAsync(orderDetail.ProductId);
|
|
|
|
|
RechargeIntroEntity entity = await _rechargeIntroRepository.GetAsync(orderDetail.ProductId);
|
|
|
|
|
await _currencyService.AddCurrencyByCharge(order.UserId, order.Id,
|
|
|
|
|
entity.AllValue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string xml = "<xml>"
|
|
|
|
|
+ "<return_code>SUCCESS</return_code>"
|
|
|
|
|
+ "<return_msg>OK</return_msg>"
|
|
|
|
|
+ "</xml>";
|
|
|
|
|
return xml;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, ex.Message);
|
|
|
|
|
|
|
|
|
|
string xml = "<xml>"
|
|
|
|
|
+ "<return_code>FAIL</return_code>"
|
|
|
|
|
+ "<return_msg>支付通知失败</return_msg>"
|
|
|
|
|
+ "</xml>";
|
|
|
|
|
return xml;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|