# Mettre à jour la carte à l’aide de fichiers plats

The Wallet Crew peut mettre à jour des Passes Apple Wallet et Google Wallet existants à partir d'un fichier CSV. Ceci est utile pour les mises à jour en masse et pour les systèmes hérités qui ne peuvent exporter que des fichiers plats.

{% hint style="warning" %}
Les importations SFTP sont une fonctionnalité optionnelle. Demandez à The Wallet Crew d'activer le SFTP sur votre locataire avant d'implémenter ce flux.

Considérez les importations SFTP comme un **dernier recours**. Évitez ce flux sauf si vous n'avez pas d'autre option (par exemple, un système hérité qui ne peut exporter que des fichiers plats).

Pour la plupart des projets, l'API est l'approche recommandée. Elle est plus facile à automatiser, plus facile à surveiller et les mises à jour sont en temps réel.

Si vous préférez une intégration en temps réel, utilisez plutôt le flux de mise à jour par API. Voir [leveraging-updated-pass-data-with-the-wallet-crew-api](https://docs.thewalletcrew.io/fr/developper/guides/wallet/leveraging-updated-pass-data-with-the-wallet-crew-api "mention").
{% endhint %}

<details>

<summary><strong>Exemples concrets</strong></summary>

* Un programme de carte-cadeau recalcule le solde toutes les heures. Une exportation en fichier plat met à jour `additionalData.balance` pour toutes les cartes actives.
* Une équipe d'automatisation marketing exporte un CSV pour préparer une campagne push. Chaque ligne met à jour `additionalData.notification_content` avant d'envoyer les notifications.
* Un système de billetterie exporte des modifications de dernière minute (porte, siège ou horaire). Une mise à jour CSV en masse maintient les billets à jour juste avant l'ouverture des portes.
* Une chaîne de salles de sport exporte le statut des abonnements chaque nuit (actif, gelé, expiré). Le lendemain, les membres voient le statut correct à l'enregistrement.
* Une équipe de support corrige un identifiant erroné à grande échelle en téléchargeant un fichier de correction ponctuel.

</details>

<div data-with-frame="true"><figure><img src="https://3097111101-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWLc8AHXW4tdrAXUBfrYF%2Fuploads%2Fgit-blob-d166db36c4e1ffc5a5f462769bb62a772eee361c%2Fupdate_pass_using_flat_files_1.png?alt=media" alt="Diagram showing a CSV file uploaded to SFTP, then processed by The Wallet Crew to update passes."><figcaption><p>Les importations de fichiers plats vous permettent de mettre à jour de nombreux passes en une seule opération.</p></figcaption></figure></div>

## Aperçu du processus

1. Téléversez votre fichier CSV sur le serveur SFTP fourni.
2. The Wallet Crew détecte automatiquement les nouveaux fichiers et les traite immédiatement.
3. Une fois traité, le fichier est déplacé vers `.processed/` ou `.error/`.
4. Chaque ligne est interprétée comme une instruction de mise à jour pour un seul pass.
5. Les passes sont mises en file d'attente pour mise à jour et traitées de manière asynchrone.

## Format de fichier

Les fichiers téléversés doivent être des [RFC 4180](https://www.ietf.org/rfc/rfc4180.txt){target="\_blank"} fichiers CSV conformes.

* **Séparateurs**: Soit `,` ou `;`
* **Ligne d'en-tête**: Obligatoire. Doit contenir les noms des colonnes.
* **Encodage**: UTF-8 recommandé
* **Analyseur**: The Wallet Crew utilise [CsvHelper](https://joshclose.github.io/CsvHelper/){target="\_blank"} avec les options par défaut

Chaque ligne de données cible un seul pass et peut inclure plusieurs mises à jour de ses champs, additionalData ou métadonnées.

## Nom de fichier

Il n'y a pas d'exigences strictes pour les noms de fichiers. Cependant, pour une meilleure organisation et traçabilité, nous recommandons la convention de nommage suivante :

```
<source>-passes-<YYYYMMDD>-<HHMMSS>.csv
```

Exemples :

```
crm-passes-20250801-083000.csv 
loyalty-passes-20250731-235959.csv
```

Remarques :

* L'extension de fichier doit être `.csv`.
* Évitez d'utiliser des caractères spéciaux (espaces, #, %, &, etc.) dans les noms de fichiers
* Si vous utilisez un script ou une intégration pour générer des fichiers, adopter un modèle de nommage basé sur un horodatage aide à éviter les duplications et facilite le débogage.
* Si le fichier est volumineux, The Wallet Crew surveille brièvement sa taille pour s'assurer qu'il est entièrement écrit avant le traitement.

## Référence des colonnes

### Colonnes d'identification du pass

Pour sélectionner le pass cible, utilisez l'une des colonnes suivantes :

* `id`: Identifiant interne The Wallet Crew du pass
* `id.<externalId>`: Nom de l'identifiant externe (tel que configuré dans votre locataire)\
  Exemple : `id.y2.customerId`

Au moins une colonne d'identifiant doit être présente dans chaque ligne.

### Colonnes de données supplémentaires

Pour mettre à jour des données additionnelles sur le pass, utilisez la syntaxe suivante :

* `additionalData.<key>`: Met à jour la clé dans le `additionalData` dictionnaire\
  Exemple : `additionalData.notification_content`

Plusieurs clés additionalData peuvent être mises à jour dans une même ligne.

### Modèle de pass

Pour changer le pass vers un autre modèle, incluez :

* `passType`: Le nom du nouveau modèle (tel que défini dans The Wallet Crew)

Si omis ou vide, le pass conservera son modèle actuel.

### Rafraîchissement des métadonnées

Pour déclencher une recomputation des métadonnées internes (par ex. codes-barres, expiration, champs d'affichage) :

* `updateMetadata`: Définir sur `true` pour déclencher la mise à jour des métadonnées

### Identifiants externes

Pour mettre à jour un identifiant externe, utilisez la syntaxe suivante :

* `identifiers.<idName>`: Met à jour l'identifiant nommé `idName`\
  Exemple : `identifiers.y2.customerId`

## Accès SFTP

Téléversez vos fichiers CSV sur le point d'accès SFTP pour votre environnement :

* **QA**: `triglav-qa.walletcrew.net` (port `22`)
* **Production**: `triglav.walletcrew.net` (port `22`)

Contactez le support The Wallet Crew pour demander vos identifiants SFTP.

## Exemples

### Exemple 1 : Mettre à jour la notification et l'URL de l'offre

```csv
id;additionalData.notification_content;additionalData.offer_url
Gk440DNzvfZcDmlA;Joyeux Noël Alice !;https://acme.com/xmas1
HKlhrhrEXx2ZASYs;Joyeux Noël Bob !;https://acme.com/xmas1
```

### Exemple 2 : Mise à jour par ID externe avec informations de fidélité

```csv
id.y2.customerId;additionalData.notification_content
00100123;Profitez de 30 % de réduction sur votre prochain achat
04503295;Merci pour votre achat ! Il ne vous reste que 10 points pour échanger un bon de 10 €
02319202;Merci pour votre achat ! Il ne vous reste que 120 points pour échanger un bon de 10 €
```

### Exemple 3 : Changer le modèle de pass et forcer le rafraîchissement des métadonnées

```csv
id;passType;updateMetadata
gH67xKlPzLZ99xa2;vip_template;true
dAk21jvUZYx39q77;standard_template;true
```

### Exemple 4 : Mettre à jour l'id externe y2.customerId et forcer le rafraîchissement des métadonnées

```csv
id.y2.customerId;identifiers.y2.customerId;passType;updateMetadata
04503295;1010013295;;true
04503296;1010013296;;true
```

## Extensibilité et mappage personnalisé

The Wallet Crew prend en charge les transformations de fichiers personnalisées à l'aide de scripts d'importation.

Cela vous permet de :

* Adapter votre format d'export existant (par ex. depuis un CRM ou un POS)
* Mapper les noms de colonnes hérités vers des clés compatibles avec The Wallet Crew
* Injecter des valeurs dynamiques (par ex. date actuelle, points calculés)
* Enrichir les données avec des recherches depuis des sources externes

Pour personnaliser le processus d'importation, vous pouvez créer un `import.custom.js` fichier dans le `scripts/` dossier dans la configuration avancée.

Si vous avez le fichier CSV suivant :

```csv
id.y2.customerId,neo_notification_content,neo_offer_title,neo_offer_body
abc12345,"Hey Arthur !","Votre offre de 20 %","20 % de réduction sur votre prochain achat"
```

Vous pouvez utiliser le script suivant :

```js
/**
 * Transforme une ligne CSV en un objet de type UpdatePassInformation.
 *
 * @param {Object<string, string>} row - La ligne CSV, en tant que dictionnaire nom_de_colonne => valeur.
 * @returns {Object} Informations de ligne transformées.
 * @returns {Object<string, string>} return.Identifiers - Identifiants pour cette ligne (par ex. ID client).
 * @returns {string|null} return.PassType - Le type de pass, ou null si non présent.
 * @returns {Object<string, string>} return.AdditionalData - Données additionnelles facultatives issues de colonnes préfixées.
 */
function transform(row){
  const identifiers = {
      "id.y2.customerId" : row["id.y2.customerId"]
  };

  const passType = row.passType || null; 

  const properties = [
    "notification_content",
    "offer_title", 
    "offer_body"
   ];

  let additionalData = {};
  for(const property of properties){
    if(row["neo_" + property] !== undefined){
      additionalData[property] = row["neo_" + property].toString(); 
    }
  }

  return {
    Identifiers : identifiers, 
    PassType: passType,
    AdditionalData : additionalData
  }
}

/**
 * Méthode optionnelle pour retourner un débit personnalisé pour un fichier d'import donné.
 *
 * @param {string} fileName - Le nom du fichier d'import.
 * @returns {number|null} Surcharge du débit, ou null pour utiliser la valeur par défaut.
 */
function getThroughput(fileName) {
  // Exemple : retourner null pour utiliser la valeur par défaut
  return null;
}

export default function(context) {
  context.register('runtime.import.updatePasses.rowTransformer', {
    Transform: transform, 
    GetThroughput: getThroughput
  });
}
```

Contactez notre équipe si vous avez besoin d'aide pour implémenter une logique de mappage personnalisée pour vos imports.

## Conseils et bonnes pratiques

* Assurez-vous que les identifiants sont exacts pour éviter des lignes ignorées.
* Testez toujours votre format de fichier en QA avant de téléverser en production.
* Utilisez un encodage cohérent (UTF-8) pour éviter les problèmes d'analyse avec des caractères spéciaux.

## FAQ

<details>

<summary><strong>Créez-vous de nouveaux passes, ou mettez-vous uniquement à jour des passes existants ?</strong></summary>

Ce flux met à jour des passes existants. Chaque ligne doit cibler un pass en utilisant `id` ou une colonne d'identifiant externe comme `id.y2.customerId`.

</details>

<details>

<summary><strong>Que se passe-t-il si une ligne contient à la fois <code>id</code> et <code>id.&#x3C;externalId></code>?</strong></summary>

Utilisez un identifiant par ligne si possible. Si vous en incluez plusieurs, assurez-vous qu'ils pointent tous vers le même pass. Cela évite les ambiguïtés et facilite le dépannage.

</details>

<details>

<summary><strong>Puis-je mettre à jour plusieurs <code>additionalData</code> clés dans une même ligne ?</strong></summary>

Oui. Ajoutez une colonne par clé, en utilisant `additionalData.<key>`. La ligne mettra à jour toutes les clés fournies dans une seule mise à jour de pass.

</details>
