メインコンテンツにジャンプ
チュートリアル

Stripe Payments in Capacitor: New Apple Guidelines

Capacitorでストライプの決済リンクを実装して、デジタル商品の決済を新しいAppleのガイドラインに準拠して行う方法を学びましょう。Capacitorアプリでデジタル商品の決済を実現する方法を学びましょう。

記事のクレジット

マーティン・ドナディュー

ページ/エリア: Enterprise製品/価格ページ。ロール: UIラベル。見られる場所: page enterprise.astro。メッセージキー `enterprise_partnership_capgo_martin_name` (Enterprise Partnership Capgo Martin Name)。

ライター

バレリア

ページ/エリア: Enterprise製品/価格ページ。ロール: UIラベル。見られる場所: page enterprise.astro。メッセージキー `enterprise_partnership_capgo_valeria_name` (Enterprise Partnership Capgo Valeria Name)。

エディター

Capacitorにおけるストライプの支払い:新しいAppleのガイドライン

Capacitorアプリケーションにおけるストライプの支払いリンクの実装:新しいAppleのガイドラインに従う

2025年5月1日以降、AppleはEpic v. Appleの裁判の結果を受けてApp Storeのレビュー規定を大幅に変更しました。これにより、アメリカのアプリ開発者はデジタル商品やサービスに対する外部の支払い方法へのリンクを許可されました。これにより、Appleのインアプリ購入システムへの代替が可能になりました。 永遠に変えるモバイル支払いのバトルこの瞬間までの道のりは長く、紛争が続きました。すべては2020年8月に始まりました。Epic Gamesは、Fortniteという人気のゲームの作成者が、AppleのApp Storeの規定を意図的に違反し、Appleの30%のコミッションを回避する直接の支払いオプションを実装しました。AppleはFortniteをApp Storeから削除し、EpicはAppleがiOSアプリの配布とインアプリ支払いを制御することを挑戦する訴訟を提起しました。

数年間の法的闘争、上告、反対上告の後、裁判所はAppleがユーザーをアプリ外の代替支払い方法に直接リンクすることを許可することを決定しました。この決定は、2008年以来App Storeのエコシステムが運営されてきた基本的な財務モデルを根本的に変えました。

最終的な判決 - さらに上告はありません

__CAPGO_KEEP_0__

__CAPGO_KEEP_0__

この判決が特に重要なのは、最終的であり、更に上訴することはできません。最高裁判所は2025年初頭にAppleの上訴を却下し、下級裁判所の決定を法律として確定させました。このことは、Appleがこの決定を更に法律上の挑戦を通じて逆転させることはできません。開発者は、Appleがこの決定を更に法律上の挑戦を通じて逆転させることはできません。

Equal Treatment Guaranteed by Law

Most importantly, the ruling explicitly states that Apple cannot discriminate against apps that use external payment methods. The court specifically prohibited Apple from:

  1. Charging additional fees or imposing extra requirements on apps that use external payment methods
  2. Giving preferential treatment in search results or featuring to apps that exclusively use Apple’s IAP system
  3. Using technical measures to make external payment experiences inferior to Apple’s own system
  4. Imposing burdensome disclosure requirements beyond basic consumer information

この判決は、Appleが外部の支払い方法を使用するアプリに差別することはできないことを明確に述べています。裁判所は、Appleが以下のことを禁止しています。外部の支払い方法を使用するアプリに追加の料金を請求したり、追加の要件を課したりすることはできません。AppleのIAPシステムを独占的に使用するアプリに優遇扱いを与えたり、検索結果や特集を優遇したりすることはできません。外部の支払い体験をAppleのシステムと比較して劣ったものにする技術的措置を取ることはできません。基本的な消費者情報を超える過度の開示要件を課すことはできません。明確な保護措置により、開発者はストライプや他の外部の支払いプロバイダーを使用することなく、Appleからの微妙な報復や差別の恐れなく実装できます。競争の場は法律上平等化され、Appleはアプリの支払い方法の選択に関係なく、すべてのアプリを平等に扱うことを義務付けられます。

Appleの壁のある庭のアプローチに対する決定は、モバイルアプリのマonetizationの方法の重要な転換点となり、開発者にとってはAppleの30%のコミッション(小規模企業の場合15%)に対する長年の不満を解決するものとなる。

Stripeを使用することでAppleのIn-App Purchasesに比べて得られる金銭的利益

この変更の財務的影響は開発者にとって大きい:

  • 支払い処理手数料の削減: Appleは通常In-App Purchasesに対して30%のコミッション(小規模企業の場合15%)を徴収するが、Stripeの手数料は約2.9% + $0.30あたり1回の取引である。この差はあなたの収益マージンを大幅に増やす。

  • 支払い処理の迅速化: Appleではあなたは通常45-90日間待たなければならないが、Stripeではあなたの銀行口座に支払いを2-3営業日以内に振り込む。

  • 返金の簡素化: 返金を直接Stripeのダッシュボードから処理するのではなく、Appleの複雑な返金システムを経由する必要がなくなる。

これらのコスト削減とキャッシュフロー改善は、特に小規模な開発者や企業にとってゲームチェンジャーとなる。

この記事では、CapacitorアプリにStripe Payment Linksを実装する方法について説明し、Appleの更新されたガイドラインに準拠しながら、これらの新しい規則を利用する方法について説明する。 setup-stripe-payment-in-us-capacitor.

この実装は Stripeの公式ドキュメントのPayment LinksCapacitorアプリ向けに特に適応

新しいガイドラインの理解

App Storeのレビューガイドラインが更新され、開発者はユーザーを外部サイトにリダイレクトして支払い処理を行うことを許可するようになりました。特にデジタル商品やサブスクリプションの場合。この変更は現在、アメリカのApp Storeで配布されているアプリにのみ適用されます。

理解するポイント:

  1. デジタル商品内でアプリ内で外部の支払いオプションにリンクすることができます
  2. この変更は、アメリカのApp Storeに配布されているアプリにのみ適用されます
  3. Appleの開示要件に従う必要があります
  4. ユーザーへのサポートや返金処理は開発者自身で行う必要があります

実際の実装について説明します

最初に、Stripe ダッシュボードで支払いリンクを作成してください:

  1. Stripe ダッシュボードの "支払いリンク" セクションに移動してください
  2. 「+新規」ボタンをクリックして新しい支払いリンクを作成してください
  3. 製品またはサブスクリプションの詳細を定義してください
  4. 「支払い後」の設定で、「確認ページを表示しない」に選択してください
  5. 成功URLとして、ユニバーサルリンクを設定してください (後で設定します)
  6. 「作成」ボタンをクリックして支払いリンクを生成してください

支払い完了後、ユーザーをアプリにリダイレクトするには、ユニバーサルリンクを設定する必要があります:

  1. ドメイン上にファイルを作成してください: apple-app-site-association ファイル
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appIDs": ["YOURTEAMID.com.yourdomain.yourapp"],
        "components": [
          {
            "/": "/checkout_redirect*",
            "comment": "Matches any URL whose path starts with /checkout_redirect"
          }
        ]
      }
    ]
  }
}
  1. ファイルをホストする https://yourdomain.com/.well-known/apple-app-site-association

  2. 正しいMIMEタイプでファイルを配信することを確認する application/json

  3. Capacitorアプリを設定して、Universal Linkを処理できるようにする。まず、 capacitor.config.ts:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. Xcodeプロジェクトにアソシエイテッドドメインの特権を追加する:
    • Xcodeプロジェクトを開く
    • アプリのターゲットを選択する
    • 「Signing & Capabilities」に移動する
    • 「+ Capability」をクリックし、「アソシエイテッドドメイン」を選択する
    • 追加する applinks:yourdomain.com

ステップ3:フォールバックページを作成する

フォールバックページを作成して、リダイレクトURLでアプリがインストールされていない場合に処理できるようにする:

<!DOCTYPE html>
<html>
<head>
  <title>Redirecting...</title>
  <meta http-equiv="refresh" content="0;url=https://yourdomain.com/app-download">
</head>
<body>
  <p>Redirecting to download page...</p>
</body>
</html>

ステップ4:Capacitorアプリに支払いボタンを実装する

Now, add the payment button to your app:

import { Capacitor } from '@capacitor/core';

export async function openPaymentLink(userEmail, userId) {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(userEmail),
    client_reference_id: userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

Safariの重要性: Safariで開くことの利点 window.openSafariで開くことの利点は、ユーザーが以前ストリーピングリンクで支払い情報を保存したことがある場合、自動的にクレジットカード情報を入力する必要がなくなるため、チェックアウトのスムーズな経験を提供し、ユーザーが再度情報を入力する必要がなくなるため、フリクションと放棄率を大幅に削減することです。

ユーザーがリダイレクトされたときに Universal Links を処理するようにアプリを設定する

  1. まず、App プラグインをインストールする
npm install @capacitor/app
  1. アプリ内でApp プラグインを登録する
import { App } from '@capacitor/app';

// In your initialization code
App.addListener('appUrlOpen', (event) => {
  // Example URL: https://yourdomain.com/checkout_redirect?session_id=cs_test_...
  const url = new URL(event.url);
  
  if (url.pathname.startsWith('/checkout_redirect')) {
    // Extract any parameters you need
    const params = new URLSearchParams(url.search);
    const sessionId = params.get('session_id');
    
    // Handle successful payment
    if (sessionId) {
      // Verify the payment on your server if needed
      verifyPayment(sessionId);
      
      // Update UI to reflect successful purchase
      updatePurchaseStatus(true);
    }
  }
});

async function verifyPayment(sessionId) {
  // Call your backend to verify the payment
  // This is optional if you're relying on webhooks
}

function updatePurchaseStatus(success) {
  // Update your app UI to reflect purchase status
}

ステップ 6: オーダー処理のためのWebhookを設定する

最後に、成功した支払いを処理するためのWebhookをサーバーに設定する

// Using Express.js as an example
const express = require('express');
const stripe = require('stripe')('sk_test_your_stripe_secret_key');
const app = express();

// Use raw body parser for webhook signature verification
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = 'whsec_your_webhook_secret';
  
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
  } catch (err) {
    console.log(`Webhook Error: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  // Handle the checkout.session.completed event
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    
    // Retrieve client_reference_id (your user ID)
    const userId = session.client_reference_id;
    
    // Grant access to the purchased content
    await grantAccess(userId, session.id);
  }
  
  res.status(200).send();
});

async function grantAccess(userId, sessionId) {
  // Your logic to grant access to the purchased content
  // This could be updating a database, sending a notification, etc.
}

app.listen(3000, () => console.log('Webhook server running on port 3000'));

Androidの互換性

エピック対アップルの判決は、モバイル支払いランドスケープを根本的に変えました。iOSアプリに直接影響を与えるだけでなく、外部支払い方法を使用してきたAndroid開発者にとっては、Android開発者の立場を強化することにもなりました。

Android開発者は、完全な自信を持って外部の支払いソリューションを実装できます。 Appleの判決の先例は、さまざまなプラットフォームの開発者を、将来の制限から守っています。この裁判の判決は、多くのAndroid開発者が何年も行ってきたことの正当性を証明しています。— 低い料金で提供する代替支払いオプション。

Google Play Storeは、Appleと比べて外部の支払い方法については、より制限が少ないことが常にありました。法律の先例が確立された今、Stripeや他の外部の支払いプロバイダーをAndroidアプリに実装するリスクはほとんどありません。Stripe Payment Linksの実装については、iOSとほぼ同じように進められます。Google Play Storeには、外部の支払い方法に関する制限がなく、特別な披露ダイアログが必要ないため、同じアプローチを使用できます。

Androidデバイス用の実装は、iOS用の実装とほぼ同じです。Google Play Storeには外部の支払い方法に関する制限がないため、同じStripe Payment Linksのアプローチを使用できます。

デープリンクを処理するには、次の手順を実行する必要があります。

  1. App Linksを設定して、URLのリダイレクトを処理するようにします。 AndroidManifest.xml リダイレクトURLを処理するためのファイルを作成して、ドメインにアップロードします。
  2. アプリの詳細を含むファイルを作成して、ドメインにアップロードします。 .well-known/assetlinks.json 同じリスナーロジックを使用して、支払いが成功した場合に処理します。
  3. __CAPGO_KEEP_0__の美しさは、プラットフォーム固有の設定を実装した後、実際の支払いフローは両方のプラットフォームで同じままです。__CAPGO_KEEP_1__ appUrlOpen __CAPGO_KEEP_0__

The beauty of Capacitor is that once you’ve implemented the platform-specific configurations, the actual payment flow code remains the same across both platforms.

支払いUIの作成

ここでは、Vueで使用できる支払いボタンコンポーネントの例を紹介します。これをあなたのCapacitorアプリに追加してください:

<template>
  <div class="payment-container">
    <div class="pricing-card">
      <h2 class="mb-4 text-xl font-bold">{{ product.name }}</h2>
      <p class="mb-6 text-gray-600">{{ product.description }}</p>
      <div class="mb-6 price-tag">
        <span class="text-2xl font-bold">${{ product.price }}</span>
        <span v-if="product.isSubscription" class="text-sm text-gray-500">/month</span>
      </div>
      <button 
        @click="handlePayment" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Purchase Now
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { Dialog } from '@capacitor/dialog';

const props = defineProps({
  product: {
    type: Object,
    required: true
  },
  userEmail: {
    type: String,
    default: ''
  },
  userId: {
    type: String,
    required: true
  }
});

const isLoading = ref(false);

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

async function openPaymentLink() {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(props.userEmail),
    client_reference_id: props.userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

async function handlePayment() {
  isLoading.value = true;
  try {
    // Only show the disclosure on iOS
    if (window.Capacitor?.getPlatform() === 'ios') {
      const userConfirmed = await showExternalPaymentDisclosure();
      if (!userConfirmed) return;
    }
    
    await openPaymentLink();
  } catch (error) {
    console.error('Payment error:', error);
    await Dialog.alert({
      title: 'Payment Error',
      message: 'There was an error initiating the payment. Please try again.'
    });
  } finally {
    isLoading.value = false;
  }
}
</script>

地域の扱い

新しいAppleガイドラインは、アメリカのApp Storeにのみ適用されるため、ユーザーの地域を検出して適切な支払い方法を適用する戦略が必要になります。IP地理情報を使用したより信頼性の高いアプローチを紹介します。

import { Capacitor } from '@capacitor/core';

async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  try {
    // Use a geolocation service to determine user's country
    const response = await fetch('https://ipapi.co/json/');
    const locationData = await response.json();
    
    // Check if the user is in the United States
    if (locationData.country_code === 'US') {
      return 'external'; // Can use Stripe Payment Links
    } else {
      return 'iap'; // Must use In-App Purchases
    }
  } catch (error) {
    console.error('Error detecting region:', error);
    return 'iap'; // Default to IAP to be safe
  }
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

このアプローチでは、ユーザーのIPアドレスに基づいてユーザーの国を決定するために、無料の ipapi.co サービスを使用します。MaxMindなどの他の地理情報サービスも使用することができ、またはセキュリティの向上のためにこのチェックをサーバー側で実行することもできます。

注意: このアプローチは機能しますが、IP地理情報は常に100%の精度ではありません。mission-criticalアプリケーションでは、複数の検出方法を使用するか、ユーザーが手動で地域を選択できるようにすることを検討してください。

より正確な位置検出のCapacitor プラグイン

より正確な位置検出を行うには、Capacitor Geolocation プラグインと@capgo/capacitor-nativegeocoderを使用して、ユーザーの国をより高精度で決定できます:

  1. 最初に、必要なプラグインをインストールしてください:
npm install @capacitor/geolocation @capgo/capacitor-nativegeocoder
  1. あなたのCapacitorプロジェクトで、プラグインを設定します。次のコードをあなたの capacitor.config.ts:
import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. 地理位置を基にした地域検出を実装する:
import { Capacitor } from '@capacitor/core';
import { Geolocation } from '@capacitor/geolocation';
import { NativeGeocoder } from '@capgo/capacitor-nativegeocoder';

async function isUserInUSA() {
  try {
    // Request permission first
    const permissionStatus = await Geolocation.requestPermissions();
    
    if (permissionStatus.location === 'granted') {
      // Get current position
      const position = await Geolocation.getCurrentPosition({
        timeout: 10000,
        enableHighAccuracy: false
      });
      
      // Use NativeGeocoder to reverse geocode the coordinates
      const results = await NativeGeocoder.reverseGeocode({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        useLocale: true,
        maxResults: 1
      });
      
      if (results.addresses.length > 0) {
        // Check if the user is in the USA
        return results.addresses[0].countryCode === 'US';
      }
    }
    
    // If we couldn't determine location or permission denied, fall back to IP detection
    return await isUserInUSAByIP();
  } catch (error) {
    console.error('Error detecting location:', error);
    // Fall back to IP detection on error
    return await isUserInUSAByIP();
  }
}

async function isUserInUSAByIP() {
  try {
    const response = await fetch('https://ipapi.co/json/');
    const data = await response.json();
    return data.country_code === 'US';
  } catch (error) {
    console.error('Error detecting IP location:', error);
    return false; // Default to false to be safe
  }
}

export async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  // Check if user is in the USA
  const isUSA = await isUserInUSA();
  return isUSA ? 'external' : 'iap';
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

この実装では、ユーザーが物理的にアメリカにいるかどうかをより正確に判断する方法を提供します。まず、デバイスのGPSとネイティブのジオコーダーを使用して、国を決定します。許可の問題やその他のエラーにより失敗した場合、IPベースの検出にフォールバックします。

必要な許可をアプリの info.plist (iOS)ファイルと AndroidManifest.xml (Android)ファイルに追加することを忘れないでください:

iOSの場合 (ios/App/App/Info.plist):

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to determine which payment method to use based on regional availability.</string>

Androidの場合 (android/app/src/main/AndroidManifest.xml):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

このアプローチを使用すると、Appleの新しいガイドラインの下でユーザーが外部の支払いオプションに適格であるかどうかを判断する最も正確な方法が得られます。

サブスクリプションの管理

Stripeを使用して支払いを実行する利点の1つは、サブスクリプションを提供して管理できることです。ここでは、Capacitorアプリでサブスクリプション管理を実行する方法を説明します:

1. サブスクリプション管理ページの作成

アプリにサブスクリプション管理ページを追加して、ユーザーの有効なサブスクリプションを表示します:

<template>
  <div class="subscription-manager">
    <div v-if="isLoading" class="loading-indicator">
      Loading subscription data...
    </div>
    
    <div v-else-if="subscription" class="subscription-info">
      <h2 class="mb-4 text-xl font-bold">Your Subscription</h2>
      
      <div class="mb-6 plan-details">
        <p><span class="font-medium">Plan:</span> {{ subscription.planName }}</p>
        <p><span class="font-medium">Status:</span> {{ subscription.status }}</p>
        <p><span class="font-medium">Renews:</span> {{ formatDate(subscription.currentPeriodEnd) }}</p>
      </div>
      
      <button 
        @click="manageSubscription" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Manage Subscription
      </button>
    </div>
    
    <div v-else class="no-subscription">
      <p class="mb-4">You don't have an active subscription.</p>
      <button 
        @click="goToPricingPage" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        View Plans
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { getUserSubscription } from '../services/subscription';

const subscription = ref(null);
const isLoading = ref(true);

onMounted(async () => {
  try {
    const userData = await getUserSubscription();
    subscription.value = userData.subscription;
  } catch (error) {
    console.error('Failed to load subscription:', error);
  } finally {
    isLoading.value = false;
  }
});

function formatDate(timestamp) {
  return new Date(timestamp * 1000).toLocaleDateString();
}

function manageSubscription() {
  // Open Stripe Customer Portal
  window.open(subscription.value.portalUrl, '_blank');
}

function goToPricingPage() {
  // Navigate to pricing page
  // router.push('/pricing');
}
</script>

2. サブスクリプション管理用の顧客ポータル

Stripeは、ユーザーがサブスクリプションを管理できる顧客ポータルを提供しています。サーバーからこのポータルへのリンクを作成できます:

// Server-side code (Node.js)
const stripe = require('stripe')('sk_your_stripe_secret_key');

async function createPortalSession(customerId) {
  const session = await stripe.billingPortal.sessions.create({
    customer: customerId,
    return_url: 'https://yourdomain.com/account',
  });
  
  return session.url;
}

アプリストアの規制に準拠する

Appleのガイドラインに準拠するように実装するには:

  1. 外部購入に関する適切な説明を含める
  2. アプリ内で購入された場合のAppleのコミッションを回避することを避ける
  3. ユーザーにAppleがトランザクションに責任を負っていないことを明確に伝える
  4. 必要な説明モーダルを実装する例:

実装のテスト

import { Dialog } from '@capacitor/dialog';

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

export async function initiateExternalPayment(userEmail, userId) {
  const userConfirmed = await showExternalPaymentDisclosure();
  
  if (userConfirmed) {
    await openPaymentLink(userEmail, userId);
  }
}

実装のテストを行うには:

アプリ内で支払いボタンをクリックし、説明モーダルが表示され、次にStripeの支払いページが開くことを確認します

  1. 2. サブスクリプション管理用の顧客ポータル
  2. テストカードを使用したストライプのテスト決済を完了する 4242 4242 4242 4242
  3. 決済後、universal linkを介してアプリに戻されるはずです
  4. 支払い後、Webhookがイベントを受信していることを確認する checkout.session.completed イベント

まとめ

iOSアプリでデジタル商品に対する外部の支払いオプションを使用できるようになったことは、開発者にとって大きな変化です。この変化は現在、アメリカのApp Storeのアプリにのみ適用されていて、Appleのインアプリ購入システムに代わる重要な代替手段を提供しています。

Stripe Payment Linksを使用することで、Capacitorを使用して、Appleのガイドラインに準拠しながら、ストリーミングされたチェックアウトエクスペリエンスを迅速に実装できます。アメリカ以外のユーザーでは、Appleのインアプリ購入システムが適用されるため、@Capacitor/native-purchasesを使用すると、StoreKitとGoogle Play Billingを直接実装できます。このアプローチでは、Appleのインアプリ購入システムに比べて、ストライプの強力な支払いインフラ、低い処理手数料(3% vs 30%)、迅速な支払い(日数ではなく月数)が得られます。 @capgo/native-purchases __CAPGO_KEEP_0__アプリでストライプの支払いリンクを実装したことはありますか?コメント欄でご意見をご覧ください!

FAQ

Have you implemented Stripe Payment Links in your Capacitor app? Share your experience in the comments below!

FAQ

Q: このアプローチは、Apple のガイドラインに準拠していますか?
A: はい、2025年5月1日以降、Apple は、アメリカのApp Storeで配布されるアプリに含まれる必要がある旨の説明を含めて、外部の支払い方法へのリンクを許可しています。

Q: 外部の支払い方法を使用する場合、Apple のコミッションを支払う必要がありますか?
A: いいえ、新しい規則の主な利点の1つは、Apple のシステム外で処理される支払いは、コミッションの対象外です。

Q: この新しい規則を利用するには、会社がアメリカに本社を持っている必要がありますか?
A: いいえ、世界中の会社が、US App Storeでアプリを配布し、購入を実施するユーザーがアメリカにいる場合にのみ、外部の支払い方法を実装できます。この規則は、市場 (US App Store) とユーザーの位置、ではなく、会社の位置に基づいています。つまり、ヨーロッパ、アジア、南アメリカ、またはどこからでも開発者が、米国に拠点を置く顧客にStripe Payment Linksを実装できます。

Q: 米国外のユーザーが外部の支払いオプションを使用しようとした場合に何が起こりますか?
A: 米国外のユーザーが外部の支払いオプションを使用しようとした場合、地域の検出 (この記事で示されているように) を実装して、米国外のユーザーに外部の支払いオプションを提供しないようにしてください。米国外の地域では、Apple のインアプリ購入システムを継続して使用する必要があります。

Q: この方法は、物理商品やアプリ外で消費されるサービスに使用できますか?
A: はい、アップルは常にアプリ外の物理商品やサービス(乗り物のシェアリングや食品の配達など)を消費する場合の外部の支払い方法を許可しています。

Keep going from Stripe Payments in Capacitor: New Apple Guidelines

Capacitor Stripe Payments in Capacitor: New Apple Guidelines Capgo code API SDK CLI Capgo Security Scanner for the product workflow in Capgo Security Scanner, Stripe Payments in Capgo: New Apple Guidelines Capgo の製品ワークフローにおけるセキュリティ、 Capgo の信頼の中心 Capgo の信頼の中心における製品ワークフロー。

リアルタイムの更新はCapacitorアプリに適用されます。

ウェブ層のバグが生じた場合、Capgoを通じて修正を配信し、アプリストアの承認待ちの日数を省きます。ユーザーはバックグラウンドで更新を受け取り、ネイティブの変更は通常のレビュー経路を通じます。

マーティンから人間のサポートを受けます。

今すぐ始めましょう。

最新のブログ記事

Capgoは、プロフェッショナルなモバイルアプリを作成するために必要な最良の洞察を提供します。