取り組みの背景——ワンタップ決済がアプリ収益を変える理由
アプリの課金フローにおける最大の障壁は、決済入力の手間です。クレジットカード番号・有効期限・CVC を手入力させる旧来の UX では、入力途中で離脱するユーザーが後を絶ちません。業界調査によると、決済フォームへの入力途中離脱率は平均70%前後に達するとも言われています。
Apple Pay と Google Pay は、その問題を根本から解決します。ユーザーがすでにデバイスに登録している支払い情報を Face ID / Touch ID / 指紋認証で即時承認できるため、決済完了までのステップを劇的に削減できます。実装事例では購入転換率が1.5〜2倍に向上した報告もあり、アプリの収益に直接影響する最重要 UX 改善のひとつです。
Rork Max と Stripe の組み合わせは、この実装を現実的なコスト・工数で達成する最短ルートです。ここで扱うのは環境設定からバックエンド構築、Rork Max でのフロントエンド実装、そして本番リリース後の最適化まで、プロが知っておくべきすべての知識を丁寧に解説します。
前提知識と環境準備
必要なアカウントとツール
本ガイドを実践するには、以下の準備が必要です。
Rork Max アカウント : Apple ネイティブ機能(Entitlements)を扱うため Rork Max が必須です
Stripe アカウント : ダッシュボードで Apple Pay 用の Merchant ID 登録と Google Pay 設定を行います
Apple Developer Program : Apple Merchant ID の取得と証明書登録に必要です(年額 $99)
バックエンドサーバー : PaymentIntent を作成するエンドポイントが必要です。Cloudflare Workers や Supabase Edge Functions が手軽で推奨です
Stripe SDK のバージョン確認
Rork Max は Expo ベースの React Native 環境です。Stripe の公式 SDK @stripe/stripe-react-native を使います。2026年現在の推奨バージョンは v0.38 以降です。
# package.json に追加(Rork Max のプロンプトで指示するか手動追加)
# "@stripe/stripe-react-native": "^0.38.0"
Rork Max のプロンプトに以下を指定することで、自動的に依存関係が追加されます。
Stripe React Native SDK を使って Apple Pay と Google Pay に対応した
決済フローを実装してください。@stripe/stripe-react-native の最新版を使用し、
Merchant ID は "merchant.com.yourapp.pay" を使用してください。
Stripe ダッシュボードの事前設定
実装に入る前に、Stripe ダッシュボードで以下を確認・設定しておきます。
Webhook エンドポイントの登録(重要) : payment_intent.succeeded イベントを受け取るエンドポイントを登録しておきます。決済完了後の処理(会員権付与・コンテンツ解放など)はこのイベントをトリガーに実装します。
Apple Pay の設定——Merchant ID から証明書まで
Apple Pay は、Google Pay に比べて事前設定が多い分、設定が正しくないとリジェクトの原因になりやすい箇所です。ここでは詰まりやすいポイントを丁寧に解説します。
Step 1: Apple Merchant ID の作成
Apple Developer Portal にログインし、「Certificates, Identifiers & Profiles」→「Identifiers」から「Merchant IDs」を選択します。
命名規則は逆ドメイン形式が推奨です。
merchant.com.yourcompany.appname
例: merchant.net.dolice.myapp
Step 2: Apple Pay Payment Processing Certificate の作成
Merchant ID を作成後、「Apple Pay Payment Processing Certificate」を追加します。ここで Stripe のダッシュボードから CSR(Certificate Signing Request)ファイルを取得する必要があります。
Stripe ダッシュボードでの手順:
「Settings」→「Payment methods」→「Apple Pay」を開く
「Add a new domain」や「Add certificate」ボタンから CSR ファイルをダウンロード
Apple Developer Portal でダウンロードした CSR をアップロードし、証明書(.cer ファイル)を生成
生成した .cer ファイルを Stripe にアップロード
この手順を省略すると Apple Pay ボタンが表示されないため、必ず実施してください。
Step 3: App Identifier への Apple Pay Capability 追加
Xcode の Signing & Capabilities で追加するのが通常の手順ですが、Rork Max の場合はプロジェクト設定のプロンプトで指示します。
Rork Max の Entitlements に以下を追加してください:
- capability: "com.apple.developer.in-app-payments"
- value: ["merchant.net.dolice.myapp"]
Rork Max は cloud compile でネイティブビルドを行うため、Xcode を直接操作せずにエンタイトルメントを設定できます。
Step 4: ドメイン検証ファイルの配置
Stripe の Apple Pay を有効にするには、アプリのドメイン(バックエンド API のドメイン)に検証ファイルを配置する必要があります。
Cloudflare Workers を使う場合の設定例:
// バックエンド(Cloudflare Workers)
// /.well-known/apple-developer-merchantid-domain-association
export default {
async fetch ( request ) {
const url = new URL (request.url);
if (url.pathname === '/.well-known/apple-developer-merchantid-domain-association' ) {
// Stripe ダッシュボードからダウンロードしたファイルの内容を返す
return new Response ( APPLE_PAY_DOMAIN_VERIFICATION_CONTENT , {
headers: { 'Content-Type' : 'text/plain' }
});
}
// 通常のルーティング処理
return handleRequest (request);
}
} ;
Google Pay の設定——最小構成で最速実装
Google Pay は Apple Pay に比べて設定が少なく、Stripe が多くの部分を自動処理してくれます。
Google Pay API の有効化
Google Pay & Wallet Console にアクセスし、ビジネスプロフィールを登録します。開発中は「TEST」環境で動作確認でき、本番公開時に「PRODUCTION」承認申請を行います。
Stripe を使う場合、Google Pay の決済処理自体は Stripe が担うため、コンソールでの設定は比較的シンプルです。
Stripe ダッシュボードでの Google Pay 有効化
「Settings」→「Payment methods」→「Wallets」で Google Pay をオンにするだけで基本設定は完了です。
バックエンドの実装——PaymentIntent の作成
Stripe の Payment Sheet で Apple Pay / Google Pay を使うには、サーバー側で PaymentIntent(または SetupIntent)を作成し、クライアントサイドの clientSecret を返すエンドポイントが必要です。
Cloudflare Workers での実装例
// workers/payment-intent.js
const corsHeaders = {
'Access-Control-Allow-Origin' : '*' ,
'Access-Control-Allow-Headers' : 'Content-Type, Authorization' ,
'Access-Control-Allow-Methods' : 'POST, OPTIONS' ,
};
export async function handleCreatePaymentIntent ( request , env ) {
if (request.method === 'OPTIONS' ) {
return new Response ( null , { headers: corsHeaders });
}
try {
const { amount , currency = 'jpy' , customerId } = await request. json ();
// Stripe API へのリクエスト
// env.STRIPE_SECRET_KEY は Cloudflare Workers の Secrets で管理
const response = await fetch ( 'https://api.stripe.com/v1/payment_intents' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ env . STRIPE_SECRET_KEY }` ,
'Content-Type' : 'application/x-www-form-urlencoded' ,
},
body: new URLSearchParams ({
amount: String (amount),
currency,
customer: customerId || '' ,
// Apple Pay / Google Pay を含むすべての支払い方法を許可
'payment_method_types[]' : 'card' ,
'automatic_payment_methods[enabled]' : 'true' ,
}),
});
if ( ! response.ok) {
const error = await response. json ();
throw new Error (error.error?.message || 'Stripe API error' );
}
const paymentIntent = await response. json ();
// クライアントには clientSecret のみ返す(秘密鍵は絶対に返さない)
return new Response (
JSON . stringify ({
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
}),
{
headers: {
... corsHeaders,
'Content-Type' : 'application/json' ,
},
}
);
} catch (error) {
console. error ( 'PaymentIntent creation error:' , error);
return new Response (
JSON . stringify ({ error: error.message }),
{
status: 500 ,
headers: { ... corsHeaders, 'Content-Type' : 'application/json' },
}
);
}
}
重要なポイント : env.STRIPE_SECRET_KEY は必ず Cloudflare Workers の Secrets(環境変数)として管理し、コードに直接書かないでください。wrangler secret put STRIPE_SECRET_KEY コマンドで安全に登録できます。
Rork Max フロントエンドの実装
バックエンドが整ったら、Rork Max でフロントエンドを実装します。以下のプロンプトを使うと、必要なコードの骨格を生成できます。
Stripe Provider の設定
まず、アプリのルートに StripeProvider を配置します。
// App.tsx または _layout.tsx に相当するファイル
import { StripeProvider } from '@stripe/stripe-react-native' ;
export default function RootLayout () {
return (
< StripeProvider
publishableKey = "pk_live_XXXXXXXXXXXXXXXXXXXXXXXXXX" // 本番の Publishable Key
merchantIdentifier = "merchant.net.dolice.myapp" // Apple Pay の Merchant ID
urlScheme = "yourapp" // ディープリンク用スキーム
>
{ /* アプリのコンポーネント */ }
</ StripeProvider >
);
}
テスト時は pk_live_ の代わりに pk_test_ で始まるテスト用キーを使用してください。
Payment Sheet の実装
// components/PaymentButton.tsx
import React, { useState, useCallback } from 'react' ;
import { View, Text, TouchableOpacity, Alert, ActivityIndicator } from 'react-native' ;
import { useStripe, PaymentSheetError } from '@stripe/stripe-react-native' ;
interface PaymentButtonProps {
amount : number ; // 金額(最小通貨単位: 円の場合は整数)
productName : string ;
onSuccess : ( paymentIntentId : string ) => void ;
onError ?: ( error : string ) => void ;
}
export function PaymentButton ({
amount ,
productName ,
onSuccess ,
onError ,
} : PaymentButtonProps ) {
const { initPaymentSheet , presentPaymentSheet } = useStripe ();
const [ loading , setLoading ] = useState ( false );
const initializePaymentSheet = useCallback ( async () => {
try {
// バックエンドから clientSecret を取得
const response = await fetch ( 'https://your-api.workers.dev/create-payment-intent' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({ amount, currency: 'jpy' }),
});
if ( ! response.ok) throw new Error ( 'サーバーエラーが発生しました' );
const { clientSecret , paymentIntentId } = await response. json ();
// Payment Sheet を初期化
const { error } = await initPaymentSheet ({
merchantDisplayName: 'Dolice Apps' ,
paymentIntentClientSecret: clientSecret,
// Apple Pay / Google Pay の設定
applePay: {
merchantCountryCode: 'JP' ,
// 購入アイテムの表示(Apple Pay のシート上に表示される)
cartItems: [
{
label: productName,
amount: String (amount),
paymentType: 'Immediate' ,
},
],
},
googlePay: {
merchantCountryCode: 'JP' ,
testEnv: false , // 本番時は false
currencyCode: 'jpy' ,
centAmount: amount, // Google Pay は最小通貨単位
},
// 住所入力は不要な場合は省略(デジタルコンテンツなど)
billingDetailsCollectionConfiguration: {
name: 'never' ,
email: 'never' ,
phone: 'never' ,
address: 'never' ,
},
style: 'alwaysDark' , // または 'alwaysLight', 'automatic'
});
if (error) throw new Error (error.message);
return paymentIntentId;
} catch (err) {
throw err;
}
}, [amount, productName, initPaymentSheet]);
const handlePayment = useCallback ( async () => {
setLoading ( true );
try {
const paymentIntentId = await initializePaymentSheet ();
// Payment Sheet を表示(Apple Pay / Google Pay ボタンを含む)
const { error } = await presentPaymentSheet ();
if (error) {
if (error.code === PaymentSheetError.Canceled) {
// ユーザーがキャンセル — エラーとして扱わない
return ;
}
throw new Error (error.message);
}
// 決済成功
onSuccess (paymentIntentId || '' );
} catch (err) {
const message = err instanceof Error ? err.message : '決済に失敗しました' ;
onError ?.(message);
Alert. alert ( 'エラー' , message);
} finally {
setLoading ( false );
}
}, [initializePaymentSheet, presentPaymentSheet, onSuccess, onError]);
return (
< TouchableOpacity
onPress = { handlePayment }
disabled = { loading }
style = { {
backgroundColor: '#000' ,
borderRadius: 12 ,
padding: 16 ,
alignItems: 'center' ,
opacity: loading ? 0.6 : 1 ,
} }
>
{ loading ? (
< ActivityIndicator color = "#fff" />
) : (
< Text style = { { color: '#fff' , fontSize: 16 , fontWeight: '600' } } >
{ amount. toLocaleString () } 円 を支払う
</ Text >
) }
</ TouchableOpacity >
);
}
購入完了後の処理
決済が成功したら、サーバー側の Webhook で会員権の付与やコンテンツの解放を行います。クライアントサイドだけで処理を完結させると、通信失敗時にステータスが不整合になるリスクがあるため、必ず Webhook を実装してください。
// Webhook ハンドラー(Cloudflare Workers)
export async function handleStripeWebhook ( request , env ) {
const signature = request.headers. get ( 'stripe-signature' );
const body = await request. text ();
try {
// Stripe の署名検証(改ざん防止)
// 実際の実装では stripe.webhooks.constructEvent を使用
const event = JSON . parse (body);
switch (event.type) {
case 'payment_intent.succeeded' : {
const paymentIntent = event.data.object;
const userId = paymentIntent.metadata?.userId;
if (userId) {
// Supabase や KV でユーザーの権限を更新
await grantPremiumAccess (userId, env);
}
break ;
}
default :
// 未処理のイベントは無視
break ;
}
return new Response ( JSON . stringify ({ received: true }), {
headers: { 'Content-Type' : 'application/json' },
});
} catch (err) {
console. error ( 'Webhook error:' , err);
return new Response ( 'Webhook handler failed' , { status: 400 });
}
}
テスト方法——本番リリース前に確認すべき全項目
Apple Pay のテスト
Apple Pay はシミュレーターでもテストカードが使えますが、実機でのテストが推奨です。Stripe の Apple Pay テストカード(4242 4242 4242 4242)を Wallet アプリに追加することでテスト環境での支払いをシミュレートできます。
テスト時は StripeProvider の publishableKey に pk_test_ で始まるキーを、バックエンドの STRIPE_SECRET_KEY に sk_test_ で始まるキーを使用してください。
確認すべき項目:
Apple Pay ボタンが Payment Sheet 上部に表示される
Face ID / Touch ID 認証で支払いが完了する
キャンセル時に適切にハンドリングされる
Webhook が正常に受信される(Stripe CLI でローカルテスト可能)
決済完了後にアプリの状態が正しく更新される
Google Pay のテスト
Google Pay は Android 実機でテストします。googlePay.testEnv: true を設定することで、テストカードが使えるサンドボックス環境で動作確認できます。
Stripe CLI を使ったローカル Webhook テスト
# Stripe CLI のインストール後
stripe listen --forward-to localhost:8787/webhook
# 別ターミナルで決済イベントをトリガー
stripe trigger payment_intent.succeeded
よくあるエラーと対処法
実装時に頻繁に遭遇するエラーとその解決策をまとめます。
「Apple Pay is not available on this device」
原因 : Merchant ID のエンタイトルメント設定が正しくないか、Apple Pay Payment Processing Certificate が Stripe に正しく登録されていない場合に発生します。
対処 :
Apple Developer Portal で Merchant ID と証明書の状態を確認する
Rork Max のビルド設定で com.apple.developer.in-app-payments エンタイトルメントが正しい Merchant ID を含んでいるか確認する
Stripe ダッシュボードで Apple Pay ドメインの検証が完了しているか確認する
「Your payment information could not be verified」
原因 : Stripe に登録したドメイン検証ファイル(.well-known/apple-developer-merchantid-domain-association)にアクセスできない場合に発生します。
対処 : Cloudflare Workers やサーバーの CORS 設定と URL ルーティングを確認し、検証ファイルが正しく返されるか curl コマンドで確認します。
curl https://your-api.workers.dev/.well-known/apple-developer-merchantid-domain-association
# ファイルの内容が返ってくれば OK
Payment Sheet が表示されない(initPaymentSheet エラー)
原因 : clientSecret の形式が不正か、PaymentIntent の作成に失敗している場合が多いです。
対処 :
バックエンドのレスポンスを console.log で確認し、clientSecret が pi_ で始まる値になっているか確認する
Stripe ダッシュボードの「Logs」で API コールのエラーを確認する
automatic_payment_methods[enabled]: true が設定されているか確認する
Google Pay ボタンが表示されない
原因 : デバイスに Google Pay カードが登録されていないか、テスト環境で testEnv が正しく設定されていない場合があります。
対処 : googlePay.testEnv: true に設定して Google Pay のテストカードを使うか、Google Pay & Wallet Console でアプリが承認されているか確認します。
本番リリース後の転換率最適化
Apple Pay / Google Pay の実装が完了したら、さらに転換率を高めるための最適化に取り組みましょう。
Payment Sheet の表示タイミング
Payment Sheet の初期化(initPaymentSheet)は重い処理のため、ユーザーが「購入」ボタンを押す前に非同期で実行しておくことで、体感速度を大幅に改善できます。
// 画面表示時に事前初期化
useEffect (() => {
// バックグラウンドで Payment Sheet を初期化
initializePaymentSheet (). catch (console.error);
}, []);
購入ボタンの配置とコピーライティング
Apple Pay / Google Pay に対応したことを視覚的に示すために、各ブランドのロゴを使用できます(Stripe のコンポーネントが自動的に表示します)。ボタンテキストは「購入」より「今すぐ手に入れる」「1タップで完了」といった行動を促すコピーが効果的です。
オファーコードとプロモーション
RevenueCAT と組み合わせることで、特定ユーザーへの割引オファーを Payment Sheet 経由でも適用できます。詳細な実装については Rork × RevenueCat 課金完全実装ガイド も合わせてご参照ください。
Stripe の決済フローをさらに深く学びたい方には、RorkアプリにStripe決済を組み込む完全ガイド も役立ちます。
モバイルアプリの収益化戦略を網羅的に
個人開発者の視点から(実体験メモ)
まとめ
ここで扱うのはRork Max と Stripe を組み合わせた Apple Pay / Google Pay の実装を、環境設定から本番最適化まで体系的に解説しました。
実装のポイントを整理します。Apple Pay は Merchant ID の取得と証明書登録、ドメイン検証の3ステップが事前に必要で、これをしっかり完了させておくことがスムーズな実装につながります。Google Pay は Stripe が多くを自動処理してくれるため比較的シンプルです。フロントエンドは Stripe Payment Sheet が Apple Pay / Google Pay を自動的に検出・表示してくれるので、コードの分岐を最小限に保てます。そしてバックエンドでは必ず Webhook で決済完了を確認し、クライアントサイドに処理を依存させないことが信頼性の高い実装の鍵です。
ワンタップ決済の導入は、アプリ収益の改善に直結する投資対効果の高い施策です。ぜひ本記事を参考に、あなたのアプリに Apple Pay / Google Pay を組み込んでみてください。