
Ce guide ajoute RefCampaign à une app Next.js avec le SDK npm. Votre CMP active ou refuse explicitement l'attribution navigateur, puis votre route checkout transmet une session RefCampaign consentie dans les metadata Stripe.

Utilisez ce chemin si votre app a déjà un frontend Next.js et une route serveur qui crée des sessions Stripe Checkout.

## Prérequis

- Un compte marchand RefCampaign avec une campagne active.
- Une clé publique et une clé secrète RefCampaign depuis le dashboard.
- Un projet Next.js App Router.
- Stripe Checkout déjà installé ou prêt à l'être.

Installez le SDK :

```bash
pnpm add @refcampaign/sdk stripe
```

Ajoutez la clé secrète à l'environnement serveur :

```bash
REFCAMPAIGN_SECRET_KEY=sk_live_votre_secret_refcampaign
STRIPE_SECRET_KEY=sk_live_votre_secret_stripe
NEXT_PUBLIC_APP_URL=https://votreapp.com
```

## Connecter l'attribution navigateur à votre CMP

Créez un composant client près de la racine de l'app. Transmettez-lui le choix d'attribution mémorisé et résolu par votre CMP : `true`, `false`, ou `null` pendant son chargement.

```tsx
// app/refcampaign-client.tsx
'use client'

import { useEffect } from 'react'
import { RefCampaignBrowser } from '@refcampaign/sdk'

export function RefCampaignClient({
  consentementAttribution,
}: {
  consentementAttribution: boolean | null
}) {
  useEffect(() => {
    RefCampaignBrowser.configure({
      siteToken: process.env.NEXT_PUBLIC_REFCAMPAIGN_SITE_TOKEN!,
    })
  }, [])

  useEffect(() => {
    if (consentementAttribution === null) return
    void RefCampaignBrowser.setConsent({
      attribution: consentementAttribution,
    })
  }, [consentementAttribution])

  return null
}
```

Montez-le dans le layout racine afin que chaque landing page reçoive l'état de la CMP. Rejouez le choix mémorisé après chaque rechargement et mettez la prop à jour immédiatement après une acceptation ou un retrait.

```tsx
// app/layout.tsx
import { RefCampaignClient } from './refcampaign-client'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="fr">
      <body>
        <RefCampaignClient consentementAttribution={cmp.consentementAttribution} />
        {children}
      </body>
    </html>
  )
}
```

## Identifier les utilisateurs après inscription ou connexion

Appelez `identify()` uniquement après consentement, dès que votre app connaît l'email utilisateur. RefCampaign hache l'email dans le navigateur et l'attache au clic consenti courant.

```tsx
// app/auth/identify-refcampaign.tsx
'use client'

import { useEffect } from 'react'
import { RefCampaignBrowser } from '@refcampaign/sdk'

type IdentifyRefCampaignProps = {
  email: string | null
}

export function IdentifyRefCampaign({ email }: IdentifyRefCampaignProps) {
  useEffect(() => {
    if (!email) return
    void RefCampaignBrowser.identify(email)
  }, [email])

  return null
}
```

Rendez ce composant après login ou signup, là où votre provider de session expose l'email.

```tsx
<IdentifyRefCampaign email={user.email} />
```

## Créer Stripe Checkout avec les metadata RefCampaign

Votre route checkout doit lire le cookie de session RefCampaign et le passer à `RefCampaignServer.getStripeMetadata()`.

```ts
// app/api/checkout/route.ts
import { NextRequest, NextResponse } from 'next/server'
import Stripe from 'stripe'
import { RefCampaignServer } from '@refcampaign/sdk'

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

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

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

  return NextResponse.json({ url: checkout.url })
}
```

Pour les paiements uniques, placez les metadata sur `payment_intent_data` :

```ts
const checkout = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: [{ price: priceId, quantity: 1 }],
  payment_intent_data: {
    metadata: refcampaign.getStripeMetadata(sessionId),
  },
  success_url: `${process.env.NEXT_PUBLIC_APP_URL}/billing/success`,
  cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing`,
})
```

## Tester en local

Lancez l'app et ouvrez `https://votreapp.com/?ref=fabrice`.

- Refusez l'attribution : aucune requête de capture RefCampaign et aucun cookie `_rc_sid`.
- Acceptez l'attribution : une requête de capture et un cookie propriétaire `_rc_sid` valable 90 jours.
- Rechargez : la CMP doit rejouer l'acceptation mémorisée.
- Retirez le consentement : le cookie doit être supprimé.

Ensuite, créez une session checkout et inspectez l'objet Stripe :

- les subscriptions doivent contenir `metadata.refcampaign_session` ;
- les paiements uniques doivent contenir la même clé sur le Payment Intent ;
- aucun checkout ne doit échouer si `_rc_sid` est absent.

## Erreurs fréquentes

N'attendez pas la page pricing pour transmettre la décision de la CMP. Les affiliés envoient souvent d'abord vers des articles, pages de comparaison ou pages docs.

Ne bloquez pas le checkout quand aucune session RefCampaign n'existe. Les clients directs doivent pouvoir acheter normalement.

Ne placez pas les metadata de subscription sur l'objet Stripe Customer. Un même client peut souscrire plusieurs fois via des parcours affiliés différents, donc les metadata au niveau subscription gardent l'attribution reliée au bon achat.

En cas de refus, ne recréez pas de session navigateur. Les coupons, codes de parrainage explicites et codes affiliés connus indépendamment côté serveur restent des alternatives valides lorsque la commande les contient déjà.

## Étapes suivantes

Lisez le [guide Stripe affiliate tracking](/fr/guides/suivi-affiliation-stripe) pour les détails côté webhook, ou utilisez la [référence SDK](https://docs.refcampaign.com/fr/docs/api/integration/sdk) si vous avez besoin des signatures complètes. Si vous cadrez encore le programme, le [guide de création d'un programme d'affiliation SaaS](/fr/blog/comment-creer-programme-affiliation-saas) couvre les règles de commission et les choix opérationnels.
