Aller au contenu principal

Commerce : vendre dans ChatGPT

Intégrer les paiements dans votre application

Le pilier Commerce du Apps SDK vous permet de monétiser votre application directement dans ChatGPT. Les utilisateurs achètent sans quitter la conversation, ce qui réduit considérablement la friction et augmente les conversions.

Configurer le Commerce

Avant de vendre quoi que ce soit, vous devez activer le commerce dans votre manifest et configurer votre compte vendeur.

{
  "name": "Mon App Commerce",
  "slug": "mon-app-commerce",
  "permissions": ["actions", "widgets", "commerce"],
  "commerce": {
    "stripeAccountId": "${STRIPE_CONNECT_ID}",
    "currency": "EUR",
    "taxHandling": "inclusive"
  }
}

Prérequis

  • Un compte Stripe Connect vérifié (OpenAI utilise Stripe en backend)
  • Les informations fiscales de votre entreprise renseignées
  • L’activation du module Commerce dans le portail développeur

Définir des produits

Les produits sont déclarés dans votre code et synchronisés avec le Store :

import { defineProduct } from "@openai/apps-sdk";

export const premiumPlan = defineProduct({
  id: "premium-monthly",
  name: "Premium Mensuel",
  description: "Accès illimité à toutes les fonctionnalités avancées",
  type: "subscription",
  pricing: {
    amount: 990, // en centimes
    currency: "EUR",
    interval: "month",
  },
  features: [
    "Analyses illimitées",
    "Export PDF et CSV",
    "Support prioritaire",
    "Accès API",
  ],
  trialDays: 7,
});

export const singleReport = defineProduct({
  id: "single-report",
  name: "Rapport Détaillé",
  description: "Analyse complète avec recommandations personnalisées",
  type: "one_time",
  pricing: {
    amount: 1490,
    currency: "EUR",
  },
});

Le flux d’achat

Le SDK gère le tunnel de paiement de bout en bout :

import { commerceFlow } from "@openai/apps-sdk";

app.action("purchaseReport", {
  description: "Lance l'achat d'un rapport détaillé pour l'utilisateur",
  parameters: {
    reportType: { type: "string", required: true },
  },
  handler: async ({ reportType }, context) => {
    // 1. Vérifier si déjà acheté
    const existing = await checkPurchase(context.user.id, reportType);
    if (existing) {
      return { alreadyPurchased: true, reportUrl: existing.url };
    }

    // 2. Déclencher le flux de paiement
    const checkout = await commerceFlow.createCheckout({
      productId: "single-report",
      userId: context.user.id,
      metadata: { reportType },
    });

    // 3. Retourner le widget de paiement
    return {
      _widget: "checkoutWidget",
      checkoutId: checkout.id,
      product: "Rapport Détaillé",
      amount: "14,90 €",
    };
  },
});

Widget de paiement intégré

Le SDK fournit un composant de paiement natif sécurisé :

export const checkoutWidget = defineWidget({
  name: "checkoutWidget",
  render: (data) => ({
    type: "card",
    title: "Finaliser votre achat",
    content: [
      { type: "text", value: data.product, style: "heading" },
      { type: "metric", label: "Total", value: data.amount },
      {
        type: "payment",
        checkoutId: data.checkoutId,
        methods: ["card", "apple_pay", "google_pay"],
        onSuccess: "paymentConfirmed",
        onCancel: "paymentCancelled",
      },
    ],
  }),
});

Gérer les abonnements

Pour les modèles par abonnement, le SDK fournit des outils de gestion complets :

app.action("manageSubscription", {
  description: "Affiche le statut et les options de gestion de l'abonnement",
  handler: async (_, context) => {
    const sub = await commerceFlow.getSubscription(context.user.id);

    if (!sub) {
      return { status: "none", _widget: "pricingTable" };
    }

    return {
      _widget: "subscriptionManager",
      status: sub.status,
      plan: sub.productId,
      currentPeriodEnd: sub.currentPeriodEnd,
      cancelAtPeriodEnd: sub.cancelAtPeriodEnd,
    };
  },
});

Webhooks de paiement

Votre serveur reçoit des notifications pour chaque événement de paiement :

app.webhook("commerce", async (event) => {
  switch (event.type) {
    case "checkout.completed":
      await activateAccess(event.userId, event.productId);
      break;
    case "subscription.renewed":
      await extendAccess(event.userId, event.productId);
      break;
    case "subscription.cancelled":
      await scheduleAccessRevocation(event.userId, event.endDate);
      break;
    case "refund.processed":
      await revokeAccess(event.userId, event.productId);
      break;
  }
});

Vérifier les droits d’accès

Dans vos actions, vérifiez que l’utilisateur a le bon niveau d’accès :

app.action("generateAdvancedReport", {
  description: "Génère un rapport avancé (fonctionnalité Premium)",
  parameters: {
    topic: { type: "string", required: true },
  },
  handler: async ({ topic }, context) => {
    // Vérifier l'abonnement
    const hasAccess = await commerceFlow.checkEntitlement(
      context.user.id,
      "premium-monthly"
    );

    if (!hasAccess) {
      return {
        _widget: "upgradePrompt",
        message: "Cette fonctionnalité nécessite un abonnement Premium",
        productId: "premium-monthly",
      };
    }

    // Générer le rapport
    const report = await generateReport(topic);
    return { _widget: "reportView", ...report };
  },
});

Commission OpenAI

OpenAI prélève une commission sur chaque transaction :

Type Commission OpenAI Vous recevez
Achat ponctuel 30 % 70 %
Abonnement (année 1) 30 % 70 %
Abonnement (année 2+) 15 % 85 %

Points clés à retenir

  • Le Commerce SDK gère paiements ponctuels, abonnements et essais gratuits
  • Stripe Connect est utilisé en backend — configurez votre compte vendeur
  • Le widget de paiement natif gère carte, Apple Pay et Google Pay
  • Les webhooks vous notifient de chaque événement transactionnel
  • Vérifiez les droits d’accès dans chaque action premium avec checkEntitlement
  • OpenAI prélève 30 % la première année, 15 % ensuite