using Aop.Api; using Aop.Api.Request; using Aop.Api.Response; using NLog; using POSV.ShoppingCart; using POSV.Utils; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; namespace POSV.PayApi { public class WeixinApi { private static Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static Dictionary> clientDic = new Dictionary>(); /// /// 获取微信账户信息 /// /// /// public static Tuple GetWeixinInfo(AccountTypeEnum accountType) { Tuple result = null; switch (accountType) { case AccountTypeEnum.门店: { if (!clientDic.ContainsKey(AccountTypeEnum.门店)) { var payMode = OrderUtils.GetPayMode("05"); var parameter = payMode.Body; string appId = parameter.ContainsKey("appid") ? parameter["appid"].ToString() : ""; string mchId = parameter.ContainsKey("mchid") ? parameter["mchid"].ToString() : ""; string subMchId = parameter.ContainsKey("submchid") ? parameter["submchid"].ToString() : ""; string key = parameter.ContainsKey("appsecret") ? parameter["appsecret"].ToString() : ""; string certText = payMode.CertText; clientDic.Add(AccountTypeEnum.门店, new Tuple(appId, mchId, subMchId, key, certText)); } return clientDic[AccountTypeEnum.门店]; } break; } return result; } /// /// 微信退款申请 /// /// /// /// /// /// /// public static Tuple RefundByWeixin(AccountTypeEnum accountType, string tradeNo, decimal totalAmount, decimal refundAmount, string refundNo, string reason) { lock (Global.Instance.SyncLock) { try { logger.Info("订单[{0}]开始发起微信退款......", tradeNo); string nonceStr = "x86" + ObjectId.GenerateNewStringId(); string totalAmountStr = Convert.ToInt32(totalAmount * 100) + ""; string RefundAmountStr = Convert.ToInt32(refundAmount * 100) + ""; var accountInfo = GetWeixinInfo(accountType); if(accountInfo != null) { if (!string.IsNullOrEmpty(accountInfo.Item5)) { string appId = accountInfo.Item1; string mchId = accountInfo.Item2; string subMchId = accountInfo.Item3; string appSecret = accountInfo.Item4; string certText = accountInfo.Item5; WxPayV3OrderRefundRequestData request = new WxPayV3OrderRefundRequestData(appId, mchId, subMchId, appSecret, nonceStr, null, tradeNo, refundNo, totalAmountStr, RefundAmountStr, "SNY", reason); byte[] certDataArray = Convert.FromBase64String(certText); X509Certificate2 cert = new X509Certificate2(certDataArray, mchId); var refundResult = WxPayV3.OrderRefund(request, cert); logger.Info("订单[{0}]微信退款请求结果:{1}", tradeNo, JsonUtils.Serialize(refundResult)); if ("SUCCESS".Equals(refundResult.return_code)) { if ("SUCCESS".Equals(refundResult.result_code)) { return new Tuple(true, null, refundResult); } else { return new Tuple(false, refundResult.err_code + refundResult.err_code_des, null); } } else { return new Tuple(false, refundResult.return_msg, null); } } else { return new Tuple(false, "未配置微信支付证书(退款必须)", null); } } else { return new Tuple(false, "未配置微信支付参数", null); } } catch (Exception ex) { logger.Error(ex, "订单[{0}]调用微信退款接口异常", tradeNo); return new Tuple(false, "调用微信退款接口异常", null); } } } /// /// 微信退款结果查询 /// /// /// public static Tuple QueryWeixinRefundResult(AccountTypeEnum accountType, string tradeNo, string refundNo) { lock (Global.Instance.SyncLock) { try { logger.Info("订单[{0}]开始发起微信退款查询请求......", tradeNo); string nonceStr = "x86" + ObjectId.GenerateNewStringId(); var accountInfo = GetWeixinInfo(accountType); if (accountInfo != null) { string appId = accountInfo.Item1; string mchId = accountInfo.Item2; string subMchId = accountInfo.Item3; string appSecret = accountInfo.Item4; WxPayV3RefundQueryRequestData request = new WxPayV3RefundQueryRequestData(appId, mchId, subMchId, appSecret, nonceStr, null, tradeNo, refundNo, null); var queryResult = WxPayV3.RefundQuery(request); logger.Info("订单[{0}]微信退款查询结果:{1}", tradeNo, JsonUtils.Serialize(queryResult)); if ("SUCCESS".Equals(queryResult.return_code)) { if ("SUCCESS".Equals(queryResult.result_code)) { return new Tuple(true, null, queryResult); } else { return new Tuple(false, queryResult.err_code + queryResult.err_code_des, null); } } else { return new Tuple(false, queryResult.return_msg, null); } } else { return new Tuple(false, "未配置微信支付参数", null); } } catch (Exception ex) { logger.Error(ex, "订单[{0}]调用微信退款查询接口异常", tradeNo); return new Tuple(false, "调用微信退款查询接口异常", null); } } } /// /// 微信退款+查询结果 /// /// /// /// /// public static Tuple RefundAndQuery(AccountTypeEnum accountType, string tradeNo, decimal totalAmount, decimal refundAmount, string reTradeNo, string reason, int timeout = 60) { try { var refundResponse = RefundByWeixin(accountType, tradeNo, totalAmount, refundAmount, reTradeNo, reason); if (refundResponse.Item1)//请求成功 { //int queryCount = 0; //int sleepTime = 3000; //if(timeout < 60) //{//微信退款较慢,显示最小60秒查询 // timeout = 60; //} //queryCount = (timeout * 1000 / sleepTime); //int i = 0; //60秒超时 //while (i < queryCount) //{ // var queryRefundResponse = QueryWeixinRefundResult(accountType, tradeNo, reTradeNo); // if (queryRefundResponse.Item1 && queryRefundResponse.Item3.refund_status_list.Count > 0 && queryRefundResponse.Item3.refund_status_list[0] == "SUCCESS") // { // return new Tuple(true, "退款成功!"); // } // i++; // System.Threading.Thread.Sleep(3000);//睡眠3秒 //} //if (i == queryCount) //{ // return new Tuple(false, "查询退款结果超时,退单失败!"); //} return new Tuple(true, "退款成功!"); } else if ("ERROR订单已全额退款".Equals(refundResponse.Item2)) { return new Tuple(true, "退款成功!"); } else { //请求失败 return new Tuple(false, refundResponse.Item2); } } catch (Exception ex) { logger.Error(ex, "微信退款发生异常"); return new Tuple(false, "退款发生异常!"); } return new Tuple(false, "退款失败!"); } } }