Apple Pay 決済の実装
Apple Pay 決済を実装し、顧客から Apple Pay 決済を受け付ける
Apple Pay 決済を実装する方法は2つあります。
事前準備
Payments Widgets を使用する場合は、事前にドメイン登録が必要です。Checkout v2 を使用する場合は不要です。
Checkout v2(外部リンク型決済)を使用する場合
PAY.JP がホスティングする Checkout v2 決済ページにユーザーをリダイレクトするだけで、Apple Pay 決済を含む複数の支払い方法に対応できます。
curl https://api.pay.jp/v2/checkout/sessions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"payment_method_types": ["card"],
"payment_method_types": ["card", "apple_pay"],
"line_items": [
{
"quantity": 1,
"price": "price_xxxxx"
}
],
"mode": "payment",
"success_url": "https://example.com/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://example.com/cancel"
}'レスポンスに含まれる url にユーザーをリダイレクトしてください。
詳細な実装方法については、外部リンク型決済を使うをご覧ください。
Payments Widgets(埋め込み型決済)を使用する場合
外部ドメインではなく、加盟店のサイト上で決済フローを管理したい場合は Payments Widgets を使用します。クライアント側とサーバー側でそれぞれの実装が必要です。
ドメイン登録が必要
Payments Widgets で Apple Pay を利用するには、事前に PAY.JP 管理画面でドメイン登録が必要です。詳細はApple Pay 決済についてをご確認ください。
1. サーバーサイドで Payment Flow を作成
サーバー側に Payment Flow を作成するエンドポイントを用意します。
このとき、Payment Flow の client_secret が必要になるので、レスポンスとして返却するようにします。
app.post('/api/create-payment-flow', async (req, res) => {
try {
const { amount } = req.body
const { data: paymentFlow } = await createPaymentFlow({
client,
body: {
amount: amount,
payment_method_types: ['apple_pay']
}
})
res.json({
client_secret: paymentFlow.client_secret
})
} catch (error) {
console.error('Payment Flow creation failed:', error)
res.status(500).json({
error: 'Payment Flow の作成に失敗しました。'
})
}
})2. クライアント側で Payment Widgets を使用して決済フォームを表示
1 で作成したエンドポイントを呼び出し、Payment Flow を作成します。
Payment Flow の client_secret を取得したら、payments-js ライブラリを使用して Payment Widgets を初期化し、決済フォームを表示します。
import { loadPayments } from '@payjp/payments-js';
// Payment Flow を作成して client_secret を取得
const response = await fetch('/api/create-payment-flow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 1000 })
});
const { client_secret } = await response.json();
const payments = await loadPayments('pk_test_xxxxx');
const widgets = payments.widgets({ clientSecret: client_secret });
// Payment Widgets を作成してマウント
const paymentForm = widgets.createForm('payment', {
paymentMethodOrder: ['card', 'apple_pay']
});
paymentForm.mount('#payment-form');Apple Pay の表示について
Apple Pay は対応端末でのみ表示されます。非対応の環境では決済フォーム上に Apple Pay の選択肢は表示されず、他の支払い方法のみが利用可能になります。
3. 決済の確定
ユーザーは表示された決済フォームで Apple Pay を選択します。
加盟店側で送信ボタンを用意し、クリックイベントなどを拾って決済情報を送信します。
Apple Pay を選択した場合、Apple Pay の認証シートが表示され、Touch ID や Face ID で認証を行います。
const submitButton = document.getElementById('submit-button');
submitButton.addEventListener('click', async () => {
const { error } = await widgets.confirmPayment({
return_url: 'https://example.com/payment/complete'
});
if (error) {
console.error('決済エラー:', error);
// エラーメッセージを表示
return;
}
// 認証完了後、return_url にリダイレクトされます
});4. 決済結果の確認
決済完了後、指定した return_url にユーザーがリダイレクトされます。このとき、URL には以下のパラメータが付与されています。
| パラメータ | 説明 |
|---|---|
payment_flow_id | Payment Flow の ID |
payment_flow_client_secret | Payment Flow の client_secret |
決済結果を確認する方法は2つあります。
方法1: フロントエンドで決済結果を確認する
payments-js の retrievePaymentFlow メソッドを使用して、フロントエンドのみで決済結果を確認できます。
import { loadPayments } from '@payjp/payments-js';
// URL パラメータから client_secret を取得
const query = new URLSearchParams(window.location.search);
const clientSecret = query.get('payment_flow_client_secret');
// payments-js を使って Payment Flow を取得
const payments = await loadPayments('pk_test_xxxxx');
const paymentFlow = await payments.retrievePaymentFlow(clientSecret);
if (paymentFlow.status === 'succeeded') {
// 決済成功画面を表示
console.log('決済が完了しました');
} else {
// 決済失敗画面を表示
console.log('決済に失敗しました');
}方法2: サーバーサイドで決済結果を確認する
Payment Flow ID を使用してサーバーサイドで決済結果を確認する方法です。 サーバーに確認用のエンドポイントを作成し、フロントエンドからそのエンドポイントを呼び出して結果を取得します。
1. 決済ステータス確認エンドポイントの作成
まず、サーバーに Payment Flow の決済ステータスを確認するエンドポイントを作成します。
app.post('/api/check-payment-status', async (req, res) => {
try {
const { payment_flow_id } = req.body
// Payment Flow のステータスを取得
const { data: paymentFlow } = await getPaymentFlow({
client,
path: { payment_flow_id }
})
res.json({
status: paymentFlow.status
})
} catch (error) {
console.error('Status check failed:', error)
res.status(500).json({
error: 'ステータスの確認に失敗しました。'
})
}
})2. 決済ステータス確認エンドポイントの呼び出し
フロントエンドから上記のエンドポイントを呼び出し、決済結果を取得します。
// URL パラメータから情報を取得
const query = new URLSearchParams(window.location.search);
const paymentFlowId = query.get('payment_flow_id');
// サーバーにステータス確認をリクエスト
const response = await fetch('/api/check-payment-status', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_flow_id: paymentFlowId
})
});
const { status } = await response.json();
if (status === 'succeeded') {
// 決済成功画面を表示
console.log('決済が完了しました');
} else {
// 決済失敗画面を表示
console.log('決済に失敗しました');
}