feat 添加后台退款功能

This commit is contained in:
AERWEN\26795 2023-10-19 20:50:53 +08:00
parent 6a749274b9
commit 5983f3d743
7 changed files with 79 additions and 15 deletions

View File

@ -125,6 +125,29 @@ namespace ARW.Service.Api.BusinessService.OrderManage.Orders
/// <returns></returns>
public async Task<string> WaitPayCancelOrder(OrderDtoApi parm)
{
// 找到该订单的商品,如果是下单立减库存,将库存加回来
var orderGoodsList = await _OrderGoodsRepository.GetListAsync(s => s.OrderGuid == parm.OrderGuid);
foreach (var item in orderGoodsList)
{
var good = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == item.GoodsGuid);
if(good.GoodsDeductStockType == 1)
{
if(item.GoodsSkuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == item.GoodsSkuId);
sku.GoodsSkuStockNum += item.GoodsTotalNum;
good.GoodsTotalInventory += item.GoodsTotalNum;
await _GoodsSkuRepository.UpdateAsync(sku);
await _GoodsRepository.UpdateAsync(good);
}
else
{
good.GoodsTotalInventory += item.GoodsTotalNum;
await _GoodsRepository.UpdateAsync(good);
}
}
}
var res = await _OrderRepository.UpdateAsync(f => new Order
{
OrderStatus = 2,

View File

@ -109,7 +109,7 @@ namespace ARW.Service.Api.BusinessService.PaymentManage
var totalPrice = goodsPrice + freight;
/* 计算核销前后价格(优惠后价格) */
var afterPriceRes = await CalculateAfterPrice(parm);
var afterPriceRes = await CalculateAfterPrice(parm, totalPrice);
if (parm.TotalAmount != afterPriceRes.DiscountPrice) throw new CustomException("前端传递金额不合法!下单失败!");
parm.TotalAmount = afterPriceRes.DiscountPrice;
@ -251,10 +251,10 @@ namespace ARW.Service.Api.BusinessService.PaymentManage
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public async Task<DiscountRes> CalculateAfterPrice(CommitPayDtoApi parm)
public async Task<DiscountRes> CalculateAfterPrice(CommitPayDtoApi parm,decimal totalPrice)
{
var res = new DiscountRes();
res.DiscountPrice = parm.TotalAmount;
res.DiscountPrice = totalPrice;
// 优惠券减免价格
if (parm.CouponList.Count > 0)
{
@ -403,6 +403,7 @@ namespace ARW.Service.Api.BusinessService.PaymentManage
OrderStatus = 1,
DeliveryType = 1,
ExpressPrice = freight,
CartIds = string.Join(",",item.CartIdsList)
};
@ -533,7 +534,7 @@ namespace ARW.Service.Api.BusinessService.PaymentManage
await _PaymentRepository.UpdateAsync(f => new Payment
{
PaymentWeixinNumber = res.transaction_id,
PaymentMoney = res.amount.payer_total / 100,
PaymentMoney = ((decimal)res.amount.payer_total) / 100,
PaymentStatus = 2,
Update_time = DateTime.Now,
}, f => f.PaymentNumber == res.out_trade_no);
@ -557,7 +558,7 @@ namespace ARW.Service.Api.BusinessService.PaymentManage
await _OrderRepository.UpdateAsync(f => new Model.Models.Business.OrderManage.Orders.Order
{
TransactionId = res.transaction_id,
PayPrice = item.GoodsTotalAmoun,
PayPrice = ((decimal)res.amount.payer_total) / 100,
PayStatus = 2,
PayTime = DateTime.Now,
Update_time = DateTime.Now,

View File

@ -29,6 +29,7 @@ using Org.BouncyCastle.Crypto.Prng;
using Senparc.CO2NET.Extensions;
using ARW.Repository.Business.OrderManage.OrderCustomerAddreses;
using ARW.Service.Business.IBusinessService.Custom.Regions;
using ARW.Repository.Business.Payments;
namespace ARW.Service.Business.BusinessService.OrderManage.Orders
{
@ -45,10 +46,11 @@ namespace ARW.Service.Business.BusinessService.OrderManage.Orders
private readonly OrderGoodsRepository _OrderGoodsRepository;
private readonly OrderCustomerAddressRepository _OrderCustomerAddressRepository;
private readonly GoodsRepository _GoodsRepository;
private readonly PaymentRepository _PaymentRepository;
private readonly IGoodsSkuService _GoodsSkuService;
private readonly IRegionService _RegionService;
public OrderServiceImpl(OrderRepository OrderRepository, GoodsRepository goodsRepository, IGoodsSkuService goodsSkuService, OrderGoodsRepository orderGoodsRepository, OrderCustomerAddressRepository orderCustomerAddressRepository, IRegionService regionService)
public OrderServiceImpl(OrderRepository OrderRepository, GoodsRepository goodsRepository, IGoodsSkuService goodsSkuService, OrderGoodsRepository orderGoodsRepository, OrderCustomerAddressRepository orderCustomerAddressRepository, IRegionService regionService, PaymentRepository paymentRepository)
{
this._OrderRepository = OrderRepository;
_GoodsRepository = goodsRepository;
@ -56,6 +58,7 @@ namespace ARW.Service.Business.BusinessService.OrderManage.Orders
_OrderGoodsRepository = orderGoodsRepository;
_OrderCustomerAddressRepository = orderCustomerAddressRepository;
_RegionService = regionService;
_PaymentRepository = paymentRepository;
}
#region

View File

@ -145,7 +145,7 @@ namespace ARW.WebApi.Controllers.Api.Wechat.WxPay
public async Task<IActionResult> Refund([FromBody] OrderQueryDto parm)
{
Pay pay = new Pay(_httpClient);
var payment = _PayServiceApi.GetFirstAsync(s => s.PaymentNumber == parm.outTradeNo).Result;
var payment = await _PayServiceApi.GetFirstAsync(s => s.PaymentNumber == parm.outTradeNo);
var transactionId = payment.PaymentWeixinNumber;
string paymentRefundNumber = "";
if (!string.IsNullOrEmpty(payment.PaymentRefundNumber))
@ -153,8 +153,8 @@ namespace ARW.WebApi.Controllers.Api.Wechat.WxPay
paymentRefundNumber = payment.PaymentRefundNumber;
}
var totalFee = payment.PaymentMoney;
var res = await pay.Refund(transactionId, totalFee, paymentRefundNumber);
var totalFee = payment.PaymentMoney * 100;
var res = await pay.Refund(transactionId, totalFee, paymentRefundNumber, "商品退款");
if (res.ResultCode.Success == false)
throw new CustomException("订单退款失败!");
else

View File

@ -20,6 +20,13 @@ using Geocoding;
using ARW.Service.Business.IBusinessService.OrderManage.OrderGoodss;
using ARW.Service.Business.IBusinessService.OrderManage.OrderCustomerAddreses;
using ARW.Service.Business.IBusinessService.ShopManager.Shops;
using ARW.Repository.Business.OrderManage.Orders;
using ARW.Repository.Business.Payments;
using Infrastructure.WeChat.TenPay;
using System.Net.Http;
using Senparc.CO2NET.HttpUtility;
using ARW.Service.Business.IBusinessService.Payments;
using ARW.Model.Models.Business.Payments;
namespace ARW.WebApi.Controllers.Business.OrderManage.Orders
{
@ -37,17 +44,21 @@ namespace ARW.WebApi.Controllers.Business.OrderManage.Orders
private readonly IOrderService _OrderService;
private readonly IOrderGoodsService _OrderGoodsService;
private readonly IOrderCustomerAddressService _OrderCustomerAddressService;
private readonly IPaymentService _PaymentService;
private readonly SenparcHttpClient _httpClient;
/// <summary>
/// 依赖注入
/// </summary>
/// <param name="OrderService">订单服务</param>
public OrderController(IOrderService OrderService, IOrderGoodsService orderGoodsService, IOrderCustomerAddressService orderCustomerAddressService, IShopService shopService)
public OrderController(IOrderService OrderService, IOrderGoodsService orderGoodsService, IOrderCustomerAddressService orderCustomerAddressService, IShopService shopService, SenparcHttpClient httpClient, IPaymentService paymentService)
{
_OrderService = OrderService;
_OrderGoodsService = orderGoodsService;
_OrderCustomerAddressService = orderCustomerAddressService;
_ShopService = shopService;
_httpClient = httpClient;
_PaymentService = paymentService;
}
@ -140,6 +151,29 @@ namespace ARW.WebApi.Controllers.Business.OrderManage.Orders
{
if (parm == null) { throw new CustomException("请求参数错误"); }
var order = await _OrderService.GetFirstAsync(s => s.OrderGuid == parm.OrderGuid);
var payment = await _PaymentService.GetFirstAsync(s => s.PaymentGuid == order.PaymentGuid);
Pay pay = new Pay(_httpClient);
var transactionId = payment.PaymentWeixinNumber;
string paymentRefundNumber = "";
if (!string.IsNullOrEmpty(payment.PaymentRefundNumber))
{
paymentRefundNumber = payment.PaymentRefundNumber;
}
var totalFee = payment.PaymentMoney * 100;
var canleRes = await pay.Refund(transactionId, totalFee, paymentRefundNumber,"商品退款");
if (canleRes.ResultCode.Success == false)
throw new CustomException("订单退款失败!");
else
{
var respones = _PaymentService.UpdateAsync(f => new Payment
{
PaymentRefundNumber = canleRes.out_refund_no,
}, f => f.PaymentNumber == canleRes.out_trade_no);
}
var res = await _OrderService.CancelOrder(parm);
return SUCCESS(res);
}

View File

@ -149,6 +149,7 @@
"TenPayV3_CertPath": "D:\\.Net\\Aerwen\\shop_template\\wecaht_information\\cert\\apiclient_cert.p12", //D:\\cert\\apiclient_cert.p12
"TenPayV3_CertSecret": "1645875842", // MchId
"TenPayV3_TenpayNotify": "http://shop.api.aerwen.net/api/WxPay/Notify", //
"TenPayV3_RefundNotify": "http://shop.api.aerwen.net/api/WxPay/refundNotifyUrl", // 退
"TenPayV3_WxOpenNotify": "http://shop.api.aerwen.net/api/WxPay/Notify", //
"TenPayV3_PrivateKey": "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7wzMe6ZBFh+Zsa4cZf0s2dfMfDlmbGD7KEly6l1aK42YsR+5VpFcB+TJH3pVAsRO0X//mMrQXDqlAzha8PgMKa5PuSc6LevfUaX6nHf454AwaTXc3CHdhClNbrHdaAqh+LqxvrAJwZydrBGwI9IgW73Ze0oFWiNGt7aLhnH30CxC1vmHkq/BrTsV7qUVenjJmmxdSR3SwtRI1IdeWOdTXasR4LU5hROvnVs/HIjzQTp+J3XMwf4zaOZgWTqz+23KZhuCVE9ZXe+quJCgWvuT+O8Do9SyG5iAZMlLg6nZYGy3L6cke/Am3KZDD9cUwQI+uS3z3gF0TYiG8fQVoJl25AgMBAAECggEBAJ+9diR6eO9uqy7aXFno3kg7GNf3EWzNt72a2aE1V79Zr3dEyxO5ePyI0aorR7d971GpysBBqs1i/8POkbEc4OFgnL5BtKMdvvLLvaDX942tex51gVMktMuuSTTZCcFeOZMAiluHb5vJZtO5M2B7CbzZhU8usDK6vAjI/6YJyW5w9cp9JLQwRGHe4P9aSbqlCE0swMDzdpGCvXB6GTSlATQtNkjnaPeZpv1HtOgJk72HNV56BY55zsYSrhTA+7Pd5jKCGPdQry84RkBnbTzM/BlFBfR5LXzwCH/cRBz3cgdhoklxT730oBnbaHDERzan4GbDY7pKqF6bIM8mJou2AbECgYEA6RikdNXFmbmuJ8GDgt/wtuEAsEQLovoCw2KFGGMk1Uu5rZJ908OKJ0aTzMdTXQEz4+QBqstJNzg2VA1blnTw/06l0RjprcJ0Ibq9BB0vCfFjR2R3OhiZlq/KjFHIeJ14+qhKKQlZ+inCL4G5VGRcR2MuHCmq3Msa6wAkCBMp7vsCgYEAzjY4p9TldFg+qJIv2x53Gz0SbqIA3g0L08tSvlxI2sWkluWMk1KVU6pMsInL/eogEGqYV/n1kjjTVJp75G7fxThdeO9BUxlpwmjTYXGlMUkLGB3/LXw//IKi6dWDJoZUW60z/yYfsPnM9/eYLXRF4dsHlb6nJvISXCLjZ4OdN9sCgYAPhJd2O8ES8dyZQvXJYbU5x5LvKSiJKhHDBi0MKZWLKaZr2sPLtEnfQYCXcnGnUGwu8L/3qd7u8SwUvmrpglGE/axmVj1AVyC6Gh95RaQbClnsp9CUKo0XDg7y9oLdHMawEUIWp0u5LsyBsyYuaxwFmKG6OD/qwQ7CtFixvOzevwKBgHZC0FEoHoOPzDd+xyVCHoqnhred/yNZlgvb0lNLt5iHurGzaeBffzYhN6QTEsNHDyZ7C22A853tKv2dLyo9j+WaQrkFdZBDxcxxs7BxrYxLWKp3IY4jcMrO3MF/6pwgc6az+Vr9sTUcvbkD7Ok8gotZwsrVMSV7tJ3UgFgwOez7AoGAB2TKMM7QrVfotvDtcDR689NvJ55RGWiKZv/BzsT5zE7LJH+0jwWl1jy24I1DSGgsPmLAt29+VLfgwfAyCz5ytMgvx6iu+cnsyriK3/SNdFZtymUegkIdzSONXslVZYqFsBKQz/M+BmgPvnQao/e8r8eWpIBZLBr93ud+LpDmEio=", //
"TenPayV3_SerialNumber": "6C34D380F6B239BEE351D9EB4AD2655FF38D4AAA", //

View File

@ -250,16 +250,16 @@ namespace Infrastructure.WeChat.TenPay
/// 退款申请接口
/// </summary>
/// <returns></returns>
public async Task<RefundReturnJson> Refund(string transactionId, decimal totalFee,string? paymentRefundNumber)
public async Task<RefundReturnJson> Refund(string transactionId, decimal totalFee,string? paymentRefundNumber,string reason)
{
try
{
string outRefundNo;
await payLog("WechatRefund", "1");
await payLog("WechatRefund", "1asdasdas");
string nonceStr = TenPayV3Util.GetNoncestr();
await payLog("WechatRefund", "2 退款微信单号transactionId" + transactionId);
await payLog("WechatRefund", "2 退款微信单号transactionId" + transactionId + "/n 订单金额:" + totalFee);
if (!string.IsNullOrEmpty(paymentRefundNumber))
{
@ -271,12 +271,13 @@ namespace Infrastructure.WeChat.TenPay
}
int refundFee = Convert.ToInt32(totalFee);
string opUserId = TenPayV3Info.MchId;
var notifyUrl = "http://aerwen.net/prod-api/api/WxPay/refundNotifyUrl";
var notifyUrl = AppSettings.GetConfig("SenparcWeixinSetting:TenPayV3_RefundNotify");
//var dataInfo = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key,
// null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl);
//TODO:该接口参数二选一传入
var dataInfo = new RefundRequsetData(transactionId, null, outRefundNo, "Senparc TenPayV3 demo退款测试", notifyUrl, null, new RefundRequsetData.Amount(refundFee, null, refundFee, "CNY"), null);
var dataInfo = new RefundRequsetData(transactionId, null, outRefundNo, reason, notifyUrl, null, new RefundRequsetData.Amount(refundFee, null, refundFee, "CNY"), null);
await payLog("WechatRefund", "2.5 DataInfo" + dataInfo.ToJson());
//#region 新方法Senparc.Weixin v6.4.4+
//var result = TenPayOldV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录
@ -289,6 +290,7 @@ namespace Infrastructure.WeChat.TenPay
}
catch (Exception ex)
{
await payLog("WechatRefund", "报错:" + ex.Message);
WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
throw;