Retour aux guides
StripeIntermédiaire45 minutes

Suivi d'affiliation Stripe avec RefCampaign

Connectez Stripe Checkout, subscriptions et paiements uniques à RefCampaign pour attribuer les conversions payées.

3 min de lecture

Stripe peut transporter l'attribution RefCampaign via les metadata. Le détail important est l'emplacement de ces metadata : metadata de subscription pour le revenu récurrent, metadata de Payment Intent pour les paiements uniques.

Ce guide suppose que votre frontend capture déjà la session RefCampaign avec le SDK navigateur ou le script CDN.

Prérequis

  • Un compte Stripe avec Checkout activé.
  • Une clé secrète RefCampaign.
  • Le package @refcampaign/sdk installé côté backend.
  • Une route serveur qui crée les sessions Stripe Checkout.
pnpm add @refcampaign/sdk stripe

Stockez les secrets uniquement côté serveur :

REFCAMPAIGN_SECRET_KEY=sk_live_votre_secret_refcampaign
STRIPE_SECRET_KEY=sk_live_votre_secret_stripe
APP_URL=https://votreapp.com

Initialiser le SDK serveur

Créez un petit module importable par vos routes checkout.

// lib/billing.ts
import Stripe from 'stripe'
import { RefCampaignServer } from '@refcampaign/sdk'

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)
export const refcampaign = new RefCampaignServer(
  process.env.REFCAMPAIGN_SECRET_KEY!
)

Checkout subscription

Pour les produits récurrents, placez les metadata RefCampaign sur subscription_data.metadata. Les renouvellements pourront continuer à créditer le même affilié.

// app/api/stripe/checkout-subscription/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { refcampaign, stripe } from '@/lib/billing'

export async function POST(request: NextRequest) {
  const { priceId, customerEmail } = await request.json()
  const sessionId = request.cookies.get('_rc_sid')?.value

  const session = await stripe.checkout.sessions.create({
    mode: 'subscription',
    customer_email: customerEmail,
    line_items: [{ price: priceId, quantity: 1 }],
    subscription_data: {
      metadata: refcampaign.getStripeMetadata(sessionId),
    },
    success_url: `${process.env.APP_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.APP_URL}/pricing`,
  })

  return NextResponse.json({ url: session.url })
}

Checkout paiement unique

Pour les produits payés une seule fois, placez les metadata sur payment_intent_data.metadata.

// app/api/stripe/checkout-payment/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { refcampaign, stripe } from '@/lib/billing'

export async function POST(request: NextRequest) {
  const { priceId, customerEmail } = await request.json()
  const sessionId = request.cookies.get('_rc_sid')?.value

  const session = await stripe.checkout.sessions.create({
    mode: 'payment',
    customer_email: customerEmail,
    line_items: [{ price: priceId, quantity: 1 }],
    payment_intent_data: {
      metadata: refcampaign.getStripeMetadata(sessionId),
    },
    success_url: `${process.env.APP_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.APP_URL}/pricing`,
  })

  return NextResponse.json({ url: session.url })
}

Vérifier la couverture webhook

RefCampaign traite les revenus Stripe via votre intégration marchand. Votre rôle est de vérifier que les metadata existent avant que Stripe émette l'événement payé.

Utilisez Stripe CLI pour inspecter un checkout de test :

stripe listen --forward-to localhost:3000/api/webhooks/stripe
stripe trigger checkout.session.completed

Pour un vrai test manuel, créez un checkout depuis votre UI après avoir cliqué un lien affilié. Dans le dashboard Stripe :

  • ouvrez la Checkout Session ;
  • ouvrez la Subscription ou le Payment Intent ;
  • vérifiez que refcampaign_session apparaît dans les metadata.

Gérer les sessions absentes

Tous les acheteurs ne viennent pas d'un affilié. getStripeMetadata() peut être appelé avec une session ID absente, et le checkout doit continuer normalement.

const metadata = refcampaign.getStripeMetadata(sessionId)

const subscriptionData =
  Object.keys(metadata).length > 0
    ? { metadata }
    : undefined

Utilisez ce pattern si votre helper Stripe refuse les objets metadata vides.

Erreurs fréquentes

Ne placez pas l'attribution subscription uniquement sur les metadata Customer. Les metadata Customer sont partagées entre achats futurs et peuvent créditer le mauvais affilié quand un client se réabonne plus tard.

N'attachez pas l'attribution d'un paiement unique uniquement à la Checkout Session. RefCampaign a besoin des metadata sur l'objet Stripe qui représente l'événement payé.

Ne loggez pas les clés secrètes RefCampaign ni les payloads Stripe complets en production. Les metadata peuvent être inspectées, les secrets non.

Étapes suivantes

Associez cette configuration au guide Next.js affiliate tracking si votre checkout vit dans App Router. Pour le contexte plus large, lisez comment fonctionne le suivi d'affiliation et gardez la référence SDK sous la main pendant la review.