|
|
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.Card;
|
|
|
using POSV.Utils;
|
|
|
using System.Threading.Tasks;
|
|
|
using POSV.MessageEvent;
|
|
|
|
|
|
namespace POSV.Bill
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 会员卡免密快捷支付
|
|
|
/// </summary>
|
|
|
public partial class CardPayForm : BusinessForm
|
|
|
{
|
|
|
private OrderObject _orderObject;
|
|
|
public CardPayForm(OrderObject order)
|
|
|
{
|
|
|
InitializeComponent();
|
|
|
|
|
|
//复制新对象,避免取消后污染原对象
|
|
|
this._orderObject = ObjectUtils.Copy<OrderObject>(order);
|
|
|
}
|
|
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
{
|
|
|
base.OnLoad(e);
|
|
|
|
|
|
if (this.DesignMode) return;
|
|
|
|
|
|
this.lblAmount.Text = string.Format(this.lblAmount.Tag.ToString(), this._orderObject.PaidAmount);
|
|
|
|
|
|
Task.Factory.StartNew(() =>
|
|
|
{
|
|
|
return PayByCard();
|
|
|
}).ContinueWith(task =>
|
|
|
{
|
|
|
if (task.IsFaulted)
|
|
|
{
|
|
|
LOGGER.Error(task.Exception.GetBaseException());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (task.Result.Item1)
|
|
|
{
|
|
|
//支付成功
|
|
|
//整单状态
|
|
|
this._orderObject.OrderStatus = OrderStatus.已完成;
|
|
|
//整单支付状态
|
|
|
this._orderObject.PaymentStatus = OrderPaymentStatus.已付款;
|
|
|
//通知主界面结账成功
|
|
|
MsgEvent.Send(Constant.ORDER_PAYMENT_NOTIFY, this._orderObject);
|
|
|
|
|
|
this.OnCloseClick(null,null);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
var dialog = new DialogForm("扣款失败提醒", task.Result.Item2, MessageBoxIcon.Error, MessageBoxButtons.OK);
|
|
|
dialog.ShowDialog(this);
|
|
|
}));
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
private void ShowProcessInfo(string msg)
|
|
|
{
|
|
|
if (this.IsDisposed || !this.IsHandleCreated) return;
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
this.lblInfo.Text = msg;
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
private Tuple<bool, string> PayByCard()
|
|
|
{
|
|
|
bool status = true;
|
|
|
string message = string.Empty;
|
|
|
try
|
|
|
{
|
|
|
//1创建预支付订单
|
|
|
this.ShowProcessInfo("创建预支付订单...");
|
|
|
var data = BusinessUtils.Instance.CreateOrderCardTrade(this._orderObject);
|
|
|
if (data.Item1)
|
|
|
{
|
|
|
this.ShowProcessInfo("创建预支付订单成功");
|
|
|
|
|
|
var newVoucherNo = data.Item3;
|
|
|
var currentCard = this._orderObject.Member.CurrentCard;
|
|
|
var tradeNo = this._orderObject.TradeNo;
|
|
|
//交易参考号
|
|
|
string tradeVoucherNo = newVoucherNo.TradeVoucherNo;
|
|
|
|
|
|
//2创建卡支付明细
|
|
|
this.ShowProcessInfo("创建支付明细...");
|
|
|
var cardTradeRes = BusinessUtils.Instance.CreateCardTrade(tradeNo, this._orderObject.PaidAmount, tradeVoucherNo, currentCard);
|
|
|
if (!cardTradeRes.Item1)
|
|
|
{
|
|
|
//失败
|
|
|
status = false;
|
|
|
message = cardTradeRes.Item2;
|
|
|
this.ShowProcessInfo("创建支付明细失败<"+message+">");
|
|
|
}
|
|
|
if (status)
|
|
|
{
|
|
|
//构建会员卡支付列表,默认没有支付密码,按免密支付处理,免密支付采用扣款金额RSA加密
|
|
|
string passwd = RSAFromPkcs8.encryptData((this._orderObject.PaidAmount * 100).ToString(), Properties.Resources.RSAPublicKey, "UTF-8");
|
|
|
|
|
|
//3增加卡支付方式
|
|
|
AddCardPayType(currentCard.CardNo, passwd, cardTradeRes.Item3.PrePayment, tradeVoucherNo);
|
|
|
|
|
|
//4会员卡支付
|
|
|
this.ShowProcessInfo("发起扣款请求...");
|
|
|
var payResult = CardPay(tradeVoucherNo);
|
|
|
if (payResult.Item1)
|
|
|
{
|
|
|
//成功
|
|
|
status = true;
|
|
|
message = "支付成功";
|
|
|
this.ShowProcessInfo(message);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//失败
|
|
|
status = false;
|
|
|
message = payResult.Item2;
|
|
|
this.ShowProcessInfo("扣款失败<"+ message + ">");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
status = false;
|
|
|
message = data.Item2;
|
|
|
this.ShowProcessInfo("创建预支付订单失败<"+ message + ">");
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LOGGER.Error(ex, "会员卡支付发生异常");
|
|
|
status = false;
|
|
|
message = "会员卡支付发生异常";
|
|
|
}
|
|
|
return new Tuple<bool, string>(status, message);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 会员卡支付
|
|
|
/// </summary>
|
|
|
/// <param name="tradeVoucherNo"></param>
|
|
|
/// <returns></returns>
|
|
|
private Tuple<bool, string> CardPay(string tradeVoucherNo)
|
|
|
{
|
|
|
Tuple<bool, string> result = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
var cards = this._orderObject.Pays.FindAll(x => x.No.Equals("02"));
|
|
|
//扣款卡列表
|
|
|
var payCards = new List<PayInfo>();
|
|
|
foreach (var card in cards)
|
|
|
{
|
|
|
PayInfo c = new PayInfo();
|
|
|
c.PrePayment = card.PrePayNo;
|
|
|
c.CardNo = card.CardNo;
|
|
|
c.Amount = Convert.ToInt32(card.Amount * 100);
|
|
|
c.IsNoPwd = card.UseConfirmed ? 0 : 1;
|
|
|
c.Passwd = card.Passwd;
|
|
|
|
|
|
payCards.Add(c);
|
|
|
}
|
|
|
|
|
|
//记积分金额
|
|
|
var pointAmount = this._orderObject.Pays.FindAll(x => x.PointFlag == 1).Sum(x => x.Amount);
|
|
|
|
|
|
|
|
|
var payRequest = new CardTradePayRequest();
|
|
|
|
|
|
payRequest.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
payRequest.MemberId = this._orderObject.Member == null ? string.Empty : this._orderObject.Member.Id;
|
|
|
payRequest.Mobile = this._orderObject.Member == null ? string.Empty : this._orderObject.Member.Mobile;
|
|
|
|
|
|
payRequest.TradeVoucherNo = tradeVoucherNo;
|
|
|
|
|
|
payRequest.TotalAmount = Convert.ToInt32(this._orderObject.Amount * 100);
|
|
|
//实收金额
|
|
|
payRequest.RealAmount = Convert.ToInt32(this._orderObject.PaidAmount * 100);
|
|
|
|
|
|
payRequest.PointAmount = this._orderObject.Member == null ? 0 : Convert.ToInt32(pointAmount * 100);
|
|
|
|
|
|
payRequest.PayCardAmount = payCards.Sum(x => x.Amount);
|
|
|
|
|
|
payRequest.DiscountAmount = Convert.ToInt32(this._orderObject.DiscountAmount * 100);
|
|
|
|
|
|
payRequest.PointFlag = 2;//以卡系统计算为准
|
|
|
payRequest.PointValue = 0;
|
|
|
|
|
|
payRequest.PayInfo = payCards;
|
|
|
|
|
|
var pays = new List<Pay>();
|
|
|
foreach (var p in this._orderObject.Pays)
|
|
|
{
|
|
|
var pay = new Pay();
|
|
|
pay.PayTypeNo = p.No;
|
|
|
pay.PayType = p.Name;
|
|
|
pay.Money = Convert.ToInt32(p.Amount * 100);
|
|
|
pay.PointRule = string.Empty;
|
|
|
pay.Point = 0;
|
|
|
|
|
|
pays.Add(pay);
|
|
|
}
|
|
|
|
|
|
payRequest.Pay = pays;
|
|
|
int couponTotalAmount = 0;
|
|
|
var coupons = new List<Coupon>();
|
|
|
if (this._orderObject.Promotions != null)
|
|
|
{
|
|
|
foreach (PromotionOrder promotionOrder in this._orderObject.Promotions)
|
|
|
{
|
|
|
if (PromotionType.电子代金券 == promotionOrder.PromotionType)
|
|
|
{
|
|
|
Coupon coupon = new Coupon();
|
|
|
coupon.CouponId = promotionOrder.CouponId;
|
|
|
coupon.CouponType = "CASH";
|
|
|
coupon.Title = promotionOrder.PlanName;
|
|
|
coupon.Code = promotionOrder.PlanNo;
|
|
|
coupon.Discount = String.Format("{0}", promotionOrder.DiscountRate);
|
|
|
coupon.Cash = String.Format("{0}", promotionOrder.DiscountAmount);
|
|
|
coupon.Gift = promotionOrder.PlanName;
|
|
|
coupon.Memo = String.Format("电子代金券,优惠{0}", promotionOrder.DiscountAmount);
|
|
|
couponTotalAmount += Convert.ToInt32(promotionOrder.DiscountAmount * 100);
|
|
|
coupons.Add(coupon);
|
|
|
}
|
|
|
else if (PromotionType.电子折扣券 == promotionOrder.PromotionType)
|
|
|
{
|
|
|
Coupon coupon = new Coupon();
|
|
|
coupon.CouponId = promotionOrder.CouponId;
|
|
|
coupon.CouponType = "DISCOUNT";
|
|
|
coupon.Title = promotionOrder.PlanName;
|
|
|
coupon.Code = promotionOrder.PlanNo;
|
|
|
coupon.Discount = String.Format("{0}", promotionOrder.DiscountRate);
|
|
|
coupon.Cash = String.Format("{0}", promotionOrder.DiscountAmount);
|
|
|
coupon.Gift = promotionOrder.PlanName;
|
|
|
coupon.Memo = String.Format("电子折扣券,优惠{0}", promotionOrder.DiscountAmount);
|
|
|
couponTotalAmount += Convert.ToInt32(promotionOrder.DiscountAmount * 100);
|
|
|
coupons.Add(coupon);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (this._orderObject.Items != null)
|
|
|
{
|
|
|
foreach (OrderItem orderItem in this._orderObject.Items)
|
|
|
{
|
|
|
if (orderItem.Promotions != null)
|
|
|
{
|
|
|
foreach (PromotionItem promotionItem in orderItem.Promotions)
|
|
|
{
|
|
|
if (PromotionType.电子兑换券 == promotionItem.PromotionType)
|
|
|
{
|
|
|
Coupon coupon = new Coupon();
|
|
|
coupon.CouponId = promotionItem.CouponId;
|
|
|
coupon.CouponType = "GIFT";
|
|
|
coupon.Title = promotionItem.PlanName;
|
|
|
coupon.Code = promotionItem.PlanNo;
|
|
|
coupon.Discount = String.Format("{0}", promotionItem.DiscountRate);
|
|
|
coupon.Cash = String.Format("{0}", promotionItem.DiscountAmount);
|
|
|
coupon.Gift = promotionItem.PlanName;
|
|
|
coupon.Memo = String.Format("电子兑换券,优惠{0}", promotionItem.DiscountAmount);
|
|
|
couponTotalAmount += Convert.ToInt32(promotionItem.DiscountAmount * 100);
|
|
|
coupons.Add(coupon);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
payRequest.Coupon = coupons;
|
|
|
payRequest.CouponTotalAmount = couponTotalAmount;
|
|
|
payRequest.ShopNo = Global.Instance.Authc.StoreNo;
|
|
|
payRequest.WorkerNo = Global.Instance.Worker.No;
|
|
|
payRequest.PosNo = Global.Instance.Authc.PosNo;
|
|
|
|
|
|
var payResult = CardUtils.CardTradePay(payRequest);
|
|
|
|
|
|
if (payResult.Item1)
|
|
|
{
|
|
|
|
|
|
//会员卡扣款清单,用于打印
|
|
|
this._orderObject.CardPayResult = payResult.Item3;
|
|
|
|
|
|
var payRes = payResult.Item3;
|
|
|
//刷卡后积分计入主单
|
|
|
this._orderObject.PrePoint = OrderUtils.ToRound(payRes.PrePoint / 100.00M);
|
|
|
this._orderObject.AddPoint = OrderUtils.ToRound(payRes.GiftPoint / 100.00M);
|
|
|
this._orderObject.AftPoint = OrderUtils.ToRound(payRes.AftPoint / 100.00M);
|
|
|
|
|
|
//调整每张卡的扣款状态
|
|
|
foreach (var card in cards)
|
|
|
{
|
|
|
var payCard = payRes.CardList.Find(x => x.CardNo == card.CardNo);
|
|
|
if (payCard == null)
|
|
|
{
|
|
|
LOGGER.Error(string.Format("会员卡[{0}]支付成功后返回结果未包含该卡支付信息", card.CardNo));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
card.CardBeforeBalance = OrderUtils.ToRound(payCard.PreAmount / 100.00M);
|
|
|
card.CardAftAmount = OrderUtils.ToRound(payCard.AftAmount / 100.00M);
|
|
|
}
|
|
|
card.Status = (int)OrderPaymentStatus.已付款;
|
|
|
card.StatusDesc = payResult.Item2;
|
|
|
|
|
|
card.PayTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
|
//this.ShowMessage(this.lblInfo, payResult.Item2, false);
|
|
|
}
|
|
|
|
|
|
//会员卡扣款成功
|
|
|
result = new Tuple<bool, string>(true, "扣款成功");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//会员卡扣款失败
|
|
|
//if("0039商户订单号重复,此单已支付".Equals(payResult.Item2))
|
|
|
//{
|
|
|
// //重复支付
|
|
|
// LOGGER.Info("订单<{0}>卡<{1}>支付<{2}>元,卡系统返回0039商户订单号重复,此单已支付,收银认为订单支付完成!");
|
|
|
// result = new Tuple<bool, string>(true, "扣款成功");
|
|
|
//}
|
|
|
//else
|
|
|
//{
|
|
|
//}
|
|
|
result = new Tuple<bool, string>(false, payResult.Item2);
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LOGGER.Error(ex, "会员卡支付发生异常");
|
|
|
result = new Tuple<bool, string>(false, "会员卡支付发生异常");
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
private void AddCardPayType(string cardNo, string passwd, string prePayNO, string tradeVoucherNo)
|
|
|
{
|
|
|
var payMode = OrderUtils.GetPayMode("02");
|
|
|
//构建支付方式
|
|
|
PayItem item = OrderUtils.ToPayItem(payMode);
|
|
|
|
|
|
//租户ID
|
|
|
item.TenantId = Global.Instance.Authc.TenantId;
|
|
|
|
|
|
//订单号
|
|
|
item.OrderId = this._orderObject.Id;
|
|
|
item.TradeNo = this._orderObject.TradeNo;
|
|
|
|
|
|
//支付编号
|
|
|
item.PayNo = OrderUtils.Instance.GeneratePayNo();
|
|
|
|
|
|
item.Id = IdWorkerUtils.Instance.NextId();
|
|
|
item.Name = payMode.Name;
|
|
|
item.No = payMode.No;
|
|
|
item.PointFlag = payMode.PointFlag;
|
|
|
|
|
|
//实收金额
|
|
|
item.PaidAmount = this._orderObject.PaidAmount;
|
|
|
//找零金额
|
|
|
item.ChangeAmount = Convert.ToDecimal(0.00);
|
|
|
//已收金额,真正意义上实际收款金额
|
|
|
item.Amount = this._orderObject.PaidAmount;
|
|
|
|
|
|
item.CardNo = cardNo;
|
|
|
|
|
|
//加入卡面号,手机号信息
|
|
|
item.CardFaceNo = this._orderObject.Member.CurrentCard.FaceNo;
|
|
|
item.MemberMobileNo = this._orderObject.Member.Mobile;
|
|
|
//用户确认输入密码,免密直接支付
|
|
|
item.UseConfirmed = false;
|
|
|
|
|
|
//会员卡密码加密
|
|
|
item.Passwd = passwd;
|
|
|
|
|
|
//预支付编码
|
|
|
item.PrePayNo = prePayNO;
|
|
|
//交易参考号
|
|
|
item.TradeVoucherNo = tradeVoucherNo;
|
|
|
|
|
|
item.Memo = "会员卡支付";
|
|
|
item.Subscribe = string.Empty;
|
|
|
|
|
|
//会员卡支付状态,NOT_PAID未扣款
|
|
|
item.Status = (int)OrderPaymentStatus.未付款;
|
|
|
item.StatusDesc = "预下单成功,未扣款";
|
|
|
|
|
|
//将会员卡压入支付清单
|
|
|
this._orderObject.Pays.Add(item);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void OnCloseClick(object sender, EventArgs e)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (IsDisposed || !this.IsHandleCreated) return;
|
|
|
|
|
|
this.Invoke(new Action(() =>
|
|
|
{
|
|
|
if (IsDisposed || !this.IsHandleCreated) return;
|
|
|
|
|
|
if (this.Owner != null)
|
|
|
{
|
|
|
this.Owner.Close();
|
|
|
}
|
|
|
this.Close();
|
|
|
}));
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LOGGER.Info(ex);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|