WechatPaymentProcessor.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using Aop.Api.Domain;
  2. using DFS.Core.Abstractions.View;
  3. using Fuel.Core.Models;
  4. using Fuel.Payment.Core;
  5. using Fuel.Payment.Core.Enum;
  6. using Fuel.Payment.Core.Models;
  7. using Fuel.Payment.Service.Factory;
  8. using Newtonsoft.Json;
  9. using Org.BouncyCastle.Asn1.X509;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Globalization;
  13. using System.Linq;
  14. using System.Reflection.PortableExecutable;
  15. using System.Security.Cryptography.X509Certificates;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using Wechat.PayAPI;
  19. namespace Fuel.Payment.Service.WeChatPaymentProcessor.Wechat
  20. {
  21. public class WechatPaymentProcessor : AsyncPaymentProcessor
  22. {
  23. private NLog.Logger logger = NLog.LogManager.GetLogger("Main");
  24. public override async Task<GenericProcessResponse> Cancel(ElectronicOrderModel order)
  25. {
  26. Log.Info("MicroPay", "Micropay failure, reverse order " + order.BillNumber);
  27. order.TradeStatus = TradeStatus.CANCELLING;
  28. var result = await MicroPay.Cancel(order.BillNumber, (WayneCloud.Models.Models.WxPayConfig)order.Config, (X509Certificate2)order.Certification);
  29. if (result)
  30. {
  31. Log.Info("MicroPay", "Micropay Cancel Order successed, order " + order.BillNumber + " has been closed.");
  32. order.TradeStatus = TradeStatus.CLOSED;
  33. }
  34. return new GenericProcessResponse();
  35. }
  36. public override async Task<GenericProcessResponse> Process(ElectronicOrderModel order)
  37. {
  38. order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
  39. order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
  40. TradeStatus tradeStatus = TradeStatus.PAYERROR;
  41. var response = new GenericProcessResponse()
  42. {
  43. WeChatResponse = new WxPayData()
  44. };
  45. if (order.Optional.ContainsKey("preCreatedBillNumber"))
  46. {
  47. response = await Query(order, 40, 2000);
  48. if (response.WeChatResponse.IsSet("trade_state") &&
  49. response.WeChatResponse.GetValue("trade_state") as string == "SUCCESS")
  50. {
  51. tradeStatus = TradeStatus.SUCCESS;
  52. logger.Info("MicroPay TradeStatus.SUCCESS", $"The final MicroPay response is: {response.WeChatResponse.GetValue("trade_state")}");
  53. }
  54. else
  55. {
  56. if (response.WeChatResponse.IsSet("trade_state"))
  57. {
  58. logger.Info("MicroPay", $"The final MicroPay response is: {response.WeChatResponse.GetValue("trade_state")}");
  59. }
  60. else
  61. {
  62. logger.Info("MicroPay", $"The final MicroPay response is: {response.WeChatResponse.GetValue("trade_state")}");
  63. }
  64. }
  65. }
  66. else
  67. {
  68. response.WeChatResponse = await MicroPay.Run(ModelMapper.ConvertToWayneCloudModel(order));
  69. }
  70. logger.Info("MicroPay", "The final MicroPay response is: \r\n" + response.WeChatResponse.ToXml());
  71. return response;
  72. }
  73. public override async Task<GenericProcessResponse> Query(ElectronicOrderModel order)
  74. {
  75. return await Query(order, 1, 2000);
  76. }
  77. public override async Task<GenericProcessResponse> Query(ElectronicOrderModel order, int count, int interval)
  78. {
  79. order.TradeStatus = TradeStatus.PAYERROR;
  80. try
  81. {
  82. Log.Info("MicroPay", "Wechat OrderQuery is processing order: " + order.BillNumber);
  83. var result = await MicroPay.RunQuery(ModelMapper.ConvertToWayneCloudModel(order), count, interval);
  84. Log.Info("MicroPay", "Wechat OrderQuery process complete, result : \r\n" + result.ToXml());
  85. order.TradeStatus = TradeStatus.SUCCESS;
  86. return new GenericProcessResponse()
  87. {
  88. WeChatResponse = result
  89. };
  90. }
  91. catch (Exception e)
  92. {
  93. return new GenericProcessResponse()
  94. {
  95. };
  96. }
  97. }
  98. public override async Task<GenericProcessResponse> Return(ElectronicOrderModel order)
  99. {
  100. Log.Info("MicroPay", "MicroPay is processing refund, BillNumber = " + order.BillNumber);
  101. order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
  102. order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
  103. TradeStatus tradeStatus;
  104. //var result = Refund.Run("", order.BillNumber,
  105. // order.TotalAmount.ToString(), order.NetAmount.ToString(), out tradeStatus);
  106. var result = await Refund.Run("", ModelMapper.ConvertToWayneCloudModel(order));
  107. Log.Info("MicroPay", "The final MicroPay response is: \r\n" + result.ToXml());
  108. var Generic = new GenericProcessResponse()
  109. {
  110. WeChatResponse = result
  111. };
  112. var ProcessResults = await ReturnResult(Generic, order);
  113. Generic.ProcessResults = ProcessResults.ProcessResults;
  114. return Generic;
  115. }
  116. public override async Task<GenericProcessResponse> UnifiedOrder(ElectronicOrderModel order)
  117. {
  118. try
  119. {
  120. order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
  121. order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
  122. Log.Info("UnifiedOrder", "UnifiedOrder is processing order " + order.BillNumber);
  123. var result = await MicroPay.UnifiedOrder(ModelMapper.ConvertToWayneCloudModel(order));
  124. Log.Info("UnifiedOrder", "The final MicroPay UnifiedOrder is: \r\n" + result.ToXml());
  125. var Generic = new GenericProcessResponse()
  126. {
  127. WeChatResponse = result
  128. };
  129. var ProcessResults = await UnifiedOrderResult(Generic, order);
  130. Generic.UnifiedOrderResult = ProcessResults;
  131. return Generic;
  132. }
  133. catch (Exception ex)
  134. {
  135. Log.Info("UnifiedOrder", "WechatPaymentProcessor :" + ex.Message);
  136. return new GenericProcessResponse()
  137. {
  138. };
  139. }
  140. }
  141. protected override async Task<GenericProcessResponse> Initialize(ElectronicOrderModel order)
  142. {
  143. try
  144. {
  145. string sourceFilePath = @"C:\cw\Code\smartfuel_lite\FuelCloud\src\Fuel.Payment.Server\File\Certificate\12345678-9abc-def0-1234-56789abcdef0\apiclient_cert.p12";
  146. //string sourceFilePath = @"D:/fuelcloud/fabu/File/Certificate/12345678-9abc-def0-1234-56789abcdef0/apiclient_cert.p12";
  147. string config = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<WxPayConfig> \r\n <APPID>wxb198dafff060e651</APPID> \r\n <SUBAPPID></SUBAPPID>\r\n <MINI_PROGRAM_APPID>wxb198dafff060e651</MINI_PROGRAM_APPID>\r\n <MCHID>1617253894</MCHID>\r\n <SUBMCHID></SUBMCHID>\r\n <KEY>Kguangzhouhengshangongsi20250211</KEY>\r\n <APPSECRET>2e6ee037b95c8fb90eb415bb559f8259</APPSECRET>\r\n <SSLCERT>apiclient_cert.p12</SSLCERT>\r\n <SSLCERT_PASSWORD>1617253894</SSLCERT_PASSWORD>\r\n <NOTIFY_URL>http://paysdk.weixin.qq.com/example/ResultNotifyPage.aspx</NOTIFY_URL>\r\n <IP>8.8.8.8</IP>\r\n <PROXY_URL>http://10.152.18.220:8080</PROXY_URL>\r\n <REPORT_LEVENL>1</REPORT_LEVENL>\r\n</WxPayConfig>";
  148. FileHandler fileHandler = new FileHandler();
  149. byte[] fileBytes = fileHandler.ReadFileToByteArray(sourceFilePath);
  150. order.Certification = fileHandler.GetWxPayCertificationInfo(fileBytes, "1617253894").Result.Certification;
  151. WayneCloud.Models.Models.WxPayConfig wxPayConfig = WayneCloud.Models.Models.WxPayConfig.DeserializeFromXmlString(config);
  152. order.Config = wxPayConfig;
  153. return new GenericProcessResponse()
  154. {
  155. electronicOrderModel = order
  156. };
  157. }
  158. catch(Exception ex)
  159. {
  160. Log.Info("UnifiedOrder", "Initialize :" + ex.Message);
  161. return new GenericProcessResponse()
  162. {
  163. };
  164. }
  165. }
  166. protected override async Task<ElectronicOrderModel> PaymentResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
  167. {
  168. throw new NotImplementedException();
  169. }
  170. /// <summary>
  171. /// 统一下单结果
  172. /// </summary>
  173. /// <param name="processResponse"></param>
  174. /// <param name="eOrder"></param>
  175. /// <returns></returns>
  176. protected override async Task<object> UnifiedOrderResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
  177. {
  178. var returnCode = ReturnCode.PAY_ERROR;
  179. object response = null;
  180. var wechatResponse = order.WeChatResponse;
  181. if (electronicOrderModel.TradeStatus == TradeStatus.SUCCESS && wechatResponse.IsSet("prepay_id"))
  182. {
  183. var prepayId = wechatResponse.GetValue("prepay_id");
  184. var payInfo = new PayInfo();
  185. var config = electronicOrderModel.Config as WayneCloud.Models.Models.WxPayConfig;
  186. payInfo.appId = config.MINI_PROGRAM_APPID;
  187. payInfo.package = "prepay_id=" + prepayId;
  188. payInfo.signType = "MD5";
  189. payInfo.timeStamp = WayneCloud.Models.Models.SignUtility.GetSecondsSince1970();
  190. payInfo.nonceStr = WayneCloud.Models.Models.SignUtility.GenerateRondomString(new Random(), 32);
  191. payInfo.paySign = WayneCloud.Models.Models.SignUtility.GenerateSignature(WayneCloud.Models.Models.SignUtility.BuildSignData(payInfo), config.KEY);
  192. payInfo.billNumber = electronicOrderModel.BillNumber;
  193. response = payInfo;
  194. }
  195. electronicOrderModel.UnifiedOrderResult = response;
  196. return electronicOrderModel;
  197. }
  198. protected override async Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse processResponse, ElectronicOrderModel eOrder)
  199. {
  200. var returnCode = ReturnCode.PAY_ERROR;
  201. var wechatResponse = processResponse.WeChatResponse;
  202. if (eOrder.TradeStatus == TradeStatus.SUCCESS)
  203. {
  204. returnCode = ReturnCode.OK;
  205. }
  206. else
  207. {
  208. returnCode = ReturnCode.PAY_ERROR;
  209. if (!eOrder.IsRefund)
  210. {
  211. //cancelOrder = true;
  212. }
  213. }
  214. List<ElectronicOrderProcessResultModel> electronicOrderProcessResultModels = new List<ElectronicOrderProcessResultModel>();
  215. electronicOrderProcessResultModels.Add(new ElectronicOrderProcessResultModel()
  216. {
  217. BillNumber = eOrder.BillNumber,
  218. ResultCode = ((int)returnCode).ToString(CultureInfo.InvariantCulture),
  219. ResultMessage = returnCode.ToString(),
  220. ErrorDetail = wechatResponse.IsSet("err_code") ? wechatResponse.GetValue("err_code").ToString() : "",
  221. RawResult = wechatResponse.ToXml()
  222. });
  223. eOrder.ProcessResults = electronicOrderProcessResultModels;
  224. return eOrder;
  225. }
  226. }
  227. }