📍 Puntos de recogida y click & collect
Actualizado: 2024-12-01
Los puntos de recogida (tienda fisica, lockers, oficinas de correos) son cada vez mas populares. PrestaShop permite implementarlos como transportistas especiales con seleccion de punto en el checkout.
#Click & collect nativo
Configurar recogida en tienda
text
DESDE EL BO
1. Transporte → Transportistas → Añadir
2. Nombre: "Recogida en tienda"
3. Tiempo de transito: "Disponible en 24h"
4. Velocidad: 0 (grado de velocidad)
5. Precio: 0.00 (gratis)
6. Rangos: por precio o peso, ambos a 0
7. Zonas: solo la zona de tu tienda
8. Grupo: todos los grupos de clientes
9. Guardar
LIMITACIONES DEL METODO NATIVO
- No muestra mapa de puntos
- No permite seleccionar punto concreto
- Solo 1 direccion de recogida (la tienda)
- Para multiples puntos → modulo personalizado
#Hook displayCarrierExtraContent
Mostrar selector de punto de recogida
php
<?php
// ── Este hook se muestra debajo del transportista en el checkout ──
public function hookDisplayCarrierExtraContent(array $params): string
{
$carrier = $params['carrier'];
// Solo mostrar para nuestro transportista de puntos de recogida
if ((int) $carrier['id'] !== (int) Configuration::get('MYMODULE_PICKUP_CARRIER_ID')) {
return '';
}
// Obtener direccion del cliente para buscar puntos cercanos
$cart = Context::getContext()->cart;
$address = new Address($cart->id_address_delivery);
// Buscar puntos de recogida cercanos
$points = $this->getPickupPoints($address->postcode, $address->city);
$this->context->smarty->assign([
'pickup_points' => $points,
'selected_point' => $this->getSelectedPoint($cart->id),
'google_maps_key' => Configuration::get('MYMODULE_GMAPS_KEY'),
]);
return $this->fetch('module:mymodule/views/templates/hook/pickup-selector.tpl');
}
// ── Template pickup-selector.tpl ──
// Muestra lista de puntos + mapa interactivo
// Al seleccionar un punto, hace AJAX para guardar la seleccion
#Integrar API de puntos de recogida
Consultar API externa de puntos
php
<?php
// ── Ejemplo generico: API de puntos de recogida ──
private function getPickupPoints(string $postcode, string $city): array
{
$cacheKey = 'pickup_' . md5($postcode . $city);
// Cache 1 hora (los puntos no cambian frecuentemente)
$cached = Cache::retrieve($cacheKey);
if ($cached) {
return json_decode($cached, true);
}
// Llamar a la API del transportista
$response = Tools::file_get_contents(
'https://api.transportista.com/v1/pickup-points?'
. http_build_query([
'postcode' => $postcode,
'city' => $city,
'country' => 'ES',
'limit' => 10,
]),
false,
stream_context_create([
'http' => [
'header' => 'Authorization: Bearer ' . Configuration::get('MYMODULE_API_KEY'),
'timeout' => 5,
]
])
);
$data = json_decode($response, true);
$points = [];
foreach ($data['points'] ?? [] as $p) {
$points[] = [
'id' => $p['id'],
'name' => $p['name'],
'address' => $p['address'],
'postcode' => $p['postcode'],
'city' => $p['city'],
'lat' => $p['latitude'],
'lng' => $p['longitude'],
'hours' => $p['opening_hours'],
'distance' => $p['distance_km'],
];
}
Cache::store($cacheKey, json_encode($points));
return $points;
}
#Guardar punto seleccionado
AJAX para guardar seleccion + usar en pedido
php
<?php
// ── Controller AJAX para guardar punto seleccionado ──
// modules/mymodule/controllers/front/pickupselect.php
class MyModulePickupSelectModuleFrontController extends ModuleFrontController
{
public function initContent(): void
{
if (!$this->isTokenValid()) {
$this->ajaxRender(json_encode(['error' => 'Invalid token']));
return;
}
$pointId = Tools::getValue('point_id');
$pointName = Tools::getValue('point_name');
$pointAddr = Tools::getValue('point_address');
$cartId = (int) Context::getContext()->cart->id;
// Guardar en tabla custom
Db::getInstance()->insert('mymodule_pickup_selection', [
'id_cart' => $cartId,
'point_id' => pSQL($pointId),
'point_name' => pSQL($pointName),
'point_address' => pSQL($pointAddr),
], false, true, Db::ON_DUPLICATE_KEY);
$this->ajaxRender(json_encode(['success' => true]));
}
}
// ── Copiar seleccion al pedido cuando se valida ──
public function hookActionValidateOrder(array $params): void
{
$order = $params['order'];
$cart = $params['cart'];
$pickup = Db::getInstance()->getRow(
'SELECT * FROM `' . _DB_PREFIX_ . 'mymodule_pickup_selection`
WHERE id_cart = ' . (int) $cart->id
);
if ($pickup) {
Db::getInstance()->insert('mymodule_pickup_order', [
'id_order' => (int) $order->id,
'point_id' => pSQL($pickup['point_id']),
'point_name' => pSQL($pickup['point_name']),
'point_address' => pSQL($pickup['point_address']),
]);
}
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.