Files
2026-06-17 16:15:22 +02:00

6.5 KiB
Raw Permalink Blame History

Packeta (Zásilkovna) integration

Packeta delivers mainly to pickup points and Z-BOX lockers (plus home delivery in some regions). It's the most common choice for SK/CZ eshops. This repo is already scaffolded for Packeta's pickup-point picker — you mostly need an API key to switch it on. Shipment creation via API is extra, optional work.


1. Get a Packeta account & keys

  1. Register a client account at https://client.packeta.com (Zásilkovna / Packeta). For SK: https://www.packeta.sk.
  2. In the client portal open Client support → API / Nastavenia API (or "Integrations"). You get two different secrets — don't mix them up:
    • Web/Widget API key — public-ish key used by the browser pickup-point widget (Packeta.Widget.pick). This is the one this repo already uses.
    • API password (REST/SOAP) — secret server key used to create packets (shipments). Never expose this to the browser.
  3. (For real shipping) configure your sender/pickup address and label format in the portal.

2. Activate the pickup-point picker (already built)

The checkout template already loads the widget and wires the chosen point into the order whenever packeta_api_key is non-empty (assets/views/shop/checkout.html):

  • loads https://widget.packeta.com/v6/www/js/library.js
  • Packeta.Widget.pick(packetaKey, point => …) fills hidden pickup_point_id + pickup_point_name
  • if the key is empty it falls back to a plain text field

So to turn it on:

a) Set the Web/Widget API key

Set the env var (read by config/development.yaml / production.yamlsettings.packeta_api_key, exposed via src/shared/settings.rs):

# .env (development) or your production environment
PACKETA_API_KEY=your_web_widget_api_key

config/development.yaml already contains:

settings:
  packeta_api_key: {{ get_env(name="PACKETA_API_KEY", default="") }}

For production, add the same line under settings: in config/production.yaml (it isn't there yet).

b) Create a Packeta delivery option in the admin

Go to /admin/shipping → "Add delivery option":

  • Name: e.g. Packeta pickup point
  • Price: your fee (e.g. 2.90)
  • Requires pickup point ← this makes the picker appear at checkout
  • Active

The auto-generated code will be packeta-pickup-point (or similar). Customers now see the option, click "Choose pickup point", pick on the map, and the order stores pickup_point_id + pickup_point_name.

At this point you have a working Packeta flow — you read the pickup point on the order in /admin/orders and create the parcel manually in the Packeta portal. Many small shops stop here.


3. (Optional) Create shipments via API

Automate "register the parcel + get tracking + print label". Do the shared groundwork first (HTTP client, integrations module, carrier column, tracking columns).

Endpoint & auth

  • Packeta REST API base: https://www.zasilkovna.cz/api/rest (SOAP also available at http://www.zasilkovna.cz/api/soap.wsdl).
  • Auth = your API password (the server secret from step 1), sent in the request body, not the widget key.
  • Key operation: createPacket. You send sender id, recipient name/email/phone, the chosen pickup point id (addressId), value, weight, and COD amount; you receive a packet id + barcode (tracking). A separate packetLabelPdf call returns the label PDF.

Store the secret

PACKETA_API_PASSWORD=your_secret_api_password

Add to config/*.yaml under settings::

  packeta_api_password: {{ get_env(name="PACKETA_API_PASSWORD", default="") }}

Client sketch (src/integrations/packeta.rs)

use loco_rs::prelude::*;
use crate::shared::settings;

// createPacket accepts XML; serde_json works for the JSON REST variant.
pub async fn create_shipment(ctx: &AppContext, req: super::ShipmentRequest<'_>)
    -> Result<super::ShipmentResult>
{
    let api_password = settings::get(ctx, "packeta_api_password")
        .ok_or_else(|| Error::string("packeta_api_password not configured"))?;

    // Packeta's createPacket is XML/SOAP-ish; build the body per their docs.
    // number       = your order_number
    // name/surname = recipient
    // addressId    = req.pickup_point_id  (the chosen point)
    // cod          = req.cod_cents / 100   (0 if not COD)
    // value        = goods value
    // eshop        = your sender label/id from the portal
    let body = format!(r#"<createPacket>
      <apiPassword>{api_password}</apiPassword>
      <packetAttributes>
        <number>{}</number>
        <name>{}</name>
        <email>{}</email>
        <addressId>{}</addressId>
        <cod>{}</cod>
        <value>{}</value>
        <weight>{}</weight>
        <eshop>YOUR_SENDER_LABEL</eshop>
      </packetAttributes>
    </createPacket>"#,
        req.order_number, req.recipient_name, req.email,
        req.pickup_point_id.unwrap_or(""),
        req.cod_cents as f64 / 100.0,
        req.cod_cents as f64 / 100.0,
        req.weight_grams);

    let resp = reqwest::Client::new()
        .post("https://www.zasilkovna.cz/api/rest")
        .body(body)
        .send().await.map_err(|e| Error::string(&e.to_string()))?
        .text().await.map_err(|e| Error::string(&e.to_string()))?;

    // Parse <id> (packet id) and <barcode> (tracking) out of the XML response.
    // Then optionally call packetLabelPdf with that id to fetch the label.
    todo!("parse resp into ShipmentResult")
}

Then call it from your admin "Create shipment" action for orders whose shipping_methods.carrier == "packeta", and save tracking_number / shipment_id back on the order.


4. Testing

  • Use the Packeta sandbox/staging portal if your account offers one, or a test API password. Verify createPacket returns a packet id before going live.
  • Track the parcel at https://tracking.packeta.com/... using the returned barcode.

5. Go-live checklist

  • PACKETA_API_KEY (widget) set in production env
  • packeta_api_key line added under settings: in config/production.yaml
  • Packeta delivery option created in /admin/shipping with Requires pickup point
  • (If using API) PACKETA_API_PASSWORD set + src/integrations/packeta.rs implemented
  • Sender address & label format configured in the Packeta portal
  • Test order → pickup point saved on order → (API) tracking number stored