• Сообщество
  • Блог
Документация
Плагины и интеграцииВсе расширения для Medusa от сообществаСтартерыЗапускайте проекты быстрее с готовыми решениями
ЭкспертыПодберите специалиста для разработки и развития вашего проекта на MedusaКейсыПосмотрите примеры Medusa в продакшене и успешные внедрения
Меч Moscow
Комплексная e-commerce платформа на Medusa для московского fashion-бренда

Меч Moscow · Fashion

Gorgo снижает затраты на адаптацию Medusa к локальным рынкам.

Мы разрабатываем плагины интеграции, осуществляем поддержку и развиваем сообщество разработчиков на Medusa в Telegram.

  • Ресурсы Medusa
  • Плагины и интеграции
  • Стартеры
  • Эксперты
  • Кейсы
  • Medusa Чат в Telegram
  • Medusa Новости в Telegram
  • Документация Gorgo
  • Связаться с нами
  • TelegramGitHub
Плагины
B

Boxtal v2

Medusa.js v2 plugin for Boxtal: relay point search, shipping orders, labels, tracking, and fulfillment provider (Mondial Relay / Chronopost via Boxtal API v3).

npm install medusa-plugin-boxtal-v2
Категория
Доставка
Создано
Monptitdev-fr
Версия
0.1.0
Последнее обновление
4 дня назад
Ежемесячные загрузки
Загрузка данных
Звезды на Github
0
npmNPM

medusa-plugin-boxtal-v2

Plugin Medusa.js v2 pour Boxtal API v3 :

  • Provider de fulfillment (Mondial Relay point relais + Chronopost domicile)
  • Recherche / détail de points relais (Store API)
  • Création d’expédition, étiquettes PDF, tracking
  • Webhooks HMAC (, )
  • Calcul poids / dimensions / valeur déclarée depuis les produits

Compatible Medusa ≥ 2.12.


Table des matières

  1. Installation
  2. Configuration backend
  3. Variables d’environnement
  4. Créer les shipping options
  5. Webhooks
  6. API référence
  7. Intégration storefront
  8. Admin — sync étiquette
  9. Comportement à la commande
  10. Troubleshooting

1. Installation

1npm install medusa-plugin-boxtal-v2
2# ou
3yarn add medusa-plugin-boxtal-v2

Développement local (yalc)

1# dans medusa-plugin-boxtal-v2
2npm run build
3npx medusa plugin:publish
4
5# dans votre app Medusa
6npx medusa plugin:add medusa-plugin-boxtal-v2

Ou dépendance fichier :

1{
2 "dependencies": {
3 "medusa-plugin-boxtal-v2": "file:../medusa-plugin-boxtal-v2"
4 }
5}

2. Configuration backend

Deux enregistrements sont obligatoires dans :

  1. — charge les routes API, middlewares webhook, subscribers
  2. — enregistre le provider
1import { defineConfig, loadEnv } from "@medusajs/framework/utils"
2
3loadEnv(process.env.NODE_ENV || "development", process.cwd())
4
5module.exports = defineConfig({
6 plugins: [
7 {
8 resolve: "medusa-plugin-boxtal-v2",
9 options: {},
10 },
11 ],
12 modules: [
13 {
14 resolve: "@medusajs/medusa/fulfillment",
15 options: {
16 providers: [
17 {
18 resolve: "@medusajs/medusa/fulfillment-manual",
19 id: "manual",
20 },
21 {
22 resolve: "medusa-plugin-boxtal-v2/providers/boxtal",
23 id: "boxtal",
24 options: {
25 accessKey: process.env.BOXTAL_ACCESS_KEY,
26 secretKey: process.env.BOXTAL_SECRET_KEY,
27 environment: process.env.BOXTAL_ENVIRONMENT || "sandbox",
28 apiBaseUrl: process.env.BOXTAL_API_BASE_URL,
29 relayOfferCode: process.env.BOXTAL_RELAY_OFFER_CODE,
30 homeOfferCode: process.env.BOXTAL_HOME_OFFER_CODE,
31 relayName: process.env.BOXTAL_RELAY_NAME,
32 relayTypeLabel: process.env.BOXTAL_RELAY_TYPE_LABEL,
33 relayDescription: process.env.BOXTAL_RELAY_DESCRIPTION,
34 homeName: process.env.BOXTAL_HOME_NAME,
35 homeTypeLabel: process.env.BOXTAL_HOME_TYPE_LABEL,
36 homeDescription: process.env.BOXTAL_HOME_DESCRIPTION,
37 labelType: process.env.BOXTAL_LABEL_TYPE || "PDF_A4",
38 contentCategoryId: process.env.BOXTAL_CONTENT_CATEGORY_ID,
39 contentDescription: process.env.BOXTAL_CONTENT_DESCRIPTION,
40 sender: {
41 firstName: process.env.BUSINESS_FIRSTNAME,
42 lastName: process.env.BUSINESS_LASTNAME,
43 street: process.env.BUSINESS_STREET,
44 houseNo: process.env.BUSINESS_HOUSE_NO,
45 countryCode: process.env.BUSINESS_COUNTRY_CODE || "FR",
46 postcode: process.env.BUSINESS_POSTCODE,
47 city: process.env.BUSINESS_CITY,
48 phone: process.env.BUSINESS_PHONE,
49 email: process.env.BUSINESS_EMAIL,
50 company: process.env.BUSINESS_COMPANY,
51 },
52 },
53 },
54 ],
55 },
56 },
57 ],
58})

ID runtime du provider

Medusa compose → .

Utilisez cet ID pour détecter les options shipping côté storefront :

option.provider_id?.includes("boxtal")

3. Variables d’environnement

Copiez dans le de votre backend Medusa :

1# --- Boxtal API ---
2BOXTAL_ACCESS_KEY=
3BOXTAL_SECRET_KEY=
4BOXTAL_ENVIRONMENT=sandbox
5# Production : https://api.boxtal.com | Sandbox : https://api.boxtal.build
6BOXTAL_API_BASE_URL=https://api.boxtal.build
7
8# Offres (codes fournis par Boxtal)
9BOXTAL_RELAY_OFFER_CODE=MONR-CpourToi
10BOXTAL_HOME_OFFER_CODE=CHRP-Chrono18
11
12# Libellés checkout (optionnel)
13BOXTAL_RELAY_NAME=Mondial Relay - Livraison en point Relais
14BOXTAL_RELAY_TYPE_LABEL=Point Relais
15BOXTAL_RELAY_DESCRIPTION=Livraison en point relais — 3 à 5 jours ouvrés
16BOXTAL_HOME_NAME=Chronopost - Livraison à domicile
17BOXTAL_HOME_TYPE_LABEL=Domicile
18BOXTAL_HOME_DESCRIPTION=Livraison à domicile — 1 jour ouvré
19
20# Tarifs flat (euros) utilisés par le script setup
21BOXTAL_RELAY_PRICE=5.9
22BOXTAL_HOME_PRICE=7.9
23
24# Étiquette & contenu colis
25BOXTAL_LABEL_TYPE=PDF_A4
26BOXTAL_CONTENT_CATEGORY_ID=content:v1:80500
27BOXTAL_CONTENT_DESCRIPTION=Articles de décoration artisanale
28
29# Valeur déclarée : items (marchandises) | order_total (total payé)
30BOXTAL_DECLARED_VALUE_MODE=items
31
32# Fallback dimensions si produit sans L/W/H (cm)
33BOXTAL_DEFAULT_PACKAGE_LENGTH_CM=30
34BOXTAL_DEFAULT_PACKAGE_WIDTH_CM=20
35BOXTAL_DEFAULT_PACKAGE_HEIGHT_CM=10
36
37# Webhooks
38BOXTAL_WEBHOOK_SECRET=
39BOXTAL_WEBHOOK_CALLBACK_URL=https://votre-domaine.com/hooks/boxtal
40
41# Expéditeur (obligatoire pour créer une shipping-order)
42BUSINESS_FIRSTNAME=
43BUSINESS_LASTNAME=
44BUSINESS_COMPANY=
45BUSINESS_STREET=
46BUSINESS_HOUSE_NO=
47BUSINESS_POSTCODE=
48BUSINESS_CITY=
49BUSINESS_COUNTRY_CODE=FR
50BUSINESS_PHONE=
51BUSINESS_EMAIL=
52
53# Requis pour le calcul poids/dims à l’expédition
54DATABASE_URL=

4. Créer les shipping options

Après configuration, créez les 2 options (relais + domicile) liées au provider :

1# Depuis le code source du plugin (recommandé en monorepo)
2cd medusa-plugin-boxtal-v2
3# Pointer DATABASE_URL vers la DB de l’app, puis :
4npx medusa exec ./src/scripts/setup-boxtal-shipping.ts

Ou copiez dans votre app et exécutez-le avec .

Le script crée :

Code typeUsage
Point relais (sélection obligatoire)
Livraison à domicile

Assurez-vous que vos produits ont un shipping profile relié à la même zone France que le script.


5. Webhooks

  1. Exposez publiquement (tunnel Cloudflare / ngrok en local).
  2. Définissez et .
  3. Enregistrez les subscriptions :
1npx medusa exec ./src/scripts/setup-boxtal-webhook.ts
2npx medusa exec ./src/scripts/list-boxtal-webhooks.ts

Événements gérés : (étiquette), (suivi).

Le middleware du plugin active sur pour la vérif HMAC ().


6. API référence

Toutes les routes Store nécessitent le header .

Recherche de points relais.

Query params :

ParamTypeDescription
stringCode postal (recommandé)
stringVille
/ numberOrigine GPS (tri proximité)
stringOptionnel — poids du panier pour filtrer

Réponse 200 :

1{
2 "relayPoints": [
3 {
4 "id": "71039",
5 "code": "71039",
6 "name": "TABAC DE LA GARE",
7 "address": "12 rue Example",
8 "city": "Paris",
9 "zipCode": "75001",
10 "country": "FR",
11 "latitude": 48.86,
12 "longitude": 2.34,
13 "network": "MONR",
14 "distance": 0.4,
15 "schedule": ["Lundi - Vendredi : 09:00 – 19:00"],
16 "scheduleDetailed": ["Lundi : 09:00 – 12:00, 14:00 – 19:00", "..."]
17 }
18 ],
19 "meta": {
20 "totalFound": 12,
21 "parcelWeight": 0.5,
22 "sortedByProximity": true,
23 "searchOrigin": { "latitude": 48.86, "longitude": 2.34, "label": "75001 Paris" }
24 }
25}

Détail d’un point ( = code parcel point).

Mêmes query optionnels : , , .

Réponse 200 :

Webhook Boxtal (pas de publishable key). Body JSON + signature HMAC.

Auth admin requise. Force la récupération étiquette / tracking depuis Boxtal.

Réponse :

1{
2 "order_id": "order_01...",
3 "synced": true,
4 "results": [{ "fulfillment_id": "ful_...", "synced": true, "label_url": "...", "tracking_number": "..." }]
5}

7. Intégration storefront

7.1 Détecter les options Boxtal

Après :

1function isBoxtalProvider(providerId?: string | null) {
2 return !!providerId?.includes("boxtal")
3}
4
5function isBoxtalRelayOption(option: {
6 provider_id?: string | null
7 type?: { code?: string | null }
8 data?: { deliveryType?: string }
9}) {
10 if (!isBoxtalProvider(option.provider_id)) return false
11 return (
12 option.type?.code === "boxtal-relay" ||
13 option.data?.deliveryType === "relay"
14 )
15}
16
17function isBoxtalHomeOption(option: {
18 provider_id?: string | null
19 type?: { code?: string | null }
20 data?: { deliveryType?: string }
21}) {
22 if (!isBoxtalProvider(option.provider_id)) return false
23 return (
24 option.type?.code === "boxtal-home" ||
25 option.data?.deliveryType === "home"
26 )
27}

7.2 Client HTTP (exemple)

1const BACKEND = process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL!
2const PUBLISHABLE_KEY = process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY!
3
4async function searchRelayPoints(params: {
5 zipCode?: string
6 city?: string
7 latitude?: number
8 longitude?: number
9 cartId?: string
10}) {
11 const q = new URLSearchParams()
12 if (params.cartId) q.set("cart_id", params.cartId)
13 if (params.zipCode) q.set("zipCode", params.zipCode)
14 if (params.city) q.set("city", params.city)
15 if (params.latitude != null) q.set("latitude", String(params.latitude))
16 if (params.longitude != null) q.set("longitude", String(params.longitude))
17
18 const res = await fetch(`${BACKEND}/store/boxtal/relay-points?${q}`, {
19 headers: {
20 "Content-Type": "application/json",
21 "x-publishable-api-key": PUBLISHABLE_KEY,
22 },
23 cache: "no-store",
24 })
25 const data = await res.json()
26 if (!res.ok) throw new Error(data.message || "Erreur points relais")
27 return data as { relayPoints: RelayPoint[]; meta?: unknown }
28}

Next.js : vous pouvez proxifier via côté app pour éviter d’exposer l’URL backend, ou appeler Medusa directement depuis le serveur.

7.3 Metadata panier (obligatoire)

Avant de finaliser le checkout, stockez le choix dans cart.metadata et dans shipping method data.

Point relais :

1const metadata = {
2 carrier: "boxtal",
3 deliveryType: "relay",
4 parcelPointCode: point.code, // code Boxtal (obligatoire)
5 relayPointId: point.code,
6 relayPointName: point.name,
7 relayPointAddress: `${point.address}, ${point.zipCode} ${point.city}`,
8 relayPointNetwork: point.network,
9}

Domicile :

1const metadata = {
2 carrier: "boxtal",
3 deliveryType: "home",
4}

7.4 Attacher la shipping method

1// 1) Mettre à jour le panier
2await sdk.store.cart.update(cartId, { metadata: { ...cart.metadata, ...metadata } })
3
4// 2) Sélectionner l’option + data pour validateFulfillmentData
5await sdk.store.cart.addShippingMethod(cartId, {
6 option_id: shippingOptionId, // id Medusa de l’option boxtal-relay ou boxtal-home
7 data: {
8 carrier: "boxtal",
9 deliveryType: metadata.deliveryType, // "relay" | "home"
10 parcelPointCode: metadata.parcelPointCode,
11 relayPointId: metadata.relayPointId,
12 relayPointName: metadata.relayPointName,
13 relayPointAddress: metadata.relayPointAddress,
14 },
15})

Le provider valide que / est présent pour .

7.5 Flux checkout recommandé

11. Charger shipping options du cart
22. Afficher options Boxtal (relais / domicile)
33. Si relais :
4 a. Demander code postal (ou utiliser shipping_address)
5 b. GET /store/boxtal/relay-points
6 c. L’utilisateur choisit un point
7 d. setBoxtalShipping (metadata + shipping method data)
84. Si domicile :
9 a. setBoxtalShipping avec deliveryType "home"
105. Continuer paiement → complete cart

7.6 Afficher le point relais après commande

Lire ou :

CléDescription
|
Nom du point
Adresse formatée
/ Code Boxtal

Le subscriber copie ces champs du panier vers la commande.

7.7 Types TypeScript utiles

1export type BoxtalRelayPoint = {
2 id: string
3 code: string
4 name: string
5 address: string
6 city: string
7 zipCode: string
8 country: string
9 latitude?: number
10 longitude?: number
11 network?: string
12 distance?: number
13 schedule?: string[] | null
14 scheduleDetailed?: string[] | null
15}

8. Admin — sync étiquette

Après fulfillment, l’étiquette peut arriver avec quelques secondes de délai.

1POST /admin/orders/{order_id}/boxtal-shipping/sync
2Authorization: Bearer <admin_token>

Ou script :

npx medusa exec ./src/scripts/sync-boxtal-label.ts order_01...

Données stockées sur le fulfillment () :


9. Comportement à la commande

MomentAction
Copie metadata Boxtal cart → order
Copie poids/dims variante→produit vers metadata lignes
Création fulfillmentAppel Boxtal avec colis calculé
Webhook / syncMet à jour label + tracking

Poids : variante → metadata → produit parent (grammes). Min. 0,1 kg.
Dimensions : variante → metadata → produit → défauts env (cm).
Valeur déclarée : somme des lignes (euros) par défaut.

Renseignez / / / (ou sur chaque variante) dans l’admin.


10. Troubleshooting

SymptômeCause probableFix
Options shipping absentesSetup non exécuté / mauvais provider_idRelancer
Erreur « point relais manquant » non passéVérifier data
Colis 0,1 kgPoids produit / variante videRemplir poids (g) en admin
Valeur déclarée 1 €Ancien bug centimes — versions ≥ 0.1.0 corrigéesUtiliser
Pas d’étiquetteWebhook local / délai Boxtal
401 sur Store APIPublishable key manquanteHeader

Scripts de test (repo plugin)

1npx medusa exec ./src/scripts/test-boxtal-connection.ts
2npx medusa exec ./src/scripts/test-boxtal-package-payload.ts order_xxx
3npx medusa exec ./src/scripts/test-boxtal-live-shipment.ts order_xxx

Licence

MIT

Еще в этой категории

Посмотреть все
Доставка
DHL eCommerce logo

DHL eCommerce

От Mitchellston

Выполняйте заказы с помощью DHL eCommerce

Загрузка данных
GitHubnpm
Доставка
Mondial Relay logo

Mondial Relay

От Theodaguier

Доставляйте заказы с Mondial Relay

Загрузка данных
npm
Доставка
ApiShip logo

ApiShip

От Gorgo

Подключите доставку несколькими перевозчиками

Загрузка данных
GitHubnpm