PAY.JP
PAY.JP

Payment Flow API の仕組み

Payment Flow API を使用した支払いのライフサイクルを理解します

Payment Flow (支払い管理オブジェクト)APIは、PAY.JP API v2 で支払いを進めるための基本となるオブジェクトです。支払いプロセス全体を管理し、3D セキュア認証などの複雑な支払いフローを安全に処理します。

Payment Flowとは

Payment FlowAPIは「支払いのプロセス」を管理するオブジェクトで、支払いフロー全体を管理し、支払いの開始から完了までを追跡します。 3D セキュアなどの追加の認証フローも自動的に処理します。

明確なステータス遷移により現在の状況を把握しやすく、オーソリと確定を分離することで商品発送のタイミングなどに合わせた柔軟な支払い処理が可能です。

基本的な決済フローの流れ

Payment Flow を作成する

支払いを行うためには、まず Payment Flow を作成します。これはサーバー側で行います。

Payment Flow の作成には以下のパラメーターが必要です。

  • amount: 支払い金額
  • currency: 通貨
  • capture_method: 確定方法(デフォルトは automaticmanual を指定すると、オーソリと確定を分けることができます。)

作成した Payment Flow から client_secret を取得し、フロントエンドに渡します。 この client_secret はフロントエンド(ブラウザなど)から支払いを行うための認証トークンで、このトークンを使って支払いを実行し、確定することができます。

server.ts
// Payment Flow を作成
const { data: paymentFlow } = await createPaymentFlow({
  client,
  body: {
    amount: 1000
    // capture_methodはデフォルトで 'automatic' が設定されます
  }
})

// client_secretをフロントエンドに返す
res.json({
  client_secret: paymentFlow.client_secret
})

client_secret を使ったブラウザ側の実装

client_secret は、フロントエンドで特定の Payment Flow に対してのみ操作を許可する一時的な認証トークンです。 payments-js に client_secret を渡すと、クレジットカードなどの支払い方法に対応した入力画面が自動的に表示されます。

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

// ページ読み込み時: 決済フォームを表示
const payments = await loadPayments('pk_test_xxxxx')
const elements = payments.elements({ client_secret: clientSecret })
const paymentElement = elements.create('payment')
paymentElement.mount('#payment-element')

// ユーザーが送信ボタンをクリックした時: 支払いを実行
document.getElementById('submit-button').addEventListener('click', async (e) => {
  e.preventDefault()

  const result = await payments.confirmPayment({
    elements,
    confirmParams: { return_url: 'https://your-site.example.com/return_url' }
  })
})

「confirm」や「確認」について

このドキュメントで使用される「confirm」や「確認」という用語は、PAY.JPのAPI操作としての confirmPayment()confirm APIを指します。これは「支払いを実行する」という意味で、単に内容を確かめる一般的な用語の「確認」とは異なります。

具体的には、顧客が入力した支払い情報を使って実際に支払い処理を開始する操作を意味します。

支払い結果の処理

confirmPayment() を呼び出すと、処理が正常に進んだ場合は自動的に return_url にリダイレクトされます。エラーが発生した場合のみ、結果オブジェクトの error プロパティにエラー情報が含まれます。

// confirmPayment の呼び出し
const result = await payments.confirmPayment({
  elements,
  confirmParams: { return_url: 'https://your-site.example.com/return_url' }
})

// エラーがある場合(リダイレクトされなかった場合)
if (result.error) {
  // エラーメッセージを表示
  console.error(result.error.message)
}
// 成功した場合は自動的に return_url にリダイレクトされる

return_url ページでは、クエリーパラメーターから payment_flow_client_secret を取得し、retrievePaymentFlow() で支払い結果を確認します。

return_url.ts
// return_url ページでの結果取得
const query = new URLSearchParams(window.location.search)
const clientSecret = query.get('payment_flow_client_secret')

if (clientSecret) {
  const paymentFlow = await payments.retrievePaymentFlow(clientSecret)

  switch (paymentFlow.status) {
    case 'succeeded':
      // 支払い完了 - 注文確定などの処理
      break
    case 'requires_capture':
      // 確定待ち(capture_method=manual の場合)
      // サーバー側で capture API を呼び出す
      break
    case 'requires_payment_method':
      // 支払い方法が必要(カード情報の入力エラーなど)
      // last_payment_error にエラー詳細がある場合
      if (paymentFlow.last_payment_error) {
        console.error(paymentFlow.last_payment_error.message)
      }
      break
    case 'processing':
      // 処理中 - 結果を待機
      break
    default:
      // その他のステータス
      break
  }
}

capture_method の種類

capture_method には次の 2 つのモードがあり、それぞれ支払い確定のタイミングが異なります。

capture_method説明
automatic顧客が支払いを承認すると、自動的に確定させます。(デフォルト)
manual顧客が支払いを承認すると一旦確定を保留し、後で Capture API を使用して確定します。
オーソリと売上確定を分けたい場合に使用します。

Payment Flow のライフサイクルとステータス

支払いフローの中で Payment Flow は API の呼び出しや顧客の操作に応じて複数のステータスを遷移します。各ステータスが示す意味と次に取るべきアクションを把握しておくことで、適切なエラー処理や UI 表示を実装しやすくなります。

ステータスの遷移

ステータスの詳細

ステータス説明次のアクション
requires_payment_method支払い方法が必要な状態です。payment_method を指定して confirm するか、支払い方法を設定してから confirm します。
requires_confirmation支払い方法は設定されていますが、まだ確認されていない状態です。confirm API を呼び出して支払いを開始します。
requires_action顧客による追加のアクション(3Dセキュア認証など)が必要な状態です。handleNextAction を呼び出してください。1
processing支払い処理中の状態です。他の操作を行わずに完了を待ってください。
requires_captureオーソリは成功したが確定(capture)が必要な状態です。capture_method=manual の場合にこの状態になります。Capture API を呼び出して支払いを確定してください。
succeeded支払いが成功した状態です。支払いは完了しています。
canceledPayment Flow がキャンセルされた状態です。他のステータスに遷移できません。

フロントエンドでの requires_action の対応

requires_action ステータスは、3D セキュア認証や PayPay 決済ページでの支払い処理など、顧客による追加の操作が必要な場合に発生します。 フロントエンドの confirmPayment または confirmSetup メソッドを呼び出した場合、これらのメソッドは自動的に requires_action の処理を行います。

すでに登録済みの顧客情報を使ってサーバーサイドから confirm を呼び出した場合にステータスが requires_action になった場合は、顧客による追加操作を行うためフロントエンドで以下のように対応します。

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

// payments-js を初期化
const payments = await loadPayments('pk_test_xxxxx')

// サーバーから Payment Flow の client_secret を受け取る
// (API レスポンス、クエリパラメータなど、受け渡し方法は任意)
const clientSecret = '...'

// ページ遷移前にエラーが発生した場合のみ result が返される
const result = await payments.handleNextAction({ clientSecret })
if (result.error) {
  // エラー処理
}

handleNextAction メソッドは、requires_action に必要な処理を行うために即座にページ遷移し、必要な処理の完了後に Payment Flow に設定されている return_url にリダイレクトします。 Payment Flow に対して return_url が設定されていない場合は、フロントエンドでの処理を行う前にサーバー側で Payment Flow Update API を呼び出して return_url を設定するようにしてください。

関連リソース

Footnotes

  1. handleNextAction メソッドは Payment Flow の next_action プロパティの内容に基づいて、3Dセキュア認証や PayPay 決済ページへの遷移など、必要な処理を自動的に行います。詳細はフロントエンドでの requires_action の対応を参照してください。