You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2147 lines
87 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using NLog;
using POSV.Bill;
using POSV.Card;
using POSV.Entity;
using POSV.Entity.Pormotion;
using POSV.MessageEvent;
using POSV.PayApi;
using POSV.Payment.Abmcs;
using POSV.Payment.Saobei;
using POSV.Payment.Saobei.Parameter;
using POSV.Payment.Saobei.Result;
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 CardRechargeSaomaForm : BusinessForm
{
private static Logger logger = NLog.LogManager.GetCurrentClassLogger();
/// <summary>
/// PayStep3初始值
/// </summary>
private int initValue = 10;
/// <summary>
/// 是否等待用户输入支付密码
/// </summary>
private int timeout = 60;
private string OutTradeNo = null;
private string CardNo = null;
//倒计时计时器
private System.Windows.Forms.Timer timer = null;
private const int TIMER_INTERVAL = 1000;
private decimal PayMoney = 0.00M;
private string SAOBEI_QRCodeType = "";
private string SAOBEI_PAYTIME = "";
private string SAOBEI_OrderId = "";
/// <summary>
/// 支付渠道
/// </summary>
private PayChannelEnum _payChannel = PayChannelEnum.;
public CardRechargeSaomaForm(string cardNo, decimal payMoney, string outTradeNo)
{
InitializeComponent();
this.controlBox.Text = "会员卡充值扫码";
this.controlBox.ShowApplicationVersion = false;
this.PayMoney = payMoney;
this.OutTradeNo = outTradeNo;
this.CardNo = cardNo;
//支付结果查询的计时器
this.timer = null;
//this.timer = new System.Timers.Timer(TIMER_INTERVAL);
//this.timer.Elapsed += OnTimerElapsed;
this.timer = new System.Windows.Forms.Timer();
this.timer.Interval = TIMER_INTERVAL;
this.timer.Tick += OnTimerTick;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.SetStyle(ControlStyles.Selectable, true);
if (this.DesignMode) return;
this.Focus();
this.txtPayCode.Multiline = false;
this.txtPayCode.Focus();
this.txtPayCode.SelectAll();
this.ActiveControl = this.txtPayCode;
}
private void OnTimerTick(object sender, EventArgs e)
{
this.Invoke(new Action(() =>
{
switch (this._payChannel)
{
case PayChannelEnum.:
{
QueryPayChannel_0();
}
break;
case PayChannelEnum.:
{
QueryPayChannel_SAOBEI();
}
break;
case PayChannelEnum.:
{
QueryPayChannel_LESHUA();
}
break;
}
}));
LOGGER.Info("查询支付结果中....");
}
#region 农总行支付渠道
private void PayChannel_Abmcs()
{
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待确认扣款结果..."));
try
{
var payResult = AbmcsPayResult();
if (payResult)
{
//计时器停止
this.timer.Stop();
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
logger.Info("农总行付款成功[{0}]......", OutTradeNo);
//商户订单号
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = this.CurrentPayMode.No;
cardSaomaResult.PayModeName = this.CurrentPayMode.Name;
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
else
{
ShowMessage(this.lblInfo, "正在确认扣款状态");
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "农总行支付异常");
}
}
private bool AbmcsPayResult()
{
bool isSuccess = false;
//商户订单号
string outTradeNo = this.OutTradeNo;
var amount = PayMoney;
DLLMsdi dll = null;
try
{
/*
* 输入字符串strIn说明
*
数据字段 类型 长度 备注
交易类型 Char 1 必填字段
交易金额 Char 12 如金额为 12 元填充 000000001200
收银员号 Char 16 选填字段(如没有则留空)
小票号 Char 20 必填字段,必须唯一,交易不明时可以根据小票号查询
订单号 Char 40 选填字段退款,重印结果是必输
款台号 Char 16 选填字段(此号区分唯一终端),没有填空
门店号 Char 10 选填字段,没有填空
支付码 Char 30 被扫支付必填
支付渠道 char 1
选填
1-微信支付
2-支付宝支付
4-银联条码支付
*/
/*
* 交易类型说明:
数据字段 交易类型 备注
1 被扫支付(扫码枪扫手机条码或二维码进行支付) 交易金额必填
3 订单支付(手机扫电脑屏幕二维码) 交易金额必填,支付渠道不填
5 退款 交易金额必填
8 重印最后一笔 交易存在争议时,可验证交易是否成功。
9 重印某一笔
L 签到
S 结算
Q 查询 小票号必填
*/
dll = new DLLMsdi(@"abmcs/chaseInterfaceqr.dll");
StringBuilder strIn = new StringBuilder(1000);
strIn.Append("1").Append("|");//交易类型
var formatAmount = Convert.ToInt32(amount * 100);
strIn.Append(formatAmount.ToString().PadLeft(12, '0')).Append("|");//交易金额
strIn.Append(Global.Instance.Worker.No).Append("|");//收银员号
strIn.Append("").Append("|");//小票号
strIn.Append(outTradeNo).Append("|");//订单号
strIn.Append(Global.Instance.Authc.StoreNo).Append("|");//款台号
strIn.Append(Global.Instance.Authc.StoreNo).Append("|");//门店号
strIn.Append(this.txtPayCode.Text.Trim()).Append("|");//支付码
strIn.Append("").Append("|");//支付渠道
string strInData = strIn.ToString();
LOGGER.Info("请求农总行数据:<{0}>", strInData);
StringBuilder strOut = new StringBuilder(1000);
Abmcs gr = (Abmcs)dll.Invoke("Abmcs", typeof(Abmcs));
gr(strInData, strOut);
string ret_str = strOut.ToString();
LOGGER.Info("农总行返回结果:<{0}>", ret_str);
if (!string.IsNullOrEmpty(ret_str))
{
string[] ret = ret_str.Split('|');
/*
* 返回字符串strOut说明
数据字段 类型 长度 备注
交易种类 Char 1 1- 微信支付 2-支付宝支付 4-银联条码支付
返回码 Char 2 交易是否成功标示, 00 -----成功 其他 -----失败
授权码 Char 6 000000
临时支付卡号 Char 30
金额 Char 32 同输入
订单号 Char 40 订单号
有效期 Char 4 0000
交易日期 Char 8
交易时间 Char 6
交易结果描述 Char 40
商户号 Char 15 银行的商户号
终端号 Char 8 银行的终端号
参考号 Char 12
*/
if (ret.Length >= 13)
{
string resultCode = ret[1];//返回码 00 -----成功,其他 -----失败
string resultMessage = ret[9];//交易结果描述
decimal resultAmount = Convert.ToDecimal(ret[4]) / 100;//金额
string resultOrderId = ret[5];//交易结果描述
if ("00".Equals(resultCode))
{
//支付成功
isSuccess = true;
}
else
{
//支付失败
isSuccess = false;
ShowMessage(this.lblInfo, string.Format("{0}<{1}>", resultCode, resultMessage));
}
}
else
{
ShowMessage(this.lblInfo, "银行应答报文不合法,请尝试手工核销...");
}
}
else
{
ShowMessage(this.lblInfo, "银行没有应答,请尝试手工核销...");
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "农总行扫码支付[" + outTradeNo + "]金额[" + amount + "]发生异常");
isSuccess = false;
ShowMessage(this.lblInfo, "查不到支付状态,请使用手工核销功能...");
}
finally
{
if (dll != null)
{
dll.UnLoad();
}
}
return isSuccess;
}
private void QueryPayChannel_Abmcs()
{
//进度条最大值
int maximum = this.PayStep3.Maximum;
this.PayStep3.Value = (initValue++);
//判断是否超时,如果超时终止计时器,界面反馈信息
if (initValue % this.PayStep3.Maximum == 0)
{
//计时器停止
this.timer.Stop();
//发送结果通知
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "查询支付结果超时"));
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this.OutTradeNo);
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
if (DialogResult.Retry == dialog.ShowDialog())
{
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this.OutTradeNo);
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "等待确认扣款状态"));
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this.OutTradeNo);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
else
{
this.QueryAbmcsPayResult();
}
}
private void QueryAbmcsPayResult()
{
DLLMsdi dll = null;
//商户订单号
string outTradeNo = this.OutTradeNo;
try
{
dll = new DLLMsdi(@"abmcs/chaseInterfaceqr.dll");
StringBuilder strIn = new StringBuilder(1000);
strIn.Append("Q").Append("|");//交易类型
strIn.Append("").Append("|");//交易金额
strIn.Append(Global.Instance.Worker.No).Append("|");//收银员号
strIn.Append("").Append("|");//小票号
strIn.Append(outTradeNo).Append("|");//订单号
strIn.Append("").Append("|");//款台号
strIn.Append("").Append("|");//门店号
strIn.Append("").Append("|");//支付码
strIn.Append("").Append("|");//支付渠道
string strInData = strIn.ToString();
LOGGER.Info("查询请求农总行数据:<{0}>", strInData);
StringBuilder strOut = new StringBuilder(1000);
Abmcs gr = (Abmcs)dll.Invoke("Abmcs", typeof(Abmcs));
gr(strInData, strOut);
string ret_str = strOut.ToString();
LOGGER.Info("农总行返回查询结果:<{0}>", ret_str);
if (!string.IsNullOrEmpty(ret_str))
{
string[] ret = ret_str.Split('|');
/*
* 返回字符串strOut说明
数据字段 类型 长度 备注
交易种类 Char 1 1- 微信支付 2-支付宝支付 4-银联条码支付
返回码 Char 2 交易是否成功标示, 00 -----成功 其他 -----失败
授权码 Char 6 000000
临时支付卡号 Char 30
金额 Char 32 同输入
订单号 Char 40 订单号
有效期 Char 4 0000
交易日期 Char 8
交易时间 Char 6
交易结果描述 Char 40
商户号 Char 15 银行的商户号
终端号 Char 8 银行的终端号
参考号 Char 12
*/
if (ret.Length >= 13)
{
string resultCode = ret[1];//返回码 00 -----成功,其他 -----失败
string resultMessage = ret[9];//交易结果描述
decimal resultAmount = Convert.ToDecimal(ret[4]) / 100;//金额
string resultOrderId = ret[5];//交易结果描述
if ("00".Equals(resultCode))
{
//计时器停止
this.timer.Stop();
this.PayStep3.Value = this.PayStep3.Maximum;
//发送消息通知显示文本
ShowMessage(this.lblInfo, "农总行付款成功", false);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
logger.Info("农总行付款成功[{0}]......", OutTradeNo);
//商户订单号
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = this.CurrentPayMode.No;
cardSaomaResult.PayModeName = this.CurrentPayMode.Name;
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
else
{
ShowMessage(this.lblInfo, string.Format("{0}<{1}>", resultCode, resultMessage));
}
}
else
{
ShowMessage(this.lblInfo, "银行应答报文不合法,请尝试手工核销...");
}
}
else
{
//明确失败,结束查询
//计时器停止
this.timer.Stop();
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
ShowMessage(this.lblInfo, "查询不到银行付款结果,请尝试核销功能");
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "农总行付款结果查询订单[" + outTradeNo + "]发生异常");
}
finally
{
if (dll != null)
{
dll.UnLoad();
}
}
}
#endregion
#region 扫呗支付渠道
private void PayChannel_SAOBEI()
{
var isQuery = SAOBEIPayResult();
if (isQuery)
{
ShowMessage(this.lblInfo, "正在确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
private bool SAOBEIPayResult()
{
bool isQuery = false;
//商户订单号
string outTradeNo = this.OutTradeNo;
var amount = PayMoney;
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() : "";
SaobeiPaymentParam request = new SaobeiPaymentParam();
request.Terminal_trace = outTradeNo.Replace("_", "");
request.Auth_no = this.txtPayCode.Text.Trim();
request.Total_fee = string.Format("{0}", Convert.ToInt32(amount * 100));
request.Terminal_time = DateTime.Now.ToString("yyyyMMddHHmmss");
this.SAOBEI_PAYTIME = request.Terminal_time;
//支付方式 支付宝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";
}
this.SAOBEI_QRCodeType = request.Pay_type;
var saobeiPayment = SaobeiUtils.SaobeiPayment(merchant_no, terminal_id, signKey, gatewayUrl, request);
if (saobeiPayment.Item1)
{
SaobeiPaymentResult saobeiPaymentResult = saobeiPayment.Item3;
this.SAOBEI_QRCodeType = saobeiPaymentResult.Pay_type;
this.SAOBEI_OrderId = saobeiPaymentResult.Out_trade_no;
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
//支付结果需要查询
isQuery = true;
ShowMessage(this.lblInfo, "等待确认扣款结果...", true);
}
else
{
this.SAOBEI_QRCodeType = "";
this.SAOBEI_OrderId = "";
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
isQuery = false;
ShowMessage(this.lblInfo, string.Format("{0}", saobeiPayment.Item2), true);
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "扫呗支付订单[" + outTradeNo + "]金额[" + amount + "]发生异常!");
this.SAOBEI_QRCodeType = "";
this.SAOBEI_OrderId = "";
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
isQuery = true;
ShowMessage(this.lblInfo, "等待确认扣款结果...", true);
}
return isQuery;
}
public bool UpdateSaomaTicket(string orderNo, string serialNo, string payTime)
{
try
{
lock (Global.Instance.SyncLock)
{
using (var db = Global.Instance.OpenDataBase)
{
using (var transaction = db.GetTransaction())
{
string sql = "update pos_saoma_pay_ticket set serialNo ='{0}',payTime='{1}' where orderNo = '{2}' and busType = 1 and storeId ='{3}'";
sql = string.Format(sql, serialNo, payTime, orderNo, Global.Instance.BusinessPlanLog.StoreId);
db.Execute(sql, null);
transaction.Complete();
return false;
}
}
}
}
catch (Exception ex)
{
LOGGER.Error(ex);
}
return true;
}
private void QueryPayChannel_SAOBEI()
{
//进度条最大值
int maximum = this.PayStep3.Maximum;
this.PayStep3.Value = (initValue++);
//判断是否超时,如果超时终止计时器,界面反馈信息
if (initValue % this.PayStep3.Maximum == 0)
{
//计时器停止
this.timer.Stop();
//修改结果颜色
//this.PayStep3.ProgressColors = new Color[] { Color.Red , Color.Red };
//发送结果通知
ShowMessage(this.lblInfo, "查询支付结果超时", true);
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this.OutTradeNo);
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
if (DialogResult.Retry == dialog.ShowDialog())
{
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this.OutTradeNo);
ShowMessage(this.lblInfo, "等待确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this.OutTradeNo);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
else
{
this.QuerySAOBEIPayResult();
}
}
private void QuerySAOBEIPayResult()
{
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 = this.OutTradeNo;
SaobeiQueryParam request = new SaobeiQueryParam();
request.Pay_type = this.SAOBEI_QRCodeType;
request.Terminal_trace = outTradeNo.Replace("_", "");
request.Pay_trace = outTradeNo.Replace("_", "");
request.Pay_time = this.SAOBEI_PAYTIME;
request.Out_trade_no = this.SAOBEI_OrderId;
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.timer.Stop();
this.PayStep3.Value = this.PayStep3.Maximum;
//发送消息通知显示文本
ShowMessage(this.lblInfo, "扫呗支付付款成功", false);
//构建支付方式
this.AddSAOBEIPayType(saobeiPayment.Item3);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
else
{
ShowMessage(this.lblInfo, "查询结果:" + saobeiPayment.Item3.Return_msg, true);
}
}
else
{
//明确失败,结束查询
//计时器停止
this.timer.Stop();
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
ShowMessage(this.lblInfo, saobeiPayment.Item2, true);
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "扫呗支付付款结果查询发生异常");
}
}
private void AddSAOBEIPayType(SaobeiQueryResult queryParam)
{
if (queryParam != null && "SUCCESS".Equals(queryParam.Trade_state))
{
//计时器停止
this.timer.Stop();
logger.Info("扫呗支付成功[{0}]......", OutTradeNo);
//商户订单号
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = this.CurrentPayMode.No;
cardSaomaResult.PayModeName = this.CurrentPayMode.Name;
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
}
#endregion
private void QueryPayChannel_LESHUA()
{
//进度条最大值
int maximum = this.PayStep3.Maximum;
this.PayStep3.Value = (initValue++);
//判断是否超时,如果超时终止计时器,界面反馈信息
if (initValue % this.PayStep3.Maximum == 0)
{
//计时器停止
this.timer.Stop();
//修改结果颜色
//this.PayStep3.ProgressColors = new Color[] { Color.Red , Color.Red };
//发送结果通知
ShowMessage(this.lblInfo, "查询支付结果超时", true);
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this.OutTradeNo);
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
if (DialogResult.Retry == dialog.ShowDialog())
{
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this.OutTradeNo);
ShowMessage(this.lblInfo, "等待确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
}
else
{
using (var _db = Global.Instance.OpenDataBase)
{
var _ticket = _db.FirstOrDefault<SaomaPayTicket>(string.Format("where orderNo = '{0}'", this.OutTradeNo));
if (_ticket == null)
{
this.ShowToastNotify(this, "程序找不到对应的支付数据");
return;
}
Dictionary<string, string> keys = new Dictionary<string, string>();
var _data = PayMentOperation.QueryPay(this.txtPayCode.Text, this.OutTradeNo, _ticket.SerialNo, this._payChannel, keys);
if (_data.Item1)
{
this.timer.Stop();
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = this.CurrentPayMode.No;
cardSaomaResult.PayModeName = this.CurrentPayMode.Name;
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
else
{
ShowMessage(this.lblInfo, "查询结果:" + _data.Item2, true);
}
}
}
}
/// <summary>
/// 操作是否验证通过
/// </summary>
private bool PaymentVerify = false;
/// <summary>
/// 当前的支付方式
/// </summary>
private PayMode CurrentPayMode = null;
private void OnKeyboardBefore(object sender, BillKeyboardEventArgs e)
{
this.PaymentVerify = false;
this.CurrentPayMode = null;
if (this.PayMoney > 0)
{
//获取扫描码
var payCode = this.txtPayCode.Text.Trim();
if (string.IsNullOrEmpty(payCode))
{
ShowMessage(this.lblInfo, "请扫描或输入支付码...", true);
this.PaymentVerify = false;
}
else
{
this.CurrentPayMode = RechargeSaomaUtils.GetPayMode(payCode).Item3;
if (this.CurrentPayMode == null)
{
ShowMessage(this.lblInfo, "支付码不合法或尚未适配...", true);
this.PaymentVerify = false;
}
else
{
ShowMessage(this.lblInfo, "扫描" + this.CurrentPayMode.Name + "付款码...", true);
var verifyInputValue = RechargeSaomaUtils.VerifyInputValue(payCode, this.CurrentPayMode);
this.PaymentVerify = verifyInputValue.Item1;
this._payChannel = verifyInputValue.Item3;
if (!this.PaymentVerify)
{
ShowMessage(this.lblInfo, "尚未配置支付参数...", true);
}
}
}
}
else
{
ShowMessage(this.lblInfo, "付款金额非法...", true);
this.PaymentVerify = false;
}
}
private void QueryWxPayResult()
{
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, OutTradeNo, 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.timer.Stop();
this.PayStep3.Value = this.PayStep3.Maximum;
//发送消息通知显示文本
ShowMessage(this.lblInfo, "微信支付成功", false);
//构建微信支付方式
this.AddWxPayType(result);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
break;
case WxPayTradeState.USERPAYING:
{
string message = string.Format("{0}:{1}秒", "请提示用户输入支付密码", --timeout);
//MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, message));
ShowMessage(this.lblInfo, message, true);
}
break;
case WxPayTradeState.NOTPAY:
case WxPayTradeState.PAYERROR:
{
//计时器停止
this.timer.Stop();
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
ShowMessage(this.lblInfo, "密码错误或未输入,请重新扫码", true);
}
break;
default:
{
string message = string.Format("{0}:{1}秒", result.trade_state_desc, --timeout);
ShowMessage(this.lblInfo, message, true);
}
break;
}
}
else
{
string message = string.Format("正在确认微信扣款结果:{0}秒,{1}", --timeout, result.err_code_des);
ShowMessage(this.lblInfo, message, true);
}
}
else
{
LOGGER.Warn("查询支付结果网络通信错误:{0}", result.return_msg);
ShowMessage(this.lblInfo, result.return_msg, true);
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "微信支付结果查询发生异常");
}
}
private void AddWxPayType(OrderQueryResult result)
{
if (result != null && "SUCCESS".Equals(result.return_code) && "SUCCESS".Equals(result.result_code))
{
//计时器停止
this.timer.Stop();
logger.Info("微信支付成功[{0}]......", OutTradeNo);
//商户订单号
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = "05";
cardSaomaResult.PayModeName = "微信支付";
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
}
private void QueryAliPayResult()
{
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<string, object>();
content.Add("out_trade_no", OutTradeNo);
request.BizContent = JsonUtils.Serialize(content);
AlipayTradeQueryResponse response = client.Execute(request, string.Empty, appAuthToken);
switch (response.TradeStatus)
{
case "TRADE_SUCCESS":
{
//计时器停止
this.timer.Stop();
this.PayStep3.Value = this.PayStep3.Maximum;
//发送消息通知显示文本
ShowMessage(this.lblInfo, "支付宝付款成功", false);
//构建支付宝支付方式
this.AddAliPayType(response);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
break;
case "WAIT_BUYER_PAY":
{
ShowMessage(this.lblInfo, "等待买家付款...", false);
}
break;
default:
{
ShowMessage(this.lblInfo, "等待买家付款...", false);
}
break;
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "支付宝结果查询发生异常");
}
}
private void AddAliPayType(AlipayTradeQueryResponse result)
{
if (result != null && "TRADE_SUCCESS".Equals(result.TradeStatus))
{
//计时器停止
this.timer.Stop();
logger.Info("支付宝支付成功[{0}]......", OutTradeNo);
//商户订单号
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = "04";
cardSaomaResult.PayModeName = "支付宝";
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
}
private void OnKeyboardAfter(object sender, BillKeyboardEventArgs e)
{
switch (e.KeyCode)
{
case "clear":
//如果当前焦点控件是输入框
if (this.ActiveControl is TextBox)
{
var activeControl = this.ActiveControl as TextBox;
activeControl.Text = string.Empty;
}
break;
case "accept":
//验证通过
if (this.PaymentVerify && this.CurrentPayMode != null)
{
//根据支付状态
updateCardRecharge(OutTradeNo, 3, 1, this.txtPayCode.Text.Trim());
switch (this._payChannel)
{
case PayChannelEnum.:
{
this.PayChannel_0();
}
break;
case PayChannelEnum.:
{
this.PayChannel_LESHUA();
}
break;
case PayChannelEnum.:
{
this.PayChannel_SAOBEI();
}
break;
}
}
break;
case "100":
{
//如果当前焦点控件是输入框
if (this.ActiveControl is TextBox)
{
var activeControl = this.ActiveControl as TextBox;
activeControl.Text = string.Empty;
}
InputSimulatorUtils.SendKey(KeyCodes.Map["1"]);
InputSimulatorUtils.SendKey(KeyCodes.Map["0"]);
InputSimulatorUtils.SendKey(KeyCodes.Map["0"]);
}
break;
case "50":
{
//如果当前焦点控件是输入框
if (this.ActiveControl is TextBox)
{
var activeControl = this.ActiveControl as TextBox;
activeControl.Text = string.Empty;
}
InputSimulatorUtils.SendKey(KeyCodes.Map["5"]);
InputSimulatorUtils.SendKey(KeyCodes.Map["0"]);
}
break;
case "20":
{
//如果当前焦点控件是输入框
if (this.ActiveControl is TextBox)
{
var activeControl = this.ActiveControl as TextBox;
activeControl.Text = string.Empty;
}
InputSimulatorUtils.SendKey(KeyCodes.Map["2"]);
InputSimulatorUtils.SendKey(KeyCodes.Map["0"]);
}
break;
case "10":
{
//如果当前焦点控件是输入框
if (this.ActiveControl is TextBox)
{
var activeControl = this.ActiveControl as TextBox;
activeControl.Text = string.Empty;
}
InputSimulatorUtils.SendKey(KeyCodes.Map["1"]);
InputSimulatorUtils.SendKey(KeyCodes.Map["0"]);
}
break;
default:
{
InputSimulatorUtils.SendKey(KeyCodes.Map[e.KeyCode]);
}
break;
}
}
private void PayChannel_LESHUA()
{
string outTradeNo = this.OutTradeNo;
var _data = PayMentOperation.Pay(this.txtPayCode.Text, outTradeNo.Replace("_", ""), PayMoney, this._payChannel);
if (_data.Item3!=null)
{
UpdateSaomaTicket(outTradeNo, _data.Item3.OutTradeNo, this.SAOBEI_PAYTIME);
}
if (!_data.Item1)
{
if (!_data.Item2.Contains("支付中"))
{
this.txtPayCode.Enabled = true;
return;
}
ShowMessage(this.lblInfo, "正在确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
return;
}
UpdateSaomaTicket(outTradeNo, _data.Item3.OutTradeNo, this.SAOBEI_PAYTIME);
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = this.CurrentPayMode.No;
cardSaomaResult.PayModeName = this.CurrentPayMode.Name;
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = PayMoney;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(true, cardSaomaResult);
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
this.Close();
}
#region 原生支付渠道
/// <summary>
/// 查询原生支付结果
/// </summary>
private void QueryPayChannel_0()
{
//进度条最大值
int maximum = this.PayStep3.Maximum;
this.PayStep3.Value = (initValue++);
//判断是否超时,如果超时终止计时器,界面反馈信息
if (initValue % this.PayStep3.Maximum == 0)
{
//计时器停止
this.timer.Stop();
//修改结果颜色
//this.PayStep3.ProgressColors = new Color[] { Color.Red , Color.Red };
//发送结果通知
ShowMessage(this.lblInfo, "查询支付结果超时", true);
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this.OutTradeNo);
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
if (DialogResult.Retry == dialog.ShowDialog())
{
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this.OutTradeNo);
ShowMessage(this.lblInfo, "等待确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this.OutTradeNo);
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
else
{
switch (this.CurrentPayMode.No)
{
case "04":
{
QueryAliPayResult();
}
break;
case "05":
{
QueryWxPayResult();
}
break;
}
}
}
/// <summary>
/// 原生支付
/// </summary>
private void PayChannel_0()
{
switch (this.CurrentPayMode.No)
{
case "04":
{
var isQuery = AliPayResult();
if (isQuery)
{
ShowMessage(this.lblInfo, "正在确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
break;
case "05":
{
var isQuery = WxPayResult();
//需要查询支付结果的两种情况1支付提示扣款成功2支付结果未知
if (isQuery)
{
ShowMessage(this.lblInfo, "等待确认扣款状态", true);
this.initValue = 10;
this.timeout = 60;
this.txtPayCode.Enabled = false;
//启动定时器
this.timer.Start();
}
else
{
//清理支付码
this.txtPayCode.Text = string.Empty;
//重新扫码,恢复初始值
this.PayStep1.Value = 0;
this.PayStep2.Value = 0;
this.PayStep3.Value = 0;
//允许扫码框输入
this.txtPayCode.Enabled = true;
this.txtPayCode.Text = string.Empty;
this.txtPayCode.Focus();
}
}
break;
}
}
#endregion
#region 原生微信支付
/// <summary>
/// 微信支付,返回是否确认查询结果
/// </summary>
/// <returns></returns>
private bool WxPayResult()
{
bool isQuery = false;
try
{
string nonceStr = "x86" + ObjectId.GenerateNewStringId();
//门店编号
string deviceInfo = Global.Instance.Authc.StoreNo;
//门店名称
string body = Global.Instance.Authc.StoreName + "-店内充值";
//商品详情
string detail = "";
//附加数据
string attach = "";
//商户订单号
//订单总金额,单位为分,只能为整数
string totalFee = Convert.ToInt32(PayMoney * 100).ToString();
//货币类型
string feeType = "CNY";
//终端IP
string spbillCreateIp = DeviceUtils.Instance.IPAddress;
//订单优惠标记
string goodsTag = "";
//扫码支付授权码设备读取用户微信中的条码或者二维码信息用户刷卡条形码规则18位纯数字以10、11、12、13、14、15开头
string authCode = this.txtPayCode.Text.Trim();
//禁止扫码框输入
this.txtPayCode.Enabled = false;
//发起微信扣款请求
ShowMessage(this.lblInfo, "发起微信扣款请求", true);
this.PayStep2.Value = this.PayStep2.Maximum / 3;
var parameter = this.CurrentPayMode.Body;
//微信支付的配置参数
string appId = parameter["appid"].ToString();
string mchId = parameter["mchid"].ToString();
string subMchId = parameter["submchid"].ToString();
string key = parameter["appsecret"].ToString();
LOGGER.Info("订单[{0}]发起微信扣款[{1}]分", this.OutTradeNo, totalFee);
var dataInfo = new WxPayV3MicroPayRequestData(appId, mchId, subMchId, key, nonceStr, deviceInfo, body, detail, attach, this.OutTradeNo, totalFee, feeType, spbillCreateIp, goodsTag, authCode);
//扫码成功,提交被扫支付
MicropayResult result = WxPayV3.MicroPay(dataInfo);
LOGGER.Info("订单[{0}]微信扣款返回结果:{1}", this.OutTradeNo, JsonUtils.Serialize(result));
if ("SUCCESS".Equals(result.return_code))
{
if ("SUCCESS".Equals(result.result_code))
{
this.PayStep2.Value = this.PayStep2.Maximum;
//需要直接确认结果,无需等待输入密码
isQuery = true;
}
else
{
LOGGER.Warn("订单[{0}]微信支付[{1}]分发生错误,错误代码:{2},错误描述:{3}", this.OutTradeNo, totalFee, result.err_code, result.err_code_des);
//Task.Factory.StartNew(new Action(() =>
//{
// Global.Instance.BugReport(new Exception("微信支付错误" + JsonUtils.Serialize(result)));
//}));
//解析错误代码
var errCode = WxPayErrCode.NONE;
Enum.TryParse(result.err_code, out errCode);
switch (errCode)
{
//支付结果未知,请立即调用被扫订单结果查询API查询当前订单状态并根据订单的状态决定下一步的操作
case WxPayErrCode.SYSTEMERROR:
{
this.PayStep2.Value = this.PayStep2.Maximum;
ShowMessage(this.lblInfo, "网络超时,正在查询支付状态,请稍候...", true);
isQuery = true;
}
break;
case WxPayErrCode.BANKERROR:
{
this.PayStep2.Value = this.PayStep2.Maximum;
ShowMessage(this.lblInfo, "银行端超时,正在查询支付状态,请稍候...", true);
isQuery = true;
}
break;
case WxPayErrCode.USERPAYING:
{
this.PayStep2.Value = this.PayStep2.Maximum;
ShowMessage(this.lblInfo, "等待用户输入密码,请稍候...", true);
//需等待输入密码,需要确认结果
isQuery = true;
}
break;
case WxPayErrCode.ORDERPAID:
{
this.PayStep2.Value = this.PayStep2.Minimum;
ShowMessage(this.lblInfo, "订单号重复支付,请使用新订单", true);
isQuery = false;
}
break;
case WxPayErrCode.AUTHCODEEXPIRE:
{
this.PayStep2.Value = this.PayStep2.Minimum;
ShowMessage(this.lblInfo, "二维码过期,请用户在微信上刷新后再试", true);
isQuery = false;
}
break;
case WxPayErrCode.NOTENOUGH:
{
this.PayStep2.Value = this.PayStep2.Minimum;
ShowMessage(this.lblInfo, "用户余额不足,请用户换卡支付", true);
isQuery = false;
}
break;
case WxPayErrCode.NOTSUPORTCARD:
{
this.PayStep2.Value = this.PayStep2.Minimum;
ShowMessage(this.lblInfo, "不支持当前支付,请用户换卡或绑新卡支付", true);
isQuery = false;
}
break;
case WxPayErrCode.INVALID_REQUEST:
{
this.PayStep2.Value = this.PayStep2.Minimum;
if (result.err_code_des == "201 商户订单号重复")
{
ShowMessage(this.lblInfo, "商户订单号重复,请消单后重新下单", true);
}
else
{
ShowMessage(this.lblInfo, result.err_code_des, true);
}
isQuery = false;
}
break;
default:
{
this.PayStep2.Value = this.PayStep2.Minimum;
ShowMessage(this.lblInfo, result.err_code_des, true);
isQuery = false;
}
break;
}
}
}
else
{
LOGGER.Warn("订单[{0}]微信支付[{1}]分,微信支付网络通信错误:{0}", this.OutTradeNo, totalFee, result.return_msg);
ShowMessage(this.lblInfo, result.return_msg, true);
//Task.Factory.StartNew(new Action(() =>
//{
// Global.Instance.BugReport(new Exception("微信支付错误2" + JsonUtils.Serialize(result)));
//}));
}
}
catch (Exception ex)
{
ShowMessage(this.lblInfo, "微信支付发生异常,开始确认支付结果", true);
LOGGER.Error(ex, "微信支付发生异常");
//发起支付发生异常,为了避免客户已经收到请求,开始支付,这里进行补救查询
isQuery = true;
//Task.Factory.StartNew(new Action(() =>
//{
// Global.Instance.BugReport(ex);
//}));
}
return isQuery;
}
#endregion
#region 原生支付宝
/// <summary>
/// 支付宝付款,返回是否确认查询结果
/// </summary>
/// <returns></returns>
private bool AliPayResult()
{
bool isQuery = false;
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 pid = parameter.ContainsKey("pid") ? parameter["pid"].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 AlipayTradePayRequest();
var content = new Dictionary<string, object>();
//商户订单号
string outTradeNo = this.OutTradeNo;
content.Add("out_trade_no", outTradeNo);
content.Add("scene", "bar_code");// 支付场景-条码支付
content.Add("auth_code", this.txtPayCode.Text.Trim());// 支付授权码
content.Add("subject", Global.Instance.Worker.StoreInfo.Name + "-店内充值");// 订单标题
content.Add("body", Global.Instance.Authc.StoreNo + Global.Instance.Worker.StoreInfo.Name + "-店内充值");
content.Add("total_amount", PayMoney);
content.Add("operator_id", Global.Instance.Worker.No);
content.Add("store_id", Global.Instance.Authc.StoreNo);
content.Add("terminal_id", Global.Instance.Authc.PosNo);
if (!string.IsNullOrEmpty(appAuthToken))
{
var extend = new Dictionary<string, object>();
extend.Add("sys_service_provider_id", pid);
content.Add("extend_params", extend);
}
var goods = new List<Dictionary<string, object>>();
var details = new Dictionary<string, object>();
details.Add("goods_id", ObjectId.GenerateNewStringId());
details.Add("goods_name", "门店充值");
details.Add("quantity", "1");
details.Add("price", PayMoney);
details.Add("goods_category", ObjectId.GenerateNewStringId());
details.Add("body", "门店充值");
details.Add("show_url", "");
goods.Add(details);
content.Add("goods_detail", goods);
request.BizContent = JsonUtils.Serialize(content);
LOGGER.Info("订单[{0}]发起支付宝(原生)支付:<{1}>", outTradeNo, JsonUtils.Serialize(request));
AlipayTradePayResponse response = client.Execute(request, string.Empty, appAuthToken);
LOGGER.Info("订单[{0}]收到支付宝(原生)支付结果:<{1}>", outTradeNo, JsonUtils.Serialize(response));
if (!response.IsError && (response.Code == "10000" || response.Code == "10003" || response.Code == "20000"))
{
isQuery = true;
ShowMessage(this.lblInfo, "等待确认扣款结果...", true);
}
else
{
isQuery = false;
ShowMessage(this.lblInfo, string.Format("{ 0}<{ 1}> ", response.SubMsg, response.SubCode), true);
//Task.Factory.StartNew(new Action(() =>
//{
// Global.Instance.BugReport(new Exception("订单["+ outTradeNo + "]支付宝(原生)支付失败,返回结果:"+ JsonUtils.Serialize(response)));
//}));
}
}
catch (Exception ex)
{
LOGGER.Error(ex, "支付宝付款发生异常");
if (ex.Message.Contains("私钥格式错误"))
{
ShowMessage(this.lblInfo, "支付宝私钥配置错误...", true);
isQuery = false;
}
else
{
ShowMessage(this.lblInfo, "支付宝付款发生异常...", true);
isQuery = true;
}
//Task.Factory.StartNew(new Action(() =>
//{
// Global.Instance.BugReport(ex);
//}));
}
return isQuery;
}
#endregion
private void OnPayCodeEnterClick(object sender, Component.EnterEventArg e)
{
this.OnKeyboardBefore(this.billKeyboard1, new BillKeyboardEventArgs("accept"));
if (this.PaymentVerify)
{
this.OnKeyboardAfter(this.billKeyboard1, new BillKeyboardEventArgs("accept"));
}
}
private void OnPayCodeValueChanged(object sender, Component.EnterEventArg e)
{
if (this.PayStep2.Value > 0 || this.PayStep3.Value > 0) return;
string inputString = e.Value;
if (!string.IsNullOrEmpty(inputString))
{
int intputLength = inputString.Length;
this.PayStep1.Value = intputLength * 10;
}
else
{
this.PayStep1.Value = 0;
}
}
public delegate void EventHandler(CardRechargeSaomaEventArgs e);
public event EventHandler OnSaomaResultClick;
private void OnCloseTouchClick(object sender, EventArgs e)
{
//计时器停止
this.timer.Stop();
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = "";
cardSaomaResult.PayModeName = "";
cardSaomaResult.OutTradeNo = OutTradeNo;
cardSaomaResult.PayMoney = 0.00M;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(false, cardSaomaResult);
logger.Info("取消支付[{0}]......", "");
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
//再关闭当前窗体
this.Close();
}
private void btn_close(object sender, EventArgs e)
{
//计时器停止
this.timer.Stop();
CardSaomaResult cardSaomaResult = new CardSaomaResult();
cardSaomaResult.Type = 0;
cardSaomaResult.PayModeNo = "";
cardSaomaResult.PayModeName = "";
cardSaomaResult.OutTradeNo = this.OutTradeNo;
cardSaomaResult.PayMoney = 0.00M;
Tuple<bool, CardSaomaResult> saomaResult = new Tuple<bool, CardSaomaResult>(false, cardSaomaResult);
logger.Info("取消支付[{0}]......", "");
OnSaomaResultClick?.Invoke(new CardRechargeSaomaEventArgs(saomaResult));
//先关闭父窗体
if (this.Owner != null)
{
this.Owner.Close();
}
//再关闭当前窗体
this.Close();
}
/// <summary>
/// 发起扣钱请求以后更新支付单状态
/// </summary>
/// <param name="rechargeNo"></param>
/// <param name="payStatus"></param>
/// <param name="rechargeStatus"></param>
public void updateCardRecharge(string rechargeNo, int payStatus, int rechargeStatus, string authCode)
{
try
{
lock (Global.Instance.SyncLock)
{
using (var db = Global.Instance.OpenDataBase)
{
using (var transaction = db.GetTransaction())
{
logger.Info("单号:[{0}]更改订单状态 payStatus==>{1},rechargeStatus==>{2},authCode==>{3}......开始", rechargeNo, payStatus, rechargeStatus, authCode);
string sql = "update pos_card_recharge set payStatus ={0} ,rechargeStatus ={1} , authCode ='{3}' where rechargeNo = '{2}'";
sql = string.Format(sql, payStatus, rechargeStatus, rechargeNo, authCode);
db.Execute(sql, null);
//先查询核销记录是否存在
string querySql = "select * from pos_saoma_pay_ticket where orderNo = '{0}' and storeId ='{1}'";
querySql = string.Format(querySql, rechargeNo, Global.Instance.BusinessPlanLog.StoreId);
SaomaPayTicket saomaPayTicket = db.FirstOrDefault<SaomaPayTicket>(querySql);
//如果插入扫码支付记录
if (saomaPayTicket == null)
{
SaomaPayTicket entity = new SaomaPayTicket();
entity.Id = IdWorkerUtils.Instance.NextId();
entity.TenantId = Global.Instance.BusinessPlanLog.TenantId;
entity.StoreId = Global.Instance.BusinessPlanLog.StoreId;
entity.WorkerId = Global.Instance.BusinessPlanLog.WorkerId;
entity.ShiftNo = Global.Instance.BusinessPlanLog.No;
entity.OrderNo = rechargeNo;
entity.AuthCode = authCode;
entity.Money = this.PayMoney;
entity.SerialNo = this.SAOBEI_OrderId;
entity.PayTime = this.SAOBEI_PAYTIME;
entity.BusType = 1;
entity.PayStatus = 0;
entity.PayChannel = (int)this._payChannel;
entity.PayTypeNo = this.CurrentPayMode.No;
entity.PayTypeName = this.CurrentPayMode.Name;
db.Save<SaomaPayTicket>(entity);
}
transaction.Complete();
logger.Info("单号:[{0}]更改订单状态 payStatus==>{1},rechargeStatus==>{2},authCode==>{3}......成功", rechargeNo, payStatus, rechargeStatus, authCode);
}
}
}
}
catch (Exception ex)
{
LOGGER.Error(ex);
}
}
/// <summary>
/// 手工核销
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSaomaPayClick(object sender, EventArgs e)
{
//打开提示界面
var form = new SaomaCheckoutForm(this.CardNo, this.PayMoney);
form.ShowDialog();
}
}
public class CardRechargeSaomaEventArgs : EventArgs
{
private readonly Tuple<bool, CardSaomaResult> _saomaResult;
public CardRechargeSaomaEventArgs(Tuple<bool, CardSaomaResult> saomaResult)
{
this._saomaResult = saomaResult;
}
public Tuple<bool, CardSaomaResult> SaomaResult
{
get
{
return _saomaResult;
}
}
}
public enum WxPayTradeState
{
NONE = -1,
/// <summary>
/// 支付成功
/// </summary>
SUCCESS = 0,
/// <summary>
/// 转入退款
/// </summary>
REFUND = 1,
/// <summary>
/// 未支付
/// </summary>
NOTPAY = 2,
/// <summary>
/// 已关闭
/// </summary>
CLOSED = 3,
/// <summary>
/// 已撤销(刷卡支付)
/// </summary>
REVOKED = 4,
/// <summary>
/// 用户支付中
/// </summary>
USERPAYING = 5,
/// <summary>
/// 支付失败(其他原因,如银行返回失败)
/// </summary>
PAYERROR = 6
}
public enum WxPayErrCode
{
/// <summary>
/// 不能识别的参数
/// </summary>
NONE = -1,
/// <summary>
/// 接口返回错误 支付结果未知 系统超时 请立即调用被扫订单结果查询API查询当前订单状态并根据订单的状态决定下一步的操作。
/// </summary>
SYSTEMERROR = 0,
/// <summary>
/// 参数错误 支付确认失败 请求参数未按指引进行填写 请根据接口返回的详细信息检查您的程序
/// </summary>
PARAM_ERROR = 1,
/// <summary>
/// 订单已支付 支付确认失败 订单号重复 请确认该订单号是否重复支付,如果是新单,请使用新订单号提交
/// </summary>
ORDERPAID = 2,
/// <summary>
/// 商户无权限 支付确认失败 商户没有开通被扫支付权限 请开通商户号权限。请联系产品或商务申请
/// </summary>
NOAUTH = 3,
/// <summary>
/// 二维码已过期,请用户在微信上刷新后再试 支付确认失败 用户的条码已经过期 请收银员提示用户,请用户在微信上刷新条码,然后请收银员重新扫码。 直接将错误展示给收银员
/// </summary>
AUTHCODEEXPIRE = 4,
/// <summary>
/// 余额不足 支付确认失败 用户的零钱余额不足 请收银员提示用户更换当前支付的卡,然后请收银员重新扫码。建议:商户系统返回给收银台的提示为“用户余额不足.提示用户换卡支付”
/// </summary>
NOTENOUGH = 5,
/// <summary>
/// 不支持卡类型 支付确认失败 用户使用卡种不支持当前支付形式 请用户重新选择卡种 建议:商户系统返回给收银台的提示为“该卡不支持当前支付,提示用户换卡支付或绑新卡支付”
/// </summary>
NOTSUPORTCARD = 6,
/// <summary>
/// 订单已关闭 支付确认失败 该订单已关 商户订单号异常,请重新下单支付
/// </summary>
ORDERCLOSED = 7,
/// <summary>
/// 订单已撤销 支付确认失败 当前订单已经被撤销 当前订单状态为“订单已撤销”,请提示用户重新支付
/// </summary>
ORDERREVERSED = 8,
/// <summary>
/// 银行系统异常 支付结果未知 银行端超时 请立即调用被扫订单结果查询API查询当前订单的不同状态决定下一步的操作。
/// </summary>
BANKERROR = 9,
/// <summary>
/// 用户支付中,需要输入密码 支付结果未知 该笔交易因为业务规则要求,需要用户输入支付密码。 等待5秒然后调用被扫订单结果查询API查询当前订单的不同状态决定下一步的操作。
/// </summary>
USERPAYING = 10,
/// <summary>
/// 授权码参数错误 支付确认失败 请求参数未按指引进行填写 每个二维码仅限使用一次,请刷新再试
/// </summary>
AUTH_CODE_ERROR = 11,
/// <summary>
/// 授权码检验错误 支付确认失败 收银员扫描的不是微信支付的条码 请扫描微信支付被扫条码/二维码
/// </summary>
AUTH_CODE_INVALID = 12,
/// <summary>
/// XML格式错误 支付确认失败 XML格式错误 请检查XML参数格式是否正确
/// </summary>
XML_FORMAT_ERROR = 13,
/// <summary>
/// 请使用post方法 支付确认失败 未使用post传递参数 请检查请求参数是否通过post方法提交
/// </summary>
REQUIRE_POST_METHOD = 14,
/// <summary>
/// 签名错误 支付确认失败 参数签名结果不正确 请检查签名参数和方法是否都符合签名算法要求
/// </summary>
SIGNERROR = 15,
/// <summary>
/// 缺少参数 支付确认失败 缺少必要的请求参数 请检查参数是否齐全
/// </summary>
LACK_PARAMS = 16,
/// <summary>
/// 编码格式错误 支付确认失败 未使用指定编码格式 请使用UTF-8编码格式
/// </summary>
NOT_UTF8 = 17,
/// <summary>
/// 支付帐号错误 支付确认失败 暂不支持同一笔订单更换支付方 请确认支付方是否相同
/// </summary>
BUYER_MISMATCH = 18,
/// <summary>
/// APPID不存在 支付确认失败 参数中缺少APPID 请检查APPID是否正确
/// </summary>
APPID_NOT_EXIST = 19,
/// <summary>
/// MCHID不存在 支付确认失败 参数中缺少MCHID 请检查MCHID是否正确
/// </summary>
MCHID_NOT_EXIST = 20,
/// <summary>
/// 商户订单号重复 支付确认失败 同一笔交易不能多次提交 请核实商户订单号是否重复提交
/// </summary>
OUT_TRADE_NO_USED = 21,
/// <summary>
/// appid和mch_id不匹配 支付确认失败 appid和mch_id不匹配 请确认appid和mch_id是否匹配
/// </summary>
APPID_MCHID_NOT_MATCH = 22,
/// <summary>
/// 201 商户订单号重复 支付失败,不需要查询,直接提示
/// </summary>
INVALID_REQUEST = 23
}
}