あなたのチャンネルを
自由に収益化

Stripe、PayPal、Patreonなどの決済プロバイダーを接続。アクセスコードの生成とメール配信は私たちが対応します。収益の100%はあなたのものです。

対応決済プロバイダー

すでに利用している決済プロバイダーを選択してください。接続後、アクセスコードを自動生成し、お客様に個人リンクをメールで送信します。

直接決済 — チェックアウトページをホスティングします

Stripe

カード、Apple Pay、Google Payに対応。あなたのAPIキーでStripe Checkoutセッションを作成します。

ホスティング型チェックアウト

Revolut Business

Revolutチェックアウトで決済を受け付けます。簡単セットアップ、複数通貨対応。

ホスティング型チェックアウト

PayPal

PayPal決済に対応。購入者はPayPalアカウントまたはクレジットカードで支払い可能。

ホスティング型チェックアウト

クリエイタープラットフォーム — 決済は彼らが、アクセス管理は私たちが

Patreon

パトロンが最低ティアで支援すると、自動的にアクセスが付与されます。

Webhook

Gumroad

Gumroad商品としてアクセスを販売。購入後にリンクが届きます。

Webhook

LemonSqueezy

Lemon Squeezyストアでアクセスを販売。税金と決済を処理します。

Webhook

Ko-fi

「コーヒー」を購入したりメンバーシップに参加したサポーターにチャンネルアクセスが付与されます。

Webhook

Buy Me a Coffee

サポーターとメンバーに自動的にチャンネルアクセスが付与されます。

Webhook

収益の100%はあなたのものです。私たちはあなたのお金に触れることはありません。支払いはあなたが選んだプロバイダーのアカウントに直接入金されます。私たちはアクセスコードの生成とリンクのメール送信のみを行います。

プロバイダーを接続

サインインし、決済プロバイダーを選択、API認証情報を入力すると、決済リンク(Stripe/Revolut/PayPal用)またはwebhook URL(Patreon/Gumroad等用)が発行されます。

1

以下からサインイン

My TV Channelアプリで使用しているのと同じAppleアカウントを使用してください。

2

プロバイダーを選択してキーを入力

決済プロバイダーを選択し、APIキーまたはwebhookシークレットを入力。価格と期間を設定します。

3

リンクを共有

視聴者と共有する決済リンクを取得するか、プロバイダーの設定にwebhook URLを貼り付けます。

決済プロバイダーを接続

アプリで使用しているのと同じAppleアカウントでサインインしてください。

Appleでサインイン

Stripe APIキーの場所:Stripeダッシュボード → 開発者 → APIキー → シークレットキーをコピー(sk_live_で始まります)。

お客様が受け取るもの

支払い完了後、お客様は個人アクセスリンク付きのメールを受け取ります:

アクセスの準備ができました

ご購入ありがとうございます!あなたのチャンネル名へのアクセスが有効になりました。

今すぐ視聴

このリンクは個人専用です。30日間のアクセスが付与されます。

開発者向け

仕組み

決済はあなたが。アクセス管理は私たちが。お客様があなたに支払いをした時(ウェブサイト、Stripe、Patreon、その他の方法で)、あなたのサーバーが当社のAPIを呼び出してユニークなアクセスコードを生成します。そのコードをリンクとしてお客様に提供します。

1

お客様があなたに支払い

あなたのウェブサイト、Patreon、またはお好みの決済システムで。

2

あなたのサーバーがAPIを呼び出し

希望の有効期限と制限でサブスクライバーコードを生成します。

3

お客様がリンクを受け取る

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

4

お客様が視聴

アプリで開く(アクセスが付与された状態)か、ウェブブラウザで直接再生します。

収益の100%はあなたのものです。決済処理も手数料の徴収も行いません。サブスクライバーコードは、My TV Channel内のあなたのチャンネルへのアクセスを付与するだけです。

認証

すべてのパブリッシャーAPI呼び出しにはJWTトークンが必要です。My TV Channelアカウントでサインインして取得してください:

# サインインして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"
  }'

レスポンスにはtokenフィールドが含まれます。以降のすべてのリクエストで使用してください:

Authorization: Bearer YOUR_JWT_TOKEN

トークンは安全に保管してください。サーバーサイドの環境変数として保存してください。クライアントサイドのコードや公開リポジトリには絶対に公開しないでください。

ベースURL

すべてのAPIエンドポイントは以下のベースURLを使用します:

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

コードを生成

POST /subscriber-codes/generate.php

チャンネルの新しいサブスクライバーアクセスコードを作成します。認証とチャンネルの所有権が必要です。

リクエストボディ

フィールド必須説明
channel_idinteger必須あなたのチャンネルID
expires_atstring必須コードが新規利用を停止するISO 8601日時
labelstring任意内部ラベル(例:「VIP月間パス」)
pricenumber任意価格(メタデータのみ、決済処理は行いません)
currencystring任意ISO 4217通貨コード(デフォルト:USD
max_redemptionsinteger任意最大利用回数。null = 無制限
access_duration_daysinteger任意利用あたりのアクセス日数。null = expires_atまでアクセス可能

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

レスポンス

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

使い切りコード vs. 複数回使用コード:顧客ごとのユニークコードにはmax_redemptions: 1を設定。誰でも使える共有プロモコードにはnullを設定。

アクセス期間の説明

2つのモデルがサポートされています:

シナリオaccess_duration_days動作
期間限定パス30各視聴者は利用時点から30日間のアクセスを取得
イベントパスnull全視聴者がコードのexpires_at日時までアクセス可能

コード一覧

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

チャンネルのすべてのサブスクライバーコードを利用統計とともに取得します。

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

レスポンス

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

コードを無効化

POST /subscriber-codes/revoke.php

サブスクライバーコードを無効化します。コードは新規利用を受け付けなくなります。すでに付与されたアクセスは、その有効期限まで有効です。

リクエストボディ

フィールド必須説明
code_idinteger必須無効化するコードのID(生成または一覧のレスポンスから)

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

コードを利用(アプリ)

POST /subscriber-codes/redeem.php

視聴者がユニバーサルリンクを開いた時にMy TV Channelアプリが使用します。ユーザー認証が必要です。冪等性あり — 同じコードを再利用すると既存のアクセスが返されます。

リクエストボディ

フィールド必須説明
codestring必須7文字のサブスクライバーコード

レスポンス

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

注意:このエンドポイントはアプリによって自動的に呼び出されます。サーバーから呼び出す必要はありません。

コードを検証(Webプレーヤー)

POST /subscriber-codes/validate.php

再生開始前にWebプレーヤーがサブスクライバーコードを検証するために使用します。認証不要。視聴者が?subscriber=付きのチャンネルリンクを開いた時に自動的に呼び出されます。

リクエストボディ

フィールド必須説明
codestring必須7文字のサブスクライバーコード
channel_idinteger必須検証対象のチャンネルID

注意:このエンドポイントはWebプレーヤーによって自動的に呼び出されます。サーバーから呼び出す必要はありません。

Stripe連携

Stripe決済が成功した時にサブスクライバーコードを自動生成します。このwebhookハンドラをサーバーに追加してください:

// 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連携(セルフホスト)

当社のホスティング型連携の代わりに独自のwebhookハンドラを運用したい場合、サーバーでmembers:pledge:createイベントを処理する方法はこちらです:

// 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 / カスタム決済

webhookを持つ任意の決済システム(PayPal、Gumroad、LemonSqueezy、Ko-fi、Buy Me a Coffeeなど)に対して、パターンは同じです:

1

決済webhookを受信

プロバイダーのドキュメントに従ってwebhook署名を検証します。

2

生成エンドポイントを呼び出し

POST /subscriber-codes/generate.phpをJWTトークン付きで呼び出します。

3

リンクを配信

data.urlをメール、リダイレクト、またはアプリ内メッセージでお客様に送信します。

最小限のcURL例

# 30日間アクセスの使い切りコードを生成
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
  }'

# レスポンスには共有用のリンクが含まれます:
# "url": "https://your-channel.localtvbroadcast.com/?subscriber=A3F7K2N"

エラーハンドリング

HTTPステータス意味
200成功
400フィールドの不足または不正(messageで詳細を確認)
401無効または期限切れのJWTトークン
403認証ユーザーが所有していないチャンネル
404無効または期限切れのサブスクライバーコード(利用/検証)
500サーバーエラー(再試行してください)