|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|