自定义付款表单 - 在不将 PaymentIsCompleted 设置为 true 的情况下无法将订单状态设置为 Authorized

Custom payment form - unable to set order status to Authorized without setting PaymentIsCompleted to true

我们正在尝试使用 Kentico 中的结帐流程来授权信用卡付款而不是收费。为此,一旦用户完成结帐过程,我们希望订单的状态类似于 'Payment authorized',并且其 OrderIsPaid 属性 设置为 false

在付款表格中,在我对 ProcessPayment() 的覆盖中,我没有将 base.PaymentResult.PaymentIsCompleted 设置为 true,因为我只是想授权付款,而不是实际收费卡片。 (同样,这是我们希望的结帐过程结果:信用卡授权;实际上并未对卡收费。)在调用此函数后的某个时刻,订单状态设置为支付失败(在商店配置 -> 支付网关中指定) .

我希望的结果是将订单状态设置为授权(我在商店配置中指定)并将订单的 OrderIsPaid 字段设置为 false.

根据观察到的行为,我假设付款过程的成功取决于将 PaymentIsCompleted 设置为 true。我还假设 属性 与 OrderInfo.OrderIsPaid 相同。

有谁知道我怎样才能达到想要的状态?

----------------更新:基于 Trevor 回答的解决方案--------

我在支付过程中没有设置OrderCustomData。相反,我决定覆盖状态基于当前状态,是否 PaymentStatusValue=='complete',以及我们之前是否覆盖了此特定 PaymentTransactionID 的状态。

void UpdateAfter(object sender, ObjectEventArgs e)
{
    try
    {
        if (e.Object.TypeInfo.ObjectClassName.ToLower().Equals("ecommerce.order"))
        {
            /* 
             * The standard payment process behavior will not allow us to set 'IsPaid' to false without forcing the order status to the failed state.
             * (As specified in the Store Configuration app under payment methods -> edit payment method -> [Order status if payment fails:])
             * The workaround is to configure the payment methods failure status to be 'Authorization Failed' (internal name 'PaymentFailed'),
             * to set IsPaid=false in the payment code, and to use this event handler to override the status failed status based on .
            */

            OrderInfo order = (OrderInfo)e.Object;
            if (order == null)
                throw new ArgumentNullException("Order object of ecommerce.order event is null.");

            // If a payment hasn't been made, then there's nothing to override.
            if (order.OrderPaymentResult == null)
                return;

            // We will log the payment's transaction ID in ordercustomdata so next time we don't override 
            // order status unless the payment transaction ID has changed.
            string successfulPaymentTransactionId = null;
            try
            {
                successfulPaymentTransactionId = (string)order.OrderCustomData.GetValue("SuccessfulPaymentTransactionID");
            }
            catch 
            { }

            // Do not override status on an order that has the same payment transaction ID as when we last overrode it.
            if (successfulPaymentTransactionId != null && successfulPaymentTransactionId == order.OrderPaymentResult.PaymentTransactionID)
                return;

            PaymentOptionInfo paymentOption = PaymentOptionInfoProvider.GetPaymentOptionInfo(order.OrderPaymentOptionID);
            if (paymentOption == null)
                throw new ArgumentNullException(String.Format("Payment option for OrderPaymentOptionID '{0}' is null.", order.OrderPaymentOptionID));

            // Override status if: status is failed but payment status is 'completed'.
            // avoid overriding manually; Only override if we haven't yet overriden status based on the currrent payment transaction ID.
            if (order.OrderStatusID == paymentOption.PaymentOptionFailedOrderStatusID 
                && order.OrderPaymentResult.PaymentStatusValue == "completed" 
                && (successfulPaymentTransactionId == null || successfulPaymentTransactionId != order.OrderPaymentResult.PaymentTransactionID))
            {
                order.OrderStatusID = paymentOption.PaymentOptionSucceededOrderStatusID;
                order.OrderCustomData["SuccessfulPaymentTransactionID"] = order.OrderPaymentResult.PaymentTransactionID;
                order.Update();
            }
        }
    }
    catch (Exception ex)
    {
        EventLogProvider.LogException("EcommerceOrderInfoModule", "UpdateAfter", ex, 0, null, null);
    }
}

您说得对 "PaymentIsComplete" 将触发付费或未付费状态。在 Kentico 中,虽然对于您的付款,您可以设置 "Order Status" 应用于付款失败和付款成功。

商店配置 -> 付款方式 ->(编辑您的)-> 将 "Order status if payment fails" 设置为 "Payment Authorized"(可能需要创建它)

现在承认,这可能不是理想的,因为这里确实有 3 种状态的项目,完全失败、成功但未支付和已支付。因此,您可能需要使用自定义数据更新订单,然后使用事件挂钩来捕获订单状态更改并检查此值。

// If authorized, then set this to true, set paymentiscomplete to false regardless
Order.OrderCustomData.SetValue("Authorized", true);
PaymentResult.PaymentIsCompleted = false;

并且在 InitializationModule

protected override void OnInit()
{
    base.OnInit();
    CMS.DataEngine.ObjectEvents.Update.After += Update_After;
}

void Update_After(object sender, ObjectEventArgs e)
{
    try { 
    switch (e.Object.TypeInfo.ObjectClassName.ToLower())
    {
        case "ecommerce.order":
            OrderInfo theOrderObj = (OrderInfo)e.Object;

            bool hasAuthorizedStatus = CMS.Helpers.ValidationHelper.GetBoolean(theOrderObj.OrderCustomData.GetValue("Authorized"), false);
            if (hasAuthorizedStatus && theOrderObj.OrderStatusID == OrderStatusInfoProvider.GetOrderStatusInfo("ThePaymentFailureStatus", SiteContext.CurrentSiteName).StatusID)
            {
                theOrderObj.OrderStatusID = OrderStatusInfoProvider.GetOrderStatusInfo("PaymentAuthorized", SiteContext.CurrentSiteName).StatusID;
                theOrderObj.Update();
            }
            break;
    }
    }
    catch (Exception ex)
    {
        CMS.EventLog.EventLogProvider.LogException("CustomInitializationModule", "UpdateAfterError", ex);
    }
}