なぜ国内の決済代行ではなく Creem を見たのか
開発中のサービスに決済をつけるため Toss Payments へ加盟店申請を六度行い、六度とも却下された。しかし六度のうち理由を聞けたのは一度だけだ。最後の一件は「確認中」とだけ返ってきて、残る四件は今も理由が分からない。カード会社の審査基準が非公開で、具体的な項目が通知されないからだ。六度落ちて五度は理由が分からない、それがこの審査の性質だ。書類を補う問題ではなく通過可否を予測できない問題なので、再申請で突破する計画自体が立たない。
次の候補は Stripe だった。しかし韓国法人は Stripe のアカウントを開設できない。Stripe 公式の対応国ページには欧州 32 か国が並び、アジア太平洋ではオーストラリア・香港・日本・マレーシア・ニュージーランド・シンガポール・タイが対象で、インドとインドネシアが招待制と表示されているが、韓国は対応リストにも招待リストにもない(2026-08-06 確認)。
この二つが重なると選択肢は狭くなる。国内ルートは審査で止まり、Stripe は国で止まる。残るのは海外の MoR プラットフォームで、その一つが Creem だ。
付け加えると、これは技術ではなく制度の問題だ。コードをどれだけうまく書いても、決済契約が下りなければサービスは代金を受け取れない。バイブコーディングでログインも機能も作り終えたプロジェクトが最後に止まるのは、たいていここだ。
| 項目 | Toss Payments | Stripe | Creem |
|---|---|---|---|
| 韓国からの開設 | 加盟店審査の通過が必要 | 対応国リストに韓国なし | 登録してストアを作成 |
| 販売主体 | 販売者本人 | 販売者本人 | Creem(MoR) |
| 越境の税務申告 | 販売者の担当 | 販売者の担当 | Creem が 190 以上の管轄を代行 |
| 返金・係争 | 販売者の担当 | 販売者の担当 | Creem が処理 |
| 公開された手数料 | 契約ごと | 契約ごと | 3.9% + $0.40 |
Merchant of Record とは何か
Merchant of Record(略して MoR)とは、最終顧客に商品を販売する法的主体のことだ。Creem のドキュメントは自らの役割を "the legal entity responsible for selling goods or services to end customers" と記している。つまり書類上、顧客は自分ではなく Creem から買っている。
ここが一般的な決済ゲートウェイとの違いだ。ゲートウェイはカード決済という通路を貸すだけで、売り手は依然として自分なので、税務申告も返金処理も係争対応も自分に残る。MoR は売り手の席そのものを引き受ける。
だから Creem が負う項目は具体的だ。決済処理、市場ごとの税務コンプライアンス、売上税の徴収と納付、返金とチャージバックの管理、190 以上の管轄での税額計算と徴収、適法なインボイス発行、税務申告。海外顧客にソフトウェアを売った経験があれば、この一覧がなぜありがたいか分かる。EU の付加価値税ひとつ取っても、国ごとに税率も申告周期も違う。
代償は二つある。手数料が国内のカード手数料より高いこと、そして顧客のカード明細に自分のサービス名ではなく CREEM と表示されることだ。後者は問い合わせが多いらしく、Creem は顧客向けに「Why did Creem charge me」というページを別に用意している。商品ページと決済完了メールに「決済は Creem を通じて処理されます」と一行入れておけば、大半の問い合わせは減る。
コードを書かずに売る最短ルート
開発をしなくても決済まで到達できる。Creem はノーコードの経路を別に用意しており、ドキュメントではその対象を creators、vibe coders と呼んでいる。
第一に、creem.io で登録する。アカウント作成にクレジットカードは不要だ。ログインしたらストアを一つ作る。
第二に、テストモードをオンにする。実際の資金が動かない状態で決済フロー全体を最後まで通せる。本番に移すまではこの状態で作業するほうが安全だ。
第三に、ダッシュボードの Products タブで商品を作る。名前、説明、価格を入れ、単発決済(single payment)とサブスクリプション(subscription)から選び、通貨とカテゴリを指定する。電子書籍やテンプレートのようにファイルで渡す商品なら、ここでファイルをアップロードしておく。決済が終わると、そのダウンロードリンクが購入者のメールへ自動で届く。
第四に、商品の Share ボタンを押すと決済リンクが得られる。このアドレスをメールでも Instagram のプロフィールでもブログ記事の末尾でも、どこに貼っても決済が開く。ここまでがコード一行なしで到達できる地点だ。
この経路だけでも電子書籍・テンプレート・講座資料の販売は成立する。サイトを作ってから決済をつけるのではなく、まず決済リンクで売ってみて反応があればサイトを作る、という順序も取れるということだ。
コードで組み込む — Next.js での四段階
自分のサイト内で決済画面を開くのに必要なのは、API キーと product ID の二つだけだ。
第一段階、API キーを取得する。ダッシュボードの Developers メニューにある。コピーしてプロジェクト直下の .env に CREEM_API_KEY という名前で入れる。このキーはフロントエンドのコードや git リポジトリに絶対に置かない。.env が .gitignore に入っているかを先に確認する。
第二段階、アダプタを入れる。Next.js には専用アダプタがあり、これが最短だ。他のフレームワークなら TypeScript SDK(npm install creem)を、まったく別の言語なら REST API を直接呼べばよい。
第三段階、決済 API ルートを作る。app/api/checkout/route.ts の一ファイルで足りる。testMode: true はテスト中だけ有効にし、本番へ移すときに false へ変える。
第四段階、ボタンを包む。商品ページで得た product ID(prod_ で始まる)をコンポーネントに渡せば、そのボタンがそのまま決済ボタンになる。
ここまでで npm run dev を実行しボタンを押すと、Creem の決済画面が開く。テストモードではカード番号 4111 1111 1111 1111、有効期限は未来の任意の日付、CVC は任意の三桁で決済が通る。決済が終わると成功ページに戻り、アドレスバーに checkout_id・order_id・customer_id・product_id がクエリパラメータとして付いてくる。
CREEM_API_KEY=creem_test_your_api_key
CREEM_WEBHOOK_SECRET=whsec_your_webhook_secret
NEXT_PUBLIC_APP_URL=http://localhost:3000npm install @creem_io/nextjsimport { Checkout } from "@creem_io/nextjs";
export const GET = Checkout({
apiKey: process.env.CREEM_API_KEY!,
testMode: true,
defaultSuccessUrl: "/success",
});import { CreemCheckout } from "@creem_io/nextjs";
export default function Page() {
return (
<CreemCheckout productId="prod_YOUR_PRODUCT_ID">
<button>購入する</button>
</CreemCheckout>
);
}決済後を自動化する Webhook
成功ページに戻ってきたことだけを根拠に商品を開放してはいけない。決済直後に購入者がタブを閉じると、こちらのサーバーは決済が起きたことを知らないまま残る。逆に成功ページのアドレスを知った人が自分で開くこともできる。本番では Webhook を使う。
Webhook は Creem のサーバーが自分のサーバーへ直接「この決済が完了した」と知らせる通路だ。購入者のブラウザを経由しないので、タブを閉じても届く。
ダッシュボードで webhook secret を取得して .env の CREEM_WEBHOOK_SECRET に入れ、ルートをもう一つ作る。署名検証に失敗したら 401 で断つ部分が重要だ。この検証がないと、誰でも決済完了リクエストを装って商品を持ち去れる。
受け取るイベントは三つから始めれば十分だ。checkout.completed は決済が終わった瞬間、subscription.active はサブスクリプションが開始または更新された瞬間、subscription.canceled は解約された瞬間。それぞれの場所でアクセス権を開き、保ち、回収する。
import { NextRequest, NextResponse } from "next/server";
import { constructWebhookEventEntity } from "creem/webhooks";
export async function POST(request: NextRequest) {
const body = await request.text();
const event = await constructWebhookEventEntity(body, request.headers, {
secret: process.env.CREEM_WEBHOOK_SECRET!,
}).catch(() => null);
if (!event) {
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
switch (event.eventType) {
case "checkout.completed":
// アクセス権付与、メール送信、DB 更新
break;
case "subscription.active":
break;
case "subscription.canceled":
// アクセス権回収
break;
}
return NextResponse.json({ received: true });
}本番に移す前に確認すること
テストモードを切る。REST API を直接呼んでいたならアドレスも test-api.creem.io から api.creem.io へ変える。アダプタを使っているなら testMode を false にする。これを変えないと実際の決済が一件も入らないのに、画面上は何の問題もなく見える。
手数料を計算に入れる。成功した決済ごとに 3.9% + 0.40 ドル。月額費用、初期費用、隠れた費用はないとドキュメントが明記している。ただしこの数字は国内のカード手数料より安くはない。税務申告と返金・係争処理を手放した値段と見るのが妥当だ。固定の 0.40 ドルは単価が低い商品ほど重くのしかかるので、1〜2 ドルの単品販売ならセット販売やサブスクリプションへ設計を変えるほうがよい。
販売者の資格要件は自分で確認する。Creem の公開ドキュメントには、どの国の販売者が登録できるのか、事業者登録が必要か、どんな本人確認を求めるのかが書かれていない。精算の方法と周期も同様だ。「190 以上の国」という数字は税を処理する顧客側の管轄数であって、販売者の資格範囲ではない。だからこの記事でも断定しない。登録はクレジットカードなしでできるので、まずアカウントを作ってオンボーディング画面が何を求めるかを目で確かめるのが一番早い。
決済手段を確認する。ドル決済と国際カードが中心なので、KakaoPay・NaverPay・銀行振込といった韓国のローカル手段は弱い。顧客の大半が韓国の人で少額決済が多いなら、この構造は合わないかもしれない。逆に海外顧客へソフトウェアやデジタル商品を売る構造なら、もともとこちらが合う道具だ。
明細の表示名を先に伝える。前述の CREEM 表記の件だ。商品ページと決済完了メールに一行入れておけば、大半は解決する。
