shop_template_api/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs
2023-10-25 17:11:58 +08:00

692 lines
26 KiB
C#

using Infrastructure.Attribute;
using System.Threading.Tasks;
using ARW.Repository.Business.ShopManager.Shops;
using ARW.Repository.Business.GoodsManager.GoodsCategorys;
using ARW.Repository.Business.Custom.Customers;
using ARW.Model.Models.Business.Payments;
using Infrastructure;
using static Infrastructure.WeChat.TenPay.Pay;
using Infrastructure.WeChat.TenPay;
using Senparc.CO2NET.HttpUtility;
using ARW.Service.Api.IBusinessService.PayManage;
using ARW.Repository.Business.Payments;
using ARW.Repository.Business.OrderManage.Orders;
using ARW.Repository.Business.Marketing.CouponManage.Coupons;
using ARW.Model.Dto.Api.Pay;
using ARW.Repository.Business.Carts;
using ARW.Repository.Business.GoodsManager.Goodss;
using ARW.Repository.Business.GoodsManager.GoodsSpecs.GoodsSkus;
using ARW.Service.Api.IBusinessService.GoodsManager.Goodss;
using ARW.Model.Dto.Api.GoodsManager.Goodss;
using ARW.Model.Models.Business.OrderManage.OrderGoodss;
using ARW.Repository.Business.OrderManage.OrderGoodss;
using ARW.Repository.Business.OrderManage.OrderCustomerAddreses;
using ARW.Repository.Business.Custom.CustomerAddresses;
using ARW.Model.Models.Business.OrderManage.OrderCustomerAddreses;
using Senparc.Weixin.TenPayV3.Apis.BasePay;
using System;
using System.Collections.Generic;
using ARW.Common;
using ARW.Model.Models.Business.Carts;
using ARW.Repository.Business.Marketing.CouponManage.CustomerCoupons;
using ARW.Model.Models.Business.Marketing.CouponManage.CustomerCoupons;
using ARW.Model.Vo.Business.Marketing.CouponManage.CustomerCoupons;
using System.Linq;
using ARW.Model.Vo.Api.OrderManage.Orders;
using ARW.Model.Models.Business.OrderTasks;
using ARW.Model.Vo.Business.OrderManage.OrderCustomerAddreses;
using ARW.Repository.Business.OrderTasks;
namespace ARW.Service.Api.BusinessService.PaymentManage
{
/// <summary>
/// 支付业务实现类Api
///
/// @author lwh
/// @date 2023-06-12
/// </summary>
[AppService(ServiceType = typeof(IPayServiceApi), ServiceLifetime = LifeTime.Transient)]
public class PayServiceApi : BaseService<Payment>, IPayServiceApi
{
private readonly SenparcHttpClient _httpClient;
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IGoodsServiceApi _GoodsServiceApi;
private readonly ShopRepository _ShopRepository;
private readonly GoodsRepository _GoodsRepository;
private readonly GoodsCategoryRepository _GoodsCategoryRepository;
private readonly CustomerRepository _CustomerRepository;
private readonly OrderRepository _OrderRepository;
private readonly PaymentRepository _PaymentRepository;
private readonly CouponRepository _CouponRepository;
private readonly CartRepository _CartRepository;
private readonly GoodsSkuRepository _GoodsSkuRepository;
private readonly OrderGoodsRepository _OrderGoodsRepository;
private readonly OrderCustomerAddressRepository _OrderCustomerAddressRepository;
private readonly CustomerAddressRepository _CustomerAddressRepository;
private readonly CustomerCouponRepository _CustomerCouponRepository;
private readonly OrderTaskRepository _OrderTaskRepository;
public PayServiceApi(ShopRepository ShopRepository, GoodsCategoryRepository goodsCategoryRepository, CustomerRepository customerRepository, OrderRepository orderRepository, PaymentRepository paymentRepository, CouponRepository couponRepository, SenparcHttpClient httpClient, GoodsRepository goodsRepository, GoodsSkuRepository goodsSkuRepository, IGoodsServiceApi goodsServiceApi, CartRepository cartRepository, OrderGoodsRepository orderGoodsRepository, OrderCustomerAddressRepository orderCustomerAddressRepository, CustomerAddressRepository customerAddressRepository, CustomerCouponRepository customerCouponRepository, OrderTaskRepository orderTaskRepository)
{
this._ShopRepository = ShopRepository;
_GoodsCategoryRepository = goodsCategoryRepository;
_CustomerRepository = customerRepository;
_OrderRepository = orderRepository;
_PaymentRepository = paymentRepository;
_CouponRepository = couponRepository;
_httpClient = httpClient;
_GoodsRepository = goodsRepository;
_GoodsSkuRepository = goodsSkuRepository;
_GoodsServiceApi = goodsServiceApi;
_CartRepository = cartRepository;
_OrderGoodsRepository = orderGoodsRepository;
_OrderCustomerAddressRepository = orderCustomerAddressRepository;
_CustomerAddressRepository = customerAddressRepository;
_CustomerCouponRepository = customerCouponRepository;
_OrderTaskRepository = orderTaskRepository;
}
#region Api接口代码
/// <summary>
/// 统一下单的业务处理
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
public async Task<PayParams> HandelPrePay(CommitPayDtoApi parm)
{
/* 计算核销前价格(商品总额) */
var goodsPrice = await CalculateBeforePrice(parm);
/* 计算运费 */
GoodsFreightDto goodsFreightDto = new()
{
GoodsRequestList = parm.GoodsRequestList,
CustomerAddressGuid = parm.CustomerAddressGuid,
};
var freight = await _GoodsServiceApi.GetGoodsFreight(goodsFreightDto);
var totalPrice = goodsPrice + freight;
/* 计算核销前后价格(优惠后价格) */
var afterPriceRes = await CalculateAfterPrice(parm, totalPrice);
if (parm.TotalAmount != afterPriceRes.DiscountPrice) throw new CustomException("前端传递金额不合法!下单失败!");
parm.TotalAmount = afterPriceRes.DiscountPrice;
// 获取金额
var price = 1;//单位:分
//int price = (int)(afterPriceRes.DiscountPrice * 100);//单位:分
// 生成订单号
var orderNo = Common.Common.CreateNoQuery();
// 调用统一下单(接口)
Pay pay = new Pay(_httpClient);
var payEntity = await pay.PrePay(parm.OpenId, orderNo, parm.PayType, price);
if (payEntity == null)
{
throw new CustomException("下单失败!");
}
else
{
#region
/* 添加订单流水 */
var paymentGuid = await AddPayment(parm, orderNo, totalPrice, afterPriceRes.DiscountPrice);
/* 添加业务订单 */
var orderGuid = await AddOrder(parm, orderNo, paymentGuid, goodsPrice, afterPriceRes, freight);
#endregion
// 返回拼接好的支付调起信息
var res = await _PaymentRepository.GetFirstAsync(s => s.PaymentGuid == paymentGuid);
PayParams payRes = new()
{
jsApiUiPackage = payEntity,
outTradeNo = orderNo,
CreateTime = res.Create_time,
OverTime = res.Create_time.AddMinutes(30)
};
return payRes;
}
}
/// <summary>
/// 支付回调的业务处理
/// </summary>
/// <returns></returns>
public async Task HandleNotify(OrderReturnJson res)
{
/* 修改订单流水 */
var paymentGuid = await UpdatePayment(res);
/* 修改业务订单 */
await UpdateOrder(res, paymentGuid);
}
#region
#region
/// <summary>
/// 计算核销前的价格
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public async Task<decimal> CalculateBeforePrice(CommitPayDtoApi parm)
{
decimal price = 0;
foreach (var item in parm.GoodsRequestList)
{
var cart = await _CartRepository.GetFirstAsync(s => s.CartId == item.CartId);
long goodsGuid = 0;
var quantity = 0;
var skuId = 0;
if (cart != null)
{
goodsGuid = cart.GoodsGuid;
quantity = cart.CartGoodsNum;
skuId = cart.GoodsSkuId;
}
else
{
goodsGuid = item.SpuId;
quantity = item.Quantity;
skuId = item.SkuId;
}
var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == goodsGuid);
/* 计算商品总价 */
// 是否有规格
if (skuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == skuId);
if (sku != null)
{
price += sku.GoodsSkuPrice * quantity;
}
// 下单立减库存
if (goods.GoodsDeductStockType == 1)
{
sku.GoodsSkuStockNum -= quantity;
await _GoodsSkuRepository.UpdateAsync(sku);
goods.GoodsTotalInventory -= quantity;
await _GoodsRepository.UpdateAsync(goods);
}
}
else
{
price += goods.GoodsPriceHighest * quantity;
// 下单立减库存
if (goods.GoodsDeductStockType == 1)
{
goods.GoodsTotalInventory -= quantity;
await _GoodsRepository.UpdateAsync(goods);
}
}
}
return price;
}
/// <summary>
/// 计算核后的价格
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public async Task<DiscountRes> CalculateAfterPrice(CommitPayDtoApi parm, decimal totalPrice)
{
var res = new DiscountRes();
res.DiscountPrice = totalPrice;
// 优惠券减免价格
if (parm.CouponList.Count > 0)
{
foreach (var item in parm.CouponList)
{
if (item.Key != 0)
{
var customerCoupon = await _CustomerCouponRepository.GetFirstAsync(s => s.CustomerCouponId == item.Key);
var coupon = await _CouponRepository.GetFirstAsync(s => s.CouponGuid == customerCoupon.CouponGuid);
if (coupon != null)
{
res.CouponGuid = coupon.CouponGuid;
res.CouponMoney = coupon.CouponDeductionMoney;
res.DiscountPrice -= coupon.CouponDeductionMoney;
}
else
{
throw new CustomException($"优惠券Id为 {parm.CouponId} 找不到");
}
}
}
}
return res;
}
/// <summary>
/// 添加订单流水
/// </summary>
/// <param name="parm">下单信息Dto对象</param>
/// <param name="orderNo">订单号</param>
/// <param name="beforeMoney">核销前价格</param>
/// <param name="afterMoney">核销后价格</param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
public async Task<long> AddPayment(CommitPayDtoApi parm, string orderNo, decimal beforeMoney, decimal afterMoney)
{
// 添加订单流水
Payment payment = new()
{
CustomerGuid = parm.UserId,
PaymentNumber = orderNo,
PaymentBuytype = parm.PayType,
PaymentBeforeMoney = afterMoney,
//PaymentMoney = afterMoney,
PaymentStatus = 1
};
var response = await _PaymentRepository.InsertReturnSnowflakeIdAsync(payment);
if (response == 0)
throw new CustomException("订单流水数据加入失败");
return response;
}
/// <summary>
/// 添加业务订单
/// </summary>
/// <param name="parm">下单信息Dto对象</param>
/// <param name="orderNo">订单号</param>
/// <param name="paymentGuid">支付订单流水guid</param>
/// <param name="beforeMoney">商品总额</param>
/// <param name="discountRes">优惠后的结果</param>
/// <param name="freight">运费</param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
public async Task<long> AddOrder(CommitPayDtoApi parm, string orderNo, long paymentGuid, decimal beforeMoney, DiscountRes discountRes, decimal freight)
{
// 找到店铺的Guids
var sameShopGuids = parm.GoodsRequestList
.OrderByDescending(s => s.JoinCartTime)
.Select(item => item.StoreId)
.Distinct()
.ToList();
var res = new List<OrderShopApiVo>();
// 循环每个店铺中的待结算订单商品记录
foreach (var shopGuid in sameShopGuids)
{
var orderShop = new OrderShopApiVo();
orderShop.ShopGuid = shopGuid;
orderShop.OrderNo = Common.Common.CreateNoQuery();
var orderShopGoodsRequestList = new List<GoodsRequest>();
var CartIdsList = new List<int>();
foreach (var item in parm.GoodsRequestList)
{
if (item.StoreId == shopGuid)
{
// 获取当前店铺的订单备注
if (parm.StoreInfoList.Count > 0)
{
foreach (var item1 in parm.StoreInfoList)
{
if (item1.StoreId == shopGuid)
{
orderShop.ReMark = item1.Remark;
}
}
}
orderShopGoodsRequestList.Add(item);
// 关联购物车ids
CartIdsList.Add(item.CartId);
}
}
orderShop.OrderShopGoodsRequestList = orderShopGoodsRequestList;
orderShop.CartIdsList = CartIdsList;
res.Add(orderShop);
}
// 循环整理好的各个店铺的订单
foreach (var item in res)
{
/* 计算商品总价 */
var commitPayDtoApi = new CommitPayDtoApi()
{
UserId = parm.UserId,
GoodsRequestList = item.OrderShopGoodsRequestList,
CustomerAddressGuid = parm.CustomerAddressGuid
};
var goodsTotalMoney = await CalculateBeforePrice(commitPayDtoApi);
/* 计算运费 */
GoodsFreightDto goodsFreightDto = new()
{
GoodsRequestList = item.OrderShopGoodsRequestList,
CustomerAddressGuid = parm.CustomerAddressGuid,
};
freight = await _GoodsServiceApi.GetGoodsFreight(goodsFreightDto);
Model.Models.Business.OrderManage.Orders.Order order = new()
{
PaymentGuid = paymentGuid,
CustomerGuid = parm.UserId,
OrderNumber = item.OrderNo,
OrderRemark = item.ReMark,
ShopGuid = item.ShopGuid,
CouponGuid = discountRes?.CouponGuid,
CouponMoney = discountRes.CouponMoney,
GoodsTotalAmoun = goodsTotalMoney,
OrderAmount = discountRes.DiscountPrice,
PayType = parm.PayType,
PayStatus = 1,
DeliveryStatus = 1,
ReceiptStatus = 1,
IsComment = 1,
IsSettled = 1,
OrderSource = 1,
OrderStatus = 1,
DeliveryType = 1,
ExpressPrice = freight,
CartIds = string.Join(",", item.CartIdsList)
};
var response = await _OrderRepository.InsertReturnSnowflakeIdAsync(order);
if (response == 0)
throw new CustomException("业务订单数据加入失败");
/* 添加订单取消任务 */
await AddOrderTask(commitPayDtoApi, response);
/* 添加订单商品 */
await AddOrderGoods(commitPayDtoApi, response);
/* 添加订单用户地址 */
await AddOrderCustomerAddress(commitPayDtoApi, response);
}
return 0;
}
/// <summary>
/// 添加订单取消任务
/// </summary>
/// <param name="parm"></param>
/// <param name="orderGuid"></param>
/// <returns></returns>
public async Task AddOrderTask(CommitPayDtoApi parm, long orderGuid)
{
var order = await _OrderRepository.GetFirstAsync(s => s.OrderGuid == orderGuid);
var orderTask = new OrderTask
{
CustomerGuid = parm.UserId,
OrderGuid = orderGuid,
EndTime = order.Create_time.AddMinutes(30),
PayStatus = 1,
CancelStatus = 1,
};
var response = await _OrderTaskRepository.InsertReturnSnowflakeIdAsync(orderTask);
if (response == 0)
throw new CustomException("订单用户地址数据加入失败");
}
/// <summary>
/// 添加OrderGoods(订单商品副表)
/// </summary>
/// <param name="parm"></param>
/// <param name="orderGuid"></param>
/// <returns></returns>
public async Task AddOrderGoods(CommitPayDtoApi parm, long orderGuid)
{
foreach (var item in parm.GoodsRequestList)
{
decimal singlePrice = 0;
decimal toatlPrice = 0;
var cart = await _CartRepository.GetFirstAsync(s => s.CartId == item.CartId);
long goodsGuid = 0;
var quantity = 0;
var skuId = 0;
if (cart != null)
{
goodsGuid = cart.GoodsGuid;
quantity = cart.CartGoodsNum;
skuId = cart.GoodsSkuId;
}
else
{
goodsGuid = item.SpuId;
quantity = item.Quantity;
skuId = item.SkuId;
}
var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == goodsGuid);
/* 计算商品总价 */
// 是否有规格
if (skuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == skuId);
if (sku != null)
{
singlePrice = sku.GoodsSkuPrice;
toatlPrice = sku.GoodsSkuPrice * quantity;
}
}
else
{
singlePrice = goods.GoodsPriceHighest;
toatlPrice = goods.GoodsPriceHighest * quantity;
}
/* 添加OrderGoods(订单商品副表) */
OrderGoods orderGoods = new()
{
OrderGuid = orderGuid,
GoodsGuid = goodsGuid,
GoodsSkuId = skuId,
GoodsPrice = singlePrice,
GoodsTotalNum = quantity,
GoodsTotalAmoun = toatlPrice,
};
var response = await _OrderGoodsRepository.InsertReturnSnowflakeIdAsync(orderGoods);
if (response == 0)
throw new CustomException("订单商品数据加入失败");
}
}
/// <summary>
/// 添加订单用户地址
/// </summary>
/// <param name="parm"></param>
/// <param name="orderGuid"></param>
/// <returns></returns>
public async Task AddOrderCustomerAddress(CommitPayDtoApi parm, long orderGuid)
{
var customerAddress = await _CustomerAddressRepository.GetFirstAsync(s => s.CustomerAddressGuid == parm.CustomerAddressGuid);
OrderCustomerAddress orderCustomerAddress = new()
{
OrderGuid = orderGuid,
CustomerGuid = parm.UserId,
CustomerAddressGuid = customerAddress.CustomerAddressGuid,
ConsigneeName = customerAddress.CustomerAddressName,
Phont = customerAddress.CustomerAddressPhone,
ProvinceId = customerAddress.CustomerAddressProvinceId,
CityId = customerAddress.CustomerAddressCityId,
RegionId = customerAddress.CustomerAddressAreaId,
Detail = customerAddress.CustomerAddressDetailed
};
var response = await _OrderCustomerAddressRepository.InsertReturnSnowflakeIdAsync(orderCustomerAddress);
if (response == 0)
throw new CustomException("订单用户地址数据加入失败");
}
#endregion
#region
/// <summary>
/// 修改订单流水
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public async Task<long> UpdatePayment(OrderReturnJson res)
{
await _PaymentRepository.UpdateAsync(f => new Payment
{
PaymentWeixinNumber = res.transaction_id,
PaymentMoney = ((decimal)res.amount.payer_total) / 100,
PaymentStatus = 2,
Update_time = DateTime.Now,
}, f => f.PaymentNumber == res.out_trade_no);
var payment = await _PaymentRepository.GetFirstAsync(s => s.PaymentNumber == res.out_trade_no);
return payment.PaymentGuid;
}
/// <summary>
/// 修改业务订单
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public async Task UpdateOrder(OrderReturnJson res, long paymentGuid)
{
var orderList = await _OrderRepository.GetListAsync(s => s.PaymentGuid == paymentGuid);
foreach (var item in orderList)
{
await _OrderRepository.UpdateAsync(f => new Model.Models.Business.OrderManage.Orders.Order
{
TransactionId = res.transaction_id,
PayPrice = ((decimal)res.amount.payer_total) / 100,
PayStatus = 2,
PayTime = DateTime.Now,
Update_time = DateTime.Now,
}, f => f.OrderGuid == item.OrderGuid);
// 修改订单取消列表
await _OrderTaskRepository.UpdateAsync(f => new OrderTask
{
PayStatus = 2,
}, f => f.OrderGuid == item.OrderGuid);
var order = await _OrderRepository.GetFirstAsync(s => s.OrderNumber == item.OrderNumber);
/* 删除购物车中对应的商品 */
var cartIds = Tools.SpitIntArrary(order.CartIds);
foreach (var cartId in cartIds)
{
await _CartRepository.UpdateAsync(s => new Cart
{
IsDelete = true,
}, s => s.CartId == cartId);
}
/* 对应优惠券修改为已使用 */
if (order.CouponGuid != 0)
{
var customer = await _CustomerRepository.GetFirstAsync(s => s.CustomerXcxOpenid == res.payer.openid);
var customerCoupon = await _CustomerCouponRepository.GetFirstAsync(s => s.CouponGuid == order.CouponGuid && s.CustomerGuid == customer.CustomerGuid);
await _CustomerCouponRepository.UpdateAsync(s => new CustomerCoupon
{
CustomerCouponIsUsed = 2,
}, s => s.CustomerCouponId == customerCoupon.CustomerCouponId);
}
/* 店铺和商品的销售数量增加 对应库存减少*/
var orderGoodsList = await _OrderGoodsRepository.GetListAsync(s => s.OrderGuid == order.OrderGuid);
foreach (var orderGood in orderGoodsList)
{
var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == orderGood.GoodsGuid);
var shop = await _ShopRepository.GetFirstAsync(s => s.ShopGuid == goods.ShopGuid);
goods.GoodsSalesActual += orderGood.GoodsTotalNum;
await _GoodsRepository.UpdateAsync(goods);
shop.ShopSalesOrderCount += orderGood.GoodsTotalNum;
await _ShopRepository.UpdateAsync(shop);
if (goods.GoodsDeductStockType == 2)
{
if (orderGood.GoodsSkuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == orderGood.GoodsSkuId);
sku.GoodsSkuStockNum -= orderGood.GoodsTotalNum;
goods.GoodsTotalInventory -= orderGood.GoodsTotalNum;
await _GoodsSkuRepository.UpdateAsync(sku);
await _GoodsRepository.UpdateAsync(goods);
}
else
{
goods.GoodsTotalInventory -= orderGood.GoodsTotalNum;
await _GoodsRepository.UpdateAsync(goods);
}
}
}
/* 积分操作*/
}
}
#endregion
#endregion
#endregion
}
}