PAY.JP

顧客に支払い方法を登録する

Setup Flow を使用して支払い方法を顧客に紐づけて登録する

Setup Flow とは

Setup FlowAPIは、支払い方法をCustomer (顧客)APIに紐づけて登録するための仕組みです。 Payment Flow (支払い管理オブジェクト)APIが支払いを行うためのフローであるのに対し、Setup Flow は支払い方法の登録のみを行い、実際の決済は行いません。

Setup Flow を使用することで、以下のようなユースケースに対応できます。

  • 会員登録時に支払い方法を登録しておき、次回以降の決済で利用できるようにしたい場合
  • ユーザーがマイページで支払い方法を変更できるようにしたい場合

対応する支払い方法

Setup Flow では以下の支払い方法を登録できます。

  • クレジットカード
  • Apple Pay

各支払い方法の詳細については支払い方法のページをご確認ください。

支払い方法を登録する2つの方法

顧客に支払い方法を登録するには、以下の2つの方法があります。

方法説明適したケース
埋め込み型(Payment Widgets)自社サイトに決済フォームを埋め込むサイトのデザインに合わせたい場合
外部リンク型(Checkout)PAY.JP がホストする登録ページへリダイレクト素早く導入したい場合

埋め込み型(Payment Widgets)で支払い方法を登録する

Payment Widgets を使用すると、自社サイトに支払い方法の入力フォームを埋め込んで、顧客に支払い方法を登録させることができます。

処理の流れ

  1. 加盟店サーバーで Setup Flow を作成し、顧客に紐づけます。
  2. フロントエンドで Payment Widgets を使用して支払い情報の入力フォームを表示します。
  3. ユーザーが支払い情報を入力し、登録を確定します。
  4. 3D セキュアなどの追加認証が必要な場合は、認証ページへリダイレクトされます。
  5. 登録完了後、return_url で指定したページへリダイレクトされます。

実装手順

Setup Flow を利用するには、加盟店システムでサーバーサイドとフロントエンドの両方の実装が必要です。

1. サーバーサイドで Setup Flow を作成する

支払い方法を登録する顧客を指定してSetup FlowAPIを作成します。 customer に顧客 ID を指定し、payment_method_types で登録可能な支払い方法を指定します。

curl -X POST https://api.pay.jp/v2/setup_flows \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": "cus_xxxxx",
    "payment_method_types": ["card"]
  }'

レスポンスとして取得できる client_secret をフロントエンドに渡します。

レスポンス例
{
  "id": "sflw_xxxxx",
  "object": "setup_flow",
  "client_secret": "sflw_secret_xxxxx",
  "customer": "cus_xxxxx",
  "status": "requires_payment_method",
  "payment_method_types": ["card"],
  ...
}

2. フロントエンドで payments.js の利用準備を行う

PAY.JP の JavaScript ライブラリ payments.js を Web ページに読み込み、公開鍵を渡して初期化を行います。

HTML に script タグを設置する場合

<script src="https://js.pay.jp/payments.js"></script>
<script>
  const payments = PayjpPayments('pk_test_xxx');
  ...
</script>

npm などのパッケージマネージャーを利用する場合

npm install @payjp/payments-js
import { loadPayments } from '@payjp/payments-js'

const payments = await loadPayments('pk_test_xxx')
...

3. Widgets を初期化してフォームを表示する

Widgets を初期化します。 この時に「ステップ 1」で取得した client_secret を使用します。

const widgets = payments.widgets({
  clientSecret: "sflw_secret_xxxxx",
});

以下のように、指定した HTML 要素に Widgets をマウントすることで画面に決済フォームを表示します。

<div id="payment-form"></div>
const paymentForm = widgets.createForm("payment", {
  layout: "tab",
});
paymentForm.mount("#payment-form");

4. 支払い方法を確認・登録する

ユーザーがフォームに支払い情報を入力した後、登録を確定するには confirmSetup メソッドを実行します。

const result = await widgets.confirmSetup({
  return_url: 'https://example.com/setup-complete'
});

if (result.error) {
  // エラー処理
  console.error(result.error);
}

confirmSetup の実行後は自動的に別のページへ遷移し、登録処理の完了後に return_url で指定した URL へリダイレクトされます。

5. リダイレクト先で登録完了を確認する

return_url にリダイレクトされた後、支払い方法の登録が成功しているかどうかを確認する必要があります。

リダイレクト先の URL にはクエリーパラメーターとして setup_flow_id に Setup Flow の ID、setup_flow_client_secretclient_secret が付与されています。 そのため、バックエンド、フロントエンドのどちらでも該当の Setup Flow を取得し状態を確認できます。

リダイレクト先に付与されるクエリーパラメーターの例
https://example.com/setup-complete?setup_flow_id=sflw_xxxxx&setup_flow_client_secret=sflw_secret_xxxxx

フロントエンドで確認する場合は、payments.js の retrieveSetupFlow メソッドを使用して Setup Flow を取得し、status フィールドを確認します。

const setupFlow = await payments.retrieveSetupFlow(
  "sflw_secret_xxxxx"
);

if (setupFlow.status === 'succeeded') {
  // 登録成功
  const paymentMethodId = setupFlow.payment_method;
  console.log('登録された支払い方法:', paymentMethodId);
} else {
  // 登録失敗時の処理
}

登録が成功している場合は statussucceeded になり、payment_method に登録されたPayment Method (支払い方法)APIの ID が格納されます。

外部リンク型(Checkout)で支払い方法を登録する

Checkout SessionAPIsetup モードで作成すると、PAY.JP がホストする支払い方法登録ページを使用できます。 自社サイトにフォームを埋め込む必要がないため、素早く導入できます。

処理の流れ

  1. ユーザーが支払い方法登録ボタンをクリックします。
  2. 加盟店サーバーで mode: 'setup' を指定して Checkout Session を作成し、session.url にリダイレクトします。
  3. ユーザーは PAY.JP の登録ページで支払い情報を入力して登録を行います。
  4. 登録完了後、PAY.JP が Webhook で結果を通知します。
  5. 登録が成功した場合は success_url で指定したページへ、キャンセルした場合は cancel_url で指定したページへリダイレクトされます。

実装手順

1. サーバーサイドで Checkout Session を作成する

modesetup を指定して Checkout Session を作成します。 customer_id に顧客 ID を指定することで、登録された支払い方法がその顧客に紐づきます。

Checkout Session を setup モードで作成する
import { createClient, createCheckoutSession } from '@payjp/payjpv2'

const client = createClient({
  apiKey: process.env.PAYJP_API_KEY!,
})

app.post('/create-checkout-session', async (req, res) => {
  try {
    const { data: session } = await createCheckoutSession({
      client,
      body: {
        mode: 'setup',
        customer_id: 'cus_xxxxx',
        payment_method_types: ['card'],
        success_url: 'https://example.com/setup-complete',
        cancel_url: 'https://example.com/setup-cancel',
      }
    })
    res.redirect(303, session.url)
  } catch (error) {
    console.error('Checkout session creation failed:', error)
    res.status(500).json({
      error: '登録画面の生成に失敗しました。'
    })
  }
})

2. ユーザーを Checkout にリダイレクトする

支払い方法登録ボタン
<form action="/create-checkout-session" method="POST">
  <button type="submit">支払い方法を登録する</button>
</form>

3. Webhook で登録完了を確認する

登録完了の通知を受け取るには、Webhook エンドポイントを実装します。 詳しくは外部リンク型決済を使うの Webhook 実装を参照してください。

app.post('/webhook', (req, res) => {
  const event = req.body

  if (event.type === 'checkout.session.completed') {
    const session = event.data

    if (session.mode === 'setup') {
      // 支払い方法の登録完了
      // setup_flow_id を使って SetupFlow を取得し、payment_method_id を確認できます
      console.log('支払い方法が登録されました:', session.setup_flow_id)
    }
  }

  res.json({ received: true })
})

決済に利用した支払い方法を後で顧客に紐づける

ここまでは Setup Flow を使って支払い方法を登録する方法を説明しましたが、Payment Flow (支払い管理オブジェクト)APIで決済を行った際に作成された支払い方法を、後から顧客に紐づけることもできます。

Payment Flow (支払い管理オブジェクト)APIで作成されたPayment Method (支払い方法)APIは、最初は顧客に紐づいていません。 この支払い方法を後から顧客に紐づけることで、次回以降の決済で再利用できるようになります。

ユースケース

  • 初回決済時に「この支払い方法を保存する」オプションを提供したい場合
  • ゲスト決済後に会員登録した顧客に支払い方法を紐づけたい場合

実装手順

1. 決済時に PaymentMethod ID を取得する

Payment Flow が succeeded になった後、payment_method_id フィールドから支払い方法 ID を取得できます。

決済完了後に PaymentMethod ID を取得
import { createClient, getPaymentFlow } from '@payjp/payjpv2'

const client = createClient({
  apiKey: process.env.PAYJP_API_KEY!,
})

const { data: paymentFlow } = await getPaymentFlow({
  client,
  path: { payment_flow_id: 'pfw_xxxxx' }
})

if (paymentFlow.status === 'succeeded') {
  const paymentMethodId = paymentFlow.payment_method_id
  // この ID を保存しておく
}

2. 支払い方法を顧客に紐づける

Payment MethodAPI の attach API を使用して、支払い方法を顧客に紐づけます。

PaymentMethod を Customer に紐づける
curl -X POST https://api.pay.jp/v2/payment_methods/pm_xxxxx/attach \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cus_xxxxx"
  }'

紐づけの制約

  • 支払い方法は1つの顧客にのみ紐づけられます。
  • 一度顧客に紐づいた支払い方法は、別の顧客に紐付けることはできません。

登録した支払い方法で支払う

Setup Flow や attach API で登録した支払い方法で決済するには、バックエンドから直接決済を行います。 詳しくは顧客で決済するのページをご確認ください。

Setup Flow のステータス

Setup FlowAPIは作成から完了またはキャンセルまで、以下の状態を持ちます。

ステータス説明
requires_payment_method支払い方法の入力が必要な状態。Setup Flow 作成時の初期状態
requires_confirmation支払い方法が設定済みで、確定待ちの状態
requires_action3D セキュアなどの追加認証が必要な状態
processing登録処理中の状態
succeeded支払い方法の登録が正常に完了した状態
canceledSetup Flow がキャンセルされた状態