⚡ Hooks de transportistas y envio
Actualizado: 2024-12-01
Los hooks de transportistas permiten intervenir en el calculo de tarifas, mostrar contenido extra en el checkout y reaccionar a cambios de estado del envio. Son esenciales para modulos de transportista personalizados.
#Hooks principales de carrier
| Hook | Tipo | Cuando se ejecuta |
|---|---|---|
| actionCarrierProcess | action | Al seleccionar transportista en checkout |
| actionCarrierUpdate | action | Al editar un transportista en el BO |
| displayCarrierExtraContent | display | Debajo de cada transportista en checkout |
| displayBeforeCarrier | display | Antes de la lista de transportistas |
| displayAfterCarrier | display | Despues de la lista de transportistas |
| actionValidateOrder | action | Al confirmar el pedido (incluye datos de envio) |
| actionOrderStatusPostUpdate | action | Despues de cambiar el estado del pedido |
| actionObjectOrderCarrierUpdateAfter | action | Al actualizar datos del carrier en un pedido |
#getOrderShippingCost()
Calculo dinamico de coste de envio
php
<?php
// ── Metodo principal de CarrierModule ──
// Se llama automaticamente para calcular el precio de envio
class MyCarrier extends CarrierModule
{
/**
* Calcula el coste de envio para el carrito actual.
*
* @param Cart $cart El carrito del cliente
* @param float $shipping_cost Coste base configurado en rangos
* @return float|false Precio final de envio, o false si no disponible
*/
public function getOrderShippingCost($cart, $shipping_cost)
{
// $shipping_cost ya contiene el precio del rango configurado en el BO
// Puedes modificarlo o reemplazarlo completamente
// ── Ejemplo 1: Tarifa plana ──
return 4.95;
// ── Ejemplo 2: Modificar la tarifa base ──
// Recargo del 10% en temporada alta
$month = (int) date('m');
if ($month === 12 || $month === 1) {
return $shipping_cost * 1.10;
}
return $shipping_cost;
// ── Ejemplo 3: Calculo por API externa ──
$address = new Address($cart->id_address_delivery);
$weight = $cart->getTotalWeight();
$postcode = $address->postcode;
$apiCost = $this->callExternalShippingAPI($weight, $postcode);
if ($apiCost === false) {
return false; // No disponible → no mostrar este transportista
}
return $apiCost;
// ── Ejemplo 4: Envio gratis si carrito > X€ ──
$total = $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING);
if ($total >= 50.00) {
return 0.00; // Gratis
}
return $shipping_cost;
}
/**
* Coste externo (sin rango base del BO).
*/
public function getOrderShippingCostExternal($cart)
{
return $this->getOrderShippingCost($cart, 0);
}
}
#getOrderShippingCostExternal()
Coste de envio sin rangos del BO
php
<?php
// ── Se llama cuando NO hay rangos configurados en el BO ──
// Es decir, el modulo calcula TODO el precio por su cuenta
// (tipico de integraciones con APIs de transportistas)
public function getOrderShippingCostExternal($cart)
{
// Obtener datos necesarios
$address = new Address($cart->id_address_delivery);
$country = new Country($address->id_country);
$weight = $cart->getTotalWeight();
$total = $cart->getOrderTotal(true, Cart::BOTH_WITHOUT_SHIPPING);
// Dimensiones (si las guardas en el producto)
$products = $cart->getProducts();
$maxLength = 0;
foreach ($products as $p) {
$maxLength = max($maxLength, (float) $p['depth']);
}
// Llamar API del transportista
try {
$response = $this->apiClient->getRate([
'origin' => Configuration::get('MY_CARRIER_ORIGIN_ZIP'),
'destination' => $address->postcode,
'country' => $country->iso_code,
'weight' => $weight,
'total_amount' => $total,
]);
if (isset($response['price'])) {
return (float) $response['price'];
}
} catch (\Exception $e) {
PrestaShopLogger::addLog('MyCarrier API error: ' . $e->getMessage(), 3);
}
return false; // No disponible
}
#displayCarrierExtraContent
Mostrar contenido extra en el checkout
php
<?php
// ── Muestra HTML debajo del nombre del transportista en el checkout ──
// Util para: seleccionar punto de recogida, mostrar info extra, etc.
public function hookDisplayCarrierExtraContent(array $params): string
{
$carrier = $params['carrier']; // Datos del transportista
// Solo mostrar para nuestro transportista
if ((int) $carrier['id'] !== (int) $this->getCarrierId()) {
return '';
}
// Ejemplo: selector de punto de recogida
$this->context->smarty->assign([
'pickup_points' => $this->getPickupPoints(
$this->context->cart->id_address_delivery
),
'selected_point' => $this->context->cart->getDeliveryOption(),
]);
return $this->display(__FILE__, 'views/templates/hook/carrier-extra.tpl');
}
// ── Template carrier-extra.tpl ──
// <div class="my-carrier-pickup">
// <p>Selecciona un punto de recogida:</p>
// <select name="my_carrier_pickup_id">
// {foreach $pickup_points as $point}
// <option value="{$point.id}">{$point.name} - {$point.address}</option>
// {/foreach}
// </select>
// </div>
#Hooks de estado de envio
Reaccionar a cambios de estado del pedido
php
<?php
// ── Cuando el pedido cambia a "Enviado" ──
public function hookActionOrderStatusPostUpdate(array $params): void
{
$newStatus = $params['newOrderStatus'];
$orderId = (int) $params['id_order'];
// Estado 4 = Enviado (por defecto)
if ((int) $newStatus->id !== Configuration::get('PS_OS_SHIPPING')) {
return;
}
$order = new Order($orderId);
$carrier = new Carrier($order->id_carrier);
// Si es nuestro transportista, notificar a la API
if ($carrier->external_module_name === $this->name) {
$tracking = $order->getWsShippingNumber();
$this->notifyShipment($order, $tracking);
}
}
// ── Cuando se actualiza el numero de tracking ──
public function hookActionObjectOrderCarrierUpdateAfter(array $params): void
{
$orderCarrier = $params['object'];
$tracking = $orderCarrier->tracking_number;
if (!empty($tracking)) {
// Enviar tracking al cliente, actualizar API externa, etc.
$order = new Order($orderCarrier->id_order);
$this->sendTrackingEmail($order, $tracking);
}
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.