|
|
using POSV.Cef.FastTemplate.PayMent.Base;
|
|
|
using POSV.Entity;
|
|
|
using POSV.MessageEvent;
|
|
|
using POSV.Payment.Saobei;
|
|
|
using POSV.Payment.Saobei.Parameter;
|
|
|
using POSV.Payment.Saobei.Result;
|
|
|
using POSV.ShoppingCart;
|
|
|
using POSV.Utils;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
namespace POSV.Cef.FastTemplate.PayMent
|
|
|
{
|
|
|
public class SAOBEI_Pay : PayBase
|
|
|
{
|
|
|
public SAOBEI_Pay()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
public override PayItem PayStart()
|
|
|
{
|
|
|
if (!this.VerifyPay(this.m_PayCode, this.m_CurrentPayMode))
|
|
|
return null;
|
|
|
|
|
|
this.SAOBEI_QRCodeType = "";
|
|
|
this.SAOBEI_OrderId = "";
|
|
|
var saobeiPayResult = PayResult();
|
|
|
return this.QueryPay();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 异步通知
|
|
|
/// 1、方法将返回4次,第二次两秒后返回,其余一秒
|
|
|
/// 2、成功则停止返回
|
|
|
/// </summary>
|
|
|
public override void AsyncPayStart()
|
|
|
{
|
|
|
Task.Factory.StartNew(() =>
|
|
|
{
|
|
|
if (this.AsyncPayResult != null)
|
|
|
{
|
|
|
if (!this.VerifyPay(this.m_PayCode, this.m_CurrentPayMode))
|
|
|
{
|
|
|
this.m_QueryQuantity = 0;
|
|
|
this.AsyncPayResult(this.m_OrderObject, this.m_Paymodel, this.m_PayCode, this.m_Message, this.m_QueryQuantity);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (this.m_QueryQuantity == 4)
|
|
|
{
|
|
|
PayResult();
|
|
|
}
|
|
|
|
|
|
var _data = this.QueryPay();
|
|
|
|
|
|
if (_data == null && this.m_Message.Contains("支付中"))
|
|
|
{
|
|
|
this.m_QueryQuantity = 3;
|
|
|
System.Threading.Thread.Sleep(2000);
|
|
|
this.AsyncPayStart();
|
|
|
}
|
|
|
|
|
|
this.m_QueryQuantity = 0;
|
|
|
|
|
|
//回调结果
|
|
|
this.AsyncPayResult(this.m_OrderObject, this.m_Paymodel, this.m_PayCode, this.m_Message, this.m_QueryQuantity);
|
|
|
|
|
|
if (_data == null)
|
|
|
{
|
|
|
if (this.m_QueryQuantity == 0)
|
|
|
return;
|
|
|
|
|
|
if (this.m_QueryQuantity == 2)
|
|
|
System.Threading.Thread.Sleep(2000);
|
|
|
else
|
|
|
System.Threading.Thread.Sleep(1000);
|
|
|
|
|
|
this.AsyncPayStart();
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 发起支付
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
protected override Tuple<bool, string, decimal> PayResult()
|
|
|
{
|
|
|
bool isQuery = false;
|
|
|
string orderId = "";
|
|
|
decimal payAmount = 0.00M;
|
|
|
//商户订单号
|
|
|
string outTradeNo = string.Format("{0}_{1}", this.m_OrderObject.StoreNo, this.m_OrderObject.TradeNo);
|
|
|
var amount = this.m_OrderObject.ReceivableAmount - this.m_OrderObject.ReceivedAmount;
|
|
|
orderId = outTradeNo;
|
|
|
try
|
|
|
{
|
|
|
var parameter = this.m_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.m_PayCode;
|
|
|
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.m_CurrentPayMode.No == "05")
|
|
|
{
|
|
|
request.Pay_type = "010";
|
|
|
}
|
|
|
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;
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询支付
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public override PayItem QueryPay()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
var parameter = this.m_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.m_OrderObject.StoreNo, this.m_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.m_Paymodel = this.ToPayObject(saobeiPayment.Item3);
|
|
|
return this.m_Paymodel;
|
|
|
}
|
|
|
}
|
|
|
this.m_Message = saobeiPayment.Item2;
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
logger.Error(ex, "银联商务支付付款结果查询发生异常");
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 验证支付配置
|
|
|
/// </summary>
|
|
|
/// <param name="payCode"></param>
|
|
|
/// <param name="payMode"></param>
|
|
|
/// <returns></returns>
|
|
|
public override bool VerifyPay(string payCode, PayMode payMode)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(payCode))
|
|
|
{
|
|
|
this.m_Message = "付款码非法...";
|
|
|
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))
|
|
|
{
|
|
|
this.m_Message = "扫呗支付参数配置不完整...";
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 支付结果转支付对象
|
|
|
/// </summary>
|
|
|
/// <param name="_queryParam"></param>
|
|
|
/// <returns></returns>
|
|
|
protected override PayItem ToPayObject(object _queryParam)
|
|
|
{
|
|
|
var _data = _queryParam as SaobeiQueryResult;
|
|
|
|
|
|
if (_data == null)
|
|
|
{
|
|
|
this.m_Message = "接口返回数据对象无法正确转换";
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
if (_data != null && "SUCCESS".Equals(_data.Trade_state))
|
|
|
{
|
|
|
//构建支付方式
|
|
|
PayItem item = OrderUtils.ToPayItem(this.m_CurrentPayMode);
|
|
|
|
|
|
//租户ID
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
//订单号
|
|
|
item.OrderId = this.m_OrderObject.Id;
|
|
|
//订单编号
|
|
|
item.TradeNo = this.m_OrderObject.TradeNo;
|
|
|
|
|
|
//商户订单号
|
|
|
string outTradeNo = string.Format("{0}_{1}", this.m_OrderObject.StoreNo, this.m_OrderObject.TradeNo);
|
|
|
|
|
|
item.OutTradeNo = outTradeNo;
|
|
|
|
|
|
//实收金额
|
|
|
item.PaidAmount = Convert.ToDecimal(StringUtils.GetDecimal(_data.Total_fee) / 100);
|
|
|
//找零金额
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
item.Amount = item.PaidAmount;
|
|
|
|
|
|
item.CardNo = "";
|
|
|
item.TradeVoucherNo = _data.Out_trade_no;//利楚唯一订单号
|
|
|
item.Memo = PayChannelEnum.扫呗支付.ToString();
|
|
|
item.Subscribe = string.Empty;
|
|
|
item.PayChannel = PayChannelEnum.扫呗支付;
|
|
|
|
|
|
//支付状态
|
|
|
item.Status = (int)OrderPaymentStatus.已付款;
|
|
|
item.StatusDesc = string.Format("{0}", _data.Trade_state);
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return item;
|
|
|
////将支付宝支付压入支付清单
|
|
|
//this.m_OrderObject.Pays.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|