using Aop.Api; using Aop.Api.Request; using Aop.Api.Response; using DevComponents.DotNetBar.SuperGrid; using NLog; using POSV.Card; using POSV.Entity; using POSV.Entity.Pormotion; using POSV.Helper; using POSV.PayApi; using POSV.Payment.Saobei; using POSV.Payment.Saobei.Parameter; using POSV.Proxy.ThirdPartyPayMent; using POSV.ShoppingCart; using POSV.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace POSV.Member { public partial class SaomaCheckoutForm : BusinessForm { private static Logger logger = NLog.LogManager.GetCurrentClassLogger(); public decimal PayMoney = 0.00M; public string cardNo = null; /// /// 支付渠道 /// private PayChannelEnum _payChannel = PayChannelEnum.原生支付; public SaomaCheckoutForm(string cardNo,decimal amount) { InitializeComponent(); this.controlBox.Text = "扫码支付核销"; this.controlBox.ShowApplicationVersion = false; this.PayMoney = amount; this.cardNo = cardNo; } private PayMode CurrentPayMode = null; protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (this.DesignMode) return; this.Focus(); this.txtReChargeNo.Focus(); this.txtReChargeNo.SelectAll(); this.ActiveControl = this.txtReChargeNo; QueryTicket(); } /// /// 返回 /// /// /// private void OnCloseTouchClick(object sender, EventArgs e) { //先关闭父窗体 if (this.Owner != null) { this.Owner.Close(); } //再关闭当前窗体 this.Close(); } /// /// 退出 /// /// /// private void BtnClose(object sender, EventArgs e) { OnCloseTouchClick(sender, e); } /// /// 核销 /// /// /// private void BtnCheck(object sender, EventArgs e) { var row = this.payListTable.ActiveRow as GridRow; if (row == null) { this.ShowToastNotify(this, "请选择要核销的数据"); return; } var money = StringUtils.GetDecimal(row.Cells["money"].Value.ToString()); if (this.PayMoney != money) { this.ShowToastNotify(this, "要核销的金额和充值金额不一致"); return; } var orderNo = row.Cells["orderNo"].Value.ToString(); CardRecharge cardRecharge = null; try { using (var db = Global.Instance.OpenDataBase) { string sql = "select * from pos_card_recharge where rechargeNo = '{0}'"; sql = string.Format(sql, orderNo); cardRecharge = db.FirstOrDefault(sql); if (cardRecharge == null) { this.ShowToastNotify(this, "获取充值单据数据失败!"); return; } } } catch (Exception ex) { LOGGER.Error(ex); } if (!cardNo.Equals(cardRecharge.CardNo)) { this.ShowToastNotify(this, "要核销的充值卡号和当前卡号不一致!"); return; } var authCode = row.Cells["authCode"].Value.ToString(); var serialNo = row.Cells["serialNo"].Value == null ? "" : row.Cells["serialNo"].Value.ToString(); this.CurrentPayMode = RechargeSaomaUtils.GetPayMode(authCode).Item3; if (this.CurrentPayMode == null) { this.ShowToastNotify(this, "支付码不合法或尚未适配..."); return; } bool paymentVerify = RechargeSaomaUtils.VerifyInputValue(authCode, this.CurrentPayMode).Item1; if (!paymentVerify) { this.ShowToastNotify(this, "支付渠道获取失败,请检查后台配置"); return; } this._payChannel = RechargeSaomaUtils.VerifyInputValue(authCode, this.CurrentPayMode).Item3; switch (this._payChannel) { case PayChannelEnum.原生支付: { switch (this.CurrentPayMode.No) { case "04": { QueryAliPayResult(cardRecharge); } break; case "05": { QueryWxPayResult(cardRecharge); } break; } } break; case PayChannelEnum.扫呗支付: { QuerySAOBEIPayResult(cardRecharge, serialNo); } break; case PayChannelEnum.乐刷支付: { QueryLESHUAPayResult(cardRecharge ,orderNo, PayChannelEnum.乐刷支付, authCode, serialNo); } break; } } #region 扫呗支付渠道 private void QuerySAOBEIPayResult(CardRecharge cardRecharge, string serialNo) { try { var parameter = this.CurrentPayMode.Body; string merchant_no = parameter.ContainsKey("merchant_no") ? parameter["merchant_no"].ToString() : ""; string terminal_id = parameter.ContainsKey("terminal_id") ? parameter["terminal_id"].ToString() : ""; string signKey = parameter.ContainsKey("signKey") ? parameter["signKey"].ToString() : ""; string gatewayUrl = parameter.ContainsKey("gatewayUrl") ? parameter["gatewayUrl"].ToString() : ""; //商户订单号 string outTradeNo = cardRecharge.RechargeNo; SaobeiQueryParam request = new SaobeiQueryParam(); //支付方式 支付宝1、微信2 request.Pay_type = "020"; if (this.CurrentPayMode.No == "05") { request.Pay_type = "010"; } else if (this.CurrentPayMode.No == "07") { request.Pay_type = "110"; } request.Terminal_trace = outTradeNo.Replace("_", ""); //request.Pay_trace = orderNo.Replace("_", ""); //request.Pay_time = DateTime.Now.ToString("yyyyMMddHHmmss"); request.Out_trade_no = serialNo; var saobeiPayment = SaobeiUtils.SaobeiQuery(merchant_no, terminal_id, signKey, gatewayUrl, request); if (saobeiPayment.Item1) { if (saobeiPayment.Item3 != null && "SUCCESS".Equals(saobeiPayment.Item3.Trade_state)) { //发送消息通知显示文本 this.ShowToastNotify(this, "扫呗支付付款成功,正在充值"); //先查询状态再发起充值 DoQuery(cardRecharge); } else { this.ShowToastNotify(this, "查询结果:" + saobeiPayment.Item3.Return_msg); } } else { this.ShowToastNotify(this, saobeiPayment.Item2); } } catch (Exception ex) { LOGGER.Error(ex, "扫呗付款结果查询发生异常"); } } #endregion private void QueryLESHUAPayResult(CardRecharge cardRecharge ,string orderNo, PayChannelEnum payChannel, string authCode, string serialNo) { string[] _TranNo = orderNo.Split('_'); //var _order = OrderUtils.getOrderObjectByTranNo(_TranNo[1]); //if (_order == null) //{ // //发送消息通知显示文本 // this.ShowToastNotify(this, "查询不到订单对象"); // return; //} Dictionary keys = new Dictionary(); var _data = PayMentOperation.QueryPay(authCode, _TranNo[1], serialNo, payChannel, keys); if (!_data.Item1) { //发送消息通知显示文本 this.ShowToastNotify(this, _data.Item2); return; } DoQuery(cardRecharge); //发送消息通知显示文本 this.ShowToastNotify(this, "乐刷支付付款成功"); } /// /// 查询 /// /// /// private void BtnQuery(object sender, EventArgs e) { QueryTicket(); } private void QueryTicket() { string orderNo = this.txtReChargeNo.Text; List listPay = getSaomaPayTicket(orderNo); foreach (SaomaPayTicket saomaPayTicket in listPay) { if (saomaPayTicket.PayStatus==0) { saomaPayTicket.OrderStatus = "未核销"; } else if (saomaPayTicket.PayStatus == 1) { saomaPayTicket.OrderStatus = "核销成功"; } } payListTable.PrimaryGrid.DataSource = listPay; } public List getSaomaPayTicket(string orderNo) { List list = null; try { using (var db = Global.Instance.OpenDataBase) { StringBuilder sqlBuld = new StringBuilder(); sqlBuld.Append(" select * "); sqlBuld.Append(" from pos_saoma_pay_ticket "); sqlBuld.Append(" where busType =1 "); if (orderNo!=null && !"".Equals(orderNo)) { sqlBuld.Append(" and orderNo like '%"+ orderNo + "%' "); } sqlBuld.Append(" and storeId ='{0}' and shiftNo = '{1}' "); sqlBuld.Append(" order by createDate desc "); string sql = string.Format(sqlBuld.ToString(), Global.Instance.BusinessPlanLog.StoreId, Global.Instance.BusinessPlanLog.No); list = db.Query(sql).ToList(); } } catch (Exception ex) { LOGGER.Error(ex); } if (list == null) { list = new List(); } return list; } public void updateCardRechargePayType(CardRecharge cardRecharge) { try { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { string sql_pay = "update pos_card_recharge_pay set payNo ='{0}' ,payName ='{1}' where voucherNo = '{2}'"; sql_pay = string.Format(sql_pay, this.CurrentPayMode.No, this.CurrentPayMode.Name, cardRecharge.RechargeNo); db.Execute(sql_pay, null); transaction.Complete(); logger.Info("单号:[{2}]支付方式 payNo==>{1},payName==>{1}......成功", this.CurrentPayMode.No, this.CurrentPayMode.Name, cardRecharge.RechargeNo); } } } } catch (Exception ex) { LOGGER.Error(ex); } } #region 原生微信支付渠道查询 /// /// 微信支付结果查询 /// private void QueryWxPayResult(CardRecharge cardRecharge) { try { var parameter = this.CurrentPayMode.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 nonceStr = "x86" + ObjectId.GenerateNewStringId(); var dataInfo = new WxPayV3OrderQueryRequestData(appId, "", mchId, subMchId, "", nonceStr, cardRecharge.RechargeNo, key); var result = WxPayV3.OrderQuery(dataInfo); if ("SUCCESS".Equals(result.return_code)) { if ("SUCCESS".Equals(result.result_code)) { var tradeState = WxPayTradeState.NONE; Enum.TryParse(result.trade_state, out tradeState); switch (tradeState) { case WxPayTradeState.SUCCESS: { this.ShowToastNotify(this, "微信支付成功,正在进行充值"); //先查询状态再发起充值 DoQuery(cardRecharge); } break; case WxPayTradeState.USERPAYING: { this.ShowToastNotify(this, "未查询到订单是否支付成功,请再次确认"); } break; case WxPayTradeState.NOTPAY: case WxPayTradeState.PAYERROR: { this.ShowToastNotify(this, "密码错误或未输入,微信支付失败"); } break; default: break; } } else { this.ShowToastNotify(this, "未查询到订单是否支付成功,请再次确认"); } } else { LOGGER.Warn("查询支付结果网络通信错误:{0}", result.return_msg); this.ShowToastNotify(this, result.return_msg); } } catch (Exception ex) { this.ShowToastNotify(this, "微信支付结果查询发生异常,请再次确认"); LOGGER.Error(ex, "微信支付结果查询发生异常"); } } #endregion #region 原生支付宝渠道查询 /// /// 支付宝支付结果查询 /// /// private void QueryAliPayResult(CardRecharge cardRecharge) { try { var parameter = this.CurrentPayMode.Body; string appId = parameter.ContainsKey("appid") ? parameter["appid"].ToString() : ""; string privateKey = parameter.ContainsKey("privatekey") ? parameter["privatekey"].ToString() : ""; string appAuthToken = parameter.ContainsKey("appAuthToken") ? parameter["appAuthToken"].ToString() : ""; string storeNo = parameter.ContainsKey("storeNo") ? parameter["storeNo"].ToString() : ""; string signType = parameter.ContainsKey("signType") ? parameter["signType"].ToString() : "RSA"; DefaultAopClient client = null; if ("RSA2".Equals(signType)) { client = new DefaultAopClient(Global.Instance.AliPayServerUrl, appId, privateKey, "json", "utf-8", "RSA2"); } else { client = new DefaultAopClient(Global.Instance.AliPayServerUrl, appId, privateKey, false); } var request = new AlipayTradeQueryRequest(); var content = new Dictionary(); content.Add("out_trade_no", cardRecharge.RechargeNo); request.BizContent = JsonUtils.Serialize(content); AlipayTradeQueryResponse response = client.Execute(request, string.Empty, appAuthToken); switch (response.TradeStatus) { case "TRADE_SUCCESS": { //发送消息通知显示文本 this.ShowToastNotify(this, "支付宝付款成功,正在充值"); //先查询状态再发起充值 DoQuery(cardRecharge); } break; case "WAIT_BUYER_PAY": { this.ShowToastNotify(this, "等待买家付款,未查询到支付成功过状态"); } break; default: { this.ShowToastNotify(this, "等待买家付款,未查询到支付成功过状态"); } break; } } catch (Exception ex) { this.ShowToastNotify(this, "支付宝结果查询发生异常"); LOGGER.Error(ex, "支付宝结果查询发生异常"); } } #endregion /// /// 查询核销 /// /// public void DoQuery(CardRecharge cardRecharge) { //如果已经充值成功,直接提示核销成功,如果之前的订单没有充值成功,就进行核销充值 if (cardRecharge.RechargeStatus == 2) { logger.Info("支付查询已成功,凭证号[{0}]......", cardRecharge.RechargeNo); try { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......开始", cardRecharge.RechargeNo); string sql = "update pos_saoma_pay_ticket set payStatus =1 where orderNo = '{0}'"; sql = string.Format(sql, cardRecharge.RechargeNo); db.Execute(sql, null); transaction.Complete(); logger.Info("单号:[{0}]更改扫码支付状态 payStatus==>1......更新成功", cardRecharge.RechargeNo); } } } } catch (Exception ex) { LOGGER.Error(ex); } this.ShowToastNotify(this, string.Format("支付核销成功,本地订单号[{0}]已充值成功", cardRecharge.RechargeNo)); return; } else { updateCardRechargePayType(cardRecharge); } var requestRecharge = JsonUtils.Deserialize(cardRecharge.RequestMessage); logger.Info("发起充值查询 请求,凭证号[{0}]......", cardRecharge.RechargeNo); CardRechargeQueryRequest request = new CardRechargeQueryRequest(); request.PayVoucherNo = cardRecharge.RechargeNo; request.ShopNo = Global.Instance.Authc.StoreNo; request.PosNo = Global.Instance.Authc.PosNo; request.WorkerNo = Global.Instance.Worker.No; request.SourceSign = "pos"; //转换请求对象 var response = CardUtils.CardRechargeQuery(request); //先去查询充值状态 if (response.Item1 && response.Item3.Data != null && response.Item3.Data.CardNo != null) { //如果充值单号已成功充值 logger.Info("充值查询 已成功,凭证号[{0}]......", cardRecharge.RechargeNo); //更新本地充值状态 updateCardRecharge(cardRecharge.RechargeNo, 2, 2); this.ShowToastNotify(this, response.Item2); //打印充值结果 logger.Info("充值查询 成功打印,凭证号[{0}]......", cardRecharge.RechargeNo); this.ShowToastNotify(this, "开始打印"); //构建收银小票模版参数打印 var vars = CardHelper.BuilderRechargeQueryVariable(requestRecharge, response.Item3.Data); //充值打印份数 int ticketCount = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_RECHARGE_COUNT, 1); //打印延迟 int delaySecond = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_CARD_PRINT_DELAY, 1); Tuple result = CardHelper.PrinterTicket("会员卡充值", vars, true, false, ticketCount, delaySecond); this.ShowToastNotify(this, string.Format("{0}", result.Item2)); CardRechargeResponse cardRechargeResponse = new CardRechargeResponse(); cardRechargeResponse.CardNo = response.Item3.Data.CardNo; cardRechargeResponse.BatchNo = ""; cardRechargeResponse.SerialNo = response.Item3.Data.PayVoucherNo; cardRechargeResponse.RechargeNo = response.Item3.Data.RechargeNo; cardRechargeResponse.TradeTime = response.Item3.Data.OperateTime; cardRechargeResponse.PreAmount = (int)response.Item3.Data.PreAmount*100; cardRechargeResponse.Amount = (int)response.Item3.Data.ChargeAmount*100; cardRechargeResponse.GiftAmount = (int)response.Item3.Data.GiftAmount*100; cardRechargeResponse.AftAmount = (int)response.Item3.Data.AftAmount*100; cardRechargeResponse.PrePoint = (int)response.Item3.Data.PrePoint*100; cardRechargeResponse.GiftPoint = (int)response.Item3.Data.GiftPoint*100; cardRechargeResponse.AftPoint = (int)response.Item3.Data.AftPoint*100; cardRechargeResponse.GiftDetail =null; cardRechargeResponse.CouponDetail =null; CloseForm(cardRecharge.RechargeNo, requestRecharge, cardRechargeResponse); } else { //发起充值请求 Recharge(cardRecharge); } } public void Recharge(CardRecharge cardRecharge) { logger.Info("发起充值重试请求,凭证号[{0}]......", cardRecharge.RechargeNo); var request = JsonUtils.Deserialize(cardRecharge.RequestMessage); request.PayTypeNo = this.CurrentPayMode.No; request.PayType = this.CurrentPayMode.Name; //转换请求对象 var response = CardUtils.CardRecharge(request); int RechargeStatus = response.Item1 ? 2 : 3; updateCardRecharge(cardRecharge.RechargeNo, 2, RechargeStatus); //成功 if (response.Item1) { logger.Info("充值成功,凭证号[{0}]......", cardRecharge.RechargeNo); this.ShowToastNotify(this, response.Item2); //打印充值结果 logger.Info("充值成功打印,凭证号[{0}]......", cardRecharge.RechargeNo); this.ShowToastNotify(this, "开始打印"); //构建收银小票模版参数打印 var vars = CardHelper.BuilderRechargeVariable(request, response.Item3.Data); //充值打印份数 int ticketCount = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_RECHARGE_COUNT, 1); //打印延迟 int delaySecond = Global.Instance.GlobalConfigIntValue(ConfigConstant.PERIPHERAL_CASHIER_CARD_PRINT_DELAY, 1); Tuple result = CardHelper.PrinterTicket("会员卡充值", vars, true, false, ticketCount, delaySecond); this.ShowToastNotify(this, string.Format("{0}", result.Item2)); CloseForm(cardRecharge.RechargeNo, request, response.Item3.Data); } else { //对于支付成功,充值失败的可以进行重试 this.ShowToastNotify(this, response.Item2); } } /// /// 充值核销成功关闭窗口 /// public void CloseForm(string orderNo, CardRechargeRequest request, CardRechargeResponse response ) { //核心成功,关闭界面 UpDateSaoMaRecharge(orderNo); //打开提示界面 var form = new CardRechargeResultForm(request, response); form.ShowDialog(); //再关闭当前窗体 this.Close(); } public void UpDateSaoMaRecharge(string voucherNo) { try { using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { string sql = "update pos_saoma_pay_ticket set payStatus ={0} where orderNo = '{1}'"; sql = string.Format(sql, 1, voucherNo); db.Execute(sql, null); transaction.Complete(); } } } catch (Exception ex) { LOGGER.Error(ex); } } public void updateCardRecharge(string rechargeNo, int payStatus, int rechargeStatus) { try { lock (Global.Instance.SyncLock) { using (var db = Global.Instance.OpenDataBase) { using (var transaction = db.GetTransaction()) { logger.Info("单号:[{0}]更改订单状态 payStatus==>{1},rechargeStatus==>{2}......开始", rechargeNo, payStatus, rechargeStatus); string sql = "update pos_card_recharge set payStatus ={0} ,rechargeStatus ={1},planNo ='{3}',planName='{4}',createDate ='{5}' where rechargeNo = '{2}'"; sql = string.Format(sql, payStatus, rechargeStatus, rechargeNo, Global.Instance.BusinessPlanLog.No, Global.Instance.BusinessPlanLog.Name, DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); db.Execute(sql, null); transaction.Complete(); logger.Info("单号:[{0}]更改订单状态 payStatus==>{1},rechargeStatus==>{2}......成功", rechargeNo, payStatus, rechargeStatus); } } } } catch (Exception ex) { LOGGER.Error(ex); } } } }