paypal-integration について
paypal-integrationは、Shopify、WooCommerce、BigCommerceや独自ストアを使う開発者向けの決済導入ガイドです。PayPal、Venmo、Pay Laterの設定に加え、サンドボックステスト、サーバー側の決済確定、Webhook検証を扱います。
主な機能
- 01PayPalビジネスアカウントの設定
- 02主要プラットフォームへの決済導入
- 03VenmoとPay Laterの有効化
- 04注文作成と決済確定の実装
- 05Webhookの設定と検証
- 06サンドボックスで決済フローをテスト
活用シーン
- 01カード決済にPayPalを追加
- 02商品ページやカートに簡易決済を設置
- 03独自ストアにPayPal決済を実装
- 04決済確定とWebhook処理をテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill paypal-integrationインストール後、Claude Code で/paypal-integrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
tile.jsonevals/paypal-sdk-loading-and-button-rendering-/criteria.jsontask.mdevals/server-side-order-creation-and-capture-w/criteria.jsontask.mdevals/webhook-handling-with-signature-verifica/criteria.jsontask.md詳細
PayPal の統合
概要
PayPal Checkout を使うと、購入者は PayPal 残高、Venmo、Pay Later(分割払い)、または PayPal が処理するカードで支払えます。PayPal が主要な決済方法となっているドイツ、オランダ、ブラジルでは特に有用です。また、カード情報の入力を避けたい顧客がいるあらゆる市場で役立ちます。主要なプラットフォームにはすべて公式の PayPal 統合機能があり、標準的なチェックアウトであれば認証情報だけで利用でき、カスタムコードは不要です。
このスキルを使う場面
- カード決済プロセッサーと併せて、PayPal を決済方法として追加するとき
- 商品ページやカートに PayPal Express Checkout を導入するとき(購入までの手順を減らせます)
- PayPal が主要な決済方法となっている市場(ドイツ、オランダ、ブラジル)を対象にするとき
- 若い購入者にアピールするため、Venmo や Pay Later(分割払い)を追加するとき
基本手順
ステップ 1:PayPal Business アカウントを作成して設定する
- PayPal Business アカウントをまだお持ちでない場合は、paypal.com/business で PayPal Business アカウントに登録します
- ビジネスの本人確認を行います(支払いを受け取るには事前に必要です)
- 開発とテストを行う場合は、developer.paypal.com に登録し、サンドボックスの購入者/販売者アカウントを作成します
- developer.paypal.com → My Apps → Create App でアプリを作成し、Client ID と Secret を取得します
ステップ 2:プラットフォームに PayPal をインストールする
Shopify
PayPal Express Checkout は Shopify に組み込まれており、ほとんどのストアでデフォルトで有効になっています。
確認または再設定するには:
- Settings → Payments に移動します
- Payment providers で PayPal または Activate PayPal をクリックします
- まだ接続されていない場合は Activate をクリックし、PayPal Business アカウントにログインして連携します
- 次のいずれかを選択します:
- PayPal Express Checkout:従来のチェックアウトフロー(推奨)
- PayPal Complete Payments:Venmo と Pay Later にも対応する新しい統合機能
Venmo と Pay Later を有効にするには:
- PayPal Business ダッシュボードで、Account Settings → Payment Preferences に移動します
- Venmo と Pay Later を有効にします。有効化すると、PayPal アカウントでの設定が反映され、Shopify のチェックアウトに自動的に表示されます
- 商品ページに Pay Later のバナーを表示するには、Shopify App Store から PayPal Pay Later Messaging アプリをインストールします
WooCommerce
- WooCommerce PayPal Payments プラグインをインストールします(WooCommerce/PayPal が管理する公式プラグインで、WordPress.org から無料で入手できます)
- WooCommerce → Settings → Payments → PayPal Payments → Set Up に移動します
- Connect to PayPal をクリックし、PayPal Business アカウントにログインします(OAuth による設定のため、API キーをコピーして貼り付ける必要はありません)
- このプラグインでは、PayPal Standard、Venmo、Pay Later、カード入力欄、PayPal Credit オプションが自動的に有効になります
- WooCommerce → Settings → Payments → PayPal Payments → Smart Payment Buttons でボタンの配置を設定します:
- ボタンを有効にするページを選択します:商品ページ、カートページ、チェックアウトページ
- ボタンの色を設定します(金色、青、銀色、白、黒)
- 商品ページに Pay Later のメッセージを表示するには、プラグイン設定の Pay Later Messaging セクションに移動し、有効にします
PayPal Checkout(代替となる旧式の統合機能): 旧式の WooCommerce PayPal Checkout プラグインも引き続き動作しますが、新規設定には新しい WooCommerce PayPal Payments プラグインをおすすめします。
BigCommerce
- Settings → Payment Methods → Online Payment Methods に移動します
- PayPal Powered by Braintree を見つけて Set Up をクリックします
- Connect with PayPal をクリックし、PayPal Business アカウントで認証します
- 利用する決済方法(PayPal、Venmo、Pay Later)を有効にします
- 設定パネルで PayPal ボタンを表示するページを設定します
また、BigCommerce は PayPal Commerce Platform にも対応しています。すべての PayPal 決済オプションを利用するには、Settings → Payment Methods に移動し、PayPal Commerce Platform を選択します。
カスタム/ヘッドレス
ヘッドレスストアフロントでは、Orders API v2 と PayPal JavaScript SDK を使用します。
PayPal JavaScript SDK を読み込む:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID¤cy=USD&intent=capture&components=buttons"></script>
サーバーサイドで PayPal 注文を作成する:
// POST /api/paypal/create-order
async function createPayPalOrder(req, res) {
const { cartId } = req.body;
const cart = await db.carts.findUnique({ where: { id: cartId } });
const accessToken = await getPayPalAccessToken();
const orderRes = await fetch('https://api-m.paypal.com/v2/checkout/orders', {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'PayPal-Request-Id': cartId, // Idempotency key
},
body: JSON.stringify({
intent: 'CAPTURE',
purchase_units: [{
reference_id: cartId,
amount: {
currency_code: 'USD',
value: cart.total.toFixed(2),
},
}],
}),
});
const order = await orderRes.json();
res.json({ id: order.id });
}
PayPal ボタンを表示して支払いを確定する:
useEffect(() => {
if (!window.paypal) return;
window.paypal.Buttons({
style: { layout: 'vertical', color: 'gold', shape: 'rect' },
createOrder: async () => {
const res = await fetch('/api/paypal/create-order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cartId }),
});
const data = await res.json();
return data.id; // PayPal Order ID
},
onApprove: async (data) => {
// Always capture server-side — never trust client-side only
const res = await fetch('/api/paypal/capture-order', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orderId: data.orderID, cartId }),
});
const result = await res.json();
if (result.success) router.push(`/orders/${result.shopOrderId}/confirmation`);
},
onCancel: () => {
// User closed PayPal popup — leave cart intact, show no error
},
onError: (err) => {
console.error('PayPal error:', err);
setError('PayPal encountered an error. Please try again or use a card.');
},
}).render('#paypal-button-container');
}, [cartId]);
サーバーサイドで支払いを確定する:
// POST /api/paypal/capture-order
async function capturePayPalOrder(req, res) {
const { orderId, cartId } = req.body;
const accessToken = await getPayPalAccessToken();
const captureRes = await fetch(`https://api-m.paypal.com/v2/checkout/orders/${orderId}/capture`, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'PayPal-Request-Id': `capture-${orderId}`, // Idempotency key
},
});
const capture = await captureRes.json();
if (capture.status !== 'COMPLETED') {
return res.status(400).json({ error: 'Payment capture failed' });
}
// Create your internal order record
const order = await createOrderFromCart(cartId, {
paymentMethod: 'paypal',
paypalOrderId: orderId,
paypalCaptureId: capture.purchase_units[0].payments.captures[0].id,
});
res.json({ success: true, shopOrderId: order.id });
}
PayPal Webhook を処理する:
PayPal 開発者ダッシュボードで、次の Webhook を登録します:PAYMENT.CAPTURE.COMPLETED、PAYMENT.CAPTURE.REFUNDED、PAYMENT.CAPTURE.REVERSED。処理する前に、PayPal の署名検証 API を使用して Webhook の署名を検証します。
ステップ 3:PayPal サンドボックスでテストする
- developer.paypal.com → Sandbox → Accounts にアクセスし、事前に作成されたサンドボックスの購入者アカウントと販売者アカウントを使用します
- サンドボックスを使用するように環境変数を設定します:
PAYPAL_CLIENT_ID=<sandbox-client-id> PAYPAL_CLIENT_SECRET=<sandbox-client-secret> PAYPAL_API_BASE=https://api-m.sandbox.paypal.com - サンドボックスの購入者アカウントの認証情報を使って、購入フロー全体をテストします
- Webhook が起動し、ハンドラーが正しく処理することを確認します
ベストプラクティス
- 必ずサーバーサイドで支払いを確定する —
onApproveクライアントコールバックだけを信頼せず、必ずサーバーから Orders API を使用して支払いを確定します PayPal-Request-Idヘッダーを使用する — この冪等性キーにより、リクエストが再試行された場合の二重請求を防げます- 商品ページで Pay Later メッセージを有効にする — チェックアウト前に「$X の無利息 4 回払い」と表示すると AOV が向上します。WooCommerce プラグインにはこの機能が組み込まれています
onCancelを適切に処理する — ユーザーが PayPal ポップアップを閉じたときにエラーを表示せず、再試行するか別の支払い方法を選べるようにします- Webhook の署名を検証する — PayPal は偽造されたペイロードを Webhook エンドポイントに送信する可能性があります。必ず
paypal-transmission-sigヘッダーを検証します
よくある問題
| 問題 | 解決策 |
|---|---|
| 「この販売者は支払いを受け付けていません」というエラー | PayPal アカウントで販売者のオンボーディング(メールアドレスの確認、銀行口座の連携)が完了していることを確認します。また、サンドボックスと本番環境の認証情報が一致していることも確認します |
| 一部のブラウザーで PayPal ポップアップがブロックされる | createOrder コールバックは、ユーザーのクリックイベントから値を即座に返す必要があります。非同期処理による遅延でポップアップブロッカーが起動することがあります。ボタンの表示前にサーバー呼び出しを済ませるか、PayPal 組み込みの API を使用します |
| 支払い確定前に Webhook によって注文が確定される | CHECKOUT.ORDER.APPROVED ではなく PAYMENT.CAPTURE.COMPLETED Webhook を使用します。後者は資金の引き落とし前に起動します |
| Webhook の再試行で注文が重複する | 新しい注文を作成する前に、PayPal の支払い確定 ID を使って既存の注文がないか確認します |
| WooCommerce PayPal プラグインに Venmo/Pay Later が表示されない | Venmo と Pay Later は PayPal Business アカウントの設定で有効にする必要があります(プラグインだけでは有効になりません)。PayPal の Account Settings → Payment Preferences を確認します |
| 再接続後に Shopify PayPal で決済できない | Shopify → Settings → Payments で PayPal アカウントを切断してから再接続します。古い OAuth トークンが期限切れになることがあります |
関連スキル
- @stripe-integration
- @checkout-flow-optimization
- @order-processing-pipeline
- @buy-now-pay-later