OrderService.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. using Ant.Core.Utils;
  2. using Ant.Core.WebApi.Enum;
  3. using Ant.Core.WebApi.Model;
  4. using Aop.Api.Util;
  5. using Central.Control.WebApi.Config;
  6. using Central.Control.WebApi.DbEntity;
  7. using Central.Control.WebApi.EFDbContext;
  8. using Central.Control.WebApi.Enum;
  9. using Central.Control.WebApi.Log4net;
  10. using Central.Control.WebApi.Models.Request;
  11. using Central.Control.WebApi.Models.Response;
  12. using Central.Control.WebApi.Service.Interface;
  13. using Com.Alipay;
  14. using Com.Alipay.Business;
  15. using Com.Alipay.Domain;
  16. using Com.Alipay.Model;
  17. using Newtonsoft.Json;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Collections.Specialized;
  21. using System.Configuration;
  22. using System.IO;
  23. using System.Linq;
  24. using System.Text;
  25. using System.Web;
  26. namespace Central.Control.WebApi.Service
  27. {
  28. /// <summary>
  29. ///
  30. /// </summary>
  31. public class OrderService: IOrderService
  32. {
  33. IAlipayTradeService serviceClient = F2FBiz.CreateClientInstance(AliPayConfig.serverUrl, AliPayConfig.appId, AliPayConfig.merchant_private_key, AliPayConfig.version,
  34. AliPayConfig.sign_type, AliPayConfig.alipay_public_key, AliPayConfig.charset);
  35. /// <summary>
  36. /// 支付宝回写地址
  37. /// </summary>
  38. public readonly static string aliNotifyUrl = ConfigurationManager.AppSettings["aliNotifyUrl"].ToString();
  39. /// <summary>
  40. /// 支付中间页地址
  41. /// </summary>
  42. public readonly static string payRedirectUrl = ConfigurationManager.AppSettings["payredirecturl"].ToString();
  43. private readonly IDbContext _dbContent;
  44. private readonly IUserService _userService;
  45. private readonly ILog4NetHelper _log4NetHelper;
  46. private readonly IYWLogService _ywLogService;
  47. /// <summary>
  48. ///
  49. /// </summary>
  50. /// <param name="dbContent"></param>
  51. /// <param name="userService"></param>
  52. /// <param name="log4NetHelper"></param>
  53. /// <param name="ywLogService"></param>
  54. public OrderService(
  55. IDbContext dbContent,
  56. IUserService userService,
  57. ILog4NetHelper log4NetHelper,
  58. IYWLogService ywLogService)
  59. {
  60. _dbContent = dbContent;
  61. _userService = userService;
  62. _log4NetHelper = log4NetHelper;
  63. _ywLogService = ywLogService;
  64. }
  65. /// <summary>
  66. /// 下单
  67. /// </summary>
  68. /// <param name="req"></param>
  69. /// <returns></returns>
  70. public ApiResult<OrderResponseDto> Order(OrderRequestDto req)
  71. {
  72. #region 1、验证参数
  73. if (req == null
  74. || req.OrderInfo == null
  75. || req.OrderInfo.Count() == 0)
  76. {
  77. return new ApiResult<OrderResponseDto>(ApiStatusCode.InvalidParameter, "请求参数不正确");
  78. }
  79. #endregion
  80. #region 2、验证相应数据和库存
  81. var productIds = req.OrderInfo.Select(p => p.ProductId).ToList();
  82. var products = _dbContent.Set<YW_Product>().Where(p => p.IsDelete == 0 && p.Sale == Enum.SaleEnum.On && productIds.Contains(p.Id)).ToList();
  83. if (products.Count() <= 0)
  84. {
  85. return new ApiResult<OrderResponseDto>(ApiStatusCode.RecordNotFound, "未找到下单的商品");
  86. }
  87. #endregion
  88. #region 3、包装盒库存验证
  89. var session = _userService.GetLoginSession();
  90. // 修改
  91. var devicePackings = _dbContent.Set<YW_DevicePacking>().Where(p => p.IsDelete == 0 && p.DeviceId == session.UserId).ToList();
  92. if (devicePackings == null || devicePackings.Count() == 0)
  93. {
  94. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, "包装盒库存不足,请联系工作人员添加包装盒");
  95. }
  96. int orderCount = req.OrderInfo.Sum(p => p.Count);
  97. int packingCount = devicePackings.Sum(p => p.Stock * p.Capacity);
  98. if (packingCount < orderCount)
  99. {
  100. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, "包装盒库存不足,请联系工作人员添加包装盒");
  101. }
  102. // 计算使用的包装盒数量(减包装盒库存)
  103. var orderCountIndex = orderCount;
  104. foreach (var devicePacking in devicePackings)
  105. {
  106. if (orderCountIndex <= 0)
  107. {
  108. break;// 数量为0了,则直接跳出循环
  109. }
  110. int currentPackingStock = devicePacking.Stock;
  111. for (int i = 0; i < currentPackingStock; i++)
  112. {
  113. // 循环库存
  114. if (orderCountIndex <= 0)
  115. {
  116. break;// 数量为0了,则直接跳出循环
  117. }
  118. orderCountIndex = orderCountIndex - devicePacking.Capacity;
  119. devicePacking.Stock--;// 减库存
  120. }
  121. }
  122. #endregion
  123. #region 4、商品库存验证
  124. var orderId = IdGenerator.NewId();
  125. List<YW_OrderDetails> orderDetailAdds = new List<YW_OrderDetails>();
  126. List<YW_OrderProcess> orderProcessAdds = new List<YW_OrderProcess>();
  127. StringBuilder orderName = new StringBuilder();
  128. foreach (var o in req.OrderInfo)
  129. {
  130. var currentProduct = products.FirstOrDefault(p => p.Id == o.ProductId);
  131. if (currentProduct == null)
  132. {
  133. return new ApiResult<OrderResponseDto>(ApiStatusCode.RecordNotFound, $"{o.ProductId}商品不存在");
  134. }
  135. if (currentProduct.Stock < o.Count)
  136. {
  137. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, $"{currentProduct.Name}商品库存不足,请修改后重新下单");
  138. }
  139. // 扣库存
  140. currentProduct.Stock = currentProduct.Stock - o.Count;
  141. // orderDetails
  142. orderDetailAdds.Add(new YW_OrderDetails()
  143. {
  144. Id = IdGenerator.NewId(),
  145. OrderId = orderId,
  146. ProductId = currentProduct.Id,
  147. Name = currentProduct.Name,
  148. Code = currentProduct.Code,
  149. Img = currentProduct.Img,
  150. Info = currentProduct.Info,
  151. Price = currentProduct.Price,
  152. BuyingPrice = currentProduct.BuyingPrice,
  153. Count = o.Count,
  154. CreateBY = session.UserId
  155. });
  156. if (orderName.Length < 40)
  157. {
  158. orderName.Append($"{currentProduct.Name},");
  159. }
  160. }
  161. #endregion
  162. #region 5、下单
  163. YW_Order order = new YW_Order()
  164. {
  165. Id = orderId,
  166. Name = orderName.ToString().TrimEnd(','),
  167. DeviceId = session.UserId,
  168. Price = orderDetailAdds.Sum(p => p.Price * p.Count),
  169. PayStatus = PayStatusEnum.UnPay,
  170. OrderStatus = OrderStatusEnum.UnPay,
  171. // PaySerialId = Snowflake.Instance().GetId().ToString(), // 支付流水号,支付完成会回写
  172. CreateBY = session.UserId
  173. };
  174. YW_OrderProcess orderProcess = new YW_OrderProcess()
  175. {
  176. Id = IdGenerator.NewId(),
  177. OrderId = order.Id,
  178. DeviceId = session.UserId,
  179. CurrentOrderStatus = OrderStatusEnum.UnPay,
  180. Message = "下单成功",
  181. CreateBY = session.UserId
  182. };
  183. #endregion
  184. #region 6、存库
  185. _dbContent.Set<YW_Order>().Add(order);
  186. _dbContent.Set<YW_OrderProcess>().Add(orderProcess);
  187. _dbContent.Set<YW_OrderDetails>().AddRange(orderDetailAdds);
  188. // 数据库执行 库存已经改过了,会自动保存
  189. _dbContent.SaveChanges();
  190. #endregion
  191. // 写入订单日志
  192. _ywLogService.WriteOrderLog(order.Id, "下单", "下单成功", session.UserId);
  193. return new ApiResult<OrderResponseDto>(new OrderResponseDto()
  194. {
  195. OrderId = order.Id,
  196. Price = order.Price,
  197. QrCode = string.Format(payRedirectUrl, order.Id)
  198. });
  199. }
  200. /// <summary>
  201. /// 获取待烧烤的商品列表
  202. /// <summary>
  203. /// <returns></returns>
  204. public ApiResult<List<QueueOrderResponseDto>> GetQueueOrders()
  205. {
  206. var orders = _dbContent.Set<YW_Order>()
  207. .Where(p => p.IsDelete == 0
  208. && p.PayStatus == PayStatusEnum.Paid
  209. && p.OrderStatus == OrderStatusEnum.Paid)
  210. .OrderBy(p => p.CreateDT).ToList();
  211. var orderIds = orders.Select(p => p.Id).ToList();
  212. var orderDetails = _dbContent.Set<YW_OrderDetails>().Where(p => p.IsDelete == 0 && orderIds.Contains(p.OrderId)).ToList();
  213. List<QueueOrderResponseDto> result = new List<QueueOrderResponseDto>();
  214. orders.ForEach(item => {
  215. QueueOrderResponseDto resultItem = new QueueOrderResponseDto()
  216. {
  217. OrderId = item.Id,
  218. Price = item.Price,
  219. OrderDetails = orderDetails
  220. .Where(p => p.OrderId == item.Id)
  221. .Select(p => SafeClone<YW_OrderDetails, QueueOrderDetailsDto>.Trans(p))
  222. .ToList()
  223. };
  224. resultItem.OrderDetails?.ForEach(p => p.Img = $"{ProductService.ImagePrefix}{p.Img}");
  225. result.Add(resultItem);
  226. });
  227. return new ApiResult<List<QueueOrderResponseDto>>(result);
  228. }
  229. /// <summary>
  230. /// 回写流程状态
  231. /// </summary>
  232. /// <param name="req"></param>
  233. /// <returns></returns>
  234. public ApiResult OrderProcess(OrderProcessRequestDto req)
  235. {
  236. if (req == null)
  237. {
  238. return new ApiResult(ApiStatusCode.InvalidParameter, "请求参数不正确");
  239. }
  240. var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.Id == req.OrderId);
  241. if (order == null)
  242. {
  243. return new ApiResult(ApiStatusCode.InvalidParameter, "未找到相应订单");
  244. }
  245. if (order.PayStatus != PayStatusEnum.Paid)
  246. {
  247. return new ApiResult(ApiStatusCode.InvalidParameter, "未支付订单不能回写流程");
  248. }
  249. if (order.OrderStatus == OrderStatusEnum.UnPay
  250. || order.OrderStatus == OrderStatusEnum.Cancel)
  251. {
  252. return new ApiResult(ApiStatusCode.InvalidParameter, "未支付或已取消订单不能回写流程");
  253. }
  254. var session = _userService.GetLoginSession();
  255. // 修改订单状态
  256. order.OrderStatus = req.OrderStatus;
  257. // 记录订单流程
  258. YW_OrderProcess orderProcess = new YW_OrderProcess()
  259. {
  260. Id = IdGenerator.NewId(),
  261. OrderId = req.OrderId,
  262. DeviceId = session.UserId,
  263. CurrentOrderStatus = req.OrderStatus,
  264. Message = req.Message,
  265. CreateBY = session.UserId
  266. };
  267. _dbContent.Set<YW_OrderProcess>().Add(orderProcess);
  268. _dbContent.SaveChanges();
  269. // 写入订单日志
  270. _ywLogService.WriteOrderLog(order.Id, "流程回写", $"回写流程状态{req.OrderStatus.ToString()}", session.UserId);
  271. return new ApiResult();
  272. }
  273. /// <summary>
  274. /// 获取支付宝支付链接
  275. /// </summary>
  276. /// <param name="id"></param>
  277. /// <returns></returns>
  278. public string AliPayProcess(string id)
  279. {
  280. // 1、先查询订单是否存在
  281. var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.IsDelete == 0 && p.Id == id);
  282. if (order == null)
  283. {
  284. return "http://api.rgtech.ltd/html/ordernotexist.html";
  285. }
  286. string result = "http://api.rgtech.ltd/html/error.html";
  287. // 查询订单详情
  288. var orderDetails = _dbContent.Set<YW_OrderDetails>().Where(p => p.IsDelete == 0 && p.OrderId == order.Id).ToList();
  289. #region 拼写支付宝支付参数
  290. AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder();
  291. //收款账号
  292. builder.seller_id = AliPayConfig.pid;
  293. //订单编号
  294. builder.out_trade_no = order.Id;
  295. //订单总金额
  296. builder.total_amount = order.Price.ToString();
  297. //参与优惠计算的金额
  298. //builder.discountable_amount = "";
  299. //不参与优惠计算的金额
  300. //builder.undiscountable_amount = "";
  301. //订单名称
  302. builder.subject = order.Name;
  303. //自定义超时时间
  304. builder.timeout_express = "10m";
  305. //订单描述
  306. builder.body = "";
  307. //门店编号,很重要的参数,可以用作之后的营销
  308. builder.store_id = order.DeviceId;
  309. //操作员编号,很重要的参数,可以用作之后的营销
  310. //builder.operator_id = "test";
  311. //传入商品信息详情
  312. List<GoodsInfo> gList = orderDetails?.Select(od => new GoodsInfo()
  313. {
  314. goods_id = od.Id,
  315. goods_name = od.Name,
  316. price = od.Price.ToString(),
  317. quantity = od.Count.ToString()
  318. }).ToList() ?? new List<GoodsInfo>();
  319. builder.goods_detail = gList;
  320. //系统商接入可以填此参数用作返佣
  321. //ExtendParams exParam = new ExtendParams();
  322. //exParam.sysServiceProviderId = "20880000000000";
  323. //builder.extendParams = exParam;
  324. #endregion
  325. //如果需要接收扫码支付异步通知,那么请把下面两行注释代替本行。
  326. //推荐使用轮询撤销机制,不推荐使用异步通知,避免单边账问题发生。
  327. AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder, aliNotifyUrl);//商户接收异步通知的地址,采用异步回写通知
  328. switch (precreateResult.Status)
  329. {
  330. case ResultEnum.SUCCESS:
  331. result = precreateResult.response.QrCode;
  332. break;
  333. case ResultEnum.FAILED:
  334. case ResultEnum.UNKNOWN:
  335. default:
  336. // 请求失败,记录日志
  337. _log4NetHelper.Error($"[AliPayProcess]-tradePrecreate失败:{JsonConvert.SerializeObject(precreateResult)}");
  338. break;
  339. }
  340. return result;
  341. }
  342. /// <summary>
  343. /// 支付宝支付回写(已测试好,勿动)
  344. /// </summary>
  345. /// <returns></returns>
  346. public string AliPayNotify()
  347. {
  348. _log4NetHelper.Info("[AliPayNotify]-start");
  349. SortedDictionary<string, string> sPara = GetRequestPost();
  350. _log4NetHelper.Info("[AliPayNotify]-[原始请求参数]-" + JsonConvert.SerializeObject(sPara));
  351. Notify aliNotify = new Notify(AliPayConfig.charset, AliPayConfig.sign_type, AliPayConfig.pid, AliPayConfig.mapiUrl, AliPayConfig.alipay_public_key);
  352. string notifyId = HttpContext.Current.Request.Form["notify_id"];
  353. string sign = HttpContext.Current.Request.Form["sign"];
  354. _log4NetHelper.Info($"[AliPayNotify]-[基础参数]-notify_id:{notifyId};sign{sign}");
  355. //对异步通知进行验签
  356. bool verifyResult = aliNotify.Verify(sPara, notifyId, sign);
  357. if (verifyResult && CheckParams()) //验签成功 && 关键业务参数校验成功
  358. {
  359. _log4NetHelper.Info("[AliPayNotify]-验签成功");
  360. string paySerialId = HttpContext.Current.Request.Form["trade_no"] ?? string.Empty;
  361. string outTradeNo = HttpContext.Current.Request.Form["out_trade_no"] ?? string.Empty;
  362. string payResponse = JsonConvert.SerializeObject(sPara);
  363. // 写入支付日志-里面有trycatch
  364. _ywLogService.WritePayCallLog(paySerialId, outTradeNo, PayWayEnum.AliPay, payResponse);
  365. PayStatusEnum payStatus = PayStatusEnum.Fail;
  366. if (HttpContext.Current.Request.Form["trade_status"] == "TRADE_SUCCESS")
  367. {
  368. payStatus = PayStatusEnum.Paid;
  369. }
  370. PayWriteBackRequestDto payWriteBack = new PayWriteBackRequestDto()
  371. {
  372. PaySerialId = paySerialId,
  373. OrderId = outTradeNo,
  374. PayStatus = payStatus,
  375. PayWay = PayWayEnum.AliPay,
  376. BuyerId = HttpContext.Current.Request.Form["buyer_id"] ?? string.Empty,
  377. BuyAccount = HttpContext.Current.Request.Form["buyer_logon_id"] ?? string.Empty,
  378. SellerId = HttpContext.Current.Request.Form["seller_id"] ?? string.Empty,
  379. SellAccount = HttpContext.Current.Request.Form["seller_email"] ?? string.Empty,
  380. TotalAmount = ConvertHelper.ToDecimal(HttpContext.Current.Request.Form["total_amount"]),
  381. PayAmount = ConvertHelper.ToDecimal(HttpContext.Current.Request.Form["buyer_pay_amount"]),
  382. PayTime = ConvertHelper.ToDateTime(HttpContext.Current.Request.Form["gmt_payment"]),
  383. PayResponse = payResponse
  384. };
  385. // 回写到实际表中
  386. var result = PayWriteBack(payWriteBack);
  387. if (!result.IsSuccess)
  388. {
  389. // 失败了
  390. _log4NetHelper.Info($"[AliPayNotify]-[支付回写验证失败]-{result.Message}");
  391. return "false";
  392. }
  393. return "sucess";
  394. }
  395. else
  396. {
  397. _log4NetHelper.Info("[AliPayNotify]-验签失败!!!");
  398. return "false";
  399. }
  400. }
  401. /// <summary>
  402. /// 支付回写(雏形,需要根据实际需要接入支付宝或微信)
  403. /// </summary>
  404. /// <param name="req"></param>
  405. /// <returns></returns>
  406. private ApiResult PayWriteBack(PayWriteBackRequestDto req)
  407. {
  408. if (req == null
  409. || string.IsNullOrWhiteSpace(req.PaySerialId))
  410. {
  411. return new ApiResult(ApiStatusCode.InvalidParameter, "请求参数不正确");
  412. }
  413. var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.Id == req.OrderId);
  414. if (order == null)
  415. {
  416. return new ApiResult(ApiStatusCode.InvalidParameter, "未找到相应订单");
  417. }
  418. if (order.Price != req.TotalAmount)
  419. {
  420. // 写入订单日志
  421. string msg = $"回写总金额与订单金额不匹配,订单号{order.Id};订单价格{order.Price};支付流水号{req.PaySerialId};支付订单总金额{req.TotalAmount}";
  422. _ywLogService.WriteOrderLog(order.Id, "支付回写", msg, req.PayWay.ToString());
  423. return new ApiResult(ApiStatusCode.InvalidParameter, msg);
  424. }
  425. if (order.Price != req.PayAmount)
  426. {
  427. // 写入订单日志
  428. string msg = $"回写支付金额与订单金额不匹配,订单号{order.Id};订单价格{order.Price};支付流水号{req.PaySerialId};支付订单已付金额{req.PayAmount}";
  429. _ywLogService.WriteOrderLog(order.Id, "支付回写", msg, req.PayWay.ToString());
  430. return new ApiResult(ApiStatusCode.InvalidParameter, msg);
  431. }
  432. var status = GetStatusByPayWriteBack(req.PayStatus);
  433. // 修改订单状态
  434. order.PayStatus = status.Item1;
  435. order.OrderStatus = status.Item2;
  436. order.PaySerialId = req.PaySerialId;
  437. // 记录订单流程
  438. YW_PayCall payCall = new YW_PayCall()
  439. {
  440. Id = IdGenerator.NewId(),
  441. OrderId = req.OrderId,
  442. PayStatus = status.Item1,
  443. PaySerialId = req.PaySerialId,
  444. PayWay = req.PayWay,
  445. BuyerId = req.BuyerId,
  446. BuyAccount = req.BuyAccount,
  447. SellerId = req.SellerId,
  448. SellAccount = req.SellAccount,
  449. PayAmount = req.PayAmount,
  450. PayTime = req.PayTime,
  451. PayResponse = req.PayResponse,
  452. CreateBY = req.BuyAccount
  453. };
  454. _dbContent.Set<YW_PayCall>().Add(payCall);
  455. _dbContent.SaveChanges();
  456. // 记录订单日志
  457. _ywLogService.WriteOrderLog(order.Id, "支付回写", "回写成功", req.PayWay.ToString());
  458. return new ApiResult();
  459. }
  460. /// <summary>
  461. /// 支付测试
  462. /// </summary>
  463. /// <returns></returns>
  464. public ApiResult<AlipayF2FPrecreateResult> PayTest()
  465. {
  466. AlipayTradePrecreateContentBuilder builder = BuildPrecreateContent();
  467. string out_trade_no = builder.out_trade_no;
  468. //如果需要接收扫码支付异步通知,那么请把下面两行注释代替本行。
  469. //推荐使用轮询撤销机制,不推荐使用异步通知,避免单边账问题发生。
  470. // AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder);
  471. string notify_url = aliNotifyUrl; //商户接收异步通知的地址
  472. AlipayF2FPrecreateResult precreateResult = serviceClient.tradePrecreate(builder, notify_url);
  473. //以下返回结果的处理供参考。
  474. //payResponse.QrCode即二维码对于的链接
  475. //将链接用二维码工具生成二维码打印出来,顾客可以用支付宝钱包扫码支付。
  476. string result = "";
  477. return new ApiResult<AlipayF2FPrecreateResult>(precreateResult);
  478. //switch (precreateResult.Status)
  479. //{
  480. // case ResultEnum.SUCCESS:
  481. // DoWaitProcess(precreateResult);
  482. // txtRCCode.Text = precreateResult.response.QrCode;
  483. // break;
  484. // case ResultEnum.FAILED:
  485. // result = precreateResult.response.Body;
  486. // Response.Redirect("result.aspx?Text=" + result);
  487. // break;
  488. // case ResultEnum.UNKNOWN:
  489. // if (precreateResult.response == null)
  490. // {
  491. // result = "配置或网络异常,请检查后重试";
  492. // }
  493. // else
  494. // {
  495. // result = "系统异常,请更新外部订单后重新发起请求";
  496. // }
  497. // Response.Redirect("result.aspx?Text=" + result);
  498. // break;
  499. //}
  500. }
  501. /// <summary>
  502. /// 构造支付请求数据
  503. /// </summary>
  504. /// <returns>请求数据集</returns>
  505. private AlipayTradePrecreateContentBuilder BuildPrecreateContent()
  506. {
  507. AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder();
  508. //收款账号
  509. builder.seller_id = AliPayConfig.pid;
  510. //订单编号-----------------------
  511. builder.out_trade_no = DateTime.Now.ToString("yyyyMMddHHmmss") + "0000" + (new Random()).Next(1, 10000).ToString();
  512. //订单总金额-----------------------------
  513. builder.total_amount = "0.02";
  514. //参与优惠计算的金额
  515. //builder.discountable_amount = "";
  516. //不参与优惠计算的金额
  517. //builder.undiscountable_amount = "";
  518. //订单名称-------------------------------
  519. builder.subject = "smj_webapi测试订单";
  520. //自定义超时时间
  521. builder.timeout_express = "5m";
  522. //订单描述
  523. builder.body = "";
  524. //门店编号,很重要的参数,可以用作之后的营销--------------------
  525. builder.store_id = "test store id";
  526. //操作员编号,很重要的参数,可以用作之后的营销---------------------
  527. builder.operator_id = "test";
  528. //传入商品信息详情
  529. List<GoodsInfo> gList = new List<GoodsInfo>();
  530. GoodsInfo goods = new GoodsInfo();
  531. goods.goods_id = "goods id";
  532. goods.goods_name = "goods name";
  533. goods.price = "0.02";
  534. goods.quantity = "1";
  535. gList.Add(goods);
  536. builder.goods_detail = gList;
  537. //系统商接入可以填此参数用作返佣
  538. //ExtendParams exParam = new ExtendParams();
  539. //exParam.sysServiceProviderId = "20880000000000";
  540. //builder.extendParams = exParam;
  541. return builder;
  542. }
  543. /// <summary>
  544. ///
  545. /// </summary>
  546. /// <param name="payStatus"></param>
  547. /// <returns></returns>
  548. private Tuple<PayStatusEnum, OrderStatusEnum> GetStatusByPayWriteBack(PayStatusEnum payStatus)
  549. {
  550. // 临时:payStatus 0失败,1成功
  551. OrderStatusEnum orderStatus = OrderStatusEnum.UnPay;
  552. switch (payStatus)
  553. {
  554. case PayStatusEnum.Paid:// 成功
  555. orderStatus = OrderStatusEnum.Paid;
  556. break;
  557. default:// 失败
  558. break;
  559. }
  560. return new Tuple<PayStatusEnum, OrderStatusEnum>(payStatus, orderStatus);
  561. }
  562. /// <summary>
  563. /// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组
  564. /// </summary>
  565. /// <returns>request回来的信息组成的数组</returns>
  566. private SortedDictionary<string, string> GetRequestPost()
  567. {
  568. int i = 0;
  569. SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
  570. NameValueCollection coll;
  571. //Load Form variables into NameValueCollection variable.
  572. coll = HttpContext.Current.Request.Form;
  573. // Get names of all forms into a string array.
  574. String[] requestItem = coll.AllKeys;
  575. for (i = 0; i < requestItem.Length; i++)
  576. {
  577. sArray.Add(requestItem[i], HttpContext.Current.Request.Form[requestItem[i]]);
  578. }
  579. return sArray;
  580. }
  581. /// <summary>
  582. /// 对支付宝异步通知的关键参数进行校验
  583. /// </summary>
  584. /// <returns></returns>
  585. private bool CheckParams()
  586. {
  587. bool ret = true;
  588. //获得调用方的appid;
  589. //如果是非授权模式,appid是商户的appid;如果是授权模式(token调用),appid是系统商的appid
  590. string app_id = HttpContext.Current.Request.Form["app_id"];
  591. if (app_id != AliPayConfig.appId)
  592. {
  593. ret = false;
  594. _log4NetHelper.Info($"[支付回写][appid认证失败]:request_appid:{app_id};sys_appid:{AliPayConfig.appId}");
  595. }
  596. return ret;
  597. }
  598. }
  599. }