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

437 lines
18 KiB
C#

9 months ago
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);
}
}
}
}