我目前正在为PrestaShop 1.6开发一个欺诈检测模块。在此模块中,我需要在客户按下按钮以确认其订单之后,但无论付款网关如何都在付款之前调用API。
首先,在浏览完1.6中所有可用的钩子之后,我想到了使用actionValidateOrder钩子执行此操作,问题是该钩子是在付款网关提交/处理付款后立即执行的不是我要找的东西。
我还考虑过使用javascript拦截执行,然后调用验证控制器执行,但是对于每个网关来说,它变得太具体了,并且prestashop对象/ ajax / javascript之间的数据流似乎可能变成了有问题。
我知道您可以创建自定义钩子,但是我在互联网上看到的每个示例都是关于显示钩子的,没有一个显示如何创建自定义动作钩子。
这是我在actionValidateOrder挂钩中使用的
public function hookActionValidateOrder($params)
{
include_once(_PS_MODULE_DIR_.'bayonet/sdk/Paymethods.php');
$this->order = $params['order'];
$cart = $this->context->cart;
$address_delivery = new Address((int)$cart->id_address_delivery);
$address_invoice = new Address((int)$cart->id_address_invoice);
$state_delivery = new State((int)$address_delivery->id_state);
$country_delivery = new Country((int)$address_delivery->id_country);
$state_invoice = new State((int)$address_invoice->id_state);
$country_invoice = new Country((int)$address_invoice->id_country);
$customer = $this->context->customer;
$currency = $this->context->currency;
$products = $cart->getProducts();
$product_list = array();
foreach($products as $product)
{
$products_list[] = [
"product_id" => $product['id_product'],
"product_name" => $product['name'],
"product_price" => $product['price'],
"product_category" => $product['category']
];
}
$request = [
'channel' => 'ecommerce',
'consumer_name' => $customer->firstname.' '.$customer->lastname,
"consumer_internal_id" => $customer->id,
"transaction_amount" => $cart->getOrderTotal(),
"currency_code" => $currency->iso_code,
"telephone" => $address_invoice->phone,
"email" => $customer->email,
"payment_gateway" => $this->order->module,
"shipping_address" => [
"line_1" => $address_delivery->address1,
"line_2" => $address_delivery->address2,
"city" => $address_delivery->city,
"state" => $state_delivery->name,
"country" => convert_country_code($country_delivery->iso_code),
"zip_code" => $address_delivery->postcode
],
"billing_address" => [
"line_1" => $address_invoice->address1,
"line_2" => $address_invoice->address2,
"city" => $address_invoice->city,
"state" => $state_invoice->name,
"country" => convert_country_code($country_invoice->iso_code),
"zip_code" => $address_invoice->postcode
],
"products" => $products_list,
"order_id" => (int)$this->order->id
];
foreach ($paymentMethods as $key => $value) {
if ($this->order->module == $key)
{
$request['payment_method'] = $value;
if ($this->order->module == 'paypalmx')
$request['payment_gateway'] = 'paypal';
}
}
if (Configuration::get('BAYONET_API_MODE') == 0)
{
$this->bayonet = new BayonetClient([
'api_key' => Configuration::get('BAYONET_API_TEST_KEY'),
'version' => Configuration::get('BAYONET_API_VERSION')
]);
}
else if (Configuration::get('BAYONET_API_MODE') == 1)
{
$this->bayonet = new BayonetClient([
'api_key' => Configuration::get('BAYONET_API_LIVE_KEY_KEY'),
'version' => Configuration::get('BAYONET_API_VERSION')
]);
}
$this->bayonet->consulting([
'body' => $request,
'on_success' => function($response) {
$this->dataToInsert = array(
'id_cart' => $this->context->cart->id,
'order_no' => $this->order->id,
'status' => $response->decision,
'bayonet_tracking_id' => $response->bayonet_tracking_id,
'consulting_api' => 1,
'consulting_api_response' => json_encode(array(
'reason_code' => $response->reason_code,
'tracking_id' => $response->bayonet_tracking_id
)),
'is_executed' => 1,
);
Db::getInstance()->insert('bayonet', $this->dataToInsert);
if ($response->decision == 'decline')
{
$this->module = Module::getInstanceByName('bayonet');
Tools::redirect($this->context->link->getModuleLink($this->module->name,'rejected', array()));
}
},
'on_failure' => function($response) {
$this->dataToInsert = array(
'id_cart' => $this->context->cart->id,
'order_no' => $this->order->id,
'status' => $response->decision,
'bayonet_tracking_id' => $response->bayonet_tracking_id,
'consulting_api' => 0,
'consulting_api_response' => json_encode(array(
'reason_code' => $response->reason_code,
)),
'is_executed' => 1,
);
Db::getInstance()->insert('bayonet', $this->dataToInsert);
}
]);
}
在检测到钩子问题之后,这就是我尝试使用JavaScript进行的尝试,JavaScript使用ajax调用了验证页面,该页面的代码与钩子中的代码几乎相同
$('#form-pagar-mp').submit(function(event) {
if (lock == 1) {
params = {};
$.ajax({
url: url,
type: 'post',
data: params,
dataType: 'json',
processData: false,
success: function(data) {
if (data.error == 0) {
lock = 0;
}
else {
window.location.href = data.url;
}
}
});
}
});
我仍然认为使用挂钩是最好的选择,但是在所有可用的挂钩中,没有一个可以满足我的需求。现在,我真的不知道可以尝试什么,这就是为什么我需要您的帮助来解决这种情况,任何想法都将受到欢迎,我们将不胜感激。谢谢。
答案 0 :(得分:0)
您可以使用在创建订单付款之前执行的挂钩
public function hookActionObjectOrderPaymentAddBefore($params)
{
/** OrderPayment $orderPayment */
$orderPayment = $params['object'];
$cart = $this->context->cart;
// to stop order payment creation you need to redirect from this hook
}
或者在创建订单之前
public function hookActionObjectOrderAddBefore($params)
{
/** Order $order */
$order = $params['object'];
$cart = $this->context->cart;
// to stop order creation you need to redirect from this hook
}