WechatPayServices.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Transactions;
  6. using EMIS.DataLogic.SystemDAL;
  7. using EMIS.Entities;
  8. using EMIS.Utility.OnlinePay;
  9. using EMIS.ViewModel;
  10. using Senparc.Weixin.TenPay.V3;
  11. namespace EMIS.CommonLogic.SystemServices
  12. {
  13. public class WechatPayServices : BaseServices, IWechatPayServices
  14. {
  15. public WechatPayListDAL WechatPayListDAL { get; set; }
  16. public Lazy<IParameterServices> ParameterServices { get; set; }
  17. public string GetProductId()
  18. {
  19. DateTime today = DateTime.Today;
  20. string productId = ParameterServices.Value.GetParameterValue(CF_ParameterType.WechatProductId);
  21. int seed = 1;
  22. if (productId != null)
  23. {
  24. if (productId.Substring(0, 8) == today.ToString("yyyyMMdd"))
  25. {
  26. seed = Convert.ToInt32(productId.Substring(8, productId.Length - 8)) + 1;
  27. }
  28. }
  29. productId = today.ToString("yyyyMMdd") + seed.ToString().PadLeft(6, '0');
  30. ParameterServices.Value.SaveTo(CF_ParameterType.WechatProductId, productId);
  31. return productId;
  32. }
  33. public void NewPayList(Guid examinationRegistrationID, string orderID)
  34. {
  35. using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
  36. {
  37. var dupOrder = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.OrderID == orderID);
  38. var dbOrder = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  39. var examinationRegistration = WechatPayListDAL.ExaminationRegistrationRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  40. if (dbOrder != null && dbOrder.CreateTime != null)
  41. {
  42. string minutes = Math.Round((5 - DateTime.Now.Subtract(dbOrder.CreateTime.Value).TotalMinutes),1).ToString();
  43. throw new Exception("上一次创建订单未完成,请于" + minutes + "分钟之后再操作");
  44. }
  45. if (dupOrder != null)
  46. {
  47. throw new Exception("商家订单号重复,不能下单。");
  48. }
  49. var wechatPayList = new CF_WechatPayList();
  50. wechatPayList.WechatPayListID = Guid.NewGuid();
  51. wechatPayList.ExaminationRegistrationID = examinationRegistrationID;
  52. wechatPayList.OrderID = orderID;
  53. wechatPayList.RecordStatus = (int)CF_WechatPayRefundStatus.NotRefund;
  54. wechatPayList.CreateTime = DateTime.Now;
  55. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Paying;
  56. //UnitOfWork.Remove<CF_WechatPayList>(x => x.ExaminationRegistrationID == examinationRegistrationID);
  57. //UnitOfWork.Update(examinationRegistration);
  58. UnitOfWork.Add(wechatPayList);
  59. UnitOfWork.Commit();
  60. ts.Complete();
  61. }
  62. }
  63. public void PayFail(Guid examinationRegistrationID, string payForm)
  64. {
  65. var examinationRegistration = WechatPayListDAL.ExaminationRegistrationRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  66. var dbOrder = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  67. if (dbOrder != null)
  68. {
  69. dbOrder.PayForm = payForm;
  70. }
  71. if (examinationRegistration != null)
  72. {
  73. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Paying;
  74. }
  75. this.UnitOfWork.Commit();
  76. }
  77. public void SaveUrl(Guid examinationRegistrationID, string payUrl)
  78. {
  79. var dbOrder = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  80. if (dbOrder != null)
  81. {
  82. dbOrder.PayUrl = payUrl;
  83. }
  84. this.UnitOfWork.Commit();
  85. }
  86. public void UpdateTransactionID(string orderID, string wechatOrderID)
  87. {
  88. var wechatPay = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.OrderID == orderID, (x => x.EX_ExaminationRegistration));
  89. if (wechatPay == null)
  90. {
  91. throw new Exception("找不到对应的商家订单号,收款失败。");
  92. }
  93. wechatPay.WechatOrderID = wechatOrderID;
  94. if (wechatPay.EX_ExaminationRegistration == null)
  95. {
  96. throw new Exception("无法匹配对应的考试报名记录,收款失败。");
  97. }
  98. if (wechatPay.EX_ExaminationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay)
  99. {
  100. return;
  101. }
  102. wechatPay.EX_ExaminationRegistration.PayTime = DateTime.Now;
  103. wechatPay.EX_ExaminationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Paid;
  104. UnitOfWork.Commit();
  105. }
  106. public void UpdateRefund(string orderID, string refundOrderID, decimal fee)
  107. {
  108. var wechatPay = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.OrderID == orderID, (x => x.EX_ExaminationRegistration));
  109. if (wechatPay == null)
  110. {
  111. throw new Exception("找不到对应的商家订单号,退款失败。");
  112. }
  113. wechatPay.RefundOrderID = refundOrderID;
  114. wechatPay.RefundTotal = (wechatPay.RefundTotal ?? 0) + fee;
  115. if (wechatPay.EX_ExaminationRegistration == null)
  116. {
  117. throw new Exception("无法匹配对应的考试报名记录,收款失败。");
  118. }
  119. if (wechatPay.EX_ExaminationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.OnRefund)
  120. {
  121. return;
  122. }
  123. wechatPay.EX_ExaminationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Refunded;
  124. UnitOfWork.Commit();
  125. }
  126. public CF_WechatPayList GetLastOrder(Guid examinationRegistrationID)
  127. {
  128. var wechatPayList = WechatPayListDAL.WechatPayListRepository.GetSingle(x => x.ExaminationRegistrationID == examinationRegistrationID);
  129. return wechatPayList;
  130. }
  131. public List<CF_WechatPayList> SearchWeChatPayList(Guid? userID = null)
  132. {
  133. //查询已有商家订单号,但未有微信订单号的数据(这些数据是未交费,或者缴费中数据)
  134. var wechatpayList = WechatPayListDAL.GetWechatPayListQueryable().Where(x => x.WechatOrderID == null).ToList();
  135. return wechatpayList;
  136. }
  137. /// <summary>
  138. /// 根据向微信商户号查询的订单信息更新报名名单的状态
  139. /// </summary>
  140. /// <param name="orderQueryResultList"></param>
  141. public void UpdateWeChatPay(List<OrderQueryResult> orderQueryResultList)
  142. {
  143. List<CF_WechatPayList> updateWechatPayLists = new List<CF_WechatPayList>();
  144. List<EX_ExaminationRegistration> updateExaminationRegistrationList = new List<EX_ExaminationRegistration>();
  145. List<CF_WechatPayList> deleteWechatPayList = new List<CF_WechatPayList>();
  146. var outnoList = orderQueryResultList.Select(x => x.out_trade_no).ToList();
  147. var dbwechatPayLists = WechatPayListDAL.WechatPayListRepository.Entities.Where(x => outnoList.Contains(x.OrderID)).ToList();
  148. var examinationRegistrationIDList = dbwechatPayLists.Select(x => x.ExaminationRegistrationID).ToList();
  149. var dbexaminationRegistrationList = WechatPayListDAL.ExaminationRegistrationRepository.Entities.Where(x => examinationRegistrationIDList.Contains(x.ExaminationRegistrationID)).ToList();
  150. try
  151. {
  152. foreach (var order in orderQueryResultList)
  153. {
  154. var dborder = dbwechatPayLists.Where(x => x.OrderID == order.out_trade_no).FirstOrDefault();
  155. if (dborder != null)
  156. {
  157. //var wechatPay = dbwechatPayLists.Where(x => x.ExaminationRegistrationID == dborder.ExaminationRegistrationID).ToList();
  158. var examinationRegistration = dbexaminationRegistrationList.Where(x => x.ExaminationRegistrationID == dborder.ExaminationRegistrationID).FirstOrDefault();
  159. if (order.trade_state == "SUCCESS")
  160. {
  161. if (examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay && examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.Paying)
  162. {
  163. continue;
  164. }
  165. dborder.Total = decimal.Parse(order.total_fee)/100;
  166. dborder.WechatOrderID = order.transaction_id;
  167. dborder.PayForm = null;
  168. dborder.PayUrl = null;
  169. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Paid;
  170. examinationRegistration.PayTime = DateTime.ParseExact(order.time_end, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
  171. examinationRegistration.ModifyTime = DateTime.Now;
  172. updateWechatPayLists.Add(dborder);
  173. updateExaminationRegistrationList.Add(examinationRegistration);
  174. }
  175. if (order.trade_state == "CLOSED" || order.trade_state == "PAYERROR")
  176. {
  177. if (examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay && examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.Paying)
  178. {
  179. continue;
  180. }
  181. if (WechatHelper.CloseOrder(dborder.OrderID))
  182. {
  183. deleteWechatPayList.Add(dborder);
  184. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.ForPay;
  185. examinationRegistration.ModifyTime = DateTime.Now;
  186. updateExaminationRegistrationList.Add(examinationRegistration);
  187. }
  188. }
  189. if (order.trade_state == "REVOKED")
  190. {
  191. if (examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay && examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.Paying)
  192. {
  193. continue;
  194. }
  195. if (WechatHelper.CloseOrder(dborder.OrderID))
  196. {
  197. deleteWechatPayList.Add(dborder);
  198. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.ForPay;
  199. examinationRegistration.ModifyTime = DateTime.Now;
  200. updateExaminationRegistrationList.Add(examinationRegistration);
  201. }
  202. }
  203. if (order.trade_state == "REFUND")
  204. {
  205. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Refunded;
  206. examinationRegistration.ModifyTime = DateTime.Now;
  207. updateExaminationRegistrationList.Add(examinationRegistration);
  208. }
  209. if (order.trade_state == "NOTPAY" || order.trade_state == "USERPAYING")
  210. {
  211. if (dborder.CreateTime != null)
  212. {
  213. if (DateTime.Now.Subtract(dborder.CreateTime.Value).TotalSeconds > 60 * 6)
  214. {
  215. if (examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay && examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.Paying)
  216. {
  217. continue;
  218. }
  219. if (WechatHelper.CloseOrder(dborder.OrderID))
  220. {
  221. deleteWechatPayList.Add(dborder);
  222. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.ForPay;
  223. examinationRegistration.ModifyTime = DateTime.Now;
  224. updateExaminationRegistrationList.Add(examinationRegistration);
  225. }
  226. }
  227. }
  228. else {
  229. if (examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.ForPay && examinationRegistration.RecordStatus != (int)EX_ExaminationRegistrationStatus.Paying)
  230. {
  231. continue;
  232. }
  233. examinationRegistration.RecordStatus = (int)EX_ExaminationRegistrationStatus.Paying;
  234. examinationRegistration.ModifyTime = DateTime.Now;
  235. updateExaminationRegistrationList.Add(examinationRegistration);
  236. }
  237. }
  238. }
  239. else
  240. {
  241. continue;
  242. }
  243. }
  244. using (TransactionScope ts = new TransactionScope())
  245. {
  246. UnitOfWork.Delete(deleteWechatPayList);
  247. UnitOfWork.BatchUpdate(updateWechatPayLists);
  248. UnitOfWork.BatchUpdate(updateExaminationRegistrationList);
  249. ts.Complete();
  250. }
  251. }
  252. catch (Exception)
  253. {
  254. throw;
  255. }
  256. }
  257. public void DeleteCanCloseWeChatPay(List<String> OrderIDList)
  258. {
  259. UnitOfWork.Delete<CF_WechatPayList>(x => OrderIDList.Contains(x.OrderID));
  260. }
  261. }
  262. }