Magento-付款未决时使用的单一优惠券



我有Magento Single Coupon代码的问题,该代码在客户点击 place Order Order 按钮时被标记为已使用。如果PayPal付款失败或客户在订单完成之前离开页面,他将无法返回并重新订购此优惠券,该优惠券仅用于一次使用,并且已被标记为已使用。<<<<<<<<<<<<

我找到了一块代码,该代码减少了用户使用优惠券的次数,并允许他重复使用优惠券。不幸的是,在单击"位置订单"按钮时,他试图连接PayPal页面时会出现错误。为了能够再使用优惠券并访问PayPal页面,我必须在表中删除SQL数据库中的行 salesrule_coupon_usage salesrule_customer 使用此客户的ID。

这是我需要更改以自动删除客户ID的优惠券使用信息的代码:

public function cancel($observer)
{
    $order = $observer->getEvent()->getPayment()->getOrder();
    if ($order->canCancel()) {
        if ($code = $order->getCouponCode()) {
            $coupon = Mage::getModel('salesrule/coupon')->load($code, 'code');
            if ($coupon->getTimesUsed() > 0) {
                $coupon->setTimesUsed($coupon->getTimesUsed() - 1);
                $coupon->save();
            }
            $rule = Mage::getModel('salesrule/rule')->load($coupon->getRuleId());
            error_log("nrule times used=" . $rule->getTimesUsed(), 3, "var/log/debug.log");
            if ($rule->getTimesUsed() > 0) {
                $rule->setTimesUsed($rule->getTimesUsed()-1);
                $rule->save();
            }
            if ($customerId = $order->getCustomerId()) {
                if ($customerCoupon = Mage::getModel('salesrule/rule_customer')->loadByCustomerRule($customerId, $rule->getId())) {
                    $couponUsage = new Varien_Object();
                    Mage::getResourceModel('salesrule/coupon_usage')->loadByCustomerCoupon($couponUsage, $customerId, $coupon->getId());
                    if ($couponUsage->getTimesUsed() > 0) {
                        /* I can't find any #@$!@$ interface to do anything but increment a coupon_usage record */
                        $resource = Mage::getSingleton('core/resource');
                        $writeConnection = $resource->getConnection('core_write');
                        $tableName = $resource->getTableName('salesrule_coupon_usage');
                        $query = "UPDATE {$tableName} SET times_used = times_used-1 "
                            .  "WHERE coupon_id = {$coupon->getId()} AND customer_id = {$customerId} AND times_used > 0";
                        $writeConnection->query($query);
                    }
                    if ($customerCoupon->getTimesUsed() > 0) {
                        $customerCoupon->setTimesUsed($customerCoupon->getTimesUsed()-1);
                        $customerCoupon->save();
                    }
                }
            }
        }
    }
}

我相信这是一个从1.4到1.6的旧错误。但是,无论您是否有旧版本,如果您知道围绕Magento的方式,则可以很容易地将其修复到位。

问题是,您的代码在单击付款按钮时右更新Salesrule_coupon_usage表。这根本不是您想要的。您希望将其包裹在付款交易中。我不知道此错误是因为您有自定义代码或正在使用旧版本的Magento而发生,但是我会告诉您 i 如何解决问题。然后,我会给您一个与您建议的相似的修复:

Magento已经具有称为"交易"的抽象。交易用于将所有成功或失败的对象组合在一起,没有半措施。Magento将进行交易,并尝试保存所放置的每个对象。如果其中任何一个失败(例如,付款未通过),那么所有已保存的事件都是"回滚"。

幸运的是,Magento已经创建了一个交易对象,以处理成功付款时需要共同更新的各种内容的付款。您可以利用该交易并使用它来正确更新优惠券。

这是您需要做的10,000英尺视图。

  • 找到正在更新Salesrule_coupon_usage表的内容过早并杀死它。我们将添加自己的交易安全版本,因此我们不希望将其保存在其他任何地方。最简单的方法是找出与该表连接的模型并搜索该模型的创建。对于1.7和1.8,这是规则/客户模型。
  • 创建一个观察者来开始付款交易的开始。在Magento的大多数现代版本中
  • 将订单退出活动,然后将优惠券代码从活动中抽出。
  • 提取要更新的实际模型。看来有人在您的代码中找不到它,但是应该有一些模型使用Salesrule_coupon_usage表藏在某个地方。搜索" salesrule_coupon_usage"的.xml文件,然后查看使用该表的模型。同样,对我来说,在1.7上,这是规则/客户模型。
  • 加载该模型,客户更改了您的优惠券代码的价值,以表明客户使用了优惠券,但仍不保存。
  • 从活动中获取交易,并使用AddoBject方法注册您更新的优惠券对象。

你完成了。交易将自动尝试保存已添加到其中的所有对象。如果任何部分失败(包括付款失败),则将回滚整个过程,并且您的优惠券将不会使用。耶!

现在,我认为,以上是处理问题的最佳方法,但是如果您出于某种原因遇到问题,则可以选择基于收取不成功付款然后使用代码的替代方法。

再次,这是10,000英尺的视图:

  • 创建一个观察者来捕获失败的付款事件。在大多数版本中,您想要的事件是sales_order_payment_cancel。
  • 运行您拥有的代码...应该这样做。但是要澄清他人:
    • 从活动中提取订单,将优惠券代码和客户ID从中提取。
    • 更新客户,规则和salesrule_coupon_usage表。(尽管确实应该有一个模型,但我敢肯定您可以找到它)

现在,当销售失败时,您会重新通过手动放松所有内容。这不像我的第一个解决方案那样干净,但是根据您对Magento的熟悉,您可能会更容易。

我很确定,新版本的Magento版本没有这个问题,所以让我提供一个相当明显的建议作为第三个解决方案。

  • 更新Magento
  • 如果Magento是最新的,请测试禁用任何自定义模块,因为某些东西会破坏它。我注意到Amasty优惠券插件特别有货。
  • 如果您对Magento Core进行了自定义更改...祝您好运。

祝你好运!

最新更新