Stripe

決済プラットフォームAPIフィンテックサブスクリプション金融サービスAIステーブルコイン

決済・金融サービスプラットフォーム

Stripe

概要

Stripeは世界をリードするオンライン決済・金融インフラプラットフォームです。125種類以上の決済手段、包括的なAPI、AIによる不正検知、サブスクリプション管理、金融サービス機能を統合し、スタートアップから大企業まで幅広く採用されています。2025年には決済用AIファウンデーションモデル、ステーブルコイン金融サービス、マルチ通貨管理機能などの革新的な機能を発表し、単なる決済プロバイダーから包括的な金融インフラへと進化を続けています。

詳細

Stripeは2010年に設立され、開発者フレンドリーなAPIと革新的な決済技術で業界をリードしてきました。2025年現在、Stripe Connectで15,000以上のSaaSプラットフォームを支援し、1,000万以上の事業者にサービスを提供しています。最新の発表では、AIファウンデーションモデルによる決済最適化、ステーブルコイン対応の金融アカウント、101カ国でのマルチ通貨管理など、次世代の金融インフラ機能を展開しています。

主な特徴

  • 125種類の決済手段: カード決済、デジタルウォレット、銀行振込、地域特化決済に対応
  • 包括的API: 決済、サブスクリプション、金融サービスの統合API
  • AI駆動機能: 不正検知、紛争処理自動化、ベンチマーキングツール
  • ステーブルコイン対応: USDC、USDBによる国際送金・残高管理
  • マルチ通貨管理: USD、EUR、GBP等の複数通貨での残高・カード発行
  • Stripe Connect: プラットフォーム向け決済・金融サービス埋め込み
  • Stripe Billing: 柔軟なサブスクリプション・課金システム
  • グローバル対応: 50カ国以上でのライセンス取得・運営

対応決済方法

  • カード決済: Visa、Mastercard、American Express、Discover、JCB
  • デジタルウォレット: Apple Pay、Google Pay、PayPal、Amazon Pay
  • 銀行振込: ACH、SEPA、Boleto、SOFORT、Giropay
  • 地域特化: Alipay、WeChat Pay、UPI、PIX、iDEAL
  • 後払い決済: Klarna、Afterpay、Affirm
  • 仮想通貨: ステーブルコイン(USDC、USDB)

メリット・デメリット

メリット

  • 開発者体験: 直感的で包括的なAPI設計
  • グローバル展開: 50カ国以上での統一プラットフォーム
  • 包括的機能: 決済から金融サービスまでワンストップ
  • AI技術: 不正検知・リスク管理の高度化
  • 柔軟性: 小規模から大規模まで対応する拡張性
  • セキュリティ: PCI DSS Level 1準拠、高度なセキュリティ
  • 透明な料金: 隠れコストなしの明確な料金体系

デメリット

  • 手数料コスト: 小額取引では手数料率が相対的に高い
  • アカウント審査: 厳格な審査により利用開始に時間がかかる場合
  • カスタマイズ制限: プラットフォーム設計による一部制約
  • 依存リスク: Stripeのサービス停止が事業に直接影響
  • 地域制限: 一部機能・決済手段の地域限定
  • サポート: 高額プランでないと電話サポートが制限的

参考ページ

実装例

1. 基本セットアップ

# Stripe JavaScript SDK インストール
npm install stripe @stripe/stripe-js

# Stripe CLI インストール(開発・テスト用)
brew install stripe/stripe-cli/stripe
# または
npm install -g stripe-cli

# Stripe CLIログイン
stripe login

# Webhookリスナー起動(開発時)
stripe listen --forward-to localhost:3000/webhook

2. 決済処理基本実装

// サーバーサイド (Node.js)
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Payment Intent 作成
async function createPaymentIntent(amount, currency = 'jpy') {
  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount, // 円の場合は最小単位(円)
      currency: currency,
      payment_method_types: ['card'],
      confirmation_method: 'manual',
      confirm: true,
      // 3D Secure対応
      payment_method_options: {
        card: {
          request_three_d_secure: 'automatic'
        }
      },
      // メタデータ
      metadata: {
        order_id: 'order_12345',
        customer_id: 'customer_67890'
      }
    });
    
    return {
      success: true,
      client_secret: paymentIntent.client_secret,
      status: paymentIntent.status
    };
  } catch (error) {
    console.error('決済Intent作成エラー:', error);
    return {
      success: false,
      error: error.message
    };
  }
}

// 顧客作成・管理
async function createCustomer(customerData) {
  try {
    const customer = await stripe.customers.create({
      email: customerData.email,
      name: customerData.name,
      phone: customerData.phone,
      address: {
        line1: customerData.address.line1,
        line2: customerData.address.line2,
        city: customerData.address.city,
        postal_code: customerData.address.postalCode,
        country: customerData.address.country
      },
      metadata: {
        user_id: customerData.userId
      }
    });
    
    return customer;
  } catch (error) {
    console.error('顧客作成エラー:', error);
    throw error;
  }
}

// クライアントサイド (React)
import { loadStripe } from '@stripe/stripe-js';
import {
  Elements,
  CardElement,
  useStripe,
  useElements
} from '@stripe/react-stripe-js';

const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY);

function CheckoutForm() {
  const stripe = useStripe();
  const elements = useElements();
  const [isProcessing, setIsProcessing] = useState(false);
  const [paymentResult, setPaymentResult] = useState(null);

  const handleSubmit = async (event) => {
    event.preventDefault();
    
    if (!stripe || !elements) return;
    
    setIsProcessing(true);
    
    const cardElement = elements.getElement(CardElement);
    
    try {
      // サーバーから client_secret を取得
      const response = await fetch('/create-payment-intent', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          amount: 1000, // 1000円
          currency: 'jpy'
        }),
      });
      
      const { client_secret } = await response.json();
      
      // 決済確認
      const result = await stripe.confirmCardPayment(client_secret, {
        payment_method: {
          card: cardElement,
          billing_details: {
            name: 'お客様名',
            email: '[email protected]'
          }
        }
      });
      
      if (result.error) {
        setPaymentResult({ error: result.error.message });
      } else {
        setPaymentResult({ success: true, paymentIntent: result.paymentIntent });
      }
    } catch (error) {
      setPaymentResult({ error: error.message });
    } finally {
      setIsProcessing(false);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <CardElement 
        options={{
          style: {
            base: {
              fontSize: '16px',
              color: '#424770',
              '::placeholder': {
                color: '#aab7c4',
              },
            },
          },
        }}
      />
      <button 
        type="submit" 
        disabled={!stripe || isProcessing}
      >
        {isProcessing ? '処理中...' : '決済する'}
      </button>
      
      {paymentResult && (
        <div className={paymentResult.error ? 'error' : 'success'}>
          {paymentResult.error || '決済が完了しました'}
        </div>
      )}
    </form>
  );
}

export default function CheckoutPage() {
  return (
    <Elements stripe={stripePromise}>
      <CheckoutForm />
    </Elements>
  );
}

3. サブスクリプション管理

// サブスクリプション作成
async function createSubscription(customerId, priceId) {
  try {
    const subscription = await stripe.subscriptions.create({
      customer: customerId,
      items: [
        {
          price: priceId,
        },
      ],
      payment_behavior: 'default_incomplete',
      payment_settings: { save_default_payment_method: 'on_subscription' },
      expand: ['latest_invoice.payment_intent'],
      // 無料試用期間
      trial_period_days: 7,
      // 課金サイクル固定
      billing_cycle_anchor: Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60), // 30日後
      // 自動税計算
      automatic_tax: {
        enabled: true
      }
    });
    
    return subscription;
  } catch (error) {
    console.error('サブスクリプション作成エラー:', error);
    throw error;
  }
}

// 料金プラン作成
async function createPrice(productId, amount, interval) {
  try {
    const price = await stripe.prices.create({
      product: productId,
      unit_amount: amount,
      currency: 'jpy',
      recurring: {
        interval: interval, // 'month', 'year', 'week', 'day'
        interval_count: 1
      },
      // 使用量課金
      billing_scheme: 'per_unit',
      // 段階料金
      tiers_mode: 'graduated',
      tiers: [
        {
          up_to: 100,
          unit_amount: 1000,
          flat_amount: 0
        },
        {
          up_to: 'inf',
          unit_amount: 800,
          flat_amount: 0
        }
      ]
    });
    
    return price;
  } catch (error) {
    console.error('料金プラン作成エラー:', error);
    throw error;
  }
}

// サブスクリプション管理ポータル
async function createCustomerPortalSession(customerId, returnUrl) {
  try {
    const session = await stripe.billingPortal.sessions.create({
      customer: customerId,
      return_url: returnUrl,
      // カスタマイズ設定
      configuration: {
        features: {
          payment_method_update: { enabled: true },
          invoice_history: { enabled: true },
          subscription_cancel: {
            enabled: true,
            mode: 'at_period_end'
          }
        }
      }
    });
    
    return session.url;
  } catch (error) {
    console.error('カスタマーポータル作成エラー:', error);
    throw error;
  }
}

4. Webhook処理

// Webhook ハンドラー (Express.js)
const express = require('express');
const app = express();

// Webhookエンドポイント
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature'];
  const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
  
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
  } catch (err) {
    console.error('Webhook署名検証失敗:', err.message);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  // イベント処理
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log('決済成功:', paymentIntent.id);
      handlePaymentSuccess(paymentIntent);
      break;
      
    case 'payment_intent.payment_failed':
      const failedPayment = event.data.object;
      console.log('決済失敗:', failedPayment.id);
      handlePaymentFailure(failedPayment);
      break;
      
    case 'customer.subscription.created':
      const subscription = event.data.object;
      console.log('サブスクリプション作成:', subscription.id);
      handleSubscriptionCreated(subscription);
      break;
      
    case 'customer.subscription.deleted':
      const deletedSubscription = event.data.object;
      console.log('サブスクリプション削除:', deletedSubscription.id);
      handleSubscriptionCanceled(deletedSubscription);
      break;
      
    case 'invoice.payment_succeeded':
      const invoice = event.data.object;
      console.log('請求書支払い成功:', invoice.id);
      handleInvoicePaymentSuccess(invoice);
      break;
      
    case 'customer.subscription.trial_will_end':
      const trialSubscription = event.data.object;
      console.log('試用期間終了予告:', trialSubscription.id);
      handleTrialWillEnd(trialSubscription);
      break;
      
    default:
      console.log(`未対応イベントタイプ: ${event.type}`);
  }
  
  res.json({ received: true });
});

// イベントハンドラー関数
async function handlePaymentSuccess(paymentIntent) {
  // 注文処理、商品発送、メール送信等
  const orderId = paymentIntent.metadata.order_id;
  await updateOrderStatus(orderId, 'paid');
  await sendConfirmationEmail(paymentIntent.receipt_email);
}

async function handleSubscriptionCreated(subscription) {
  // ユーザーアカウントの有料プラン有効化
  const customerId = subscription.customer;
  await activatePremiumFeatures(customerId);
}

async function handleTrialWillEnd(subscription) {
  // 試用期間終了3日前通知
  const customer = await stripe.customers.retrieve(subscription.customer);
  await sendTrialEndingNotification(customer.email, subscription);
}

5. Connect(プラットフォーム向け)実装

// Connected Account作成
async function createConnectedAccount(accountData) {
  try {
    const account = await stripe.accounts.create({
      type: 'express', // 'standard', 'express', 'custom'
      country: accountData.country,
      email: accountData.email,
      business_type: accountData.businessType,
      company: {
        name: accountData.companyName,
        phone: accountData.phone,
        address: accountData.address
      },
      capabilities: {
        card_payments: { requested: true },
        transfers: { requested: true }
      },
      // 迅速オンボーディング(2025年新機能)
      settings: {
        payouts: {
          schedule: {
            interval: 'daily'
          }
        }
      }
    });
    
    return account;
  } catch (error) {
    console.error('Connected Account作成エラー:', error);
    throw error;
  }
}

// オンボーディングリンク作成
async function createAccountLink(accountId, returnUrl, refreshUrl) {
  try {
    const accountLink = await stripe.accountLinks.create({
      account: accountId,
      refresh_url: refreshUrl,
      return_url: returnUrl,
      type: 'account_onboarding',
    });
    
    return accountLink.url;
  } catch (error) {
    console.error('アカウントリンク作成エラー:', error);
    throw error;
  }
}

// プラットフォーム手数料付き決済
async function createPlatformPayment(amount, connectedAccountId, applicationFee) {
  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount: amount,
      currency: 'jpy',
      application_fee_amount: applicationFee, // プラットフォーム手数料
      transfer_data: {
        destination: connectedAccountId,
      },
      metadata: {
        platform_fee: applicationFee,
        seller_id: connectedAccountId
      }
    });
    
    return paymentIntent;
  } catch (error) {
    console.error('プラットフォーム決済作成エラー:', error);
    throw error;
  }
}

// 分割支払い(Connect)
async function createTransfer(amount, destination, metadata = {}) {
  try {
    const transfer = await stripe.transfers.create({
      amount: amount,
      currency: 'jpy',
      destination: destination,
      metadata: metadata,
      // 即時転送
      transfer_group: 'ORDER_123'
    });
    
    return transfer;
  } catch (error) {
    console.error('転送作成エラー:', error);
    throw error;
  }
}

6. 2025年新機能:ステーブルコイン・AI統合

// ステーブルコイン財務アカウント(2025年新機能)
async function createFinancialAccount(currency = 'usd') {
  try {
    const account = await stripe.treasury.financialAccounts.create({
      supported_currencies: [currency],
      features: {
        card_issuing: { requested: true },
        deposit_insurance: { requested: true },
        financial_addresses: { aba: { requested: true } },
        inbound_transfers: { ach: { requested: true } },
        intra_stripe_flows: { requested: true },
        outbound_payments: { 
          ach: { requested: true },
          us_domestic_wire: { requested: true }
        },
        outbound_transfers: { 
          ach: { requested: true },
          us_domestic_wire: { requested: true }
        }
      },
      // ステーブルコイン対応
      metadata: {
        stablecoin_enabled: 'true',
        supported_stablecoins: 'USDC,USDB'
      }
    });
    
    return account;
  } catch (error) {
    console.error('金融アカウント作成エラー:', error);
    throw error;
  }
}

// AI不正検知・紛争処理(2025年強化)
async function configureAIFraudDetection(accountId) {
  try {
    // Radar Rule設定(AI強化)
    const rules = await stripe.radar.rules.create({
      action: 'block',
      predicate: "card_country != ip_country AND risk_score > 32",
      // AI機械学習モデル適用
      metadata: {
        ai_model: 'payments_foundation_v1',
        auto_learning: 'enabled'
      }
    });
    
    return rules;
  } catch (error) {
    console.error('AI不正検知設定エラー:', error);
    throw error;
  }
}

// マルチ通貨管理(2025年新機能)
async function convertCurrency(amount, fromCurrency, toCurrency) {
  try {
    // 通貨変換API(実際のAPIは2025年リリース予定)
    const conversion = await stripe.treasury.currencyExchanges.create({
      amount: amount,
      source_currency: fromCurrency,
      destination_currency: toCurrency,
      // リアルタイム為替レート
      exchange_rate_type: 'real_time'
    });
    
    return conversion;
  } catch (error) {
    console.error('通貨変換エラー:', error);
    throw error;
  }
}

// Workflows(自動化)- 2025年新機能
async function createWorkflow(workflowData) {
  try {
    const workflow = await stripe.workflows.create({
      name: workflowData.name,
      trigger: {
        type: 'webhook',
        event_types: workflowData.eventTypes
      },
      steps: workflowData.steps.map(step => ({
        type: step.type,
        action: step.action,
        conditions: step.conditions
      }))
    });
    
    return workflow;
  } catch (error) {
    console.error('Workflow作成エラー:', error);
    throw error;
  }
}