创建中间挂单的问题

时间:2015-08-05 08:37:17

标签: php prestashop prestashop-1.6 prestashop-1.5

我创建了一个自定义付款模块,目前在从付款网站重定向后调用validateOrder(),此方法会创建订单,发送电子邮件等。但问题是,如果用户在此之前关闭了付款网站可以重定向回PrestaShop网站,在这种情况下不会创建订单。所以,我想在重定向到付款网站之前创建一个订单(比如说"pending"状态),并且在从付款网站重定向后,我可以简单地标记相同的付款并发送邮件等。

目前,我尝试拨打validateOrder两次,一次在hookdisplayPayment(此处我将状态设置为"pending"),一次在重定向后。但是现在重定向后我得到了#34;购物车无法加载,或者已经使用此购物车放置了订单"。我认为这是因为我无法使用相同的卡ID更新同一订单两次。

请注意,一旦付款成功,我只想发送一次电子邮件。目前,我使用自定义付款状态,'send_email'设置为0。

对此有什么好的解决方法?

如果重要的话,我想支持1.5+和1.6+版本。

6 个答案:

答案 0 :(得分:5)

比我的第一个答案更好的方法是在函数validateOrder的模块中创建覆盖。 您将修改:

/** @var Order $order */
$order = new Order();

分为:

/** @var Order $order */
$order = new Order($this->currentOrder);

然后测试是否加载了对象,跳过设置订单字段的部分。如果未加载,请使用挂起状态正确设置订单字段。 还要测试$ this-> currentOrder是否设置了发送电子邮件的位置,如果未设置则跳过电子邮件部分。如果设置,则表示订单处于待处理状态,您应该更改状态并发送电子邮件。

覆盖该功能后,您可以在重定向之前和之后两次调用validateOrder

答案 1 :(得分:1)

您可以尝试这样的事情:

在进行重定向之前,您可以调用一次函数validateOrder并将状态设置为pending。这将为您的模块设置变量$this->currentOrder,其ID为挂单。 重定向后不再调用validateOrder,而是创建自己的函数来调用,例如。 validateOrderAfterRedirect,其中您检查了付款并更改了当前订单的状态。它将是这样的:

// your way of checking that te payment was made
$payment_completed = $this->paymentIsComplete();
if($payment_completed) {
    $order = new Order($this->currentOrder);
    if(Validate::isLoadedObject($order) && $order->getCurrentOrderState() == [id of pending status]) {
        $order->setCurrentState([id of payment accepted status]);
    }
}

答案 2 :(得分:1)

使用"待付款"创建订单网站重定向到支付系统之前的状态。一旦客户退回系统,只需将付款状态更改为"已完成"。如果客户关闭了付款网站,状态将保持"待定"并应在检查支付系统后手动更新。

答案 3 :(得分:1)

许多支付网关提供了一种机制,在完成或未通过付款的情况下,他们会将数据(包括支付金额和购物车ID)发布到您提供给他们的网址上。

在该阶段使用服务器端脚本处理此信息时,您可以验证订单。这应该在用户重定向回您的网站之前发生。一旦将它们重定向到您的网站,它就会在后台确认付款。

这种方法首选的原因在于,这是确保客户无法操纵网址以使您的商店认为他们已为订单付款的唯一方法,实际上没有钱转手,之后您可能会结束免费送货。

答案 4 :(得分:0)

你可以通过添加这样的

来实现
$result = $this->validateOrder((int) $cart->id, Configuration::get('PPQ_CREATED_STATUS'), $total, $this->displayName, NULL, array(), (int) $currency->id, false, $customer->secure_key);

在重定向之前需要的任何播放中(其中$ this是支付模块实例)

重定向确认页面后我用了写了这个

public function hookPaymentReturn($params)
{
    $id_module = (int) Tools::getValue('id_module');
    if ($id_module === (int) $this->id) {
        $orderHistory = new OrderHistory();
        $orderHistory->changeIdOrderState(Configuration::get('PPQ_SUCCESS_STATUS'), $params['objOrder']);
    }
}

对于邮件发送,您可以配置所需的订单状态

对于我的情况(需要只用paypal工作,我有更改写我自己的一页结帐模块并编写我自己的支付模块,然后重定向到paypal我写了这个

public function hookPayment($params)
{
    $customer = &$this->context->customer;
    $cart = &$this->context->cart;
    $currency = &$this->context->currency;
    if (
            $customer->isLogged(true) &&
            $cart->nbProducts()
    ) {
        $total = (float) $cart->getOrderTotal(true, Cart::BOTH);

        $result = $this->validateOrder((int) $cart->id, Configuration::get('PPQ_CREATED_STATUS'), $total, $this->displayName, NULL, array(), (int) $currency->id, false, $customer->secure_key);
        if ($result) {
            if (!Configuration::get('PPQ_TEST_MODE')) {
                $paypal_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=' . Configuration::get('PPQ_PROFILE');
            } else {
                $paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_xclick&business=' . Configuration::get('PPQ_PROFILE');
            }
            $order_confirmation_url = $this->context->link->getPageLink('order-confirmation', null, null, array(
                'id_cart' => (int) $cart->id,
                'id_module' => (int) $this->id,
                'id_order' => (int) $this->currentOrder,
                'key' => $customer->secure_key,
            ));
            $this->context->smarty->assign(array(
                'paypal_url' => $paypal_url,
                'order_confirmation_url' => $order_confirmation_url,
                'order_id' => (int) $this->currentOrder,
                'shop_name' => $this->context->shop->name,
                'total_without_shipping' => Tools::convertPriceFull((float) $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING)),
                'total_shipping' => Tools::convertPriceFull((float) $cart->getOrderTotal(true, Cart::ONLY_SHIPPING)),
                'currency_iso' => Tools::strtoupper($currency->iso_code)
            ));
            return $this->display(__FILE__, 'paypalquick.tpl');
        } else {
            $this->context->controller->errors[] = $this->l('Can\'t create order. Pleas contact with us');
        }
    } else {
        $this->context->controller->errors[] = $this->l('Problem with loginin or cart empty');
    }
}

和tpl

<form id="paypalquick" action="{$paypal_url}" method="post" enctype="multipart/form-data">
<input type="hidden" value="{l s='%s order #%s' sprintf=[$shop_name|escape:'html':'UTF-8', $order_id|intval] mod='paypalquick'}" name="item_name"/>
<input type="hidden" value="{$total_without_shipping}" name="amount"/>
<input type="hidden" value="{$total_shipping}" name="shipping"/>
<input type="hidden" value="{$currency_iso}" name="currency_code"/>
<input type="hidden" value="{$order_confirmation_url}" name="return"/>
<div class="text-center">
    <button class="submit">{l s='Go to PayPal for payment' mod='paypalquick'}</button>
</div>

但这是我的私人信息卡,你可以在默认情况下使用它,但你可以看到如何制作它。

答案 5 :(得分:-1)

我认为我们需要您在网站验证时(在离开此事项之前)调用另一个挂钩(您创建)并挂起状态,并将ValidateOrder hook()保持为已确认付款

此致

亚瑟