Aller au contenu
WebViewGold Du vibe coding à l'App Store
Français
Obtenir WebViewGold

Claude Code + paiements

Achats intégrés pour une web app Claude Code : RevenueCat dans WebViewGold

Dans les apps iOS et Android, les abonnements numériques passent par les stores ; sur votre site web, Stripe peut rester. WebViewGold lance l'achat sur le store via RevenueCat avec un seul schéma d'URL : le travail dans votre base de code se résume à une séparation propre par plateforme, un webhook et une vérification des droits d'accès. Ce guide montre comment laisser Claude Code construire exactement cela et comment prouver que tout fonctionne avant la validation.

Dès $109 en paiement unique par plateforme, ou notre équipe s'occupe de tout dès $698.

  • Garantie d'approbation – ou remboursement sous 14 jours
  • Aucun codage requis
  • Paiement unique, mises à jour gratuites
  • Support humain 24/7
  • Conçu en Allemagne depuis 2014 · ISO 27001

La règle, et comment les pièces s'assemblent

La guideline Apple 3.1.1 impose que les contenus, fonctionnalités et abonnements numériques débloqués dans une app iOS passent par l'achat intégré ; la politique Paiements de Google Play dit la même chose pour Play Billing. Les biens physiques et les services utilisés en dehors de l'app en sont exemptés. Les exceptions régionales ont beaucoup bougé depuis 2025 : les guidelines actuelles d'Apple autorisent les boutons et liens vers d'autres moyens de paiement dans les apps de la vitrine des États-Unis, et Google a modifié ses règles américaines après le jugement Epic v. Google. Lisez-les dans leur version actuelle avant de vous appuyer dessus ; l'approche la plus simple, acceptée partout, reste l'achat intégré dans l'app et Stripe sur le web. Le guide Stripe ou achat intégré vous aide à trancher.

Côté WebViewGold, le travail est léger. RevenueCat est l'intégration par défaut : votre bouton navigue vers revenuecat://purchase?external_id=USER_ID&product=PRODUCT_ID, la feuille d'achat native du store apparaît, RevenueCat enregistre la transaction et envoie un webhook à votre serveur, et votre serveur écrit le droit d'accès (entitlement) que votre web app vérifie. restoreinapppurchases:// restaure les achats et cancelinapppurchase:// ouvre les réglages d'abonnement du store. Sur iOS 15 et versions ultérieures, revenuecat://launchPaywall?external_id=USER_ID&offering=OFFERING_ID affiche le paywall RevenueCat que vous avez conçu dans leur dashboard ; la documentation ne mentionne ce schéma que pour iOS, Android utilise donc revenuecat://purchase produit par produit. Notez que l'utilisation des achats intégrés dans un produit final nécessite la licence étendue WebViewGold (Extended License, voir la documentation des achats intégrés).

Ce que fait Claude Code et ce que vous faites

DomaineClaude CodeVous
Consoles des storesRédige la liste des produits et les textes du paywall, que vous n'avez plus qu'à collerContrat Paid Apps, coordonnées bancaires et fiscalité, produits d'abonnement dans App Store Connect et la Play Console
RevenueCatExplique quels champs remplir, rien de plusProjet avec les deux apps, produits, entitlement, offering, URL du webhook et valeur de son en-tête Authorization
WebViewGoldPeut définir les clés RevenueCat dans Config.swift / Config.java si vous le demandezBundle ID et nom de package identiques à ceux de RevenueCat, builds, testeurs sandbox
Web appBranche paywall, liens de restauration et de gestion, route du webhook, table des droits, polling après l'achat, une commande de contrôle contre Stripe dans l'appApprouver le plan, définir les variables d'environnement, tester l'achat sur les appareils

La mise en place, dans l'ordre qui évite d'attendre

Les contrats des stores et la validation des produits prennent le plus de temps : commencez par là.

  1. Les produits dans les deux stores

    Dans App Store Connect, signez le contrat Paid Apps, puis créez un groupe d'abonnements avec des produits comme pro_monthly et pro_yearly. Dans la Play Console, créez les mêmes ID produit sous forme d'abonnements avec un forfait de base (base plan) ; Play exige que l'app soit dans au moins un canal de test. Le guide de configuration RevenueCat détaille chaque champ.

  2. Le projet RevenueCat

    Ajoutez l'app App Store et l'app Play Store, importez les produits, rattachez-les à un entitlement nommé pro et placez-les dans une offering. Sous Integrations → Webhooks, saisissez https://app.example.com/api/webhooks/revenuecat et une valeur d'en-tête Authorization que vous générez vous-même.

  3. Les clés WebViewGold

    iOS : dans Config.swift, réglez kRevenueCatEnable sur true et renseignez revenueCatAPIKey et revenueCatProjectID ; laissez kRevenueCatShowDefaultOfferingPaywall sur false, sauf si vous voulez vraiment un paywall à chaque lancement. Android : renseignez REVENUECAT_API_KEY et REVENUECAT_PROJECT_ID dans Config.java. Utilisez la clé SDK publique que RevenueCat affiche pour l'app de chaque plateforme.

  4. Lancez le prompt en mode plan

    Ici, c'est le plan qui a le plus de valeur : il doit lister chaque endroit où votre app vend quelque chose ou mentionne un prix. Approuvez-le, laissez l'agent implémenter, puis ajoutez chez votre hébergeur la variable d'environnement REVENUECAT_WEBHOOK_AUTH et les identifiants de votre base de données, et déployez.

  5. Compilez et testez en sandbox

    TestFlight sur iOS, test interne sur Android, avec les vérifications ci-dessous. Si vous préférez confier les builds natifs et la configuration des stores à quelqu'un d'autre, notre équipe Full Service configure et compile les deux apps.

Mon WebView iOS est enfin approuvé. Merci !!

Taha Farooqui · CodeCanyon

Le prompt Claude Code

Remplacez les ID produit et les noms de routes. Le dernier point crée une commande slash réutilisable que vous pouvez lancer avant chaque version.

À coller dans Claude Code (d'abord en mode plan)
Dans nos apps iOS et Android (construites avec WebViewGold, reconnaissables au jeton WebViewGoldApp dans le user agent), les achats numériques doivent passer par l'App Store et Google Play. WebViewGold intègre RevenueCat : naviguer vers revenuecat://purchase?external_id=USER_ID&product=PRODUCT_ID lance un achat natif, restoreinapppurchases:// restaure les achats et cancelinapppurchase:// ouvre les réglages d'abonnement du store. Sur iOS 15 ou plus récent, revenuecat://launchPaywall?external_id=USER_ID&offering=OFFERING_ID affiche le paywall RevenueCat ; la documentation ne le mentionne que pour iOS, Android utilise donc revenuecat://purchase produit par produit. Lisez les sections In-App Purchases dans https://www.webviewgold.com/llms-full.txt et n'utilisez rien qui n'y soit pas documenté. Nos ID produit sont pro_monthly et pro_yearly, l'entitlement est pro.

Commencez par un plan et attendez mon approbation. Le plan doit lister chaque endroit où nous vendons, affichons un prix ou faisons la promotion de quelque chose de numérique (checkout Stripe, page des tarifs, bandeaux de mise à niveau, e-mails avec liens de paiement) et comment chacun se comporte dans l'app.

Implémentez ensuite :
1. src/lib/native.ts : réutilisez isNativeApp() et ajoutez isIOSApp(), basé sur le user agent.
2. Actions du paywall : buyPro(productId) navigue vers revenuecat://purchase avec l'ID de l'utilisateur connecté (encodé pour l'URL) comme external_id. Ne lancez jamais d'achat pour un utilisateur déconnecté ; envoyez-le d'abord vers la connexion. Dans les navigateurs, gardez le flux Stripe existant tel quel.
3. Dans l'app, masquez chaque bouton Stripe, chaque prix web et chaque lien de paiement externe. Ne mentionnez pas de prix web moins chers.
4. Le paywall affiche le nom de la formule, la durée, le prix par période, le fait que l'abonnement se renouvelle automatiquement jusqu'à résiliation, et des liens vers /terms et /privacy. Sur iOS, privilégiez launchPaywall, qui affiche les prix du store. Là où nous affichons notre propre paywall, lisez la vitrine du store avec getstorelocation:// (window.storeLocation) et prenez les prix dans une table par vitrine dans src/config/prices.ts.
5. Un bouton Restaurer les achats (restoreinapppurchases://) et un lien Gérer l'abonnement (cancelinapppurchase://) dans les réglages et sur le paywall, uniquement dans l'app.
6. POST /api/webhooks/revenuecat : comparez l'en-tête Authorization avec REVENUECAT_WEBHOOK_AUTH, lisez event.type, event.app_user_id, event.product_id, event.expiration_at_ms, event.environment et event.store, et faites un upsert d'une ligne entitlements (user_id, entitlement, product_id, store, expires_at, will_renew, sandbox). CANCELLATION signifie seulement que le renouvellement automatique est désactivé ; l'accès dure jusqu'à expires_at. Ajoutez la migration.
7. GET /api/me/entitlement indique si l'utilisateur a pro en ce moment. Après le lancement d'un achat, interrogez cet endpoint toutes les 4 secondes pendant une minute au maximum, et de nouveau sur visibilitychange, puis débloquez l'interface. Le webhook est la seule source de vérité ; ne débloquez jamais à partir d'un état côté client.
8. Créez .claude/commands/iap-check.md : une commande slash qui cherche, dans les composants affichés dans l'app, les appels Stripe, les liens de checkout et les prix codés en dur, et signale tout ce qui entrerait en conflit avec la guideline Apple 3.1.1.

Terminez par les variables d'environnement, les réglages du dashboard RevenueCat que je dois saisir et un plan de test.

La route du webhook qui gère vos droits d'accès

RevenueCat envoie avec chaque événement la valeur d'en-tête Authorization que vous avez saisie dans son dashboard. app_user_id est l'external_id transmis par votre bouton : c'est pourquoi il doit s'agir de votre ID utilisateur stable.

typescript
// app/api/webhooks/revenuecat/route.ts
import { NextResponse } from "next/server";
import { db } from "@/lib/server";

const GRANTS = new Set(["INITIAL_PURCHASE", "RENEWAL", "PRODUCT_CHANGE", "UNCANCELLATION", "NON_RENEWING_PURCHASE"]);

export async function POST(req: Request) {
  // La valeur que vous avez saisie dans RevenueCat -> Integrations -> Webhooks -> Authorization header
  if (req.headers.get("authorization") !== process.env.REVENUECAT_WEBHOOK_AUTH) {
    return NextResponse.json({ error: "unauthorized" }, { status: 401 });
  }
  const { event } = await req.json();
  const userId: string | undefined = event?.app_user_id;
  if (!userId || userId.startsWith("$RCAnonymousID")) {
    return NextResponse.json({ ok: true, skipped: "no user id" }); // achat sans external_id
  }

  const base = {
    userId,
    entitlement: "pro",
    productId: event.product_id,
    store: event.store,                      // APP_STORE ou PLAY_STORE
    sandbox: event.environment === "SANDBOX",
  };
  const expiresAt = event.expiration_at_ms ? new Date(event.expiration_at_ms) : null;

  if (GRANTS.has(event.type)) {
    await db.entitlements.upsert({ ...base, expiresAt, willRenew: true });
  } else if (event.type === "CANCELLATION" || event.type === "BILLING_ISSUE") {
    // Renouvellement auto désactivé ou paiement échoué : garder l'accès jusqu'à l'expiration signalée par le store
    await db.entitlements.upsert({ ...base, expiresAt, willRenew: false });
  } else if (event.type === "EXPIRATION") {
    await db.entitlements.upsert({ ...base, expiresAt: new Date(), willRenew: false });
  }
  // Les événements TRANSFER contiennent plutôt transferred_from / transferred_to ; gérez-les si vous autorisez les changements de compte
  return NextResponse.json({ ok: true });
}

Checklist de vérification (sandbox, vrais appareils)

  • iOS : installez le build TestFlight et achetez. Les achats TestFlight passent par la sandbox et ne sont pas facturés ; les abonnements s'y renouvellent une fois par jour, jusqu'à six fois. Pour tester plus vite les renouvellements et l'expiration, connectez-vous avec un compte Apple sandbox (App Store Connect → Users and Access → Sandbox), dont la fréquence de renouvellement est réglable.
  • Android : ajoutez votre compte Gmail sous Play Console → Setup → License testing, installez l'app depuis le canal de test interne (pas un APK installé à la main) et achetez ; les achats de test ne sont pas facturés.
  • Dans RevenueCat, basculez le dashboard sur les données sandbox et retrouvez le client grâce à votre ID utilisateur. Si l'achat apparaît plutôt sous un ID anonyme, external_id était vide.
  • Votre table entitlements contient une ligne avec sandbox = true, et l'app débloque pro en quelques secondes sans rechargement manuel.
  • Supprimez l'app, réinstallez-la, connectez-vous, touchez Restaurer les achats : l'accès revient. Touchez Gérer l'abonnement : l'écran d'abonnement du store s'ouvre.
  • Ouvrez le site web dans un navigateur desktop avec le même compte : pro y est aussi débloqué, et Stripe est toujours proposé aux visiteurs web.
  • Lancez /iap-check dans Claude Code : aucun bouton Stripe, lien de checkout ou prix web n'est accessible dans l'app.

Pièges

  • Un external_id instable. Transmettez l'ID utilisateur de votre base de données, pas une adresse e-mail susceptible de changer. Exigez la connexion avant le paywall : les clients RevenueCat et vos comptes restent ainsi en correspondance un pour un.
  • Des prix codés en dur. Les prix des stores varient selon les pays et changent avec les taxes. Préférez le paywall RevenueCat sur iOS, et gardez toute table par vitrine synchronisée avec les stores.
  • Prendre CANCELLATION pour la fin. Cet événement désactive seulement le renouvellement automatique. Retirez l'accès sur EXPIRATION ou quand expires_at est dépassé.
  • Des sessions effacées. Avec deletecache (iOS) ou CLEAR_CACHE_ON_STARTUP (Android) sur true, les utilisateurs sont déconnectés à chaque lancement et votre bouton n'a aucun ID utilisateur à envoyer.
  • Stripe qui s'infiltre dans l'app. Une page des tarifs accessible depuis un lien du pied de page, un e-mail de mise à niveau qui s'ouvre dans l'app, une page de confirmation du checkout : chacun représente un risque au regard de la 3.1.1. C'est à cela que sert la commande slash.

Questions fréquentes

Dois-je forcément utiliser RevenueCat ?

Non. WebViewGold propose aussi une API manuelle (inapppurchase:// et inappsubscription:// avec des URL de succès et d'expiration, plus les variables injectées planID, transactionIdentifier et subreceipts). RevenueCat est le choix par défaut parce qu'il vous donne un seul entitlement et un seul webhook pour les deux stores.

Puis-je garder Stripe pour mon site web ?

Oui. Les visiteurs dans le navigateur gardent le checkout Stripe. Les deux sources écrivent dans la même table des droits : un utilisateur qui a payé sur le web est donc aussi pro dans l'app, tant que l'app ne fait pas la promotion de l'achat sur le web.

Qu'en est-il des règles américaines sur les liens de paiement externes ?

Les guidelines actuelles d'Apple autorisent les boutons et liens vers d'autres moyens de paiement pour les apps de la vitrine des États-Unis, et Google a modifié sa politique américaine après le jugement Epic. Les règles diffèrent selon les régions et évoluent sans cesse : lisez le texte actuel des guidelines et des politiques avant de bâtir dessus.

Claude Code a-t-il besoin de mes secrets RevenueCat ?

Non. Les clés SDK publiques de Config.swift et Config.java sont conçues pour être livrées dans l'app. La valeur Authorization du webhook et les clés de base de données vivent dans les variables d'environnement de votre hébergeur ; ne donnez à l'agent que leurs noms.

Comment la web app sait-elle qu'un achat a réussi ?

La documentation ne définit pas de callback de succès pour revenuecat://purchase : considérez donc le webhook comme la source de vérité. Après le lancement d'un achat, l'app interroge brièvement votre endpoint de droits et débloque l'accès dès que la ligne apparaît.

Trois façons de mettre votre app dans les stores

Même résultat, charge de travail différente de votre côté. Les trois formules incluent la garantie d'approbation et le support humain 24/7.

Faites-le vous-même

$109 par plateforme, paiement unique

La licence WebViewGold : un projet Xcode ou Android Studio prêt à l'emploi. Collez votre URL, définissez le nom et l'icône, activez les fonctionnalités, compilez et soumettez. Mises à jour gratuites à vie.

Voir les offres sur la page principale

Full Service

$698 par plateforme $798

Envoyez-nous votre URL et votre icône. Notre équipe configure, compile et livre votre app sous 72 heures, en marque blanche, projets sources inclus. Les deux plateformes pour $1,158.

Détails du Full Service Propulsé par WeSetupYourWebViewApp

Prix Soldes d'hiver valables jusqu'au 31 décembre 2026.

Prêt à publier votre app ?

Garantie d'approbation App Store & Google Play – ou remboursement sous 14 jours

Vous préférez déléguer ? Full Service : nous configurons, compilons et livrons sous 72 heures, dès $698 par plateforme. Des questions ? Chattez avec nous 24/7.

Les remboursements sont accordés aux conditions indiquées dans notre FAQ : un refus non lié au contenu par Apple et/ou Google, demandé dans les 14 jours suivant l'achat.