Monétisez votre chaîne
à votre façon

Connectez Stripe, PayPal, Patreon, ou tout autre fournisseur de paiement. Nous gérons les codes d'accès et l'envoi des emails. Vous conservez 100% des revenus.

Fournisseurs de paiement supportés

Choisissez le fournisseur de paiement que vous utilisez déjà. Nous nous y connectons, générons automatiquement les codes d'accès, et envoyons à vos clients leur lien personnel par email.

Paiement direct — nous hébergeons une page de paiement pour vous

Stripe

Acceptez les cartes, Apple Pay, Google Pay. Nous créons des sessions Stripe Checkout avec votre clé API.

Paiement hébergé

Revolut Business

Acceptez les paiements via Revolut checkout. Mise en place rapide, multi-devises.

Paiement hébergé

PayPal

Acceptez les paiements PayPal. Les acheteurs paient avec leur compte PayPal ou leur carte bancaire.

Paiement hébergé

Plateformes de créateurs — ils gèrent le paiement, nous gérons l'accès

Patreon

Les patrons obtiennent automatiquement l'accès lorsqu'ils souscrivent à votre palier minimum.

Webhook

Gumroad

Vendez l'accès comme un produit Gumroad. Les acheteurs reçoivent leur lien après l'achat.

Webhook

LemonSqueezy

Vendez l'accès via votre boutique LemonSqueezy. Gère les taxes et les paiements.

Webhook

Ko-fi

Les supporters qui vous offrent un "café" ou rejoignent votre abonnement obtiennent l'accès à la chaîne.

Webhook

Buy Me a Coffee

Les supporters et les membres reçoivent automatiquement l'accès à votre chaîne.

Webhook

Vous conservez 100% des revenus. Nous ne touchons jamais à votre argent. Les paiements vont directement sur votre compte chez le fournisseur de votre choix. Nous ne faisons que générer les codes d'accès et envoyer le lien par email.

Connectez votre fournisseur

Connectez-vous, choisissez votre fournisseur de paiement, entrez vos identifiants API, et nous vous donnons soit un lien de paiement (pour Stripe/Revolut/PayPal), soit une URL webhook (pour Patreon/Gumroad/etc.).

1

Connectez-vous ci-dessous

Utilisez le même compte Apple que dans l'application My TV Channel.

2

Choisissez le fournisseur et entrez vos clés

Sélectionnez votre fournisseur de paiement et entrez votre clé API ou secret webhook. Définissez le prix et la durée.

3

Partagez votre lien

Obtenez un lien de paiement à partager avec votre audience, ou collez l'URL webhook dans les paramètres de votre fournisseur.

Connectez votre fournisseur de paiement

Connectez-vous avec le même compte Apple que celui utilisé dans l'application.

Sign in with Apple

Où trouver votre clé API Stripe : Allez sur le Tableau de bord Stripe → Développeurs → Clés API → copiez votre Clé secrète (commence par sk_live_).

Ce que vos clients recevront

Après un paiement réussi, votre client reçoit un email avec son lien d'accès personnel :

Votre accès est prêt

Merci pour votre achat ! Vous avez maintenant accès à Nom de votre chaîne.

Regarder maintenant

Ce lien est personnel. Il vous donne 30 jours d'accès.

Pour les développeurs

Comment ça marche

Vous gérez le paiement. Nous gérons l'accès. Quand un client vous paie (via votre site web, Stripe, Patreon, ou toute autre méthode), votre serveur appelle notre API pour générer un code d'accès unique. Vous transmettez ce code à votre client sous forme de lien.

1

Le client vous paie

Sur votre site web, Patreon, ou tout autre système de paiement de votre choix.

2

Votre serveur appelle notre API

Générez un code abonné avec l'expiration et les limites de votre choix.

3

Le client reçoit un lien

Comme https://your-channel.localtvbroadcast.com/?subscriber=ABC2DEF

4

Le client regarde

S'ouvre dans l'application (avec accès accordé) ou se lit directement dans le navigateur web.

Vous conservez 100% des revenus. Nous ne traitons pas les paiements et ne prenons aucune commission. Les codes abonnés donnent simplement accès à votre chaîne dans My TV Channel.

Authentification

Tous les appels API éditeur nécessitent un token JWT. Obtenez-en un en vous connectant avec votre compte My TV Channel :

# Connectez-vous pour obtenir votre token JWT
curl -X POST https://localtvbroadcast.com/api/mytvchannel/auth/login.php \
  -H "Content-Type: application/json" \
  -d '{
    "email": "you@example.com",
    "password": "your-password"
  }'

La réponse inclut un champ token. Utilisez-le dans toutes les requêtes suivantes :

Authorization: Bearer YOUR_JWT_TOKEN

Gardez votre token en sécurité. Stockez-le comme variable d'environnement côté serveur. Ne l'exposez jamais dans du code côté client ou des dépôts publics.

URL de base

Tous les endpoints API utilisent l'URL de base suivante :

https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/

Générer un code

POST /subscriber-codes/generate.php

Créez un nouveau code d'accès abonné pour votre chaîne. Nécessite l'authentification et la propriété de la chaîne.

Corps de la requête

ChampTypeRequisDescription
channel_idintegerrequisL'identifiant de votre chaîne
expires_atstringrequisDate ISO 8601 à laquelle le code cesse d'accepter de nouvelles utilisations
labelstringoptionnelLibellé interne (ex. "Pass Mensuel VIP")
pricenumberoptionnelVotre prix (métadonnées uniquement, nous ne traitons pas le paiement)
currencystringoptionnelCode devise ISO 4217 (par défaut : USD)
max_redemptionsintegeroptionnelNombre max d'utilisations. null = illimité
access_duration_daysintegeroptionnelJours d'accès par utilisation. null = accès jusqu'à expires_at

Exemple

curl -X POST https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/generate.php \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": 42,
    "expires_at": "2026-12-31T23:59:59Z",
    "label": "Monthly Pass - March",
    "price": 9.99,
    "currency": "USD",
    "max_redemptions": 1,
    "access_duration_days": 30
  }'

Réponse

{
  "success": true,
  "message": "Subscriber code generated",
  "data": {
    "id": 1,
    "code": "A3F7K2N",
    "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N",
    "channel_id": 42,
    "label": "Monthly Pass - March",
    "price": 9.99,
    "currency": "USD",
    "max_redemptions": 1,
    "expires_at": "2026-12-31T23:59:59+00:00",
    "access_duration_days": 30
  }
}

Codes à usage unique vs. multi-usage : Définissez max_redemptions: 1 pour un code unique par client. Définissez-le à null pour un code promo partagé utilisable par tous.

Durée d'accès expliquée

Deux modèles sont supportés :

Scénarioaccess_duration_daysComportement
Pass à durée limitée30Chaque spectateur obtient 30 jours à partir du moment où il utilise le code
Pass événementnullTous les spectateurs ont accès jusqu'à la date expires_at du code

Lister les codes

GET /subscriber-codes/list.php?channel_id={id}

Récupérez tous les codes abonnés de votre chaîne, avec les statistiques d'utilisation.

Exemple

curl https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/list.php?channel_id=42 \
  -H "Authorization: Bearer YOUR_TOKEN"

Réponse

{
  "success": true,
  "data": {
    "codes": [
      {
        "id": 1,
        "code": "A3F7K2N",
        "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N",
        "label": "Monthly Pass - March",
        "price": 9.99,
        "currency": "USD",
        "max_redemptions": 1,
        "redemption_count": 0,
        "expires_at": "2026-12-31T23:59:59+00:00",
        "access_duration_days": 30,
        "is_active": true,
        "created_at": "2026-02-21 14:00:00"
      }
    ]
  }
}

Révoquer un code

POST /subscriber-codes/revoke.php

Désactivez un code abonné. Le code n'acceptera plus de nouvelles utilisations. L'accès déjà accordé reste valide jusqu'à sa propre expiration.

Corps de la requête

ChampTypeRequisDescription
code_idintegerrequisL'identifiant du code à révoquer (issu de la réponse generate ou list)

Exemple

curl -X POST https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/revoke.php \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "code_id": 1 }'

Utiliser un code (App)

POST /subscriber-codes/redeem.php

Utilisé par l'application My TV Channel lorsqu'un spectateur ouvre un lien universel. Nécessite l'authentification de l'utilisateur. Idempotent — réutiliser le même code renvoie l'accès existant.

Corps de la requête

ChampTypeRequisDescription
codestringrequisLe code abonné de 7 caractères

Réponse

{
  "success": true,
  "message": "Access granted",
  "data": {
    "channel": {
      "id": 42,
      "handle": "your-channel",
      "name": "Your Channel",
      "description": "...",
      "thumbnail_url": "..."
    },
    "access_expires_at": "2026-04-21T14:00:00+00:00",
    "already_redeemed": false
  }
}

Note : Cet endpoint est appelé automatiquement par l'application. Vous n'avez pas besoin de l'appeler depuis votre serveur.

Valider un code (Lecteur Web)

POST /subscriber-codes/validate.php

Utilisé par le lecteur web pour valider un code abonné avant de lancer la lecture. Aucune authentification requise. Appelé automatiquement lorsqu'un spectateur ouvre un lien de chaîne avec ?subscriber=.

Corps de la requête

ChampTypeRequisDescription
codestringrequisLe code abonné de 7 caractères
channel_idintegerrequisIdentifiant de la chaîne à valider

Note : Cet endpoint est appelé automatiquement par le lecteur web. Vous n'avez pas besoin de l'appeler depuis votre serveur.

Intégration Stripe

Générez automatiquement un code abonné lorsqu'un paiement Stripe réussit. Ajoutez ce gestionnaire de webhook à votre serveur :

// Express.js webhook handler for Stripe
const express = require('express');
const stripe = require('stripe')('sk_...');

const MY_TV_API = 'https://localtvbroadcast.com/api/mytvchannel';
const MY_TV_TOKEN = process.env.MY_TV_TOKEN;  // Your JWT token
const CHANNEL_ID = 42;  // Your channel ID

app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const event = stripe.webhooks.constructEvent(req.body, sig, 'whsec_...');

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;

    // Generate a subscriber code
    const resp = await fetch(`${MY_TV_API}/subscriber-codes/generate.php`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${MY_TV_TOKEN}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        channel_id: CHANNEL_ID,
        expires_at: '2027-01-01T00:00:00Z',
        label: `Stripe ${session.id}`,
        price: session.amount_total / 100,
        currency: session.currency.toUpperCase(),
        max_redemptions: 1,
        access_duration_days: 30
      })
    });

    const { data } = await resp.json();

    // Send the link to your customer
    await sendEmail(session.customer_email, {
      subject: 'Your access link',
      body: `Watch here: ${data.url}`
    });
  }

  res.json({ received: true });
});
# Flask webhook handler for Stripe
import stripe, requests, os
from flask import Flask, request, jsonify

app = Flask(__name__)
stripe.api_key = 'sk_...'

MY_TV_API = 'https://localtvbroadcast.com/api/mytvchannel'
MY_TV_TOKEN = os.environ['MY_TV_TOKEN']
CHANNEL_ID = 42

@app.route('/webhooks/stripe', methods=['POST'])
def stripe_webhook():
    sig = request.headers['Stripe-Signature']
    event = stripe.Webhook.construct_event(request.data, sig, 'whsec_...')

    if event['type'] == 'checkout.session.completed':
        session = event['data']['object']

        # Generate a subscriber code
        resp = requests.post(
            f'{MY_TV_API}/subscriber-codes/generate.php',
            headers={
                'Authorization': f'Bearer {MY_TV_TOKEN}',
                'Content-Type': 'application/json'
            },
            json={
                'channel_id': CHANNEL_ID,
                'expires_at': '2027-01-01T00:00:00Z',
                'label': f'Stripe {session["id"]}',
                'price': session['amount_total'] / 100,
                'currency': session['currency'].upper(),
                'max_redemptions': 1,
                'access_duration_days': 30
            }
        )

        url = resp.json()['data']['url']
        send_email(session['customer_email'], f'Watch here: {url}')

    return jsonify(received=True)
// PHP webhook handler for Stripe
<?php
$payload = file_get_contents('php://input');
$sig = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = \Stripe\Webhook::constructEvent($payload, $sig, 'whsec_...');

$myTvApi = 'https://localtvbroadcast.com/api/mytvchannel';
$myTvToken = getenv('MY_TV_TOKEN');
$channelId = 42;

if ($event->type === 'checkout.session.completed') {
    $session = $event->data->object;

    // Generate a subscriber code
    $ch = curl_init("{$myTvApi}/subscriber-codes/generate.php");
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer {$myTvToken}",
            'Content-Type: application/json'
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'channel_id' => $channelId,
            'expires_at' => '2027-01-01T00:00:00Z',
            'label' => "Stripe {$session->id}",
            'price' => $session->amount_total / 100,
            'currency' => strtoupper($session->currency),
            'max_redemptions' => 1,
            'access_duration_days' => 30
        ])
    ]);

    $resp = json_decode(curl_exec($ch));
    curl_close($ch);

    // Send the link to your customer
    mail($session->customer_email, 'Your access link', "Watch here: {$resp->data->url}");
}

http_response_code(200);
echo json_encode(['received' => true]);

Intégration Patreon (auto-hébergée)

Si vous préférez exécuter votre propre gestionnaire de webhook plutôt que d'utiliser notre intégration hébergée, voici comment gérer l'événement members:pledge:create sur votre serveur :

// Node.js - Patreon webhook handler
const crypto = require('crypto');

app.post('/webhooks/patreon', express.json(), async (req, res) => {
  // Verify Patreon signature
  const signature = req.headers['x-patreon-signature'];
  const hash = crypto
    .createHmac('md5', process.env.PATREON_WEBHOOK_SECRET)
    .update(JSON.stringify(req.body))
    .digest('hex');

  if (signature !== hash) return res.status(403).send('Invalid signature');

  const event = req.headers['x-patreon-event'];
  const { data, included } = req.body;

  if (event === 'members:pledge:create') {
    const patron = included.find(i => i.type === 'user');
    const email = patron?.attributes?.email;
    const amountCents = data.attributes.currently_entitled_amount_cents;

    // Only grant access for tiers >= $5
    if (amountCents >= 500) {
      const resp = await fetch(
        'https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/generate.php',
        {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${process.env.MY_TV_TOKEN}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            channel_id: 42,
            expires_at: '2027-01-01T00:00:00Z',
            label: `Patreon: ${email}`,
            max_redemptions: 1,
            access_duration_days: 30
          })
        }
      );

      const { data: codeData } = await resp.json();

      // Send via Patreon message or your own email service
      await sendEmail(email, {
        subject: 'Your TV Channel access is ready!',
        body: `Thanks for your support! Watch here: ${codeData.url}`
      });
    }
  }

  res.json({ received: true });
});

Webhook générique / Paiement personnalisé

Pour tout système de paiement avec webhooks (PayPal, Gumroad, LemonSqueezy, Ko-fi, Buy Me a Coffee, etc.), le schéma est le même :

1

Recevez le webhook de paiement

Vérifiez la signature du webhook selon la documentation de votre fournisseur.

2

Appelez l'endpoint generate

POST /subscriber-codes/generate.php avec votre token JWT.

3

Transmettez le lien

Envoyez data.url à votre client par email, redirection, ou message in-app.

Exemple cURL minimal

# Generate a single-use code valid for 30 days of access
curl -X POST https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/generate.php \
  -H "Authorization: Bearer $MY_TV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": 42,
    "expires_at": "2027-01-01T00:00:00Z",
    "max_redemptions": 1,
    "access_duration_days": 30
  }'

# Response includes the link to share:
# "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N"

Gestion des erreurs

Statut HTTPSignification
200Succès
400Champs manquants ou invalides (consultez message pour les détails)
401Token JWT invalide ou expiré
403La chaîne n'appartient pas à l'utilisateur authentifié
404Code abonné invalide ou expiré (redeem/validate)
500Erreur serveur (réessayez)