|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using POSV.ShoppingCart;
|
|
|
|
|
using POSV.Utils;
|
|
|
|
|
using POSV.MessageEvent;
|
|
|
|
|
using POSV.Entity;
|
|
|
|
|
using Aop.Api;
|
|
|
|
|
using Aop.Api.Request;
|
|
|
|
|
using Aop.Api.Response;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using POSV.PayApi;
|
|
|
|
|
using POSV.Member;
|
|
|
|
|
using POSV.Proxy.ThirdPartyPayMent;
|
|
|
|
|
using POS.Language.Language;
|
|
|
|
|
using POSV.Payment.Abmcs;
|
|
|
|
|
using POSV.Payment.Saobei.Result;
|
|
|
|
|
using POSV.Payment.Saobei.Parameter;
|
|
|
|
|
using POSV.Payment.Saobei;
|
|
|
|
|
using POSV.Payment.AllinPay.Models.ParamModels;
|
|
|
|
|
using POSV.Payment.AllinPay;
|
|
|
|
|
using POSV.Payment.AllinPay.Models.ResponseModels;
|
|
|
|
|
|
|
|
|
|
namespace POSV.Bill
|
|
|
|
|
{
|
|
|
|
|
[ToolboxItem(true)]
|
|
|
|
|
public partial class AllinPayControl : AbstractBill
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// PayStep3初始值
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int initValue = 10;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否等待用户输入支付密码
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int timeout = 60;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//倒计时计时器
|
|
|
|
|
//private System.Timers.Timer timer = null;
|
|
|
|
|
private System.Windows.Forms.Timer timer = null;
|
|
|
|
|
|
|
|
|
|
private const int TIMER_INTERVAL = 1000;
|
|
|
|
|
|
|
|
|
|
private int count = 0;
|
|
|
|
|
|
|
|
|
|
public static object _lock = new object();
|
|
|
|
|
|
|
|
|
|
public bool isPay = false;
|
|
|
|
|
|
|
|
|
|
//subin 20231011 add 上一次支付状态,默认支付成功
|
|
|
|
|
public bool lastPayed = true;
|
|
|
|
|
//subin 20231011 end
|
|
|
|
|
|
|
|
|
|
private bool _paylock = true;
|
|
|
|
|
|
|
|
|
|
private string SAOBEI_QRCodeType = "";
|
|
|
|
|
private string SAOBEI_PAYTIME = "";
|
|
|
|
|
private string SAOBEI_OrderId = "";
|
|
|
|
|
|
|
|
|
|
public AllinPayControl()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
|
|
|
|
//支付结果查询的计时器
|
|
|
|
|
//this.timer = new System.Timers.Timer(TIMER_INTERVAL);
|
|
|
|
|
//this.timer.Elapsed += OnTimerElapsed;
|
|
|
|
|
|
|
|
|
|
PayStep1.Text = "<font size=\"+3\"><b> " + LangProxy.ToLang("等待扫描") + " </b></font><br/><font size=\"-1\"> " + LangProxy.ToLang("请扫描付款码") + " </font>";
|
|
|
|
|
PayStep2.Text = "<font size=\"+3\"><b>" + LangProxy.ToLang("发起扣款") + "</b></font><br/><font size=\"-1\">" + LangProxy.ToLang("发起扣款请求") + " </font>";
|
|
|
|
|
PayStep3.Text = "<font size=\"+3\"><b>" + LangProxy.ToLang("确认结果") + "</b></font><br/><font size=\"-1\">" + LangProxy.ToLang("确认扣款结果") + " </font>";
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnLoad(e);
|
|
|
|
|
|
|
|
|
|
this.SetStyle(ControlStyles.Selectable, true);
|
|
|
|
|
|
|
|
|
|
if (this.DesignMode) return;
|
|
|
|
|
|
|
|
|
|
this.txtPayCode.Multiline = false;
|
|
|
|
|
this.txtPayCode.Focus();
|
|
|
|
|
this.txtPayCode.SelectAll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnPaintBackground(PaintEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
e.Graphics.Clear(Focused ? SystemColors.Control : SystemColors.Control);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnGotFocus(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Invalidate();
|
|
|
|
|
base.OnGotFocus(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnLostFocus(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnLostFocus(e);
|
|
|
|
|
Invalidate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetFocus()
|
|
|
|
|
{
|
|
|
|
|
this.txtPayCode.Focus();
|
|
|
|
|
this.txtPayCode.SelectAll();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Focused
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (this.ActiveControl == null)
|
|
|
|
|
{
|
|
|
|
|
this.ActiveControl = this.txtPayCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this.ActiveControl.Focused;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 订单对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
private OrderObject _orderObject = null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 支付渠道
|
|
|
|
|
/// </summary>
|
|
|
|
|
private PayChannelEnum _payChannel = PayChannelEnum.原生支付;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void BindUi(OrderObject orderObject)
|
|
|
|
|
{
|
|
|
|
|
if (orderObject == null) return;
|
|
|
|
|
|
|
|
|
|
this.initValue = 10;
|
|
|
|
|
this.SAOBEI_QRCodeType = "";
|
|
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
|
|
|
|
|
|
|
this.isPay = false;
|
|
|
|
|
this._paylock = true;
|
|
|
|
|
//清理支付码
|
|
|
|
|
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();
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "请扫描或输入支付码..."));
|
|
|
|
|
|
|
|
|
|
this._orderObject = orderObject;
|
|
|
|
|
//初始化支付状态
|
|
|
|
|
this.isPay = false;
|
|
|
|
|
|
|
|
|
|
//subin 20231011 add初始化上一次支付状态
|
|
|
|
|
this.lastPayed = true;
|
|
|
|
|
//subin 20231011 end
|
|
|
|
|
|
|
|
|
|
//微信支付不允许抹零
|
|
|
|
|
this._orderObject.MalingAmount = 0;
|
|
|
|
|
//微信支付不允许找零
|
|
|
|
|
this._orderObject.ChangeAmount = 0;
|
|
|
|
|
|
|
|
|
|
//将当前应收金额赋值
|
|
|
|
|
this.txtPayCode.Focus();
|
|
|
|
|
this.txtPayCode.SelectAll();
|
|
|
|
|
|
|
|
|
|
//刷新支付汇总清单
|
|
|
|
|
this.billSummary1.Refresh(orderObject);
|
|
|
|
|
|
|
|
|
|
//支付结果查询的计时器
|
|
|
|
|
if (this.timer != null)
|
|
|
|
|
{
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
}
|
|
|
|
|
this.timer = null;
|
|
|
|
|
this.timer = new System.Windows.Forms.Timer();
|
|
|
|
|
this.timer.Interval = TIMER_INTERVAL;
|
|
|
|
|
this.timer.Tick += OnTimerTick;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnTimerTick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.Invoke(new Action(() =>
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
switch (this._payChannel)
|
|
|
|
|
{
|
|
|
|
|
case PayChannelEnum.原生支付:
|
|
|
|
|
{
|
|
|
|
|
QueryPayChannel_0();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.乐刷支付:
|
|
|
|
|
{
|
|
|
|
|
QueryPayChannel_LESHUA();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.扫呗支付:
|
|
|
|
|
{
|
|
|
|
|
QueryPayChannel_SAOBEI();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#region subin 2023-06-21 增加通联支付
|
|
|
|
|
case PayChannelEnum.通联支付:
|
|
|
|
|
{
|
|
|
|
|
QueryPayChannel_Allin();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("查询支付结果中....");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <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._orderObject == null)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "订单数据错误啦,请拍个照..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (this._orderObject.PaidAmount > 0)
|
|
|
|
|
{
|
|
|
|
|
//获取扫描码
|
|
|
|
|
var payCode = this.txtPayCode.Text.Trim();
|
|
|
|
|
if (string.IsNullOrEmpty(payCode))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "请扫描或输入支付码..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#region subin 2023-07-02 修改原付款码支付方式
|
|
|
|
|
#region 原始
|
|
|
|
|
//this.CurrentPayMode = GetPayMode(payCode);
|
|
|
|
|
#endregion
|
|
|
|
|
//var tmpPayMode = GetPayMode(payCode);
|
|
|
|
|
this.CurrentPayMode = (PayMode)this.Tag;
|
|
|
|
|
//this.CurrentPayMode.No = tmpPayMode.No;
|
|
|
|
|
//this.CurrentPayMode.Name = tmpPayMode.Name;
|
|
|
|
|
|
|
|
|
|
//判断支付码是否合法
|
|
|
|
|
if (payCode.Length < 16)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付码不合法..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (this.CurrentPayMode == null)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付码不合法或尚未适配..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "扫描" + this.CurrentPayMode.Name + "付款码..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = VerifyInputValue(payCode, this.CurrentPayMode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "付款金额非法..."));
|
|
|
|
|
|
|
|
|
|
this.PaymentVerify = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (_paylock)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_paylock = false;
|
|
|
|
|
if (this.PaymentVerify && this.CurrentPayMode != null)
|
|
|
|
|
{
|
|
|
|
|
//保存扫描支付单号
|
|
|
|
|
|
|
|
|
|
SaveSaomaTicket(string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo), this.txtPayCode.Text.Trim());
|
|
|
|
|
switch (this._payChannel)
|
|
|
|
|
{
|
|
|
|
|
case PayChannelEnum.原生支付:
|
|
|
|
|
{
|
|
|
|
|
this.PayChannel_0();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.乐刷支付:
|
|
|
|
|
{
|
|
|
|
|
this.PayChannel_LeShua();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.扫呗支付:
|
|
|
|
|
{
|
|
|
|
|
if (this.VerifyOrderPay().Item1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.PayChannel_SAOBEI();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#region subin 2023-06-26 增加通联支付
|
|
|
|
|
case PayChannelEnum.通联支付:
|
|
|
|
|
{
|
|
|
|
|
if (this.VerifyOrderAllinPay().Item1)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!lastPayed)
|
|
|
|
|
{
|
|
|
|
|
var oldTradeNo = this._orderObject.TradeNo;
|
|
|
|
|
//尝试重新获取一次单号
|
|
|
|
|
var ticket = OrderUtils.Instance.GenerateTicketNoEx();
|
|
|
|
|
if (ticket.Item1)
|
|
|
|
|
{
|
|
|
|
|
this._orderObject.TradeNo = ticket.Item3;
|
|
|
|
|
LOGGER.Info($"订单支付失败,重新生成订单号,原单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{oldTradeNo}]==>新单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{_orderObject.TradeNo}]......开始");
|
|
|
|
|
|
|
|
|
|
foreach (var item in this._orderObject.Items)
|
|
|
|
|
{
|
|
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
LOGGER.Info($"订单支付失败,原订单[{oldTradeNo}]商品<{item.ShortName}:{item.Id}>,重置订单号:{_orderObject.TradeNo}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (var db = Global.Instance.OpenDataBase)
|
|
|
|
|
{
|
|
|
|
|
//订单保存成功更新核销状态
|
|
|
|
|
|
|
|
|
|
string sql = "update pos_saoma_pay_ticket set orderNo ='{0}' where orderNo = '{1}'";
|
|
|
|
|
sql = string.Format(sql, string.Format("{0}_{1}", Global.Instance.BusinessPlanLog.StoreNo, _orderObject.TradeNo), string.Format("{0}_{1}", Global.Instance.BusinessPlanLog.StoreNo, oldTradeNo));
|
|
|
|
|
db.Execute(sql, null);
|
|
|
|
|
|
|
|
|
|
LOGGER.Info($"订单支付失败,重新生成订单号,原单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{oldTradeNo}]==>新单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{_orderObject.TradeNo}]......pos_saoma_pay_ticket更新成功");
|
|
|
|
|
|
|
|
|
|
//发送支付失败,重新生成订单号事件
|
|
|
|
|
MsgEvent.Send(Constant.ORDER_PAYMENT_ERROR_GENERATENO, _orderObject.TradeNo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOGGER.Info($"订单支付失败,重新生成订单号,原单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{oldTradeNo}]==>新单号:[{Global.Instance.BusinessPlanLog.StoreNo}_{_orderObject.TradeNo}]......更新成功");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "获取全局单号失败,收银参数禁止使用本机单号,请重新操作"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.PayChannel_Allin();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_paylock = true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_paylock = true;
|
|
|
|
|
|
|
|
|
|
LOGGER.Error(ex, "支付渠道异常");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "正在支付中..."));
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 优先记录核销
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="busNo"></param>
|
|
|
|
|
/// <param name="authCode"></param>
|
|
|
|
|
public void SaveSaomaTicket(string busNo, string authCode)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
lock (Global.Instance.SyncLock)
|
|
|
|
|
{
|
|
|
|
|
using (var db = Global.Instance.OpenDataBase)
|
|
|
|
|
{
|
|
|
|
|
using (var transaction = db.GetTransaction())
|
|
|
|
|
{
|
|
|
|
|
//先查询核销记录是否存在
|
|
|
|
|
string querySql = "select * from pos_saoma_pay_ticket where orderNo = '{0}' and busType = 0 and storeId ='{1}'";
|
|
|
|
|
querySql = string.Format(querySql, busNo, 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 = busNo;
|
|
|
|
|
entity.AuthCode = authCode;
|
|
|
|
|
entity.Money = this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount;
|
|
|
|
|
entity.SerialNo = null;
|
|
|
|
|
entity.PayTime = this.SAOBEI_PAYTIME;
|
|
|
|
|
entity.BusType = 0;
|
|
|
|
|
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}]进行扫描支付,付款码{1}", busNo, authCode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = 0 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据扫描码适配支付方式
|
|
|
|
|
///
|
|
|
|
|
/// 支付宝授权码,25~30开头的长度为16~24位的数字
|
|
|
|
|
///
|
|
|
|
|
/// 微信授权码 18位纯数字,以10、11、12、13、14、15开头
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="payCode"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private PayMode GetPayMode(string payCode)
|
|
|
|
|
{
|
|
|
|
|
PayMode result = null;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(payCode) && payCode.Length >= 16)
|
|
|
|
|
{
|
|
|
|
|
string prefix = payCode.Substring(0, 2);
|
|
|
|
|
|
|
|
|
|
switch (prefix)
|
|
|
|
|
{
|
|
|
|
|
case "10":
|
|
|
|
|
case "11":
|
|
|
|
|
case "12":
|
|
|
|
|
case "13":
|
|
|
|
|
case "14":
|
|
|
|
|
case "15":
|
|
|
|
|
{
|
|
|
|
|
//微信
|
|
|
|
|
result = OrderUtils.GetPayMode("05");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "25":
|
|
|
|
|
case "26":
|
|
|
|
|
case "27":
|
|
|
|
|
case "28":
|
|
|
|
|
case "29":
|
|
|
|
|
case "30":
|
|
|
|
|
{
|
|
|
|
|
//支付宝
|
|
|
|
|
result = OrderUtils.GetPayMode("04");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "62":
|
|
|
|
|
{
|
|
|
|
|
//云支付
|
|
|
|
|
result = OrderUtils.GetPayMode("07");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#region subin 2023-07-02 add
|
|
|
|
|
case "50":
|
|
|
|
|
{
|
|
|
|
|
//通联支付
|
|
|
|
|
result = OrderUtils.GetPayMode("50");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 验证付款码、支付参数是否正确
|
|
|
|
|
|
|
|
|
|
private bool VerifyWxPay(string payCode, PayMode payMode)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(payCode) || payCode.Length != 18)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "微信付款码非法..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parameter = payMode.Body;
|
|
|
|
|
|
|
|
|
|
string appId = parameter.ContainsKey("appid") ? parameter["appid"].ToString() : "";
|
|
|
|
|
string mchId = parameter.ContainsKey("mchid") ? parameter["mchid"].ToString() : "";
|
|
|
|
|
string subMchId = parameter.ContainsKey("submchid") ? parameter["submchid"].ToString() : "";
|
|
|
|
|
string key = parameter.ContainsKey("appsecret") ? parameter["appsecret"].ToString() : "";
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(mchId) || string.IsNullOrEmpty(key))//Yao 2023-06-13 test
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "微信支付参数配置不完整..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool VerifyAliPay(string payCode, PayMode payMode)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(payCode) || (payCode.Length < 16 || payCode.Length > 24))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付宝付款码非法..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parameter = payMode.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() : "";
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(privateKey))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付宝支付参数配置不完整..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool VerifyInputValue(string payCode, PayMode payMode)
|
|
|
|
|
{
|
|
|
|
|
bool isVerify = false;
|
|
|
|
|
|
|
|
|
|
var parameter = payMode.Body;
|
|
|
|
|
|
|
|
|
|
if (parameter == null || parameter.Count == 0)//Yao 2023-06-13 test
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "尚未配置支付参数..."));
|
|
|
|
|
isVerify = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//获取支付渠道
|
|
|
|
|
string channel = (parameter.ContainsKey("channel") ? parameter["channel"].ToString() : "").ToLower();
|
|
|
|
|
|
|
|
|
|
//没有配置支付渠道,默认原生支付,兼容处理
|
|
|
|
|
if (string.IsNullOrEmpty(channel))
|
|
|
|
|
{
|
|
|
|
|
this._payChannel = PayChannelEnum.原生支付;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
switch (channel)
|
|
|
|
|
{
|
|
|
|
|
case "alipay":
|
|
|
|
|
case "wxpay":
|
|
|
|
|
case "subalipay":
|
|
|
|
|
case "subwxpay":
|
|
|
|
|
{
|
|
|
|
|
this._payChannel = PayChannelEnum.原生支付;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "leshua":
|
|
|
|
|
{
|
|
|
|
|
this._payChannel = PayChannelEnum.乐刷支付;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "saobei":
|
|
|
|
|
{
|
|
|
|
|
this._payChannel = PayChannelEnum.扫呗支付;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#region subin 2023-06-16 增加通联支付
|
|
|
|
|
case "allinpay":
|
|
|
|
|
{
|
|
|
|
|
this._payChannel = PayChannelEnum.通联支付;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("适配到支付渠道:{0}", this._payChannel.ToString());
|
|
|
|
|
|
|
|
|
|
switch (this._payChannel)
|
|
|
|
|
{
|
|
|
|
|
case PayChannelEnum.原生支付:
|
|
|
|
|
{
|
|
|
|
|
switch (payMode.No)
|
|
|
|
|
{
|
|
|
|
|
case "04":
|
|
|
|
|
{
|
|
|
|
|
isVerify = VerifyAliPay(payCode, payMode);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "05":
|
|
|
|
|
{
|
|
|
|
|
isVerify = VerifyWxPay(payCode, payMode);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "目前暂不支持该类型付款码..."));
|
|
|
|
|
|
|
|
|
|
isVerify = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.乐刷支付:
|
|
|
|
|
{
|
|
|
|
|
isVerify = VerifyLeShuaPay(payCode);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.扫呗支付:
|
|
|
|
|
{
|
|
|
|
|
isVerify = VerifySAOBEIPay(payCode, payMode);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PayChannelEnum.通联支付:
|
|
|
|
|
{
|
|
|
|
|
isVerify = VerifyAllinPay(payCode, payMode);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isVerify;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#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 };
|
|
|
|
|
|
|
|
|
|
//发送结果通知
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "查询支付结果超时"));
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
|
|
|
|
|
if (DialogResult.Retry == dialog.ShowDialog())
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
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._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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)//Yao 2023-06-11 test
|
|
|
|
|
{
|
|
|
|
|
case "04":
|
|
|
|
|
{
|
|
|
|
|
var isQuery = AliPayResult();
|
|
|
|
|
|
|
|
|
|
if (isQuery)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
//清理支付码
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
//清理支付码
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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.Worker.StoreInfo.Name + "-店内消费";
|
|
|
|
|
//商品详情
|
|
|
|
|
string detail = "";
|
|
|
|
|
//附加数据
|
|
|
|
|
string attach = "";
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
//订单总金额,单位为分,只能为整数
|
|
|
|
|
string totalFee = Convert.ToInt32((this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount) * 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;
|
|
|
|
|
|
|
|
|
|
//发起微信扣款请求
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(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}]分", outTradeNo, totalFee);
|
|
|
|
|
|
|
|
|
|
var dataInfo = new WxPayV3MicroPayRequestData(appId, mchId, subMchId, key, nonceStr, deviceInfo, body, detail, attach, outTradeNo, totalFee, feeType, spbillCreateIp, goodsTag, authCode);
|
|
|
|
|
|
|
|
|
|
////扫码成功,提交被扫支付
|
|
|
|
|
MicropayResult result = WxPayV3.MicroPay(dataInfo);
|
|
|
|
|
//Yao 2023-06-11 test
|
|
|
|
|
//设置package订单参数
|
|
|
|
|
//NewParameters.Add("appid", this.AppId); //公众账号ID
|
|
|
|
|
//NewParameters.Add("mch_id", this.MchId); //商户号
|
|
|
|
|
|
|
|
|
|
//if (!string.IsNullOrEmpty(this.SubMchId))
|
|
|
|
|
//{
|
|
|
|
|
// NewParameters.Add("sub_mch_id", this.SubMchId); //子商户号
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//NewParameters.Add("device_info", this.DeviceInfo); //终端设备号
|
|
|
|
|
//NewParameters.Add("nonce_str", this.NonceStr); //随机字符串
|
|
|
|
|
//NewParameters.Add("sign_type", this.SignType); //签名类型
|
|
|
|
|
//NewParameters.Add("body", this.Body); //商品简单描述
|
|
|
|
|
//NewParameters.Add("detail", this.Detail); //商品详细列表
|
|
|
|
|
//NewParameters.Add("attach", this.Attach); //附加数据
|
|
|
|
|
//NewParameters.Add("out_trade_no", this.OutTradeNo); //商户系统内部的订单号
|
|
|
|
|
//NewParameters.Add("total_fee", this.TotalFee); //订单总金额
|
|
|
|
|
//NewParameters.Add("fee_type", this.FeeType); //货币类型
|
|
|
|
|
//NewParameters.Add("spbill_create_ip", this.SpbillCreateIp); //终端IP
|
|
|
|
|
//NewParameters.Add("goods_tag", this.GoodsTag); //商品标记
|
|
|
|
|
//NewParameters.Add("auth_code", this.AuthCode); //授权码
|
|
|
|
|
//Sign = CreateMd5Sign("key", this.Key);
|
|
|
|
|
//NewParameters.Add("sign", Sign); //签名
|
|
|
|
|
|
|
|
|
|
//param.setMeruserid("ZHTGR_YST16675473608354765");
|
|
|
|
|
//param.setPayuserid("ZHTGR_YST16631207277914507");
|
|
|
|
|
//param.setReqsn("po-" + System.currentTimeMillis());
|
|
|
|
|
//param.setAmount(1L);
|
|
|
|
|
//param.setPaytype("H5_CASHIER_VSP");
|
|
|
|
|
//param.setConsumer_ip("10.40.8.35");
|
|
|
|
|
//param.setRemark("支付测试");
|
|
|
|
|
//param.setReturl("https://www.baidu.com");
|
|
|
|
|
//param.setNotify_url("https://www.baidu.com");
|
|
|
|
|
//param.setVspCusId("");
|
|
|
|
|
|
|
|
|
|
//param.setAuthCode("");
|
|
|
|
|
//param.setFee(0L);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//POSV.Helper.HttpHelper.Post("order.consumeApply", param);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("订单[{0}]微信扣款返回结果:{1}", 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}", 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;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "网络超时,正在查询支付状态,请稍候..."));
|
|
|
|
|
|
|
|
|
|
isQuery = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.BANKERROR:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Maximum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "银行端超时,正在查询支付状态,请稍候..."));
|
|
|
|
|
|
|
|
|
|
isQuery = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.USERPAYING:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Maximum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "等待用户输入密码,请稍候..."));
|
|
|
|
|
|
|
|
|
|
//需等待输入密码,需要确认结果
|
|
|
|
|
isQuery = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.ORDERPAID:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "订单号重复支付,请使用新订单"));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.AUTHCODEEXPIRE:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "二维码过期,请用户在微信上刷新后再试"));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.NOTENOUGH:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "用户余额不足,请用户换卡支付"));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.NOTSUPORTCARD:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "不支持当前支付,请用户换卡或绑新卡支付"));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case WxPayErrCode.INVALID_REQUEST:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
if (result.err_code_des == "201 商户订单号重复")
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "商户订单号重复,请消单后重新下单"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, result.err_code_des));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Minimum;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, result.err_code_des));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("订单[{0}]微信支付[{1}]分,微信支付网络通信错误:{0}", outTradeNo, totalFee, result.return_msg);
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, result.return_msg));
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(new Exception("微信支付错误2" + JsonUtils.Serialize(result)));
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "微信支付发生异常,开始确认支付结果"));
|
|
|
|
|
|
|
|
|
|
LOGGER.Error(ex, "微信支付发生异常");
|
|
|
|
|
|
|
|
|
|
//发起支付发生异常,为了避免客户已经收到请求,开始支付,这里进行补救查询
|
|
|
|
|
isQuery = true;
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(ex);
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isQuery;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
var dataInfo = new WxPayV3OrderQueryRequestData(appId, "", mchId, subMchId, "", nonceStr, outTradeNo, key);
|
|
|
|
|
|
|
|
|
|
var result = WxPayV3.OrderQuery(dataInfo);
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("订单[{0}]微信(原生)查询支付结果:{1}", outTradeNo, JsonUtils.Serialize(result));
|
|
|
|
|
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();
|
|
|
|
|
//更新付款状态
|
|
|
|
|
lock (_lock)
|
|
|
|
|
{
|
|
|
|
|
if (!isPay)
|
|
|
|
|
{
|
|
|
|
|
isPay = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "微信支付成功"));
|
|
|
|
|
|
|
|
|
|
//构建微信支付方式
|
|
|
|
|
this.AddWxPayType(result);
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(outTradeNo);
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "微信支付成功");
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "密码错误或未输入,请重新扫码"));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
string message = string.Format("{0}:{1}秒", result.trade_state_desc, --timeout);
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, message));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (result.err_code == "ORDERNOTEXIST")
|
|
|
|
|
{
|
|
|
|
|
//计时器停止
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "微信:未收到该订单,请重新扫码"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
string message = string.Format("正在确认微信扣款结果:{0}秒,{1}", --timeout, result.err_code_des);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, message));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("查询支付结果网络通信错误:{0}", result.return_msg);
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, result.return_msg));
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(new Exception("查询微信支付结果网络通信错误" + JsonUtils.Serialize(result)));
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "微信支付结果查询发生异常");
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(ex);
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddWxPayType(OrderQueryResult result)
|
|
|
|
|
{
|
|
|
|
|
if (result != null && "SUCCESS".Equals(result.return_code) && "SUCCESS".Equals(result.result_code))
|
|
|
|
|
{
|
|
|
|
|
//构建微信支付方式
|
|
|
|
|
PayItem item = OrderUtils.ToPayItem(this.CurrentPayMode);
|
|
|
|
|
|
|
|
|
|
//租户ID
|
|
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
|
|
//订单号
|
|
|
|
|
item.OrderId = this._orderObject.Id;
|
|
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
item.OutTradeNo = outTradeNo;
|
|
|
|
|
|
|
|
|
|
//实收金额
|
|
|
|
|
item.PaidAmount = DecimalUtils.Fen2Yuan(result.total_fee);
|
|
|
|
|
//找零金额
|
|
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
|
|
item.Amount = item.PaidAmount;
|
|
|
|
|
|
|
|
|
|
item.CardNo = "";
|
|
|
|
|
|
|
|
|
|
item.TradeVoucherNo = result.transaction_id;
|
|
|
|
|
|
|
|
|
|
item.Memo = result.openid;
|
|
|
|
|
item.Subscribe = result.is_subscribe;
|
|
|
|
|
|
|
|
|
|
item.PayChannel = this._payChannel;
|
|
|
|
|
|
|
|
|
|
//微信支付状态
|
|
|
|
|
item.Status = (int)OrderPaymentStatus.已付款; ;
|
|
|
|
|
item.StatusDesc = string.Format("微信支付<{0}>", result.result_code);
|
|
|
|
|
|
|
|
|
|
//将微信支付压入支付清单
|
|
|
|
|
this._orderObject.Pays.Add(item);
|
|
|
|
|
|
|
|
|
|
//刷新界面数据
|
|
|
|
|
this.billSummary1.Refresh(this._orderObject);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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 = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
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", this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount);
|
|
|
|
|
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", this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount);
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待确认扣款结果..."));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
isQuery = false;
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, string.Format("{0}<{1}>", response.SubMsg, response.SubCode)));
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(new Exception("订单["+ outTradeNo + "]支付宝(原生)支付失败,返回结果:"+ JsonUtils.Serialize(response)));
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "支付宝付款发生异常");
|
|
|
|
|
|
|
|
|
|
if (ex.Message.Contains("私钥格式错误"))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付宝私钥配置错误..."));
|
|
|
|
|
|
|
|
|
|
isQuery = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "支付宝付款发生异常..."));
|
|
|
|
|
|
|
|
|
|
isQuery = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(ex);
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
return isQuery;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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>();
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
content.Add("out_trade_no", outTradeNo);
|
|
|
|
|
|
|
|
|
|
request.BizContent = JsonUtils.Serialize(content);
|
|
|
|
|
|
|
|
|
|
AlipayTradeQueryResponse response = client.Execute(request, string.Empty, appAuthToken);
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("支付宝(原生)查询订单[{0}]支付状态结果:<{1}>", outTradeNo, JsonUtils.Serialize(response));
|
|
|
|
|
|
|
|
|
|
switch (response.TradeStatus)
|
|
|
|
|
{
|
|
|
|
|
case "TRADE_SUCCESS":
|
|
|
|
|
{
|
|
|
|
|
//计时器停止
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
//更新付款状态
|
|
|
|
|
lock (_lock)
|
|
|
|
|
{
|
|
|
|
|
if (!isPay)
|
|
|
|
|
{
|
|
|
|
|
isPay = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "支付宝付款成功"));
|
|
|
|
|
|
|
|
|
|
//构建支付宝支付方式
|
|
|
|
|
this.AddAliPayType(response);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "支付宝付款成功");
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(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();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case "WAIT_BUYER_PAY":
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待买家付款..."));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待买家付款..."));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "支付宝结果查询发生异常");
|
|
|
|
|
|
|
|
|
|
//Task.Factory.StartNew(new Action(() =>
|
|
|
|
|
//{
|
|
|
|
|
// Global.Instance.BugReport(ex);
|
|
|
|
|
//}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddAliPayType(AlipayTradeQueryResponse result)
|
|
|
|
|
{
|
|
|
|
|
if (result != null && "TRADE_SUCCESS".Equals(result.TradeStatus))
|
|
|
|
|
{
|
|
|
|
|
//构建微信支付方式
|
|
|
|
|
PayItem item = OrderUtils.ToPayItem(this.CurrentPayMode);
|
|
|
|
|
|
|
|
|
|
//租户ID
|
|
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
|
|
//订单号
|
|
|
|
|
item.OrderId = this._orderObject.Id;
|
|
|
|
|
//订单编号
|
|
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
item.OutTradeNo = outTradeNo;
|
|
|
|
|
|
|
|
|
|
//实收金额
|
|
|
|
|
item.PaidAmount = StringUtils.GetDecimal(result.TotalAmount);
|
|
|
|
|
//找零金额
|
|
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
|
|
item.Amount = item.PaidAmount;
|
|
|
|
|
|
|
|
|
|
item.CardNo = "";
|
|
|
|
|
item.TradeVoucherNo = result.TradeNo;
|
|
|
|
|
item.Memo = result.BuyerUserId;
|
|
|
|
|
item.Subscribe = string.Empty;
|
|
|
|
|
|
|
|
|
|
item.PayChannel = this._payChannel;
|
|
|
|
|
|
|
|
|
|
//支付宝支付状态
|
|
|
|
|
item.Status = (int)OrderPaymentStatus.已付款;
|
|
|
|
|
item.StatusDesc = string.Format("支付宝付款<{0}>", result.TradeStatus);
|
|
|
|
|
|
|
|
|
|
//将支付宝支付压入支付清单
|
|
|
|
|
this._orderObject.Pays.Add(item);
|
|
|
|
|
|
|
|
|
|
//刷新界面数据
|
|
|
|
|
this.billSummary1.Refresh(this._orderObject);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 乐刷支付渠道
|
|
|
|
|
|
|
|
|
|
private void PayChannel_LeShua()
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待确认扣款结果..."));
|
|
|
|
|
|
|
|
|
|
//zhangy 2020-08-12 10:44 修复混合支付情况,扣款金额错误
|
|
|
|
|
var amount = this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount;
|
|
|
|
|
var _data = PayMentOperation.Pay(this.txtPayCode.Text, _orderObject.TradeNo, amount, this._payChannel);
|
|
|
|
|
|
|
|
|
|
//zhangy 2020-08-12 10:44 屏蔽
|
|
|
|
|
//var _data = PayMentOperation.Pay(this.txtPayCode.Text, _orderObject.TradeNo, _orderObject.PaidAmount, this._payChannel);
|
|
|
|
|
|
|
|
|
|
if (_data.Item3 != null)
|
|
|
|
|
{
|
|
|
|
|
UpdateSaomaTicket(string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo), _data.Item3.OutTradeNo, _data.Item3.FinishDate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_data.Item1)
|
|
|
|
|
{
|
|
|
|
|
if (!_data.Item2.Contains("支付中"))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, _data.Item2));
|
|
|
|
|
this.txtPayCode.Enabled = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, _data.Item2));
|
|
|
|
|
|
|
|
|
|
this.initValue = 10;
|
|
|
|
|
this.timeout = 60;
|
|
|
|
|
this.txtPayCode.Enabled = false;
|
|
|
|
|
//启动定时器
|
|
|
|
|
this.timer.Start();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UpdateSaomaTicket(_data.Item3.OutTradeNo, string.Format("{0}_{1}", _orderObject.StoreNo, _data.Item3.TradeNo), _data.Item3.FinishDate);
|
|
|
|
|
|
|
|
|
|
if (this._orderObject.Pays == null)
|
|
|
|
|
{
|
|
|
|
|
this._orderObject.Pays = new List<PayItem>();
|
|
|
|
|
}
|
|
|
|
|
_data.Item3.OrderId = this._orderObject.Id;
|
|
|
|
|
_data.Item3.Order = this._orderObject.Pays.Count;
|
|
|
|
|
this._orderObject.Pays.Add(_data.Item3);
|
|
|
|
|
|
|
|
|
|
//计时器停止
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(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();
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "乐刷支付付款成功");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void QueryPayChannel_LESHUA()
|
|
|
|
|
{
|
|
|
|
|
//进度条最大值
|
|
|
|
|
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._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
|
|
|
|
|
if (DialogResult.Retry == dialog.ShowDialog())
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
OnPayCodeCheckClick(null, null);
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
using (var _db = Global.Instance.OpenDataBase)
|
|
|
|
|
{
|
|
|
|
|
var _ticket = _db.FirstOrDefault<SaomaPayTicket>(string.Format("where orderNo = '{0}_{1}'", this._orderObject.StoreNo, this._orderObject.TradeNo));
|
|
|
|
|
if (_ticket == null)
|
|
|
|
|
{
|
|
|
|
|
this.LOGGER.Info("在SaomaPayTicket 中查询不到相关数据");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dictionary<string, string> keys = new Dictionary<string, string>();
|
|
|
|
|
|
|
|
|
|
var _data = PayMentOperation.QueryPay(this.txtPayCode.Text, this._orderObject.TradeNo, _ticket.SerialNo, this._payChannel, keys);
|
|
|
|
|
if (!_data.Item1)
|
|
|
|
|
{
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, _data.Item2));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateSaomaTicket(_data.Item3.OutTradeNo, string.Format("{0}_{1}", _orderObject.StoreNo, _data.Item3.TradeNo), _data.Item3.FinishDate);
|
|
|
|
|
|
|
|
|
|
if (this._orderObject.Pays == null)
|
|
|
|
|
{
|
|
|
|
|
this._orderObject.Pays = new List<PayItem>();
|
|
|
|
|
}
|
|
|
|
|
_data.Item3.OrderId = this._orderObject.Id;
|
|
|
|
|
_data.Item3.Order = this._orderObject.Pays.Count;
|
|
|
|
|
this._orderObject.Pays.Add(_data.Item3);
|
|
|
|
|
//计时器停止
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "乐刷支付付款成功"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "乐刷支付付款成功");
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(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();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool VerifyLeShuaPay(string payCode)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
var _data = PayMentOperation.VerifyParameter(payCode);
|
|
|
|
|
|
|
|
|
|
return _data.Item1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region 扫呗支付渠道
|
|
|
|
|
|
|
|
|
|
private void PayChannel_SAOBEI()
|
|
|
|
|
{
|
|
|
|
|
this.SAOBEI_QRCodeType = "";
|
|
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
|
|
var saobeiPayResult = SAOBEIPayResult();
|
|
|
|
|
|
|
|
|
|
if (saobeiPayResult.Item1)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
//清理支付码
|
|
|
|
|
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 Tuple<bool, string> VerifyOrderPay()
|
|
|
|
|
{
|
|
|
|
|
using (var _db = Global.Instance.OpenDataBase)
|
|
|
|
|
{
|
|
|
|
|
var _data = _db.FirstOrDefault<SaomaPayTicket>(string.Format("where orderNo = '{0}_{1}'", this._orderObject.StoreNo, this._orderObject.TradeNo));
|
|
|
|
|
|
|
|
|
|
if (_data == null)
|
|
|
|
|
{
|
|
|
|
|
return new Tuple<bool, string>(false, "无需核销");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_data.PayStatus == 1)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(_data.SerialNo))
|
|
|
|
|
{
|
|
|
|
|
SaobeiQueryResult saobeiQuery = new SaobeiQueryResult();
|
|
|
|
|
saobeiQuery.Trade_state = "SUCCESS";
|
|
|
|
|
saobeiQuery.Total_fee = (_data.Money * 100).ToString();
|
|
|
|
|
saobeiQuery.Out_trade_no = _data.SerialNo;
|
|
|
|
|
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "扫呗支付成功"));
|
|
|
|
|
//构建支付方式
|
|
|
|
|
this.AddSAOBEIPayType(saobeiQuery);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "扫呗支付付款成功");
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(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();
|
|
|
|
|
return new Tuple<bool, string>(true, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Tuple<bool, string>(false, "支付异常,请联系管理员");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_data.Money != this._orderObject.ReceivableAmount - this._orderObject.MalingAmount)
|
|
|
|
|
{
|
|
|
|
|
return new Tuple<bool, string>(false, "金额不相等,该核销数据无效");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
SaobeiQueryParam request = new SaobeiQueryParam();
|
|
|
|
|
if (_data.PayTypeNo.Equals("05"))
|
|
|
|
|
{
|
|
|
|
|
request.Pay_type = "010";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
request.Pay_type = "110";
|
|
|
|
|
}
|
|
|
|
|
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))
|
|
|
|
|
|| saobeiPayment.Item3.Return_msg.Equals("支付成功"))
|
|
|
|
|
{
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "扫呗支付成功"));
|
|
|
|
|
//构建支付方式
|
|
|
|
|
this.AddSAOBEIPayType(saobeiPayment.Item3);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "扫呗支付付款成功");
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(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();
|
|
|
|
|
return new Tuple<bool, string>(true, "");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Tuple<bool, string>(false, "");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Tuple<bool, string, decimal> SAOBEIPayResult()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
bool isQuery = false;
|
|
|
|
|
string orderId = "";
|
|
|
|
|
decimal payAmount = 0.00M;
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
var amount = this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount;
|
|
|
|
|
orderId = outTradeNo;
|
|
|
|
|
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)); //支付方式 支付宝1、微信2
|
|
|
|
|
request.Pay_type = "020";
|
|
|
|
|
request.Terminal_time = DateTime.Now.ToString("yyyyMMddHHmmss");
|
|
|
|
|
this.SAOBEI_PAYTIME = request.Terminal_time;
|
|
|
|
|
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;
|
|
|
|
|
//请求之前,先把支付时间更新到扫呗支付表,防止软件假死、或者卡死导致核销不了
|
|
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
|
|
|
|
|
var saobeiPayment = SaobeiUtils.SaobeiPayment(merchant_no, terminal_id, signKey, gatewayUrl, request);
|
|
|
|
|
if (saobeiPayment.Item1)
|
|
|
|
|
{
|
|
|
|
|
SaobeiPaymentResult saobeiPaymentResult = saobeiPayment.Item3;
|
|
|
|
|
//支付结果需要查询
|
|
|
|
|
isQuery = true;
|
|
|
|
|
this.SAOBEI_QRCodeType = saobeiPaymentResult.Pay_type;
|
|
|
|
|
this.SAOBEI_OrderId = saobeiPaymentResult.Out_trade_no;
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待确认扣款结果..."));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
isQuery = false;
|
|
|
|
|
this.SAOBEI_QRCodeType = "";
|
|
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, string.Format("{0}", saobeiPayment.Item2)));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "扫呗支付订单[" + outTradeNo + "]金额[" + amount + "]发生异常!");
|
|
|
|
|
isQuery = false;
|
|
|
|
|
this.SAOBEI_QRCodeType = "";
|
|
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, this.SAOBEI_OrderId, this.SAOBEI_PAYTIME);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查不到支付状态,请使用手工核销功能..."));
|
|
|
|
|
}
|
|
|
|
|
return new Tuple<bool, string, decimal>(isQuery, orderId, payAmount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 };
|
|
|
|
|
|
|
|
|
|
//发送结果通知
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "查询支付结果超时"));
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("查询支付结果超时,系统无法确认本单已经支付,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
|
|
|
|
|
if (DialogResult.Retry == dialog.ShowDialog())
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
OnPayCodeCheckClick(null, null);
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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 = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
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();
|
|
|
|
|
//更新付款状态
|
|
|
|
|
lock (_lock)
|
|
|
|
|
{
|
|
|
|
|
if (!isPay)
|
|
|
|
|
{
|
|
|
|
|
isPay = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "扫呗支付成功"));
|
|
|
|
|
//构建支付方式
|
|
|
|
|
this.AddSAOBEIPayType(saobeiPayment.Item3);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "扫呗支付付款成功");
|
|
|
|
|
//微信支付更新核销状态
|
|
|
|
|
//UpdateSaoMa(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
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查询结果:" + saobeiPayment.Item2));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, saobeiPayment.Item2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "银联商务支付付款结果查询发生异常");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddSAOBEIPayType(SaobeiQueryResult queryParam)
|
|
|
|
|
{
|
|
|
|
|
if (queryParam != null && "SUCCESS".Equals(queryParam.Trade_state))
|
|
|
|
|
{
|
|
|
|
|
//构建支付方式
|
|
|
|
|
PayItem item = OrderUtils.ToPayItem(this.CurrentPayMode);
|
|
|
|
|
|
|
|
|
|
//租户ID
|
|
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
|
|
//订单号
|
|
|
|
|
item.OrderId = this._orderObject.Id;
|
|
|
|
|
//订单编号
|
|
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
item.OutTradeNo = outTradeNo;
|
|
|
|
|
|
|
|
|
|
//实收金额
|
|
|
|
|
item.PaidAmount = Convert.ToDecimal(StringUtils.GetDecimal(queryParam.Total_fee) / 100);
|
|
|
|
|
//找零金额
|
|
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
|
|
item.Amount = item.PaidAmount;
|
|
|
|
|
|
|
|
|
|
item.CardNo = "";
|
|
|
|
|
item.TradeVoucherNo = queryParam.Out_trade_no;//利楚唯一订单号
|
|
|
|
|
item.Memo = this._payChannel.ToString();
|
|
|
|
|
item.Subscribe = string.Empty;
|
|
|
|
|
item.PayChannel = this._payChannel;
|
|
|
|
|
|
|
|
|
|
//支付状态
|
|
|
|
|
item.Status = (int)OrderPaymentStatus.已付款;
|
|
|
|
|
item.StatusDesc = string.Format("{0}", queryParam.Trade_state);
|
|
|
|
|
|
|
|
|
|
//将支付宝支付压入支付清单
|
|
|
|
|
this._orderObject.Pays.Add(item);
|
|
|
|
|
|
|
|
|
|
//刷新界面数据
|
|
|
|
|
this.billSummary1.Refresh(this._orderObject);
|
|
|
|
|
|
|
|
|
|
if (Global.Instance.GlobalConfigBoolValue(ConfigConstant.CONFIG_CASHIER_ISPAYVOICE))
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
{
|
|
|
|
|
switch (item.No)
|
|
|
|
|
{
|
|
|
|
|
case "04"://支付宝
|
|
|
|
|
Voice.Pay.PayVoicePlay.PlayReceiveMoney(Voice.PayTypeEnum.Alipay, item.PaidAmount);
|
|
|
|
|
break;
|
|
|
|
|
case "05"://微信
|
|
|
|
|
Voice.Pay.PayVoicePlay.PlayReceiveMoney(Voice.PayTypeEnum.WeiXinPay, item.PaidAmount);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool VerifySAOBEIPay(string payCode, PayMode payMode)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(payCode))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "付款码非法..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parameter = payMode.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() : "";
|
|
|
|
|
if (string.IsNullOrEmpty(merchant_no) || string.IsNullOrEmpty(terminal_id) || string.IsNullOrEmpty(signKey) || string.IsNullOrEmpty(gatewayUrl))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "扫呗支付参数配置不完整..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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 override void Clear()
|
|
|
|
|
{
|
|
|
|
|
base.Clear();
|
|
|
|
|
|
|
|
|
|
this.txtPayCode.Text = string.Empty;
|
|
|
|
|
this.txtPayCode.Enabled = true;
|
|
|
|
|
|
|
|
|
|
this._orderObject = null;
|
|
|
|
|
|
|
|
|
|
this._payChannel = PayChannelEnum.无;
|
|
|
|
|
|
|
|
|
|
if (this.timer != null)
|
|
|
|
|
{
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
this.timer = null;
|
|
|
|
|
|
|
|
|
|
LOGGER.Info("释放查询任务");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this.lastPayed)
|
|
|
|
|
{
|
|
|
|
|
//发送支付失败,重新生成订单号事件
|
|
|
|
|
MsgEvent.Send(Constant.ORDER_PAYMENT_ERROR_GENERATENO, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnPayCodeCheckClick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
//打开提示界面
|
|
|
|
|
var form = new AllinPayCheckForm(this._orderObject, this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount, true);
|
|
|
|
|
form.ShowDialog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region subin 2023-06-20 通联支付
|
|
|
|
|
private bool VerifyAllinPay(string payCode, PayMode payMode)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(payCode))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "付款码非法..."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parameter = payMode.Body;
|
|
|
|
|
|
|
|
|
|
//通联支付参数
|
|
|
|
|
string appId = parameter.ContainsKey("appId") ? parameter["appId"].ToString() : "";
|
|
|
|
|
string appKey = parameter.ContainsKey("appKey") ? parameter["appKey"].ToString() : "";
|
|
|
|
|
string url = parameter.ContainsKey("gatewayUrl") ? parameter["gatewayUrl"].ToString() : "";
|
|
|
|
|
var payuserid = parameter.ContainsKey("payuserid") ? (parameter["payuserid"] != null ? parameter["payuserid"].ToString() : "") : "";
|
|
|
|
|
//string bizUserId = parameter.ContainsKey("bizUserId") ? parameter["bizUserId"].ToString() : "";
|
|
|
|
|
var vspCusid = parameter.ContainsKey("vspCusid") ? (parameter["vspCusid"] != null ? parameter["vspCusid"].ToString() : "") : "";
|
|
|
|
|
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(url) || string.IsNullOrEmpty(payuserid))
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "通联支付参数配置不完整..."));
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appKey) || string.IsNullOrEmpty(url))
|
|
|
|
|
{
|
|
|
|
|
//公共参数
|
|
|
|
|
LOGGER.Warn("通联支付公共参数配置不完整");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(payuserid) || string.IsNullOrEmpty(vspCusid))
|
|
|
|
|
{
|
|
|
|
|
//公共参数
|
|
|
|
|
LOGGER.Warn("通联支付业务参数配置不完整");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if (string.IsNullOrEmpty(payuserid))
|
|
|
|
|
//{
|
|
|
|
|
// MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "通联支付参数未配置门店付款会员号..."));
|
|
|
|
|
// return false;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Tuple<bool, string> VerifyOrderAllinPay()
|
|
|
|
|
{
|
|
|
|
|
using (var _db = Global.Instance.OpenDataBase)
|
|
|
|
|
{
|
|
|
|
|
var _ticket = _db.FirstOrDefault<SaomaPayTicket>(string.Format("where orderNo = '{0}_{1}'", this._orderObject.StoreNo, this._orderObject.TradeNo));
|
|
|
|
|
|
|
|
|
|
if (_ticket == null)
|
|
|
|
|
{
|
|
|
|
|
return new Tuple<bool, string>(false, "无需核销");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_ticket.PayStatus == 1)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(_ticket.SerialNo))
|
|
|
|
|
{
|
|
|
|
|
var orderDetail = new OrderDetail
|
|
|
|
|
{
|
|
|
|
|
reqsn = _ticket.OrderNo,
|
|
|
|
|
trxid = _ticket.SerialNo,
|
|
|
|
|
status = _ticket.OrderStatus,
|
|
|
|
|
amount = (int)_ticket.Money * 100,
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "通联支付付款成功");
|
|
|
|
|
|
|
|
|
|
//构建支付方式,播放支付语音
|
|
|
|
|
AddAllinPayType(orderDetail);
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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();
|
|
|
|
|
return new Tuple<bool, string>(true, "通联支付付款成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Tuple<bool, string>(false, "支付异常,请联系管理员");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_ticket.Money != this._orderObject.ReceivableAmount - this._orderObject.MalingAmount)
|
|
|
|
|
{
|
|
|
|
|
return new Tuple<bool, string>(false, "金额不相等,该核销数据无效");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var payParam = this.CurrentPayMode.Body;
|
|
|
|
|
|
|
|
|
|
AllinpayLib.AppId = payParam.ContainsKey("appId") ? payParam["appId"].ToString() : "";
|
|
|
|
|
AllinpayLib.AppKey = payParam.ContainsKey("appKey") ? payParam["appKey"].ToString() : "";
|
|
|
|
|
AllinpayLib.Url = payParam.ContainsKey("gatewayUrl") ? payParam["gatewayUrl"].ToString() : "";
|
|
|
|
|
|
|
|
|
|
var info = new GetOrderDetailModel()
|
|
|
|
|
{
|
|
|
|
|
reqsn = this._orderObject.TradeNo,
|
|
|
|
|
};
|
|
|
|
|
var param = new GetOrderDetailParamInfo
|
|
|
|
|
{
|
|
|
|
|
bizContent = JsonUtils.Serialize(info)
|
|
|
|
|
};
|
|
|
|
|
var response = AllinpayHelper.GetOrderDetail(param);
|
|
|
|
|
if (!response.IsSuccess)
|
|
|
|
|
{
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, response.ShowUserMsg));
|
|
|
|
|
//LOGGER.Warn("订单号<{0}>支付查询异常:{1}", this._orderObject.TradeNo, response.ShowUserMsg);
|
|
|
|
|
LOGGER.Warn("订单[{0}]通联支付查询,网络通信错误:{1}", _orderObject.TradeNo, response.ShowUserMsg);
|
|
|
|
|
return new Tuple<bool, string>(false, "支付查询异常");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var _data = JsonUtils.Deserialize<OrderDetail>(response.ResultInfo.data);
|
|
|
|
|
var _statusDesc = "进行中";
|
|
|
|
|
switch (_data.status)
|
|
|
|
|
{
|
|
|
|
|
case "1":
|
|
|
|
|
_statusDesc = "未支付";
|
|
|
|
|
break;
|
|
|
|
|
case "3":
|
|
|
|
|
_statusDesc = "交易失败";
|
|
|
|
|
break;
|
|
|
|
|
case "4":
|
|
|
|
|
_statusDesc = "交易成功";
|
|
|
|
|
break;
|
|
|
|
|
case "5":
|
|
|
|
|
_statusDesc = "交易成功-发生退款";
|
|
|
|
|
break;
|
|
|
|
|
case "6":
|
|
|
|
|
_statusDesc = "关闭";
|
|
|
|
|
break;
|
|
|
|
|
case "99":
|
|
|
|
|
_statusDesc = "进行中";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_statusDesc.Equals("交易成功"))
|
|
|
|
|
{
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "通联支付付款成功"));
|
|
|
|
|
|
|
|
|
|
//构建支付方式,播放支付语音
|
|
|
|
|
AddAllinPayType(_data);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "通联支付付款成功");
|
|
|
|
|
//清理支付码
|
|
|
|
|
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();
|
|
|
|
|
return new Tuple<bool, string>(true, "通联支付付款成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Tuple<bool, string>(false, "支付异常:" + _statusDesc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddAllinPayType(OrderDetail queryParam)
|
|
|
|
|
{
|
|
|
|
|
if (queryParam != null && "4".Equals(queryParam.status))
|
|
|
|
|
{
|
|
|
|
|
//构建支付方式
|
|
|
|
|
PayItem item = OrderUtils.ToPayItem(this.CurrentPayMode);
|
|
|
|
|
|
|
|
|
|
//租户ID
|
|
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
|
|
//订单号
|
|
|
|
|
item.OrderId = this._orderObject.Id;
|
|
|
|
|
//订单编号
|
|
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
item.OutTradeNo = outTradeNo;
|
|
|
|
|
|
|
|
|
|
//实收金额
|
|
|
|
|
item.PaidAmount = Convert.ToDecimal(StringUtils.GetDecimal(queryParam.amount) / 100);
|
|
|
|
|
//找零金额
|
|
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
|
|
item.Amount = item.PaidAmount;
|
|
|
|
|
|
|
|
|
|
//通联扣款实收手续费,单位:分
|
|
|
|
|
item.Ext2 = ((decimal)queryParam.fee) / 100 + "";
|
|
|
|
|
|
|
|
|
|
item.CardNo = "";
|
|
|
|
|
item.TradeVoucherNo = queryParam.trxid;//通联唯一订单号
|
|
|
|
|
item.Memo = this._payChannel.ToString();
|
|
|
|
|
|
|
|
|
|
item.Subscribe = string.Empty;
|
|
|
|
|
item.PayChannel = this._payChannel;
|
|
|
|
|
|
|
|
|
|
//支付状态
|
|
|
|
|
item.Status = (int)OrderPaymentStatus.已付款;
|
|
|
|
|
item.StatusDesc = string.Format("{0}", queryParam.status);
|
|
|
|
|
|
|
|
|
|
//将通联支付压入支付清单
|
|
|
|
|
this._orderObject.Pays.Add(item);
|
|
|
|
|
|
|
|
|
|
//刷新界面数据
|
|
|
|
|
this.billSummary1.Refresh(this._orderObject);
|
|
|
|
|
|
|
|
|
|
if (Global.Instance.GlobalConfigBoolValue(ConfigConstant.CONFIG_CASHIER_ISPAYVOICE))
|
|
|
|
|
{
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
|
|
{
|
|
|
|
|
Voice.Pay.PayVoicePlay.PlayReceiveMoney(Voice.PayTypeEnum.AllinPay, item.PaidAmount);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PayChannel_Allin()
|
|
|
|
|
{
|
|
|
|
|
bool isQuery = false;
|
|
|
|
|
var allinPay_OrderId = "";
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
//string outTradeNo = this._orderObject.TradeNo;
|
|
|
|
|
var _amount = this._orderObject.ReceivableAmount - this._orderObject.ReceivedAmount;
|
|
|
|
|
|
|
|
|
|
var _recieverList = new List<ApplyReciever>();
|
|
|
|
|
var applyParam = new AgentCollectApplyParamInfo();
|
|
|
|
|
|
|
|
|
|
var isResquest = false;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var payParam = this.CurrentPayMode.Body;
|
|
|
|
|
|
|
|
|
|
//AllinpayLib.AppId = payParam.ContainsKey("appId") ? payParam["appId"].ToString() : "";
|
|
|
|
|
//AllinpayLib.AppKey = payParam.ContainsKey("appKey") ? payParam["appKey"].ToString() : "";
|
|
|
|
|
//AllinpayLib.Url = payParam.ContainsKey("gatewayUrl") ? payParam["gatewayUrl"].ToString() : "";
|
|
|
|
|
|
|
|
|
|
var _vspCusid = payParam.ContainsKey("vspCusid") ? payParam["vspCusid"].ToString() : "";
|
|
|
|
|
var _payuserid = payParam.ContainsKey("payuserid") ? payParam["payuserid"].ToString() : "";
|
|
|
|
|
var _bizUserId = payParam.ContainsKey("bizUserId") ? payParam["bizUserId"].ToString() : "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//decimal _bizUserAmount = 0;
|
|
|
|
|
#region subin 分账变更内容
|
|
|
|
|
if (this._orderObject.OrderCount > 0)
|
|
|
|
|
{
|
|
|
|
|
//1.20230917 由单账号收退款后端统一分账改为多账号收退款前端分账
|
|
|
|
|
//ZHTQY_OUT16890697512466994 大同市平城区开闻快餐店
|
|
|
|
|
_recieverList.Add(new ApplyReciever { bizUserId = _bizUserId, amount = Convert.ToInt32(_amount * 100) });
|
|
|
|
|
|
|
|
|
|
#region 20230920 注销,由多账号收退款前端分账改为单账号收退款后端统一分账
|
|
|
|
|
//2.20230920 注销,由多账号收退款前端分账改为单账号收退款后端统一分账
|
|
|
|
|
//using (var db = Global.Instance.OpenDataBase)
|
|
|
|
|
//{
|
|
|
|
|
// var productIdList = this._orderObject.Items.Select(item => item.ProductId).Distinct();
|
|
|
|
|
// var productIds = string.Join(",", productIdList);
|
|
|
|
|
|
|
|
|
|
// StringBuilder sqlBuld = new StringBuilder();
|
|
|
|
|
// sqlBuld.Append("SELECT ssa.bizUserId,sfa.goodId FROM pos_split_shop_account ssa ");
|
|
|
|
|
// sqlBuld.Append("LEFT JOIN pos_split_food_account sfa ON sfa.shopId=ssa.id ");
|
|
|
|
|
// sqlBuld.Append("WHERE sfa.goodId IN ('{0}'); ");
|
|
|
|
|
|
|
|
|
|
// string sql = string.Format(sqlBuld.ToString(), productIds.Replace(",", "','"));
|
|
|
|
|
// var orderSubStoreDetail = db.Query<OrderSubStoreDetail>(sql).ToList();
|
|
|
|
|
|
|
|
|
|
// var bizUseIdLst = orderSubStoreDetail.Count() > 0 ? orderSubStoreDetail.Select(item => item.BizUserId).Distinct().ToList() : new List<string>();
|
|
|
|
|
|
|
|
|
|
// if (bizUseIdLst.Count() == 0)
|
|
|
|
|
// {
|
|
|
|
|
// LOGGER.Warn("订单[{0}]通联支付[{1}]分支付异常:收款方列表为空", _orderObject.TradeNo, Convert.ToInt32(_amount * 100));
|
|
|
|
|
// MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, string.Format("{0}", "收款方列表为空")));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// foreach (var item in bizUseIdLst)
|
|
|
|
|
// {
|
|
|
|
|
// var goodLst = orderSubStoreDetail.Where(m => m.BizUserId == item).ToList().Select(m => m.GoodId);
|
|
|
|
|
// var goodIds = string.Join(",", goodLst);
|
|
|
|
|
// var total = this._orderObject.Items.Where(m => goodIds.Contains(m.ProductId)).Sum(m => m.TotalAmonut);
|
|
|
|
|
// _bizUserAmount += total;
|
|
|
|
|
// _recieverList.Add(new ApplyReciever { bizUserId = item, amount = Convert.ToInt32(total * 100) });
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Maximum / 3;
|
|
|
|
|
|
|
|
|
|
//托管代收
|
|
|
|
|
var applyInfo = new AgentCollectApplyModel
|
|
|
|
|
{
|
|
|
|
|
reqsn = this._orderObject.TradeNo,
|
|
|
|
|
payuserid = _payuserid,
|
|
|
|
|
vspCusid = _vspCusid,
|
|
|
|
|
payuseridtype = "",
|
|
|
|
|
paytype = "CODEPAY_VSP_ORG",
|
|
|
|
|
amount = Convert.ToInt32(_amount * 100),
|
|
|
|
|
fee = 0,
|
|
|
|
|
frontUrl = "",
|
|
|
|
|
backUrl = "",
|
|
|
|
|
limit_pay = "no_credit",
|
|
|
|
|
source = "2",
|
|
|
|
|
authcode = this.txtPayCode.Text,
|
|
|
|
|
consumer_ip = "10.40.8.35",
|
|
|
|
|
remark = "POSV代付",
|
|
|
|
|
recieverList = JsonUtils.Serialize(_recieverList)
|
|
|
|
|
};
|
|
|
|
|
applyParam.bizContent = JsonUtils.Serialize(applyInfo);
|
|
|
|
|
|
|
|
|
|
//请求之前,先把支付时间更新到扫码支付表,防止软件假死、或者卡死导致核销不了
|
|
|
|
|
allinPay_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, allinPay_OrderId, applyParam.timestamp);
|
|
|
|
|
var _response = AllinpayHelper.AgentCollectApply(applyParam);
|
|
|
|
|
if (_response.IsSuccess)
|
|
|
|
|
{
|
|
|
|
|
isResquest = true;
|
|
|
|
|
this.lastPayed = true;
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Maximum;
|
|
|
|
|
|
|
|
|
|
// 支付结果需要查询
|
|
|
|
|
isQuery = true;
|
|
|
|
|
var _data = JsonUtils.Deserialize<AgentCollectApply>(_response.ResultInfo.data);
|
|
|
|
|
allinPay_OrderId = _data.orderNo;
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, allinPay_OrderId, applyParam.timestamp);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "等待确认扣款结果..."));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
isResquest = true;
|
|
|
|
|
this.lastPayed = false;
|
|
|
|
|
|
|
|
|
|
this.PayStep2.Value = this.PayStep2.Maximum;
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("订单[{0}]通联支付[{1}]分,支付错误:{2}", _orderObject.TradeNo, Convert.ToInt32(_amount * 100), _response.LogMsg);
|
|
|
|
|
isQuery = false;
|
|
|
|
|
allinPay_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, allinPay_OrderId, applyParam.timestamp);
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, string.Format("{0}", _response.ShowUserMsg)));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.lastPayed = false;
|
|
|
|
|
//清理支付码
|
|
|
|
|
this.txtPayCode.Text = string.Empty;
|
|
|
|
|
//允许扫码框输入
|
|
|
|
|
this.txtPayCode.Enabled = true;
|
|
|
|
|
this.txtPayCode.Text = string.Empty;
|
|
|
|
|
this.txtPayCode.Focus();
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查询结果:" + _response.ShowUserMsg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "订单[" + outTradeNo + "]通联支付[" + Convert.ToInt32(_amount * 100) + "]分,支付发生异常!");
|
|
|
|
|
isQuery = false;
|
|
|
|
|
allinPay_OrderId = "";
|
|
|
|
|
UpdateSaomaTicket(outTradeNo, allinPay_OrderId, applyParam.timestamp);
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查不到支付状态,请使用手工核销功能..."));
|
|
|
|
|
|
|
|
|
|
if (isResquest)
|
|
|
|
|
{
|
|
|
|
|
this.lastPayed = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//return new Tuple<bool, string, decimal>(isQuery, outTradeNo, (decimal)_amount * 100);
|
|
|
|
|
|
|
|
|
|
if (isQuery)
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "正在确认扣款状态"));
|
|
|
|
|
|
|
|
|
|
this.initValue = 10;
|
|
|
|
|
this.timeout = 90;
|
|
|
|
|
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 void QueryPayChannel_Allin()
|
|
|
|
|
{
|
|
|
|
|
//进度条最大值
|
|
|
|
|
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._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
var dialog = new DialogForm("支付结果", "没有查询到支付结果,系统无法确认本单已经支付", MessageBoxIcon.Warning, MessageBoxButtons.RetryCancel);
|
|
|
|
|
if (DialogResult.Retry == dialog.ShowDialog())
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Warn("收银员手动选择重新查询一次结果,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "等待确认扣款状态"));
|
|
|
|
|
|
|
|
|
|
this.initValue = 10;
|
|
|
|
|
|
|
|
|
|
this.timeout = 90;
|
|
|
|
|
|
|
|
|
|
this.txtPayCode.Enabled = false;
|
|
|
|
|
//启动定时器
|
|
|
|
|
this.timer.Start();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
OnPayCodeCheckClick(null, null);
|
|
|
|
|
|
|
|
|
|
LOGGER.Warn("收银员手动放弃结果确认,订单号<{0}>", this._orderObject.TradeNo);
|
|
|
|
|
|
|
|
|
|
//清理支付码
|
|
|
|
|
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.QueryAllinPayResult();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void QueryAllinPayResult()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var payParam = this.CurrentPayMode.Body;
|
|
|
|
|
|
|
|
|
|
AllinpayLib.AppId = payParam.ContainsKey("appId") ? payParam["appId"].ToString() : "";
|
|
|
|
|
AllinpayLib.AppKey = payParam.ContainsKey("appKey") ? payParam["appKey"].ToString() : "";
|
|
|
|
|
AllinpayLib.Url = payParam.ContainsKey("gatewayUrl") ? payParam["gatewayUrl"].ToString() : "";
|
|
|
|
|
|
|
|
|
|
//商户订单号
|
|
|
|
|
string outTradeNo = string.Format("{0}_{1}", this._orderObject.StoreNo, this._orderObject.TradeNo);
|
|
|
|
|
//string outTradeNo = this._orderObject.TradeNo;
|
|
|
|
|
var info = new GetOrderDetailModel()
|
|
|
|
|
{
|
|
|
|
|
reqsn = this._orderObject.TradeNo,
|
|
|
|
|
};
|
|
|
|
|
var param = new GetOrderDetailParamInfo
|
|
|
|
|
{
|
|
|
|
|
bizContent = JsonUtils.Serialize(info)
|
|
|
|
|
};
|
|
|
|
|
var _response = AllinpayHelper.GetOrderDetail(param);
|
|
|
|
|
if (!_response.IsSuccess)
|
|
|
|
|
{
|
|
|
|
|
//明确失败,结束查询
|
|
|
|
|
//计时器停止
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, _response.ShowUserMsg));
|
|
|
|
|
LOGGER.Warn("订单[{0}]通联支付查询,错误:{0}", _orderObject.TradeNo, _response.ShowUserMsg);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var _data = JsonUtils.Deserialize<OrderDetail>(_response.ResultInfo.data);
|
|
|
|
|
var _statusDesc = "进行中";
|
|
|
|
|
switch (_data.status)
|
|
|
|
|
{
|
|
|
|
|
case "1":
|
|
|
|
|
_statusDesc = "未支付";
|
|
|
|
|
break;
|
|
|
|
|
case "3":
|
|
|
|
|
_statusDesc = "交易失败";
|
|
|
|
|
break;
|
|
|
|
|
case "4":
|
|
|
|
|
_statusDesc = "交易成功";
|
|
|
|
|
break;
|
|
|
|
|
case "5":
|
|
|
|
|
_statusDesc = "交易成功-发生退款";
|
|
|
|
|
break;
|
|
|
|
|
case "6":
|
|
|
|
|
_statusDesc = "关闭";
|
|
|
|
|
break;
|
|
|
|
|
case "99":
|
|
|
|
|
_statusDesc = "进行中";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ("4".Equals(_data.status))
|
|
|
|
|
{
|
|
|
|
|
//计时器停止
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
//更新付款状态
|
|
|
|
|
lock (_lock)
|
|
|
|
|
{
|
|
|
|
|
if (!isPay)
|
|
|
|
|
{
|
|
|
|
|
isPay = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.PayStep3.Value = this.PayStep3.Maximum;
|
|
|
|
|
|
|
|
|
|
//发送消息通知显示文本
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(true, "通联支付成功"));
|
|
|
|
|
|
|
|
|
|
//构建支付方式,播放支付语音
|
|
|
|
|
AddAllinPayType(_data);
|
|
|
|
|
|
|
|
|
|
//发送自动完成结账事件
|
|
|
|
|
MsgEvent.Send(Constant.PAY_AUTO_EVENT_NOTIFY, "通联支付付款成功");
|
|
|
|
|
//清理支付码
|
|
|
|
|
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 if ("3".Equals(_data.status))
|
|
|
|
|
{
|
|
|
|
|
//计时器停止
|
|
|
|
|
this.timer.Stop();
|
|
|
|
|
this.lastPayed = 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();
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查询结果:" + _statusDesc));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
MsgEvent.Send(Constant.PAY_MESSAGE_EVENT_NOTIFY, new Tuple<bool, string>(false, "查询结果:" + _statusDesc));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LOGGER.Error(ex, "通联支付结果查询发生异常");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|