StripeがUSDCで始めたサブスク決済をJPYCで再現できるか?
こんにちは!Web3特化の開発会社 Komlock lab でエンジニアをしている小原です。
2025年10月16日、Stripeが、USDCを用いたサブスク決済を、Polygon と Base 上で提供開始したと発表しました。
ブロックチェーン上でどうやってサブスク決済を実現しているんだろう?という疑問から調べていたところ、
Xでも「JPYCでのサブスク決済の実現性はどう考えているか」という質問をもらいました。
Web3決済の世界では一回払いは比較的簡単に実装できますが、
サブスク決済をどう自動化するかはまだ模索段階にある気がします。
今回は JPYCを使ったサブスクリプション決済(定期課金)の実装方法 について整理してみます。
背景:サブスクリプション決済の課題
Web2の世界では、クレジットカードやPayPayなどの決済手段を使って、定期的に自動で課金する仕組みが一般的です。
しかし、ブロックチェーン上でJPYCを使ったサブスクリプション決済を実装する場合、いくつかの課題があります。
- 自動実行の仕組み:ブロックチェーン上では、誰かが明示的にトランザクションを送信しない限り処理が実行されません。定期的な自動実行には何らかの仕組みが必要です。
- ガス代の問題:毎回の決済でガス代が発生するため、ユーザーがETHを常に持っている必要があります。
- ユーザーの承認:毎回ユーザーが手動で承認するのでは、サブスクリプションとして成立しません。
これらの課題を解決するためのアプローチをいくつか検討してみましょう。
アプローチ1:サーバーサイドでの定期実行 + EIP-3009
背景と仕組み
まず、前提として「EIP-3009」について軽くおさらいします。
私の前回の記事では、
この仕組みを使って一回払いのガスレス決済を実装しました。
今回はこれを応用して、複数回分の署名を事前に作成し、
サーバー側のジョブで定期的に実行することでサブスク決済を再現します。
フロー図
- ユーザーはフロントエンド上でサブスクを申し込む際、各月分の署名(EIP-3009)を作成します。
- これらの署名データはサーバーに送信され、安全に保存されます。
- サーバーはCronなどの定期実行ジョブを使い、決済日に署名を用いてJPYCの送金を実行します。
- 実際のトランザクションはサーバーがリレーするため、ユーザーはガス代を持っていなくても支払いが完了します。
実装のポイント
この方式を実際に試す場合は、以下の3点を押さえておくとスムーズです。
-
署名のライフサイクル管理
- 各月の署名ごとに
validAfter/validBefore/nonceを設定 -
validAfterで決済実行可能になる日時(引き落としたい日)を指定し、validBeforeで署名の有効期限を設定 - 重複や期限切れを避けるため、署名をDBで明確に管理
- 各月の署名ごとに
事前承認署名の作成実装例(Typescript)
// フロントエンド:サブスクリプション申し込み時
const createSubscriptionSignatures = async (
amount: bigint,
merchantAddress: string,
months: number // 契約期間(月数)
) => {
const signatures = [];
for (let i = 0; i < months; i++) {
// 各月の決済日を計算
const paymentDate = new Date();
paymentDate.setMonth(paymentDate.getMonth() + i);
// 署名の有効期限(決済日から1週間後まで)
const validAfter = Math.floor(paymentDate.getTime() / 1000);
const validBefore = validAfter + 7 * 24 * 60 * 60; // 1週間
const signature = await signTransferAuthorization({
to: merchantAddress,
amount: amount,
validAfter: validAfter,
validBefore: validBefore,
nonce: generateNonce(userAddress, i), // 各月ごとに異なるnonce
});
signatures.push({
signature,
validAfter,
validBefore,
nonce: generateNonce(userAddress, i),
});
}
return signatures;
};
-
定期実行ジョブの設計
- サーバーやバックエンドで定期的に署名を実行する仕組みを用意する
- 例:スケジューラー(Cron、Cloud Scheduler、GitHub Actions など)を使って決済処理を自動でトリガーする
- 処理の再実行や失敗時の通知を入れておくと安全
定期実行ジョブ実装例(Node)
// サーバーサイド:定期実行ジョブ
import { transferWithAuthorization } from '@jpyc/sdk-core';
import { scheduleJob } from 'node-schedule';
// 毎日午前0時に実行
scheduleJob('0 0 * * *', async () => {
const subscriptions = await getActiveSubscriptions();
for (const subscription of subscriptions) {
const today = Math.floor(Date.now() / 1000);
// 今日が決済日かチェック
if (subscription.paymentDate === today) {
// 事前に作成された署名を取得
const signature = await getSignatureForDate(
subscription.userId,
subscription.paymentDate
);
try {
// JPYC SDK の transferWithAuthorization を使って署名送金を実行
await transferWithAuthorization({
from: subscription.userAddress,
to: MERCHANT_ADDRESS,
amount: subscription.amount,
validAfter: signature.validAfter,
validBefore: signature.validBefore,
nonce: signature.nonce,
signature: signature.signature,
});
// 決済成功を記録
await recordPaymentSuccess(subscription.id);
} catch (error) {
// 決済失敗を記録(残高不足など)
await recordPaymentFailure(subscription.id, error);
}
}
}
});
-
セキュリティと解約処理
- 未使用の署名は、JPYC SDK が提供する
cancelAuthorization()を使って無効化できる - これにより、ユーザーが解約した後に残った署名が不正に実行されるのを防げる
- 署名データは暗号化して保存し、漏洩リスクを最小化する
- 未使用の署名は、JPYC SDK が提供する
メリット・デメリット
メリット
- ユーザーはガス代を持っていなくてもOK
- 既存のJPYC SDKとEIP-3009の仕組みをそのまま活用できる
- サーバー側で確実に実行できる
デメリット
- 長期間の契約では、事前に大量の署名を作成する必要がある
- 署名が期限切れになる可能性がある
- サブスクリプションの途中変更が難しく、既存の署名をキャンセルして新しい署名を作成する必要があり、手続きが複雑になる
アプローチ2:Gelato Networkを使った自動実行
背景と仕組み
アプローチ1では、サーバーサイドで定期的に署名を実行する必要があり、完全自動化はできません。
そこで、Gelato Networkなどのオラクルサービスを利用することで、
スマートコントラクト上の関数を完全自動で実行できるようになります。
Gelatoは、指定した条件(時間経過、ブロック数など)を満たしたときに、
自動的にトランザクションを実行してくれるサービスです。
フロー図
上のフロー図の通り、Gelatoが自動的に実行してくれるのが特徴です。
- ユーザーがサブスクコントラクトを作成し、JPYCコントラクトの利用許可 (approve) をサブスクコントラクトに与える
- Gelatoに定期実行タスクを登録(例:30日ごとに
executePaymentを呼び出す) - 決済日になると、Gelatoが自動的に
executePaymentを実行 - サブスクコントラクトが
transferFrom()によりJPYCコントラクト経由で送金
実装のポイント
この方式では、サブスクリプション管理用のスマートコントラクトと組み合わせて使います。
-
スマートコントラクトの準備
- サブスクリプション情報を管理するコントラクトを作成
-
executePayment関数でtransferFromにより決済を実行する仕組みを実装
-
Gelatoタスクの設定
- スマートコントラクトの
executePayment関数を定期的に呼び出すタスクを作成 - 実行間隔(例:30日ごと)と開始時刻を指定
- スマートコントラクトの
-
コスト管理
- Gelato Networkの利用料を考慮
- 実行頻度に応じたコスト計算が必要
メリット・デメリット
メリット
- 完全に自動化できる
- スマートコントラクト上で透明性が高い
デメリット
- Gelato Networkの利用には追加コストがかかる
- コントラクトの実装とデプロイが必要
- より複雑な実装になる
アプローチ3:Superfluid Protocolによるストリーミング決済
Superfluidを使えば、こういったリアルタイムでお金が流れるストリーミング決済が実現できるらしいです。
背景と仕組み
従来のサブスクリプション決済は、「月末に1ヶ月分をまとめて支払う」という方式が一般的です。
しかし、この方法では月の途中で解約しても返金されないなど、ユーザーにとって不利な面があります。
Superfluidは、Ethereum上でリアルタイムのストリーミング決済を実現するプロトコルで、
毎秒ごとに少額ずつ支払いが流れるという新しいアプローチを実現します。
例えば、月額3,000円のサブスクであれば
- 従来:月末に3,000円を一括で支払う
- Superfluid:毎秒約0.001円ずつリアルタイムで支払いが流れる
これにより、使った分だけ支払うという理想的なサブスクモデルが実現できます。
技術的な仕組み
Superfluidのストリーミング決済は、オンチェーンでリアルタイムに実行されるのが特徴です。
一般的なブロックチェーン決済では、トランザクションを実行するたびにガス代がかかりますが、
Superfluidでは独自の方法でこの問題を解決しています。
ポイント1:スマートコントラクトで残高を動的に計算
-
balanceOf()などの関数が呼び出されるタイミングで、スマートコントラクトが毎回残高を計算します - 実際には毎秒トランザクションを発行するのではなく、「開始時刻」と「流量(flowRate)」を記録しておき、参照時に計算で求めます
- そのため、リアルタイムでストリーミングされているように見えても、実際にはガス代が発生しません
ポイント2:JPYCxへのラップ/アンラップ
- SuperfluidではSuper Token(この場合はJPYCx)を使用します
- JPYCをJPYCxにラップすることで、Superfluidプロトコル上で利用可能になります
- ストリーム受取側は、JPYCxを
unwrap()することで通常のJPYCに戻して引き出せます
この仕組みにより、従来の「トランザクションごとにガス代がかかる」という制約から解放され、
毎秒の極小額決済がコスト効率よく実現できています。
フロー図
- ユーザーがJPYCをSuper Token(JPYCx)にラップする
- Superfluidコントラクトに送金先と流量(flowRate)を設定してフローを開始
- 以降、毎秒自動的に少額ずつ送金が流れ続ける
- 解約したい時は
deleteFlow()でフローを停止
メリット・デメリット
メリット
- 使った分だけ支払い:月の途中で解約しても損がない
- 自動実行:サーバーレスで完全にオンチェーンで完結
- 透明性が高い:リアルタイムで資金の流れが可視化される
- 事業者にも有利:即座にキャッシュフローが改善
デメリット
- JPYCをラップする必要がある:SuperfluidのSuper Tokenに変換する手間がかかる
- まだ日本では普及していない:海外では実績があるが、国内の事例は少ない
- ユーザー教育が必要:「ストリーミング決済」という概念自体が新しい
JPYCでの実現可能性
JPYCでSuperfluidを使うには、JPYCをSuper Token(JPYCx)にラップする必要があります。
これは技術的には可能性がありますが、以下の点を検討・検証する必要があります。
- 現在のJPYCとSuperfluidの互換性
- Super Tokenへのラップ/アンラップのUX設計
- ガス代の負担方法
将来的には、Superfluidのストリーミング決済モデルは、サブスクリプションの理想形として普及する可能性があります。特に、Web3ネイティブなサービスでは、「使った分だけ支払う」という透明性の高い課金モデルがユーザーに受け入れられやすいでしょう。
アプローチ4:AP2 + x402プロトコル(将来の展望)
背景と仕組み
これまでのアプローチでは、サブスクリプション決済のために
スマートコントラクトを開発したり、複雑な署名管理をしたりする必要がありました。
しかし、AIエージェントの時代が到来すれば、
人間の代わりにAIが自律的に決済を処理することが可能になります。
AP2(Agent Payments Protocol)とx402プロトコルは、
このAIエージェント時代の決済を実現するための新しい仕組みです。
- AP2:Googleが提唱するオープンスタンダードで、AIエージェントが人間の代理として安全かつ円滑に決済を行うことを目的としています
- x402:HTTPレスポンスの「402 Payment Required」を利用し、AIエージェントが自律的に決済を完了できる仕組みを提供します
フロー図
- ユーザーがサブスクリプションに申し込む際に、AP2/x402プロトコルに準拠した決済設定を行う
- AIエージェントが定期的に決済を自動実行
- スマートコントラクトを自分で実装する必要がなくなる
メリット・デメリット
メリット
- スマートコントラクト不要:自分でコントラクトを作成・デプロイする必要がない
- 実装が大幅に簡素化:標準化されたプロトコルに準拠するだけでOK
- AIエージェントによる自動決済:自律的な決済実行が可能
デメリット
- まだ本格実装されていない:現時点では標準化の途上
- 実績が少ない:プロダクション環境での利用事例が少ない
実装の考え方
AP2とx402が本格的に実装されれば、サブスクリプション決済の実装が劇的に簡単になることが期待されます。
将来的には以下のような流れで実装できる可能性があります。
- AP2エージェントに決済設定を委任(トークン、金額、決済間隔、加盟店アドレスなど)
- x402プロトコルで決済フローを設定
- AIエージェントが自律的に定期決済を実行
現時点では実装されていませんが、今後最も期待できるアプローチの一つです。
まとめ
| アプローチ | メリット | デメリット | 適用ケース |
|---|---|---|---|
| 1. サーバーサイド + EIP-3009 | 実装がシンプル、既存SDK活用可能 | サーバーに依存、署名管理が必要 | 短期契約(1〜3ヶ月) |
| 2. Gelato Network | 完全自動化、透明性が高い | 追加コスト、実装が複雑 | 長期契約(3ヶ月以上) |
| 3. Superfluid Protocol | 使った分だけ支払い、自動実行 | ラップが必要、まだ普及途上 | Web3ネイティブサービス |
| 4. AP2 + x402 | スマコン不要、実装が簡単 | まだ本格実装されていない | 将来の選択肢 |
本記事では、JPYCを使ったサブスクリプション決済の実現可能性について、4つのアプローチを調査・整理しました。
ただし、これらはあくまで理論上の可能性を検討した段階であり、実際に各アプローチが現在のJPYCで実装可能かどうかは未検証です。
今後、実際にコードを書いて実装し、本当に実現可能なのかを検証していく予定です。実装の過程や結果については、また記事にまとめていきます!
記事が参考になった方は、ぜひ Zenn のフォローや
X(@brto_0224) のフォローもよろしくお願いします 🙌
参考資料
Discussion