You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
8.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.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;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using GDZZ.Application.Service.WXPay.Dto;
namespace GDZZ.Application.Service.WXPay
{
[ApiDescriptionSettings("Application", Name = "WXPay", Order = 1)]
public class WXPayService: IWXPayService, IDynamicApiController, ITransient
{
public static readonly string TenPayKey = Config.SenparcWeixinSetting.TenPayV3_Key; //与微信小程序后台的AppId设置保持一致区分大小写。
private readonly SqlSugarRepository<BaseUser> Baseuser; // wx用户仓储
private readonly SqlSugarRepository<SysUser> _sysUserRep; // 用户表仓储
private readonly SqlSugarRepository<SysTenant> _sysTenantRep; //租户仓储
private readonly SqlSugarRepository<SeIF> self; //职业仓储
private readonly SqlSugarRepository<Balance> balance; //职业仓储
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<Balance> balance,
SqlSugarRepository<SeIF> Self,
SqlSugarRepository<MiniRecharge> rechargeRep,
SqlSugarRepository<MiniPayTake> payTakeRep,
WechatOAuth wechatOAuth,
IHttpContextAccessor _httpContextAccessor,
IEventPublisher eventPublisher)
{
this.balance = balance;
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>
/// <returns></returns>
[HttpGet]
[Route("Mini/v1/GetUserBalance")]
public async Task<BalanceOut> GetUserBalance()
{
var balan = await this.balance.SingleAsync(x => x.UserID == UserManager.UserId);
if (balan == null)
return null;
return new BalanceOut()
{
Amount= balan.Amount,
UserID= UserManager.UserId,
};
}
/// <summary>
///微信小程序支付
/// </summary>
/// <param name="productId">商品Id</param>
/// <returns></returns>
[HttpPost]
[Route("Mini/v1/wxpay")]
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.OrderId.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]
[Route("Mini/v1/NotifyUrl")]
public async Task<string> NotifyUrl()
{
try
{
Console.WriteLine("");
ResponseHandler resHandler = new ResponseHandler(_httpContextAccessor.HttpContext);
string returnCode = resHandler.GetParameter("return_code");
resHandler.SetKey(TenPayKey);
if (resHandler.IsTenpaySign() && returnCode.ToUpper() == "SUCCESS")
{
//attach
var paymentId =long.Parse(resHandler.GetParameter("attach"));
//业务处理
var paytake = await this.payTakeRep.Where(x => x.OrderId == paymentId).SingleAsync();
if (!paytake.IsEmpty())
{
paytake.PayStatus =(int)PayStatusEnum.Paying;
this.payTakeRep.Update(paytake);
}
var recharge = await this.rechargeRep.Where(x=>x.Id == paymentId).SingleAsync();
if(!recharge.IsEmpty())
{
recharge.Status = (int)RechargeEnum.Finish;
this.rechargeRep.Update(recharge);
var balan = await this.balance.Where(x => x.UserID == paytake.CreatedUserId).SingleAsync();
if (!balan.IsEmpty())
{
balan.Amount += recharge.PaymentMoney;
this.balance.Update(balan);
}
}
}
string xml = "<xml>"
+ "<return_code>SUCCESS</return_code>"
+ "<return_msg>OK</return_msg>"
+ "</xml>";
return xml;
}
catch (Exception ex)
{
string xml = "<xml>"
+ "<return_code>FAIL</return_code>"
+ "<return_msg>支付通知失败</return_msg>"
+ "</xml>";
return xml;
}
}
}
}