Stripe
決済・金融サービスプラットフォーム
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;
}
}