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.
Sans code
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.
Gumroad
Vendez l'accès comme un produit Gumroad. Les acheteurs reçoivent leur lien après l'achat.
LemonSqueezy
Vendez l'accès via votre boutique LemonSqueezy. Gère les taxes et les paiements.
Ko-fi
Les supporters qui vous offrent un "café" ou rejoignent votre abonnement obtiennent l'accès à la chaîne.
Buy Me a Coffee
Les supporters et les membres reçoivent automatiquement l'accès à votre chaîne.
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.
Mise en place
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.).
Connectez-vous ci-dessous
Utilisez le même compte Apple que dans l'application My TV Channel.
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.
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.
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 maintenantCe lien est personnel. Il vous donne 30 jours d'accès.
Aperçu
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.
Le client vous paie
Sur votre site web, Patreon, ou tout autre système de paiement de votre choix.
Votre serveur appelle notre API
Générez un code abonné avec l'expiration et les limites de votre choix.
Le client reçoit un lien
Comme https://your-channel.localtvbroadcast.com/?subscriber=ABC2DEF
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.
Pour commencer
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/
Référence API
Générer un code
/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
| Champ | Type | Requis | Description |
|---|---|---|---|
| channel_id | integer | requis | L'identifiant de votre chaîne |
| expires_at | string | requis | Date ISO 8601 à laquelle le code cesse d'accepter de nouvelles utilisations |
| label | string | optionnel | Libellé interne (ex. "Pass Mensuel VIP") |
| price | number | optionnel | Votre prix (métadonnées uniquement, nous ne traitons pas le paiement) |
| currency | string | optionnel | Code devise ISO 4217 (par défaut : USD) |
| max_redemptions | integer | optionnel | Nombre max d'utilisations. null = illimité |
| access_duration_days | integer | optionnel | Jours 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énario | access_duration_days | Comportement |
|---|---|---|
| Pass à durée limitée | 30 | Chaque spectateur obtient 30 jours à partir du moment où il utilise le code |
| Pass événement | null | Tous les spectateurs ont accès jusqu'à la date expires_at du code |
Lister les codes
/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
/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
| Champ | Type | Requis | Description |
|---|---|---|---|
| code_id | integer | requis | L'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)
/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
| Champ | Type | Requis | Description |
|---|---|---|---|
| code | string | requis | Le 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)
/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
| Champ | Type | Requis | Description |
|---|---|---|---|
| code | string | requis | Le code abonné de 7 caractères |
| channel_id | integer | requis | Identifiant 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.
Liens universels
Chaque code correspond à un lien universel qui fonctionne partout :
https://{your-channel-handle}.localtvbroadcast.com/?subscriber={CODE}
Le lien retourné dans la réponse generate est prêt à être partagé. Quand un spectateur clique dessus :
| Scénario | Comportement |
|---|---|
| App installée | Ouvre l'application My TV Channel, accorde l'accès, affiche la chaîne |
| App non installée | Ouvre le lecteur web dans le navigateur, valide le code, lance la lecture |
Les codes sont insensibles à la casse. A3F7K2N et a3f7k2n sont traités de manière identique. Les codes n'utilisent que les caractères 2346789ACDEFGHJKMNPQRTUVWXYZ pour éviter les ambiguïtés (pas de 0/O, 1/I/L, 5/S, 8/B).
Intégrations
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 :
Recevez le webhook de paiement
Vérifiez la signature du webhook selon la documentation de votre fournisseur.
Appelez l'endpoint generate
POST /subscriber-codes/generate.php avec votre token JWT.
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 HTTP | Signification |
|---|---|
| 200 | Succès |
| 400 | Champs manquants ou invalides (consultez message pour les détails) |
| 401 | Token JWT invalide ou expiré |
| 403 | La chaîne n'appartient pas à l'utilisateur authentifié |
| 404 | Code abonné invalide ou expiré (redeem/validate) |
| 500 | Erreur serveur (réessayez) |