/// <summary> /// 等待付款时 /// </summary> public virtual void OnWaitingPaying( PaymentTransaction transaction, PaymentTransactionState previousState) { var logManager = Application.Ioc.Resolve <LogManager>(); var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); foreach (var childTransaction in transaction.ReleatedTransactions) { var canProcessWaitingPaying = childTransaction.Check(c => c.CanProcessWaitingPaying); if (canProcessWaitingPaying.First) { // 处理关联交易的等待付款 logManager.LogTransaction( $"Merged transaction {transaction.Serial} waiting paying " + $"with child transaction {childTransaction.Serial}"); transactionManager.Process( childTransaction.Id, ExternalSerialPrefix + transaction.Serial, PaymentTransactionState.WaitingPaying); } else { // 有冲突时记录到交易记录 logManager.LogTransaction( $"Merged transaction {transaction.Serial} waiting paying " + $"with child transaction {childTransaction.Serial} failed, " + $"reason is {canProcessWaitingPaying.Second}"); transactionManager.AddDetailRecord( transaction.Id, null, new T("Can't process waiting paying on child transaction {0}, reason is {1}", childTransaction.Serial, canProcessWaitingPaying.Second)); } } }
/// <summary> /// 担保交易付款后 /// </summary> public virtual void OnSecuredPaid(PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoDeliveryGoodsParameters> parameters) { var logManager = Application.Ioc.Resolve <LogManager>(); var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); foreach (var childTransaction in transaction.ReleatedTransactions) { var canProcessSecuredPaid = childTransaction.Check(c => c.CanProcessSecuredPaid); if (canProcessSecuredPaid.First) { // 处理关联交易的担保交易已付款 logManager.LogTransaction( $"Merged transaction {transaction.Serial} secured paid " + $"with child transaction {childTransaction.Serial}"); transactionManager.Process( childTransaction.Id, ExternalSerialPrefix + transaction.Serial, PaymentTransactionState.SecuredPaid); } else { // 有冲突时记录到交易记录 logManager.LogTransaction( $"Merged transaction {transaction.Serial} secured paid " + $"with child transaction {childTransaction.Serial} failed, " + $"reason is {canProcessSecuredPaid.Second}"); transactionManager.AddDetailRecord( transaction.Id, null, new T("Can't process secured paid on child transaction {0}, reason is {1}", childTransaction.Serial, canProcessSecuredPaid.Second)); } } }
/// <summary> /// 交易成功时 /// </summary> public void OnSuccess( IDatabaseContext context, PaymentTransaction transaction, PaymentTransactionState previousState) { var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction(string.Format("TestTransaction Success: {0}", transaction.Serial)); }
/// <summary> /// 交易终止时 /// </summary> public void OnAbort( PaymentTransaction transaction, PaymentTransactionState previousState) { var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction(string.Format("TestTransaction Aborted: {0}", transaction.Serial)); }
/// <summary> /// 等待付款时 /// </summary> public void OnWaitingPaying( PaymentTransaction transaction, PaymentTransactionState previousState) { // 记录到日志 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction(string.Format("OrderTransaction waiting paying: {0}", transaction.Serial)); }
/// <summary> /// 担保交易付款后 /// </summary> public void OnSecuredPaid(PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoSendGoodsParameters> parameters) { // TODO:记录到日志 // TODO: 记录到订单记录 // TODO: 处理订单已付款 }
/// <summary> /// 交易终止时 /// 不会终止关联交易,只会清除所有关联交易 /// </summary> public virtual void OnAbort( PaymentTransaction transaction, PaymentTransactionState previousState) { var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction( $"Merged transaction {transaction.Serial} aborted, clear all child transactions"); transaction.ReleatedTransactions.Clear(); }
/// <summary> /// 担保交易付款后 /// </summary> public virtual void OnSecuredPaid(PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoSendGoodsParameters> parameters) { foreach (var childTransaction in transaction.ReleatedTransactions) { var handlers = childTransaction.GetHandlers(); handlers.ForEach(h => h.OnSecuredPaid(childTransaction, previousState, parameters)); } }
/// <summary> /// 交易成功时 /// </summary> public virtual void OnSuccess( PaymentTransaction transaction, PaymentTransactionState previousState) { foreach (var childTransaction in transaction.ReleatedTransactions) { var handlers = childTransaction.GetHandlers(); handlers.ForEach(h => h.OnSuccess(childTransaction, previousState)); } }
/// <summary> /// 等待付款时 /// </summary> public virtual void OnWaitingPaying( IDatabaseContext context, PaymentTransaction transaction, PaymentTransactionState previousState) { foreach (var childTransaction in transaction.ReleatedTransactions) { var handlers = childTransaction.GetHandlers(); handlers.ForEach(h => h.OnWaitingPaying(context, childTransaction, previousState)); } }
/// <summary> /// 担保交易付款后 /// </summary> public void OnSecuredPaid( IDatabaseContext context, PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoSendGoodsParameters> parameters) { // 记录到日志 // 记录到订单记录 // 处理订单已付款 }
/// <summary> /// 担保交易付款后 /// 付款后自动发货 /// </summary> public void OnSecuredPaid(PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoDeliveryGoodsParameters> parameters) { var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction(string.Format("TestTransaction Secured Paid: {0}", transaction.Serial)); parameters.Add(new AutoDeliveryGoodsParameters() { LogisticsName = "TestLogistics", InvoiceNo = "00000000" }); }
/// <summary> /// 等待付款时 /// </summary> public void OnWaitingPaying( PaymentTransaction transaction, PaymentTransactionState previousState) { // 记录到日志 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction($"OrderTransaction waiting paying, serial is {transaction.Serial}"); // 单独处理时确保合并交易终止 var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); transactionManager.EnsureParentTransactionAbortedIfProcessNotFromParent( transaction, null, new T( "Child transaction {0} process waiting paying standalone, " + "this merge transaction should be aborted", transaction.Serial)); }
/// <summary> /// 尝试把交易切换到指定的交易状态 /// 失败时记录错误并抛出例外 /// </summary> /// <param name="transactionId">交易Id</param> /// <param name="externalSerial">外部交易流水号,等于空时不更新</param> /// <param name="state">交易状态</param> public virtual void Process( Guid transactionId, string externalSerial, PaymentTransactionState state) { try { ProcessInternal(transactionId, externalSerial, state); } catch (Exception e) { var errorMessage = new T("Change transaction state to {0} failed: {1}", new T(state.GetDescription()), new T(e.Message)); AddDetailRecord(transactionId, null, errorMessage); SetLastError(transactionId, errorMessage); throw; } }
/// <summary> /// 交易终止时 /// </summary> public void OnAbort( PaymentTransaction transaction, PaymentTransactionState previousState) { // 记录到日志 // 不会影响到订单的状态 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction( $"Order transaction aborted, serial is {transaction.Serial}"); // 确保合并交易终止 var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); transactionManager.EnsureParentTransactionAborted( new[] { transaction.Id }, null, new T( "Child transaction {0} aborted, " + "this merge transaction should be aborted too", transaction.Serial)); }
/// <summary> /// 交易成功时 /// </summary> public void OnSuccess( PaymentTransaction transaction, PaymentTransactionState previousState) { // 记录到日志 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction( $"OrderTransaction successed, serial is {transaction.Serial}"); // 如果之前的状态是等待付款,则处理订单已付款 // 如之前的状态是担保交易已付款,则处理订单确认收货 // 否则不处理 var orderManager = Application.Ioc.Resolve <SellerOrderManager>(); var orderId = transaction.ReleatedId.Value; if (previousState == PaymentTransactionState.Initial || previousState == PaymentTransactionState.WaitingPaying) { // 添加到订单记录 orderManager.AddDetailRecord(orderId, null, new T("Order paid from transaction, serial is {0}", transaction.Serial)); // 处理订单已付款,不一定会成功(例如其他关联交易未付款时) orderManager.ProcessOrderPaid(orderId); } else if (previousState == PaymentTransactionState.SecuredPaid) { // 添加到订单记录 orderManager.AddDetailRecord(orderId, null, new T("Order confirmed from payment platform after secured paid, serial is {0}", transaction.Serial)); // 处理订单交易成功(确认收货),不一定会成功 orderManager.ProcessSuccess(orderId); } // 单独处理时确保合并交易终止 var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); transactionManager.EnsureParentTransactionAbortedIfProcessNotFromParent( transaction, null, new T( "Child transaction {0} process success standalone, " + "this merge transaction should be aborted", transaction.Serial)); }
/// <summary> /// 担保交易付款后 /// </summary> public void OnSecuredPaid(PaymentTransaction transaction, PaymentTransactionState previousState, IList <AutoDeliveryGoodsParameters> parameters) { // 记录到日志 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogTransaction( $"OrderTransaction secured paid, serial is {transaction.Serial}"); // 记录到订单记录 var orderManager = Application.Ioc.Resolve <SellerOrderManager>(); var orderId = transaction.ReleatedId.Value; orderManager.AddDetailRecord(orderId, null, new T("Order secured paid from transaction, serial is {0}", transaction.Serial)); // 处理订单已付款,不一定会成功(例如其他关联交易未付款时) orderManager.ProcessOrderPaid(orderId); // 单独处理时确保合并交易终止 var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>(); transactionManager.EnsureParentTransactionAbortedIfProcessNotFromParent( transaction, null, new T( "Child transaction {0} process secured paid standalone, " + "this merge transaction should be aborted", transaction.Serial)); }
/// <summary> /// 交易终止时 /// 不会终止关联交易,只会清除所有关联交易 /// </summary> public virtual void OnAbort( PaymentTransaction transaction, PaymentTransactionState previousState) { transaction.ReleatedTransactions.Clear(); }
/// <summary> /// 尝试把交易切换到指定的交易状态 /// </summary> /// <param name="transactionId">交易Id</param> /// <param name="externalSerial">外部交易流水号,等于空时不更新</param> /// <param name="state">交易状态</param> public virtual void Process(long transactionId, string externalSerial, PaymentTransactionState state) { // 获取交易 var transaction = GetById(transactionId); if (transaction == null) { throw new BadRequestException(new T("Payment transaction not found")); } // 判断是否可以处理指定的交易状态 // 已经是指定的交易状态时返回成功 Pair <bool, string> result; if (transaction.State == state) { return; } else if (state == PaymentTransactionState.WaitingPaying) { result = transaction.Check(c => c.CanProcessWaitingPaying); } else if (state == PaymentTransactionState.SecuredPaid) { result = transaction.Check(c => c.CanProcessSecuredPaid); } else if (state == PaymentTransactionState.Success) { result = transaction.Check(c => c.CanProcessSuccess); } else if (state == PaymentTransactionState.Aborted) { result = transaction.Check(c => c.CanProcessAborted); } else { throw new BadRequestException(string.Format(new T("Unsupported transaction state: {0}"), state)); } if (!result.First) { throw new BadRequestException(result.Second); } // 获取交易类型对应的处理器 var handlers = transaction.GetHandlers(); // 设置交易状态 var previousState = transaction.State; Context.Save(ref transaction, t => { t.State = state; t.LastError = null; // 清空最后发生的错误 t.LastUpdated = DateTime.UtcNow; if (!string.IsNullOrEmpty(externalSerial)) { t.ExternalSerial = externalSerial; // 更新外部流水号 } }); // 使用处理器处理指定的交易状态 var parameters = new List <AutoSendGoodsParameters>(); if (state == PaymentTransactionState.WaitingPaying) { handlers.ForEach(h => h.OnWaitingPaying(Context, transaction, previousState)); } else if (state == PaymentTransactionState.SecuredPaid) { handlers.ForEach(h => h.OnSecuredPaid(Context, transaction, previousState, parameters)); } else if (state == PaymentTransactionState.Success) { handlers.ForEach(h => h.OnSuccess(Context, transaction, previousState)); } else if (state == PaymentTransactionState.Aborted) { handlers.ForEach(h => h.OnAbort(Context, transaction, previousState)); } else { throw new BadRequestException(string.Format(new T("Unsupported transaction state: {0}"), state)); } // 成功时添加详细记录 AddDetailRecord(transaction.Id, null, string.Format( new T("Change transaction state to {0}"), new T(transaction.State.GetDescription()))); // 需要自动发货时进行发货 foreach (var parameter in parameters) { SendGoods(transaction.Id, parameter.LogisticsName, parameter.InvoiceNo); } }
/// <summary> /// 交易成功时 /// </summary> public void OnSuccess( IDatabaseContext context, PaymentTransaction transaction, PaymentTransactionState previousState) { throw new NotImplementedException(); }
/// <summary> /// 交易终止时 /// </summary> public void OnAbort( PaymentTransaction transaction, PaymentTransactionState previousState) { throw new NotImplementedException(); }
/// <summary> /// 交易终止时 /// 不会终止关联交易,只会清除所有关联交易 /// </summary> public virtual void OnAbort( IDatabaseContext context, PaymentTransaction transaction, PaymentTransactionState previousState) { transaction.ReleatedTransactions.Clear(); }
/// <summary> /// 尝试把交易切换到指定的交易状态 /// </summary> /// <param name="transactionId">交易Id</param> /// <param name="externalSerial">外部交易流水号,等于空时不更新</param> /// <param name="state">交易状态</param> protected virtual void ProcessInternal( Guid transactionId, string externalSerial, PaymentTransactionState state) { using (UnitOfWork.Scope()) { // 开启事务 UnitOfWork.Context.BeginTransaction(); // 获取交易 var transaction = Get(transactionId); if (transaction == null) { throw new BadRequestException(new T("Payment transaction not found")); } // 判断是否可以处理指定的交易状态 // 已经是指定的交易状态时返回成功 Pair <bool, string> result; if (transaction.State == state) { return; } else if (state == PaymentTransactionState.WaitingPaying) { result = transaction.Check(c => c.CanProcessWaitingPaying); } else if (state == PaymentTransactionState.SecuredPaid) { result = transaction.Check(c => c.CanProcessSecuredPaid); } else if (state == PaymentTransactionState.Success) { result = transaction.Check(c => c.CanProcessSuccess); } else if (state == PaymentTransactionState.Aborted) { result = transaction.Check(c => c.CanProcessAborted); } else { throw new BadRequestException(new T("Unsupported transaction state: {0}", state)); } if (!result.First) { throw new BadRequestException(result.Second); } // 获取交易类型对应的处理器 var handlers = transaction.GetHandlers(); // 设置交易状态 var previousState = transaction.State; Save(ref transaction, t => { t.State = state; t.LastError = null; // 清空最后发生的错误 if (!string.IsNullOrEmpty(externalSerial)) { t.ExternalSerial = externalSerial; // 更新外部流水号 } }); // 使用处理器处理指定的交易状态 var parameters = new List <AutoDeliveryGoodsParameters>(); if (state == PaymentTransactionState.WaitingPaying) { handlers.ForEach(h => h.OnWaitingPaying(transaction, previousState)); } else if (state == PaymentTransactionState.SecuredPaid) { handlers.ForEach(h => h.OnSecuredPaid(transaction, previousState, parameters)); } else if (state == PaymentTransactionState.Success) { handlers.ForEach(h => h.OnSuccess(transaction, previousState)); } else if (state == PaymentTransactionState.Aborted) { handlers.ForEach(h => h.OnAbort(transaction, previousState)); } else { throw new BadRequestException(new T("Unsupported transaction state: {0}", state)); } // 成功时添加详细记录 AddDetailRecord(transaction.Id, null, new T("Change transaction state to {0}", new T(transaction.State.GetDescription()))); // 需要自动发货时进行发货 foreach (var parameter in parameters) { NotifyAllGoodsShippedBackground( transaction.Id, parameter.LogisticsName, parameter.InvoiceNo); } // 结束事务 UnitOfWork.Context.FinishTransaction(); } }