Monetizza il tuo canale
A modo tuo
Collega Stripe, PayPal, Patreon o qualsiasi fornitore di pagamento. Noi gestiamo i codici di accesso e l'invio delle email. Mantieni il 100% dei ricavi.
Nessun codice richiesto
Fornitori di pagamento supportati
Scegli il fornitore di pagamento che usi già. Noi lo colleghiamo, generiamo automaticamente i codici di accesso e inviamo ai tuoi clienti il loro link personale via email.
Pagamento diretto — ospitiamo una pagina di checkout per te
Stripe
Accetta carte, Apple Pay, Google Pay. Creiamo sessioni Stripe Checkout con la tua chiave API.
Checkout ospitatoRevolut Business
Accetta pagamenti tramite checkout Revolut. Configurazione rapida, supporta più valute.
Checkout ospitatoPayPal
Accetta pagamenti PayPal. Gli acquirenti pagano con il loro conto PayPal o carta di credito.
Checkout ospitatoPiattaforme per creator — loro gestiscono il pagamento, noi l'accesso
Patreon
I patron ottengono automaticamente l'accesso quando sottoscrivono il tuo livello minimo.
Gumroad
Vendi l'accesso come prodotto Gumroad. Gli acquirenti ricevono il link dopo l'acquisto.
LemonSqueezy
Vendi l'accesso tramite il tuo negozio Lemon Squeezy. Gestisce tasse e pagamenti.
Ko-fi
I sostenitori che ti offrono un "caffè" o si iscrivono alla tua membership ottengono l'accesso al canale.
Buy Me a Coffee
I sostenitori e i membri ricevono automaticamente l'accesso al tuo canale.
Mantieni il 100% dei ricavi. Non tocchiamo mai i tuoi soldi. I pagamenti vanno direttamente sul tuo conto presso il fornitore che scegli. Noi generiamo solo i codici di accesso e inviamo il link via email.
Configurazione
Connetti il tuo fornitore
Accedi, scegli il tuo fornitore di pagamento, inserisci le tue credenziali API e ti forniamo un link di pagamento (per Stripe/Revolut/PayPal) o un URL webhook (per Patreon/Gumroad/ecc.).
Accedi qui sotto
Usa lo stesso account Apple che usi nell'app My TV Channel.
Scegli il fornitore e inserisci le chiavi
Seleziona il tuo fornitore di pagamento e inserisci la tua chiave API o il segreto webhook. Imposta prezzo e durata.
Condividi il tuo link
Ottieni un link di pagamento da condividere con il tuo pubblico, o incolla l'URL webhook nelle impostazioni del tuo fornitore.
Connetti il tuo fornitore di pagamento
Accedi con lo stesso account Apple che usi nell'app.
Dove trovare la tua chiave API Stripe: Vai su Dashboard Stripe → Sviluppatori → Chiavi API → copia la tua Chiave segreta (inizia con sk_live_).
Cosa riceveranno i tuoi clienti
Dopo un pagamento riuscito, il tuo cliente riceve un'email con il suo link di accesso personale:
Il tuo accesso è pronto
Grazie per il tuo acquisto! Ora hai accesso a Nome del tuo canale.
Guarda oraQuesto link è personale. Ti dà 30 giorni di accesso.
Panoramica
Come funziona
Tu gestisci il pagamento. Noi gestiamo l'accesso. Quando un cliente ti paga (tramite il tuo sito web, Stripe, Patreon o qualsiasi altro metodo), il tuo server chiama la nostra API per generare un codice di accesso unico. Tu dai quel codice al tuo cliente come link.
Il cliente ti paga
Sul tuo sito web, Patreon o qualsiasi sistema di pagamento tu scelga.
Il tuo server chiama la nostra API
Genera un codice abbonato con la scadenza e i limiti che desideri.
Il cliente riceve un link
Come https://your-channel.localtvbroadcast.com/?subscriber=ABC2DEF
Il cliente guarda
Si apre nell'app (con accesso garantito) o riproduce direttamente nel browser web.
Mantieni il 100% dei ricavi. Non elaboriamo pagamenti né prendiamo commissioni. I codici abbonato semplicemente concedono l'accesso al tuo canale all'interno di My TV Channel.
Per iniziare
Autenticazione
Tutte le chiamate API dell'editore richiedono un token JWT. Ottienine uno accedendo con il tuo account My TV Channel:
# Accedi per ottenere il tuo 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 risposta include un campo token. Usalo in tutte le richieste successive:
Authorization: Bearer YOUR_JWT_TOKEN
Mantieni il tuo token al sicuro. Salvalo come variabile d'ambiente lato server. Non esporlo mai nel codice lato client o in repository pubblici.
URL di base
Tutti gli endpoint API utilizzano il seguente URL di base:
https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/
Riferimento API
Genera un codice
/subscriber-codes/generate.php
Crea un nuovo codice di accesso abbonato per il tuo canale. Richiede autenticazione e proprietà del canale.
Corpo della richiesta
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| channel_id | integer | obbligatorio | L'ID del tuo canale |
| expires_at | string | obbligatorio | Data ISO 8601 in cui il codice smette di accettare nuovi riscatti |
| label | string | opzionale | Etichetta interna (es. "Pass Mensile VIP") |
| price | number | opzionale | Il tuo prezzo (solo metadati, non elaboriamo il pagamento) |
| currency | string | opzionale | Codice valuta ISO 4217 (predefinito: USD) |
| max_redemptions | integer | opzionale | Utilizzi massimi. null = illimitati |
| access_duration_days | integer | opzionale | Giorni di accesso per riscatto. null = accesso fino a expires_at |
Esempio
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
}'
Risposta
{
"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
}
}
Codici monouso vs. multiuso: Imposta max_redemptions: 1 per un codice unico per cliente. Impostalo a null per un codice promozionale condiviso che chiunque può usare.
Durata dell'accesso spiegata
Sono supportati due modelli:
| Scenario | access_duration_days | Comportamento |
|---|---|---|
| Pass a tempo limitato | 30 | Ogni spettatore ottiene 30 giorni dal momento del riscatto |
| Pass evento | null | Tutti gli spettatori hanno accesso fino alla data expires_at del codice |
Elenco codici
/subscriber-codes/list.php?channel_id={id}
Recupera tutti i codici abbonato per il tuo canale, con statistiche di riscatto.
Esempio
curl https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/list.php?channel_id=42 \
-H "Authorization: Bearer YOUR_TOKEN"
Risposta
{
"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"
}
]
}
}
Revoca un codice
/subscriber-codes/revoke.php
Disattiva un codice abbonato. Il codice non accetterà più nuovi riscatti. L'accesso già concesso rimane valido fino alla propria scadenza.
Corpo della richiesta
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| code_id | integer | obbligatorio | L'ID del codice da revocare (dalla risposta di generazione o elenco) |
Esempio
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 }'
Riscatta un codice (App)
/subscriber-codes/redeem.php
Utilizzato dall'app My TV Channel quando uno spettatore apre un link universale. Richiede autenticazione utente. Idempotente — riscattare nuovamente lo stesso codice restituisce l'accesso esistente.
Corpo della richiesta
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| code | string | obbligatorio | Il codice abbonato di 7 caratteri |
Risposta
{
"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
}
}
Nota: Questo endpoint viene chiamato automaticamente dall'app. Non è necessario chiamarlo dal tuo server.
Valida un codice (Lettore web)
/subscriber-codes/validate.php
Utilizzato dal lettore web per validare un codice abbonato prima di avviare la riproduzione. Non richiede autenticazione. Chiamato automaticamente quando uno spettatore apre un link canale con ?subscriber=.
Corpo della richiesta
| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| code | string | obbligatorio | Il codice abbonato di 7 caratteri |
| channel_id | integer | obbligatorio | ID canale da validare |
Nota: Questo endpoint viene chiamato automaticamente dal lettore web. Non è necessario chiamarlo dal tuo server.
Link universali
Ogni codice corrisponde a un link universale che funziona ovunque:
https://{your-channel-handle}.localtvbroadcast.com/?subscriber={CODE}
Il link restituito nella risposta generate è pronto per essere condiviso. Quando uno spettatore ci clicca:
| Scenario | Comportamento |
|---|---|
| App installata | Apre l'app My TV Channel, concede l'accesso, mostra il canale |
| App non installata | Apre il lettore web nel browser, valida il codice, avvia la riproduzione |
I codici non distinguono maiuscole e minuscole. A3F7K2N e a3f7k2n sono trattati in modo identico. I codici usano solo i caratteri 2346789ACDEFGHJKMNPQRTUVWXYZ per evitare ambiguità (nessun 0/O, 1/I/L, 5/S, 8/B).
Integrazioni
Integrazione Stripe
Genera automaticamente un codice abbonato quando un pagamento Stripe va a buon fine. Aggiungi questo gestore webhook al tuo server:
// 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]);
Integrazione Patreon (Self-Hosted)
Se preferisci gestire il tuo webhook handler invece di usare la nostra integrazione ospitata, ecco come gestire l'evento members:pledge:create sul tuo server:
// 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 generico / Pagamento personalizzato
Per qualsiasi sistema di pagamento con webhook (PayPal, Gumroad, LemonSqueezy, Ko-fi, Buy Me a Coffee, ecc.), il modello è lo stesso:
Ricevi il webhook di pagamento
Verifica la firma del webhook secondo la documentazione del tuo fornitore.
Chiama l'endpoint di generazione
POST /subscriber-codes/generate.php con il tuo token JWT.
Consegna il link
Invia data.url al tuo cliente tramite email, reindirizzamento o messaggio in-app.
Esempio cURL minimo
# Genera un codice monouso valido per 30 giorni di accesso
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
}'
# La risposta include il link da condividere:
# "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N"
Gestione degli errori
| Stato HTTP | Significato |
|---|---|
| 200 | Successo |
| 400 | Campi mancanti o non validi (controlla message per i dettagli) |
| 401 | Token JWT non valido o scaduto |
| 403 | Canale non di proprietà dell'utente autenticato |
| 404 | Codice abbonato non valido o scaduto (riscatto/validazione) |
| 500 | Errore del server (riprova) |