Monetize seu canal
Do seu jeito

Conecte Stripe, PayPal, Patreon ou qualquer provedor de pagamento. Nós cuidamos dos códigos de acesso e do envio de emails. Você fica com 100% da receita.

Provedores de pagamento suportados

Escolha o provedor de pagamento que você já usa. Nós conectamos a ele, geramos códigos de acesso automaticamente e enviamos por email o link pessoal para seus clientes.

Pagamento direto — hospedamos uma página de checkout para você

Stripe

Aceite cartões, Apple Pay, Google Pay. Criamos sessões Stripe Checkout com sua chave API.

Checkout hospedado

Revolut Business

Aceite pagamentos via checkout Revolut. Configuração rápida, suporta múltiplas moedas.

Checkout hospedado

PayPal

Aceite pagamentos PayPal. Compradores pagam com sua conta PayPal ou cartão de crédito.

Checkout hospedado

Plataformas para criadores — eles cuidam do pagamento, nós cuidamos do acesso

Patreon

Os patronos recebem acesso automaticamente quando contribuem no seu nível mínimo.

Webhook

Gumroad

Venda acesso como um produto Gumroad. Os compradores recebem o link após a compra.

Webhook

LemonSqueezy

Venda acesso pela sua loja Lemon Squeezy. Cuida de impostos e pagamentos.

Webhook

Ko-fi

Apoiadores que compram um "café" ou se inscrevem na sua membership recebem acesso ao canal.

Webhook

Buy Me a Coffee

Apoiadores e membros recebem automaticamente acesso ao seu canal.

Webhook

Você fica com 100% da receita. Nunca tocamos no seu dinheiro. Os pagamentos vão diretamente para sua conta no provedor que você escolher. Nós apenas geramos os códigos de acesso e enviamos o link por email.

Conecte seu provedor

Faça login, escolha seu provedor de pagamento, insira suas credenciais API e nós fornecemos um link de pagamento (para Stripe/Revolut/PayPal) ou uma URL de webhook (para Patreon/Gumroad/etc.).

1

Faça login abaixo

Use a mesma conta Apple que você usa no app My TV Channel.

2

Escolha o provedor e insira as chaves

Selecione seu provedor de pagamento e insira sua chave API ou segredo webhook. Defina preço e duração.

3

Compartilhe seu link

Obtenha um link de pagamento para compartilhar com seu público, ou cole a URL do webhook nas configurações do seu provedor.

Conecte seu provedor de pagamento

Faça login com a mesma conta Apple que você usa no app.

Entrar com Apple

Onde encontrar sua chave API Stripe: Vá para Painel Stripe → Desenvolvedores → Chaves API → copie sua Chave secreta (começa com sk_live_).

O que seus clientes receberão

Após um pagamento bem-sucedido, seu cliente recebe um email com seu link de acesso pessoal:

Seu acesso está pronto

Obrigado pela sua compra! Agora você tem acesso a Nome do Seu Canal.

Assistir agora

Este link é pessoal. Ele dá 30 dias de acesso.

Para desenvolvedores

Como funciona

Você cuida do pagamento. Nós cuidamos do acesso. Quando um cliente paga você (pelo seu site, Stripe, Patreon ou qualquer outro método), seu servidor chama nossa API para gerar um código de acesso único. Você dá esse código ao seu cliente como um link.

1

O cliente paga você

No seu site, Patreon ou qualquer sistema de pagamento que você escolher.

2

Seu servidor chama nossa API

Gera um código de assinante com a expiração e os limites que você desejar.

3

O cliente recebe um link

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

4

O cliente assiste

Abre no app (com acesso concedido) ou reproduz diretamente no navegador web.

Você fica com 100% da receita. Não processamos pagamentos nem cobramos comissão. Códigos de assinante simplesmente concedem acesso ao seu canal dentro do My TV Channel.

Autenticação

Todas as chamadas API de publicador requerem um token JWT. Obtenha um fazendo login com sua conta My TV Channel:

# Faça login para obter seu 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"
  }'

A resposta inclui um campo token. Use-o em todas as requisições subsequentes:

Authorization: Bearer YOUR_JWT_TOKEN

Mantenha seu token seguro. Armazene-o como uma variável de ambiente no servidor. Nunca exponha em código do lado do cliente ou repositórios públicos.

URL base

Todos os endpoints da API usam a seguinte URL base:

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

Gerar um código

POST /subscriber-codes/generate.php

Cria um novo código de acesso de assinante para seu canal. Requer autenticação e propriedade do canal.

Corpo da requisição

CampoTipoObrigatórioDescrição
channel_idintegerobrigatórioO ID do seu canal
expires_atstringobrigatórioData ISO 8601 quando o código para de aceitar novos resgates
labelstringopcionalEtiqueta interna (ex. "Passe Mensal VIP")
pricenumberopcionalSeu preço (apenas metadados, não processamos pagamento)
currencystringopcionalCódigo de moeda ISO 4217 (padrão: USD)
max_redemptionsintegeropcionalUsos máximos. null = ilimitado
access_duration_daysintegeropcionalDias de acesso por resgate. null = acesso até expires_at

Exemplo

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
  }'

Resposta

{
  "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
  }
}

Códigos de uso único vs. múltiplos usos: Defina max_redemptions: 1 para um código único por cliente. Defina como null para um código promocional compartilhado que qualquer um pode usar.

Duração do acesso explicada

Dois modelos são suportados:

Cenárioaccess_duration_daysComportamento
Passe com tempo limitado30Cada espectador recebe 30 dias a partir do momento do resgate
Passe de eventonullTodos os espectadores têm acesso até a data expires_at do código

Listar códigos

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

Recupera todos os códigos de assinante do seu canal, com estatísticas de resgate.

Exemplo

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

Resposta

{
  "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"
      }
    ]
  }
}

Revogar um código

POST /subscriber-codes/revoke.php

Desativa um código de assinante. O código não aceitará mais novos resgates. O acesso já concedido permanece válido até sua própria expiração.

Corpo da requisição

CampoTipoObrigatórioDescrição
code_idintegerobrigatórioO ID do código a revogar (da resposta de geração ou listagem)

Exemplo

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 }'

Resgatar um código (App)

POST /subscriber-codes/redeem.php

Usado pelo app My TV Channel quando um espectador abre um link universal. Requer autenticação do usuário. Idempotente — resgatar o mesmo código novamente retorna o acesso existente.

Corpo da requisição

CampoTipoObrigatórioDescrição
codestringobrigatórioO código de assinante de 7 caracteres

Resposta

{
  "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: Este endpoint é chamado automaticamente pelo app. Você não precisa chamá-lo do seu servidor.

Validar um código (Player web)

POST /subscriber-codes/validate.php

Usado pelo player web para validar um código de assinante antes de iniciar a reprodução. Não requer autenticação. Chamado automaticamente quando um espectador abre um link de canal com ?subscriber=.

Corpo da requisição

CampoTipoObrigatórioDescrição
codestringobrigatórioO código de assinante de 7 caracteres
channel_idintegerobrigatórioID do canal para validar

Nota: Este endpoint é chamado automaticamente pelo player web. Você não precisa chamá-lo do seu servidor.

Integração Stripe

Gere automaticamente um código de assinante quando um pagamento Stripe é bem-sucedido. Adicione este handler de webhook ao seu servidor:

// 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]);

Integração Patreon (Self-Hosted)

Se você prefere rodar seu próprio handler de webhook em vez de usar nossa integração hospedada, veja como lidar com o evento members:pledge:create no seu servidor:

// 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 genérico / Pagamento personalizado

Para qualquer sistema de pagamento com webhooks (PayPal, Gumroad, LemonSqueezy, Ko-fi, Buy Me a Coffee, etc.), o padrão é o mesmo:

1

Receba o webhook de pagamento

Verifique a assinatura do webhook conforme a documentação do seu provedor.

2

Chame o endpoint de geração

POST /subscriber-codes/generate.php com seu token JWT.

3

Entregue o link

Envie data.url para seu cliente via email, redirecionamento ou mensagem no app.

Exemplo cURL mínimo

# Gere um código de uso único válido por 30 dias de acesso
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
  }'

# A resposta inclui o link para compartilhar:
# "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N"

Tratamento de erros

Status HTTPSignificado
200Sucesso
400Campos ausentes ou inválidos (verifique message para detalhes)
401Token JWT inválido ou expirado
403Canal não pertence ao usuário autenticado
404Código de assinante inválido ou expirado (resgate/validação)
500Erro do servidor (tente novamente)