# Créer des produits, à l'unité et en lot

Créer un produit depuis la console, créer une série entière, importer un fichier, et lire les refus avant qu'ils ne coûtent une production.

Source : https://docs.sealtrust.io/creer-des-produits/

---

En quittant cette page, vous saurez créer un produit seul, créer une série
complète à partir d'un modèle, importer un fichier de plusieurs centaines de
lignes, et lire chaque refus affiché par la console. Vous saurez aussi ce qui
devient définitif au moment de la création.

## Trois objets, trois rôles

- Un **modèle produit** décrit un article de votre catalogue : son nom, sa
  référence interne, sa catégorie, sa photo de couverture.
- Un **lot de production** regroupe les exemplaires fabriqués ensemble, sous un
  code de lot et une date.
- Un **produit** est l'exemplaire. C'est lui qui porte un code imprimé ou une
  puce, et c'est lui qui se vérifie.

Cette page parle de la création des produits. Le modèle et le lot restent
facultatifs pour y arriver. Ils changent ce que verra la personne qui scanne.

> [!INFO] Un passeport ne vous oblige pas à sérialiser
> Le règlement ESPR autorise trois niveaux pour un passeport numérique de
> produit : le modèle, le lot et l'exemplaire (considérant 33). Créer un
> exemplaire par article vendu n'est donc pas une obligation générale. Un
> passeport de modèle couvre tous les exemplaires qui partagent le même code
> produit. Seules certaines batteries sont concernées à l'exemplaire (règlement
> 2023/1542).

## Ce qu'il faut préparer

### La marque et son numéro

Chaque produit appartient à une marque. Le sélecteur de marque de la console
affiche le nom suivi de son numéro, sous la forme `Exemple SAS (#12)`. Quand
votre compte ne donne accès qu'à une seule marque, le sélecteur est verrouillé
sur elle. Notez ce numéro : les imports par fichier le réclament dans la
colonne `brand_id`.

### La catégorie

Elle est obligatoire pour chaque produit, et vous la choisissez dans la liste
que la console propose. Elle alimente l'attribut « Category » des métadonnées
du jeton.

### Le modèle produit

Facultatif, et c'est lui qui décide de l'image. Sans modèle lié, le jeton ne
portera aucune image de couverture. Avec un modèle dépourvu d'image, non plus.
L'image retenue est l'image de couverture du modèle ; à défaut, le premier
média de type image rattaché à ce modèle.

Les modèles se créent dans **Catalogue > Modèles produit**. La liste affiche une
colonne ID : c'est ce numéro que les imports attendent dans `product_model_id`.

### Le lot de production

Facultatif pour créer un produit. Il se crée dans **Catalogue > Lots de
production**. La référence de lot, la marque et le modèle produit sont
obligatoires. La quantité, le site de fabrication, le pays d'origine et les
notes sont facultatifs. Le formulaire a deux étapes, et la première ne se
valide pas sans ces trois valeurs. La liste des lots affiche également une
colonne ID, à reporter dans `product_batch_id`.

### Ce que votre offre autorise

Deux contrôles s'exécutent, et le moment change selon la **méthode
d'authentification**, c'est-à-dire ce que l'exemplaire portera physiquement, un
code imprimé, une puce, ou les deux. C'est le libellé employé par la console
dans ses formulaires, et vos fichiers d'import le nomment `auth_method`.

- **La méthode d'authentification autorisée par votre offre.** Une marque dont
  l'offre n'inclut pas le NFC reçoit un refus 403 portant le code
  `AUTH_METHOD_NOT_ALLOWED`, avec la liste des méthodes autorisées.
- **Le quota de produits.** Il se compte par mois, sur la période de
  facturation. Un dépassement renvoie un refus 403 portant le code
  `QUOTA_EXCEEDED`, avec le nombre déjà créé, le maximum et la période.

Pour un exemplaire en `qr`, le serveur vérifie les deux au moment de la
création. Pour un exemplaire à puce, il vérifie les deux plus tard, au moment
où la puce est encodée et le jeton frappé. Préparer 500 exemplaires NFC peut
donc réussir, et le refus `AUTH_METHOD_NOT_ALLOWED` ou `QUOTA_EXCEEDED`
n'apparaître qu'à l'encodage.

## Choisir la méthode d'authentification

Un produit porte une seule des trois valeurs suivantes.

| Valeur | Ce que porte l'exemplaire | Ce qui se passe à la création |
| --- | --- | --- |
| `qr` | un code imprimé | depuis l'onglet « Produit unique » et depuis l'import CSV, l'exemplaire part en frappe tout de suite ; depuis une série créée à partir d'un modèle, rien n'est frappé et vous frappez le lot ensuite |
| `nfc` | une puce | rien n'est frappé, l'exemplaire attend l'encodage de sa puce |
| `nfc+qr` | une puce et un code imprimé | rien n'est frappé, l'exemplaire attend l'encodage de sa puce |

> [!INFO] Le QR seul est un mode complet
> Un produit en `qr` se vérifie, porte un certificat et porte son passeport,
> exactement comme un produit à puce. Choisissez `nfc` ou `nfc+qr` quand vous
> voulez en plus la lecture d'une puce sur le produit physique.

> [!DANGER] La méthode d'authentification devient définitive
> La méthode choisie est écrite dans les métadonnées du jeton, sous l'attribut
> « Authentication ». L'empreinte de ces métadonnées est inscrite sur la chaîne
> au moment de la frappe, et le contrat n'expose aucune fonction pour la
> remplacer. Un exemplaire créé en `nfc` alors qu'il ne porte qu'un code
> imprimé gardera cette mention pour toujours.

## Créer un produit à l'unité

Ouvrez **Catalogue > Créer un produit**, onglet « Produit unique ».

| Champ | Obligatoire | Ce qu'il fait |
| --- | --- | --- |
| Nom du produit | oui | devient le champ `name` des métadonnées |
| Marque | oui | rattache l'exemplaire et alimente l'attribut « Brand » |
| Catégorie | oui | alimente l'attribut « Category » |
| Modèle produit | non | fournit l'image de couverture |
| Authentification | oui | `nfc`, `qr` ou `nfc+qr`, valeur par défaut `nfc` |

Le bouton de création reste inactif tant que le nom, la marque et la catégorie
ne sont pas renseignés.

### Prévisualisez avant de créer

Le bouton « Prévisualiser ce qui sera écrit en chaîne » affiche les métadonnées
exactes que portera le jeton et l'image de couverture. L'adresse du contrat
figure dans les métadonnées affichées, sous l'attribut « Contract ». La console
n'envoie rien et ne frappe rien pendant cet aperçu.

Quatre avertissements peuvent apparaître. Le serveur les écrit en anglais et la
console les affiche tels quels.

- « No product model linked », aucun modèle lié, le jeton ne portera aucune
  image de couverture ;
- « The linked model has no image », le modèle lié n'a pas d'image, même
  conséquence ;
- « No category », aucune catégorie, l'attribut « Category » resterait vide ;
- « No active contract in the registry », aucun contrat actif dans le registre,
  la frappe échouerait.

Votre navigateur charge l'image, donc une adresse morte apparaît comme une
image cassée. C'est le dernier moment où vous voyez encore une erreur d'image.

### Ce qui se passe ensuite

Pour un produit en `qr`, la frappe est mise en file et la console affiche
« Mint en cours sur la blockchain ». Le code est ensuite téléchargeable en
image PNG depuis **Catalogue > Produits**, colonne QR.

Pour un produit en `nfc` ou `nfc+qr`, la console crée un lot dont les articles
sont en attente d'encodage, avec le statut `ready_to_scan`. Aucun jeton
n'existe encore à ce stade. Selon le profil de votre compte, la console affiche
en plus un lien vers l'écran d'encodage, ou masque ce lien.

> [!ATTENTION] Les contrôles d'un produit à puce se font plus tard
> Pour un produit en `qr`, le serveur contrôle la méthode d'authentification
> autorisée et le quota mensuel de votre offre au moment de la création. Pour un
> produit à puce, il contrôle les deux au moment où la puce est encodée et le
> jeton frappé.
> Préparer 500 exemplaires NFC peut donc réussir, et le refus
> `AUTH_METHOD_NOT_ALLOWED` ou `QUOTA_EXCEEDED` n'apparaître qu'à l'encodage.

> [!INFO] Encodage physique réalisé par SealTrust
> Selon le profil de votre compte, la console masque les boutons qui déclenchent
> l'encodage physique et la frappe d'un lot, parce que SealTrust réalise
> l'encodage. Ces boutons masqués comprennent « Minter un lot depuis ce modèle »
> sur la fiche d'un modèle, ainsi que « Frapper le lot (groupé) » et « Préparer
> les QR à imprimer » sur la page d'un lot. La création en série depuis un
> modèle fait donc partie des actions masquées, y compris pour une série en
> `qr`. **Catalogue > Créer un produit** reste disponible, avec ses trois
> onglets, et vous suivez l'avancement dans le catalogue.

## Créer plusieurs produits d'un coup

L'onglet « Lot (plusieurs produits) » affiche un tableau. Chaque ligne est un
exemplaire, avec son nom, sa marque, sa catégorie, son modèle et sa méthode
d'authentification. « Ajouter une ligne » en ajoute une, l'icône de corbeille en
retire une.

Le bouton « Créer le lot » reste inactif tant qu'une ligne n'a pas son nom, sa
marque et sa catégorie.

Cet onglet envoie toutes les lignes au même endroit. Si une seule ligne porte
du NFC, la totalité du tableau part en file d'encodage, y compris les lignes en
`qr`, et la console ne frappe rien. Pour mélanger des méthodes
d'authentification dans un même envoi, passez par l'onglet « Depuis CSV », qui
sépare les lignes.

Votre saisie est conservée dans le navigateur. Si votre session expire pendant
la préparation, l'onglet actif et les lignes en cours sont restaurés après la
reconnexion.

## Créer une série depuis un modèle

Ce chemin crée le lot de production, les exemplaires, leurs noms et leurs
références en une fois.

Selon le profil de votre compte, le bouton décrit ci-dessous n'apparaît pas, y
compris pour une série en `qr`. Créez alors vos exemplaires depuis
**Catalogue > Créer un produit**, qui reste disponible.

Ouvrez **Catalogue > Modèles produit**, ouvrez le modèle, puis « Minter un lot
depuis ce modèle ». Le bouton reste inactif tant que le modèle n'a pas de
catégorie.

| Champ | Obligatoire | Détail |
| --- | --- | --- |
| Quantité | oui | de 1 à 10 000 |
| Date de production | non | le jour même par défaut |
| Code de lot | oui | pré-rempli sous la forme `SKU-AAAAMMJJ-HHMM` |
| Site de fabrication | non | texte libre |
| Méthode d'authentification | oui | `nfc`, `qr` ou `nfc+qr` |
| Lot scellé | non | proposé uniquement quand la méthode d'authentification inclut le NFC |

La console crée le lot de production, puis les exemplaires demandés. Chaque
exemplaire prend le nom du modèle suivi de son rang sur trois chiffres, par
exemple `Sac Exemple #001`, et une référence externe formée du code de lot
suivi du même rang, par exemple `SAC-20260820-1030-001`.

Sur ce chemin, la création d'une série depuis un modèle ne frappe rien, quelle
que soit la méthode d'authentification choisie, y compris en `qr`. Les deux
autres chemins se comportent autrement : l'onglet « Produit unique » et l'import
CSV frappent les exemplaires en `qr` dès la création.

Pour une série en `qr`, la console vous dépose sur la page du lot. Vous y
frappez le lot avec « Frapper le lot (groupé) », vous attendez la confirmation,
puis vous préparez les codes à imprimer avec « Préparer les QR à imprimer ».
Ce sont deux boutons distincts, la frappe étant asynchrone, et le second
n'apparaît qu'une fois des exemplaires frappés. Ces deux boutons sont eux aussi
masqués selon le profil de votre compte.

Pour une série qui porte du NFC, la console vous dépose sur l'écran d'encodage.
Les exemplaires y attendent leur puce, et la frappe a lieu à l'encodage.

> [!DANGER] Le lot scellé ne s'annule pas
> Cocher « Lot scellé » met la détection d'ouverture en service sur chaque puce
> de la série. C'est définitif sur la puce. Les tags doivent être des NTAG 424
> DNA TT à languette intacte.

## Importer un fichier

L'onglet « Depuis CSV » lit le fichier dans votre navigateur, vous montre ce
qu'il a compris, puis envoie les lignes acceptées.

### Les colonnes

| Colonne | Obligatoire | Contenu |
| --- | --- | --- |
| `product_name` | oui | le nom de l'exemplaire, non vide |
| `brand_id` | oui | le numéro de votre marque, un entier |
| `category_id` | oui | le numéro de la catégorie, un entier |
| `external_ref` | non | votre propre référence |
| `metadata_uri` | non | l'adresse de vos métadonnées |
| `product_model_id` | non | le numéro du modèle, un entier |
| `product_batch_id` | non | le numéro du lot de production, un entier |
| `auth_method` | non | `nfc`, `qr` ou `nfc+qr` |
| `owner_email` | non | lue par l'import, sans effet sur le produit créé |

Un fichier d'exemple minimal :

```csv title="produits.csv"
product_name,brand_id,category_id,product_model_id,auth_method
Sac Exemple 001,12,3,45,qr
Sac Exemple 002,12,3,45,qr
Sac Exemple 003,12,3,45,nfc+qr
```

> [!ATTENTION] La colonne `owner_email` ne désigne personne
> Le lecteur de fichier accepte cette colonne, et la création n'enregistre aucun
> destinataire à partir d'elle. Remplir cette colonne ne rattache donc aucun
> exemplaire à un client final.

### Comment le fichier est lu

- La première ligne est l'en-tête et compte comme la ligne 1. Les numéros
  affichés dans les refus sont ceux que votre tableur affiche.
- Le lecteur retire les espaces au bord des valeurs.
- Le lecteur ignore les lignes entièrement vides, sans message.
- Quand `external_ref` est vide, le lecteur le remplit avec le numéro de ligne
  sur quatre chiffres, par exemple `csv-0002`.
- Quand `metadata_uri` est vide, le serveur génère les métadonnées et les dépose
  sur IPFS.
- Un `auth_method` vide prend la valeur du sélecteur affiché au-dessus de
  l'aperçu, et l'aperçu marque alors cette ligne comme venant du sélecteur. Ce
  sélecteur ne propose que `nfc` et `qr`. Pour obtenir `nfc+qr`, écrivez la
  valeur dans le fichier.
- `auth_method` ignore la casse et les espaces. Les seuls séparateurs acceptés
  sont la virgule et le plus : `QR`, `NFC+QR`, `nfc,qr` et `qr + nfc` sont
  compris, `nfc/qr` et `nfc qr` font refuser la ligne.

### Ce qui fait refuser le fichier entier

- Une colonne obligatoire absente de l'en-tête. La console nomme les colonnes
  manquantes et n'importe rien.
- Le même nom de colonne deux fois, une fois les espaces retirés, par exemple
  `brand_id` et ` brand_id`. Rien n'est importé, parce qu'une des deux cellules
  serait gardée et l'autre perdue sans message.

La console affiche à part les colonnes que l'import n'utilise pas, sous leur
propre libellé. Le fichier reste utilisable. Cette liste sert à repérer un
`authmethod` écrit sans le tiret bas, qui serait sinon ignoré en silence.

### Ce qui fait refuser une ligne

La console n'importe pas une ligne refusée, et le produit correspondant
n'existera pas. Le message porte le numéro de ligne, la colonne fautive et la valeur
écrite dans le fichier.

| Message | Cause |
| --- | --- |
| `product_name` est vide | la cellule du nom est vide |
| `brand_id` est obligatoire et doit être un nombre entier | cellule vide ou valeur non entière |
| `category_id` est obligatoire et doit être un nombre entier | cellule vide ou valeur non entière |
| `product_model_id` doit être un nombre entier quand la colonne est remplie | valeur non entière |
| `product_batch_id` doit être un nombre entier quand la colonne est remplie | valeur non entière |
| `auth_method` n'est pas une valeur acceptée | mot hors des trois méthodes acceptées, par exemple `rfid` |
| cette ligne a moins de cellules que l'en-tête, les dernières colonnes n'existent donc pas dessus | la ligne est trop courte |
| cette ligne a plus de cellules que l'en-tête, et la cellule en trop serait perdue | la ligne est trop longue |

La console ne remplace jamais une valeur illisible par une supposition. Le
résultat partirait dans les métadonnées du jeton, dont l'empreinte est inscrite
sur la chaîne à la frappe, sans retour possible.

### Le mode de frappe

Avant l'envoi, la console vous propose deux choix pour les exemplaires qui
partent en frappe directe.

- **Une transaction par produit.** C'est le mode par défaut et celui qui a
  toujours été utilisé. Si une frappe échoue, elle échoue seule.
- **Regrouper jusqu'à 50 produits par transaction.** Ce mode divise les frais
  de chaîne. Il n'a jamais tourné sur un vrai lot en production. Essayez-le sur
  un petit lot avant de l'employer sur une série.

Ce choix n'engage que cet import et ne modifie aucun réglage.

### Après l'envoi

Les lignes à puce partent en file d'encodage, les lignes en `qr` partent en
file de frappe. La console affiche le compte de chacune. Le serveur refuse un
envoi de plus de 10 000 lignes destinées à la frappe directe, et vous demande
de découper le fichier.

## Le point d'entrée de création en lot de l'API

> [!ATTENTION] Cette voie ne crée que des exemplaires en `qr`
> Votre ligne ne porte aucune méthode d'authentification. Le serveur pose `qr`
> sur chaque ligne du lot, et il pose lui-même l'identifiant technique de chaque
> exemplaire. Un appel machine n'a aucune puce en main, donc le `nfc` et le
> `nfc+qr` ne s'obtiennent pas par cette voie. Pour créer des exemplaires à
> puce, passez par la console.

Voici ce que ce point d'entrée accepte et refuse aujourd'hui.

- Adresse : `POST https://api.sealtrust.io/v1/partner/mint/batch`.
- Droit requis sur la clef : `mint:batch`. Votre offre doit inclure l'accès API.
- Cinq champs par ligne, et cinq seulement : `product_name`, `brand_id`,
  `category_id`, `metadata_uri` sont obligatoires, `external_ref` est
  facultatif. Tout autre champ fait échouer la requête en 400.
- 500 articles au maximum par appel. L'API refuse un lot vide.
- Toutes les lignes doivent porter le numéro de marque de la clef. Une seule
  ligne d'une autre marque fait refuser le lot entier en 403.
- Aucun champ de méthode d'authentification, et aucun champ d'identifiant
  technique. Le serveur pose les deux sur chaque ligne : la méthode vaut `qr`,
  et l'identifiant technique est émis par le serveur. Vous ne choisissez donc
  ni l'un ni l'autre par cette voie. L'attribut « Authentication » des
  métadonnées prend la valeur « QR Code + Blockchain », et cette méthode est
  définitive. Pour créer des exemplaires en `nfc` ou en `nfc+qr`, passez par la
  console.
- Votre offre doit autoriser la méthode `qr`. Sinon le lot entier est refusé en
  403 avec le code `AUTH_METHOD_NOT_ALLOWED`.

La réponse arrive en 200 dès que le lot est mis en file. Elle contient quatre
champs. Aucun ne dit qu'un exemplaire est déjà créé, la création ayant lieu
ensuite, hors de votre appel.

```json title="200 OK"
{
  "job_id": "0000a1b2c3d4e5f6",
  "status": "queued",
  "items_count": 2,
  "brand_id": 12
}
```

Vous lisez ensuite l'état du lot avec
`GET https://api.sealtrust.io/v1/partner/mint/batch/status/0000a1b2c3d4e5f6`,
qui demande le même droit `mint:batch`. Le champ `status` reprend telle quelle
la valeur de la file d'exécution. Vous verrez le plus souvent `queued`,
`started`, `finished` et `failed`. La file peut aussi renvoyer `deferred`,
`scheduled`, `stopped` et `canceled`. `unknown` signifie qu'aucun lot
accessible avec votre clef ne correspond à cet identifiant.

Bouclez tant que le statut vaut `queued` ou `started`. Arrêtez-vous sur toute
autre valeur, `finished`, `failed` et `unknown` comprises, et arrêtez-vous
aussi sur une valeur que vous ne connaissez pas. Une boucle qui repart sur
tout ce qu'elle ne reconnaît pas ne se termine jamais. Un lot `finished` ne
vous dit rien du nombre de produits créés.

> [!INFO] Rejouer un envoi sans créer de doublon
> L'en-tête `Idempotency-Key` est facultatif et mémorisé 24 heures. Rejouer la
> même clef avec le même lot renvoie la réponse du premier appel, sans
> refrapper. Rejouer la même clef avec un lot différent renvoie 409. L'égalité
> des deux lots porte sur le contenu : l'ordre des lignes, l'ordre des champs
> et les cellules vides n'y changent rien.

## Erreurs fréquentes

| Ce que vous voyez | Cause | Ce qu'il faut faire |
| --- | --- | --- |
| Le fichier est refusé pour colonnes manquantes | l'en-tête n'a pas `product_name`, `brand_id` ou `category_id` | ajoutez les colonnes nommées dans le message |
| Rien n'est importé et un nom de colonne est signalé en double | l'en-tête nomme deux fois la même colonne une fois les espaces retirés | renommez ou supprimez le doublon |
| Une ligne est refusée pour un `auth_method` non accepté | un mot hors des trois méthodes acceptées, par exemple `rfid` | écrivez `nfc`, `qr` ou `nfc+qr` |
| Toutes les lignes prennent la même méthode d'authentification alors que le fichier en précise plusieurs | la colonne est écrite `authmethod` et figure parmi les colonnes non utilisées | renommez la colonne `auth_method` |
| Refus 403 avec le code `AUTH_METHOD_NOT_ALLOWED` | votre offre n'autorise pas la méthode d'authentification demandée | créez ces exemplaires en `qr`, ou changez d'offre |
| Refus 403 avec le code `QUOTA_EXCEEDED` | le quota mensuel de produits est atteint | attendez la période suivante ou changez d'offre |
| L'aperçu annonce qu'aucune image ne sera portée | aucun modèle lié, ou modèle sans image | liez un modèle et donnez-lui une image de couverture avant de créer |
| Les exemplaires à puce sont créés mais aucun jeton n'existe | c'est le fonctionnement normal, la frappe a lieu à l'encodage | passez à l'encodage des puces |
| Les exemplaires créés par l'API portent tous `qr` alors que vous vouliez du NFC | le point d'entrée de création en lot de l'API ne crée que des exemplaires en `qr` | créez les exemplaires à puce depuis la console |
| L'API répond 400 en nommant `owner_email` ou `contract_address` | ces champs ont été retirés du lot de l'API le 20/08/2026 | retirez-les de vos lignes |
| L'API répond 409 sur un envoi rejoué | la même clef d'idempotence a déjà servi pour un lot différent | changez de clef d'idempotence |
