# Comment créer une page de liste d'attente pour une application mobile avant sa sortie sur l'App Store

> Une liste d'attente avant lancement pour une app iOS ou Android qui demande le téléphone utilisé, envoie les testeurs iPhone vers TestFlight et remplit un test fermé Play.

Publié le 2026-10-25 · https://ikiform.com/fr/guides/waitlist/mobile-app

Placez sur la landing page de votre app un formulaire de liste d'attente qui demande quel téléphone la personne utilise et si elle veut tester en avant-première. Envoyez les testeurs iPhone dans un groupe TestFlight avec un webhook et l'API App Store Connect, et chargez les testeurs Android dans un test fermé Google Play à partir d'un export. Le jour du lancement, envoyez à chaque groupe le lien vers sa boutique.

Avant qu'une app ne soit sur une boutique, il n'y a pas de bouton d'installation vers lequel envoyer les gens. Une liste d'attente sur votre propre landing page entretient leur intérêt d'ici là, et remplit un second rôle que les boutiques ne remplissent pas : trouver les testeurs dont vous avez besoin avant le lancement.

## Ce qui change pour une application mobile

- **Deux boutiques, deux listes.** L'e-mail de lancement renvoie vers l'App Store ou Google Play, et les invitations de test passent par TestFlight ou un test fermé Play. Il vous faut connaître la plateforme de chaque personne pour envoyer le bon lien.
- **Les testeurs doivent correspondre au compte de la boutique.** TestFlight envoie une invitation par e-mail à n'importe quelle adresse. Un test fermé Play n'accepte que les comptes Google de sa liste : un testeur Android inscrit avec une adresse professionnelle ne peut donc pas installer le build.
- **Google Play peut exiger des testeurs avant le lancement.** Les comptes développeur personnels créés après le 13 novembre 2023 doivent mener un test fermé avec au moins 12 testeurs restés inscrits 14 jours d'affilée avant de pouvoir publier en production. Une liste d'attente est l'endroit d'où viennent ces 12 personnes.
- **Les boutiques ont leurs propres outils d'avant-lancement.** Ils valent la peine d'être utilisés à côté d'une liste d'attente, pas à sa place. Voir la comparaison ci-dessous.

|   | Précommandes App Store ou pré-inscription Play | Votre propre liste d'attente |
| --- | --- | --- |
| Nécessite une fiche sur la boutique | Oui, approuvée et prête | Non. Elle fonctionne dès le premier jour de la landing page |
| Ce que vous obtenez | Un compteur, et une notification de la boutique ou un téléchargement automatique à la sortie | L'e-mail, la plateforme et les réponses de chaque personne |
| Peut inviter des testeurs | Non | Oui, par e-mail vers TestFlight ou un test fermé Play |
| Limites | La pré-inscription Play reste désactivée pour les nouveaux comptes personnels tant que l'exigence de test n'est pas remplie | Vous envoyez vous-même l'e-mail de lancement |

## Les champs d'une liste d'attente d'app

Demandez d'abord la plateforme, car elle change le sens du champ e-mail. Le modèle de téléphone est facultatif et vous indique sur quels appareils tester. La case bêta distingue les personnes qui veulent tester de celles qui veulent l'e-mail de lancement.

Formulaire : App waitlist

- **E-mail** (`email`, email, obligatoire)
- **Prénom** (`first_name`, text)
- **Quel téléphone utilisez-vous ?** (`platform`, radio, obligatoire)
- **Modèle de téléphone** (`device`, text)
- **Invitez-moi à tester l'app avant le lancement** (`beta`, checkbox)

Le radio `platform` est obligatoire : chaque inscription atterrit donc dans une liste exploitable. Collez la définition dans l'onglet **Fields** du formulaire.

## Le formulaire

Le formulaire fonctionne en HTML simple sur n'importe quelle landing page. Le script fait deux petites choses : il présélectionne la plateforme d'après le navigateur du visiteur, et n'affiche l'indication sur le compte Google qu'aux utilisateurs Android.

`index.html`:

```html
<form id="app-waitlist" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <fieldset>
    <legend>Which phone do you use?</legend>
    <label><input type="radio" name="platform" value="iphone" required> iPhone</label>
    <label><input type="radio" name="platform" value="android"> Android</label>
  </fieldset>

  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" inputmode="email" required>
  <p id="email-hint" hidden>Use the Google account you sign in to Google Play with.</p>

  <label for="first_name">First name</label>
  <input id="first_name" name="first_name" autocomplete="given-name" maxlength="60">

  <label for="device">Phone model</label>
  <input id="device" name="device" maxlength="80" placeholder="iPhone 15, Pixel 8">

  <label><input type="checkbox" name="beta" value="true"> Invite me to test the app before launch</label>
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>
  <button>Join the waitlist</button>
</form>

<script>
  const form = document.getElementById("app-waitlist");
  const agent = navigator.userAgent;
  const guess = /iPhone|iPad/.test(agent) ? "iphone" : /Android/.test(agent) ? "android" : null;
  if (guess) form.querySelector(`[name="platform"][value="${guess}"]`).checked = true;
  const hint = () => {
    document.getElementById("email-hint").hidden = form.platform.value !== "android";
  };
  form.addEventListener("change", hint);
  hint();
</script>
```

- La supposition ne fait que présélectionner un radio. Les gens peuvent la changer, et sans le script rien n'est sélectionné : `required` les oblige alors à choisir.
- `inputmode="email"` et `autocomplete="email"` comptent ici plus qu'ailleurs : la plupart des visiteurs de la landing page d'une app sont sur téléphone.
- Réglez **Redirect after submit** sur une page de remerciement qui explique la suite pour chaque plateforme. Pour une version du formulaire avec un framework, voir le [guide principal](https://ikiform.com/fr/guides/waitlist.md#form) et ajoutez ces champs.

## Diriger les testeurs vers chaque boutique

Schéma : Comment les testeurs iPhone et Android rejoignent la bêta de chaque boutique

1. Un utilisateur d'iPhone qui coche la case bêta déclenche un webhook signé.
2. Votre relais le vérifie et appelle l'API App Store Connect pour ajouter l'adresse à un groupe TestFlight.
3. Apple envoie l'invitation TestFlight par e-mail dès qu'un build est disponible pour le groupe.
4. Les testeurs Android sont collectés de la même façon, puis exportés en CSV et filtrés par plateforme.
5. Vous collez les comptes Google dans la liste d'e-mails du test fermé dans la Play Console.
6. Vous leur envoyez le lien d'inscription au test depuis votre outil d'e-mailing.

Apple a une API pour les testeurs ; les tests fermés de Google Play se gèrent dans la Play Console ou via Google Groups, le côté Android est donc un export hebdomadaire.

### iPhone : ajouter des testeurs à TestFlight

Dans App Store Connect, créez un groupe de test externe et une clé d'API sous **Users and Access** › **Integrations**, avec le rôle App Manager ou Admin. Ajoutez ensuite un relais qui écoute le webhook `submission.created` d'Ikiform. Celui-ci est un route handler Next.js qui utilise `jose` pour signer le jeton d'Apple ; il tourne sur n'importe quel serveur doté de `fetch`.

`app/api/testflight/route.ts`:

```ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { importPKCS8, SignJWT } from "jose";

async function appStoreToken() {
  const key = await importPKCS8(process.env.ASC_PRIVATE_KEY!, "ES256");
  return new SignJWT({})
    .setProtectedHeader({ alg: "ES256", kid: process.env.ASC_KEY_ID!, typ: "JWT" })
    .setIssuer(process.env.ASC_ISSUER_ID!)
    .setAudience("appstoreconnect-v1")
    .setIssuedAt()
    .setExpirationTime("15m")
    .sign(key);
}

export async function POST(request: Request) {
  const payload = await request.text();
  try {
    const event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
    if (event.type !== "submission.created") return new Response(null, { status: 204 });
    const { email, first_name, platform, beta } = event.data.fields;
    if (platform !== "iphone" || beta !== true) return new Response(null, { status: 204 });

    const response = await fetch("https://api.appstoreconnect.apple.com/v1/betaTesters", {
      method: "POST",
      headers: { authorization: `Bearer ${await appStoreToken()}`, "content-type": "application/json" },
      body: JSON.stringify({
        data: {
          type: "betaTesters",
          attributes: { email: String(email), firstName: first_name ? String(first_name) : undefined },
          relationships: { betaGroups: { data: [{ type: "betaGroups", id: process.env.ASC_BETA_GROUP_ID! }] } },
        },
      }),
    });
    if (response.ok || response.status === 409) return new Response(null, { status: 204 });
    return new Response(`App Store Connect answered ${response.status}`, { status: 502 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
}
```

- `ASC_PRIVATE_KEY` est le contenu du fichier `.p8` fourni par Apple, sauts de ligne compris. `ASC_KEY_ID` et `ASC_ISSUER_ID` sont sur la même page.
- Les jetons d'Apple durent au plus 20 minutes : le relais en signe donc un nouveau à chaque livraison.
- Un `409` signifie qu'Apple a refusé la modification pour cause de conflit, souvent parce que l'adresse est déjà testeuse. Le relais le considère comme fait : si un testeur ne reçoit jamais d'invitation, vérifiez le groupe dans App Store Connect. Tout autre échec répond `502`, et Ikiform réessaie la livraison.
- TestFlight autorise jusqu'à 10 000 testeurs externes par app. Le premier build donné à un groupe externe passe par la Beta App Review, et chaque build expire après 90 jours.

Ajoutez l'URL du relais sous **Webhooks** dans Ikiform et copiez le secret `whsec_` dans `IKIFORM_WEBHOOK_SECRET`. Un espace de travail peut avoir 3 endpoints : celui-ci peut donc tourner à côté d'un relais qui alimente votre outil d'e-mailing.

### Android : remplir un test fermé

L'API de publication de Google Play gère les testeurs des tests fermés via Google Groups, pas par adresses individuelles : ce côté est donc un export hebdomadaire. Exportez la liste avec **Export CSV**, filtrez-la dans un tableur sur `platform` = `android` et `beta` = `true`, et ajoutez les e-mails à la liste d'e-mails du test fermé sous **Test and release** › **Testing** › **Closed testing** › **Manage track** › **Testers** dans la Play Console. Envoyez ensuite à ces personnes le lien d'inscription au test depuis votre outil d'e-mailing.

Si vous visez l'exigence des 12 testeurs, invitez-en plus de 12. Les personnes qui se désinscrivent ou ne s'inscrivent jamais ne comptent pas, et les 14 jours exigent 12 testeurs inscrits pendant toute la période.

> Ikiform n'envoie pas d'e-mail à la personne qui remplit le formulaire. Les e-mails de notification vont uniquement à vous et à votre équipe : il n'y a donc ni réponse automatique, ni e-mail de confirmation, ni double opt-in. Envoyez-les depuis votre outil d'e-mailing, déclenché par un [webhook](https://ikiform.com/fr/docs/webhooks.md). TestFlight envoie sa propre invitation, les testeurs iPhone ont donc des nouvelles d'Apple. Les testeurs Android n'ont des nouvelles que de vous.

## Le jour du lancement

Exportez toute la liste et répartissez-la par `platform`. Envoyez à chaque moitié un e-mail avec un seul lien de boutique. Les personnes qui ont choisi iPhone n'ont pas besoin du lien Play, et un seul e-mail avec deux badges perd des clics sur un petit écran. Si vous avez collecté `device`, comparez vos rapports de crash aux modèles indiqués avant d'envoyer.

## Vérifiez que tout fonctionne

1. Dans **Allowed domains** du formulaire, ajoutez le domaine de votre site, plus `localhost` pendant le développement. Laissez vide pour accepter les envois de partout.
2. Ouvrez la page sur un téléphone. La bonne plateforme est présélectionnée, et sur Android l'indication sur le compte Google s'affiche.
3. Envoyez en tant que testeur iPhone. La soumission affiche `platform` à `iphone` et `beta` à `true`.
4. Ouvrez l'endpoint du relais sous **Webhooks**. La livraison affiche `succeeded`, et l'adresse figure dans votre groupe TestFlight.
5. Envoyez en tant que testeur Android, exportez le CSV et vérifiez que la ligne ressort avec le filtre `platform` réglé sur `android`.
6. Envoyez avec le honeypot rempli, `_gotcha=bot`. L'envoi reçoit quand même une réponse de succès, mais la soumission est stockée comme spam et n'envoie ni e-mail ni webhook.

## Pièges

| Problème | Que faire |
| --- | --- |
| Les livraisons du relais échouent avec `502` et Apple a répondu `401` | Le jeton est faux : vérifiez l'id de clé, l'id d'émetteur et que la clé privée a gardé ses sauts de ligne dans la variable d'environnement. |
| Un testeur a été ajouté mais n'a reçu aucun e-mail TestFlight | Le groupe n'a pas encore de build, ou le premier build est encore en Beta App Review. Les invitations partent dès qu'un build est disponible pour le groupe. |
| Un testeur Android ne peut pas ouvrir le lien d'inscription | L'adresse de la liste n'est pas le compte Google connecté sur le téléphone. Demandez-lui de se réinscrire avec ce compte. |
| `422 validation_failed` | L'envoi ne correspond pas à la définition des champs du formulaire. `error.fields` nomme chaque champ et la raison. Faites correspondre le `name` de l'input à l'id du champ. |
| La soumission est dans le tableau de bord mais aucun e-mail ni webhook n'est arrivé | Elle a été stockée comme spam. Le spam n'envoie rien. Ouvrez-la sous le filtre **Spam** pour voir les raisons, et marquez-la comme non-spam pour envoyer son e-mail et ses webhooks. |

## Questions

### Ai-je besoin d'une liste d'attente si l'App Store propose les précommandes ?

Elles n'ont pas le même rôle. Les précommandes et la pré-inscription Play exigent une fiche approuvée sur la boutique et vous donnent un compteur, pas des contacts. Une liste d'attente fonctionne dès le premier jour, vous donne l'e-mail et la plateforme de chaque personne, et vous permet d'inviter des testeurs.

### Comment trouver 12 testeurs pour l'exigence de test fermé de Google Play ?

Demandez-les sur votre liste d'attente. Une case bêta et une question sur la plateforme vous montrent qui a un téléphone Android et veut tester. Mettez leurs comptes Google dans la liste d'e-mails du test fermé et envoyez-leur le lien d'inscription.

### Ikiform peut-il ajouter automatiquement des testeurs à TestFlight ?

Pas directement. Ikiform envoie un webhook signé pour chaque inscription, et un court relais que vous déployez ajoute l'adresse à un groupe TestFlight via l'API App Store Connect, comme montré ci-dessus.

### Ikiform peut-il envoyer un e-mail à la personne qui a rempli le formulaire ?

Non. Ikiform envoie des e-mails à vous et à votre équipe, pas à l'expéditeur : il n'y a donc ni réponse automatique ni e-mail de confirmation. Envoyez un webhook à votre outil d'e-mailing et envoyez la confirmation depuis celui-ci.

### Ikiform est-il gratuit ?

Non, il n'y a pas d'offre gratuite. Les tests sont gratuits : vous pouvez envoyer 50 soumissions de test par mois depuis localhost avant de payer. Pour passer en production, Pro commence à 6 $/mois pour 500 soumissions, ou vous pouvez payer une seule fois 10 000 soumissions pour 49 $ ou 50 000 soumissions pour 149 $, avec des crédits qui n'expirent jamais.

## Autres guides

- [Liste d'attente pour un nouveau SaaS](https://ikiform.com/fr/guides/waitlist.md): Créez une liste d'attente avant lancement sur votre landing page : le formulaire, l'anti-spam, les doublons, les e-mails de confirmation et un export propre le jour J.
- [Inscription bêta avec sélection](https://ikiform.com/fr/guides/waitlist/beta-signup.md): Un formulaire de candidature bêta avec des questions de sélection appliquées côté serveur, et un script qui note les candidats et choisit chaque cohorte.
- [Liste de lancement Product Hunt](https://ikiform.com/fr/guides/waitlist/product-hunt.md): Collectez une liste des semaines avant Product Hunt, taguez chaque inscription par canal et envoyez l'e-mail du jour J en deux vagues calées sur l'heure du Pacifique.
- [Liste d'attente en HTML simple](https://ikiform.com/fr/guides/waitlist/html.md): Une page de liste d'attente complète en HTML simple, sans build, qui fonctionne sans JavaScript, remercie sur place quand il se charge, et se replie si besoin.
- [Liste d'attente Next.js](https://ikiform.com/fr/guides/waitlist/nextjs.md): Une liste d'attente Next.js App Router : une server action qui transmet avec une clé secrète, useActionState, un merci optimiste et une limite par visiteur.
- [Liste d'attente sur Framer](https://ikiform.com/fr/guides/waitlist/framer.md): Deux façons de collecter des inscriptions sur Framer : le formulaire Framer avec un webhook vers Ikiform, ou un code component qui garde limites et anti-spam.
