Monetarisieren Sie Ihren Kanal
auf Ihre Weise
Verbinden Sie Stripe, PayPal, Patreon oder einen anderen Zahlungsanbieter. Wir verwalten die Zugangscodes und den E-Mail-Versand. Sie behalten 100% der Einnahmen.
Kein Code erforderlich
Unterstützte Zahlungsanbieter
Wählen Sie den Zahlungsanbieter, den Sie bereits nutzen. Wir verbinden uns damit, generieren automatisch Zugangscodes und senden Ihren Kunden ihren persönlichen Link per E-Mail.
Direktzahlung — wir hosten eine Checkout-Seite für Sie
Stripe
Akzeptieren Sie Karten, Apple Pay, Google Pay. Wir erstellen Stripe Checkout-Sitzungen mit Ihrem API-Schlüssel.
Gehosteter CheckoutRevolut Business
Akzeptieren Sie Zahlungen über den Revolut-Checkout. Schnelle Einrichtung, unterstützt mehrere Währungen.
Gehosteter CheckoutPayPal
Akzeptieren Sie PayPal-Zahlungen. Käufer bezahlen mit ihrem PayPal-Konto oder ihrer Kreditkarte.
Gehosteter CheckoutCreator-Plattformen — sie wickeln die Zahlung ab, wir verwalten den Zugang
Patreon
Patrons erhalten automatisch Zugang, wenn sie Ihre Mindeststufe unterstützen.
Gumroad
Verkaufen Sie Zugang als Gumroad-Produkt. Käufer erhalten ihren Link nach dem Kauf.
LemonSqueezy
Verkaufen Sie Zugang über Ihren LemonSqueezy-Shop. Verwaltet Steuern und Zahlungen.
Ko-fi
Unterstützer, die Ihnen einen "Kaffee" spendieren oder Ihrer Mitgliedschaft beitreten, erhalten Kanalzugang.
Buy Me a Coffee
Unterstützer und Mitglieder erhalten automatisch Zugang zu Ihrem Kanal.
Sie behalten 100% der Einnahmen. Wir berühren Ihr Geld nie. Zahlungen gehen direkt auf Ihr Konto beim gewählten Anbieter. Wir generieren nur die Zugangscodes und senden den Link per E-Mail.
Einrichtung
Ihren Anbieter verbinden
Melden Sie sich an, wählen Sie Ihren Zahlungsanbieter, geben Sie Ihre API-Zugangsdaten ein, und wir geben Ihnen entweder einen Zahlungslink (für Stripe/Revolut/PayPal) oder eine Webhook-URL (für Patreon/Gumroad/etc.).
Unten anmelden
Verwenden Sie dasselbe Apple-Konto, das Sie in der My TV Channel App nutzen.
Anbieter wählen & Schlüssel eingeben
Wählen Sie Ihren Zahlungsanbieter und geben Sie Ihren API-Schlüssel oder Webhook-Secret ein. Legen Sie Preis und Dauer fest.
Link teilen
Erhalten Sie einen Zahlungslink zum Teilen mit Ihrem Publikum, oder fügen Sie die Webhook-URL in die Einstellungen Ihres Anbieters ein.
Ihren Zahlungsanbieter verbinden
Melden Sie sich mit demselben Apple-Konto an, das Sie in der App verwenden.
Wo Sie Ihren Stripe API-Schlüssel finden: Gehen Sie zum Stripe Dashboard → Entwickler → API-Schlüssel → kopieren Sie Ihren Geheimen Schlüssel (beginnt mit sk_live_).
Was Ihre Kunden erhalten
Nach einer erfolgreichen Zahlung erhält Ihr Kunde eine E-Mail mit seinem persönlichen Zugangslink:
Ihr Zugang ist bereit
Vielen Dank für Ihren Kauf! Sie haben jetzt Zugang zu Ihr Kanalname.
Jetzt ansehenDieser Link ist persönlich. Er gewährt Ihnen 30 Tage Zugang.
Überblick
So funktioniert es
Sie wickeln die Zahlung ab. Wir verwalten den Zugang. Wenn ein Kunde bei Ihnen bezahlt (über Ihre Website, Stripe, Patreon oder eine andere Methode), ruft Ihr Server unsere API auf, um einen einzigartigen Zugangscode zu generieren. Diesen Code geben Sie Ihrem Kunden als Link.
Kunde bezahlt bei Ihnen
Auf Ihrer Website, bei Patreon oder einem anderen Zahlungssystem Ihrer Wahl.
Ihr Server ruft unsere API auf
Generieren Sie einen Abonnenten-Code mit dem Ablaufdatum und den Limits, die Sie festlegen.
Kunde erhält einen Link
Wie https://ihr-kanal.localtvbroadcast.com/?subscriber=ABC2DEF
Kunde schaut zu
Öffnet sich in der App (mit gewährtem Zugang) oder wird direkt im Webbrowser abgespielt.
Sie behalten 100% der Einnahmen. Wir verarbeiten keine Zahlungen und nehmen keine Provision. Abonnenten-Codes gewähren einfach Zugang zu Ihrem Kanal innerhalb von My TV Channel.
Erste Schritte
Authentifizierung
Alle Publisher-API-Aufrufe erfordern ein JWT-Token. Erhalten Sie eines, indem Sie sich mit Ihrem My TV Channel Konto anmelden:
# Anmelden, um Ihr JWT-Token zu erhalten
curl -X POST https://localtvbroadcast.com/api/mytvchannel/auth/login.php \
-H "Content-Type: application/json" \
-d '{
"email": "sie@beispiel.de",
"password": "ihr-passwort"
}'
Die Antwort enthält ein token-Feld. Verwenden Sie es in allen nachfolgenden Anfragen:
Authorization: Bearer YOUR_JWT_TOKEN
Bewahren Sie Ihr Token sicher auf. Speichern Sie es als serverseitige Umgebungsvariable. Geben Sie es niemals in clientseitigem Code oder öffentlichen Repositories preis.
Basis-URL
Alle API-Endpunkte verwenden die folgende Basis-URL:
https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/
API-Referenz
Code generieren
/subscriber-codes/generate.php
Erstellen Sie einen neuen Abonnenten-Zugangscode für Ihren Kanal. Erfordert Authentifizierung und Kanalbesitz.
Anfragekörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| channel_id | integer | erforderlich | Die ID Ihres Kanals |
| expires_at | string | erforderlich | ISO 8601-Datum, ab dem der Code keine neuen Einlösungen mehr akzeptiert |
| label | string | optional | Internes Label (z.B. "VIP-Monatspass") |
| price | number | optional | Ihr Preis (nur Metadaten, wir verarbeiten keine Zahlung) |
| currency | string | optional | ISO 4217-Währungscode (Standard: USD) |
| max_redemptions | integer | optional | Maximale Nutzungen. null = unbegrenzt |
| access_duration_days | integer | optional | Tage Zugang pro Einlösung. null = Zugang bis expires_at |
Beispiel
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
}'
Antwort
{
"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
}
}
Einmal- vs. Mehrfach-Codes: Setzen Sie max_redemptions: 1 für einen einzigartigen Code pro Kunde. Setzen Sie es auf null für einen gemeinsamen Promo-Code, den jeder verwenden kann.
Zugangsdauer erklärt
Zwei Modelle werden unterstützt:
| Szenario | access_duration_days | Verhalten |
|---|---|---|
| Zeitlich begrenzter Pass | 30 | Jeder Zuschauer erhält 30 Tage ab dem Zeitpunkt der Einlösung |
| Event-Pass | null | Alle Zuschauer haben Zugang bis zum expires_at-Datum des Codes |
Codes auflisten
/subscriber-codes/list.php?channel_id={id}
Rufen Sie alle Abonnenten-Codes für Ihren Kanal ab, einschließlich Einlösungsstatistiken.
Beispiel
curl https://localtvbroadcast.com/api/mytvchannel/subscriber-codes/list.php?channel_id=42 \
-H "Authorization: Bearer YOUR_TOKEN"
Antwort
{
"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"
}
]
}
}
Code widerrufen
/subscriber-codes/revoke.php
Deaktivieren Sie einen Abonnenten-Code. Der Code akzeptiert keine neuen Einlösungen mehr. Bereits gewährter Zugang bleibt bis zu seinem eigenen Ablaufdatum gültig.
Anfragekörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| code_id | integer | erforderlich | Die ID des zu widerrufenden Codes (aus der Generierungs- oder Listenantwort) |
Beispiel
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 }'
Code einlösen (App)
/subscriber-codes/redeem.php
Wird von der My TV Channel App verwendet, wenn ein Zuschauer einen Universal Link öffnet. Erfordert Benutzerauthentifizierung. Idempotent — das erneute Einlösen desselben Codes gibt den bestehenden Zugang zurück.
Anfragekörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| code | string | erforderlich | Der 7-stellige Abonnenten-Code |
Antwort
{
"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
}
}
Hinweis: Dieser Endpunkt wird automatisch von der App aufgerufen. Sie müssen ihn nicht von Ihrem Server aus aufrufen.
Code validieren (Web-Player)
/subscriber-codes/validate.php
Wird vom Web-Player verwendet, um einen Abonnenten-Code vor der Wiedergabe zu validieren. Keine Authentifizierung erforderlich. Wird automatisch aufgerufen, wenn ein Zuschauer einen Kanallink mit ?subscriber= öffnet.
Anfragekörper
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| code | string | erforderlich | Der 7-stellige Abonnenten-Code |
| channel_id | integer | erforderlich | Kanal-ID zur Validierung |
Hinweis: Dieser Endpunkt wird automatisch vom Web-Player aufgerufen. Sie müssen ihn nicht von Ihrem Server aus aufrufen.
Universal Links
Jeder Code ist einem Universal Link zugeordnet, der überall funktioniert:
https://{ihr-kanal-handle}.localtvbroadcast.com/?subscriber={CODE}
Der in der generate-Antwort zurückgegebene Link ist bereit zum Teilen. Wenn ein Zuschauer darauf klickt:
| Szenario | Verhalten |
|---|---|
| App installiert | Öffnet die My TV Channel App, gewährt Zugang und zeigt den Kanal |
| App nicht installiert | Öffnet den Web-Player im Browser, validiert den Code und startet die Wiedergabe |
Codes unterscheiden nicht zwischen Groß- und Kleinschreibung. A3F7K2N und a3f7k2n werden identisch behandelt. Codes verwenden nur die Zeichen 2346789ACDEFGHJKMNPQRTUVWXYZ, um Verwechslungen zu vermeiden (kein 0/O, 1/I/L, 5/S, 8/B).
Integrationen
Stripe-Integration
Generieren Sie automatisch einen Abonnenten-Code, wenn eine Stripe-Zahlung erfolgreich ist. Fügen Sie diesen Webhook-Handler zu Ihrem Server hinzu:
// 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]);
Patreon-Integration (selbst gehostet)
Wenn Sie lieber Ihren eigenen Webhook-Handler betreiben möchten, anstatt unsere gehostete Integration zu nutzen, können Sie das members:pledge:create-Event auf Ihrem Server wie folgt verarbeiten:
// 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 });
});
Generischer Webhook / Individuelle Zahlung
Für jedes Zahlungssystem mit Webhooks (PayPal, Gumroad, LemonSqueezy, Ko-fi, Buy Me a Coffee, etc.) ist das Muster dasselbe:
Zahlungs-Webhook empfangen
Überprüfen Sie die Webhook-Signatur gemäß der Dokumentation Ihres Anbieters.
Generate-Endpunkt aufrufen
POST /subscriber-codes/generate.php mit Ihrem JWT-Token.
Link zustellen
Senden Sie data.url an Ihren Kunden per E-Mail, Weiterleitung oder In-App-Nachricht.
Minimales cURL-Beispiel
# 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"
Fehlerbehandlung
| HTTP-Status | Bedeutung |
|---|---|
| 200 | Erfolg |
| 400 | Fehlende oder ungültige Felder (Details in message) |
| 401 | Ungültiges oder abgelaufenes JWT-Token |
| 403 | Kanal gehört nicht dem authentifizierten Benutzer |
| 404 | Ungültiger oder abgelaufener Abonnenten-Code (einlösen/validieren) |
| 500 | Serverfehler (erneut versuchen) |