Paidy決済の流れ

コンシューマーがメールアドレスと携帯番号だけで手軽に、安全に決済を行えるのがPaidy決済の大きな特徴です。

通常の決済

通常の決済とは、定期購入の決済と区別される一度限りの決済のことを示します。通常の決済はPaidy Checkout経由でコンシューマーが開始し、Paidy API経由でマーチャントが管理していきます。

[payments overview diagram]

通常の決済の典型的な流れ

  • Paidy Checkoutの流れに従って数回クリックするだけで、コンシューマーが手軽に注文を行います。
  • PaidyがSMSを通じてコンシューマーを認証し、決済をAuthorizeして決済データを作成します。
  • 次にマーチャントが既存の注文管理システムを使って注文処理と発送を行い、コンシューマーに請求できる段階になったらAPI経由で決済をCaptureします。

また、API経由で決済をキャンセルしたり、払い戻しを行ったりすることもできます。

定期購入の決済

定期購入の決済とは、コンシューマーとマーチャント双方の同意に基づいて一定の間隔で繰り返し行う決済のことを示します。定期購入の決済は、Paidy Checkout経由でコンシューマーが作成したトークンを使って開始します。このトークンとは、単にコンシューマーのPaidyアカウントを識別するだけのものです。トークンの作成後、マーチャントはPaidy API経由で(そのトークンを使用する)定期購入の決済を新たに開始したり、各トークンや決済を管理したりできるようになります。

[payments overview diagram]

定期購入の決済の典型的な流れ(トークンの作成を含む)

  • コンシューマーがPaidy Checkoutを使って注文を行います。
  • Paidyがコンシューマーを認証し、トークンを作成します。
  • そうするとPaidyが決済のAuthorizeを行い、決済データが作成されます。
  • コンシューマーに請求を行う準備ができたら、マーチャントがAPI経由で決済をCaptureします。
  • 以後、API経由でCreateリクエストやCaptureリクエストを送信するだけで、前述のトークンを使用する決済を簡単に開始できるようになります。

開始した決済は、通常の決済の場合と同様にPaidy API経由で管理していきます。

決済のライフサイクル

[決済のライフサイクル]

 

  • ステータス

    説明

  • AUTHORIZED

    正常に開始された新規決済に付与されるステータスです。
    ステータスがAUTHORIZEDである決済に対して行えるリクエストは、CaptureCloseRetrieveUpdateです。

  • REJECTED

    Authorizeに失敗した決済に付与されるステータスです。
    ステータスがREJECTEDである決済に対して行えるリクエストは、Retrieveだけです。

  • CLOSED

    CaptureあるいはCloseが完了した決済に付与されるステータスです。
    ステータスがCLOSEDである決済に対して行えるリクエストは、RefundRetrieveUpdateです。

Paidy API

決済データが作成されたら、Paidy APIを使って簡単かつ安全に決済を管理できるようになります。その際、APIリクエストはマーチャントのバックエンドサーバーから行う必要があります。

API経由で行える操作は次の通りです。

APIはJSON型のリクエストとレスポンスを使用するRESTエンドポイントです。通信はすべてHTTPSを介して安全に行われます。

安全な通信

Paidyにとって最も重要なのは、セキュリティとデータの整合性を維持することです。ネットワーク通信を暗号化し、インターネット上に存在するウェブサイトが本物であることを確認するために業界で標準的に採用されているプロトコルが、TLSです。PaidyはこのTLSのバージョン1.1以降をサポートしています。さらに、あらゆるデータを安全にやり取りするために、HTTPS通信を利用しています。

APIのバージョン

現行のAPIのバージョンは2016-07-01です。このバージョン番号はAPIリクエストを行う毎にヘッダーで指定するか、あるいはマーチャントダッシュボードで設定できます。

APIのバージョンがヘッダーで指定されていない場合、マーチャントダッシュボードで設定されているバージョンに基づいて処理が行われます。 さらにマーチャントダッシュボードでもこの設定を行っていない場合は、現行のAPIのバージョンが自動的に適用されます。

リクエストを行う前に、ご利用中のバージョンのAPIでそのエンドポイントを利用できるかどうかご確認ください。v1とv2では、リクエストの方法もエンドポイントのURIも異なっています。v1の仕様に従ったリクエストをv2用のエンドポイントに送信すると(あるいはその逆でも)リクエストが失敗します。

metadataフィールド

オブジェクトに関する補足的な情報をmetadataフィールドに保存できます。このmetadataフィールドは、tokenオブジェクト、決済オブジェクト、capturesオブジェクト、refundsオブジェクトのすべてに含まれています。例えば、マーチャントが保存しておかなければならないデータを割り当てるためのフィールドがPaidy APIに存在しない場合、このフィールドにキーと値のペアを保存することができます。また、各フィールドにセットできるキーは20件までです。

例:


"metadata": {
  "key1": "value1",
  "key2": "value2"
}


  • tokenオブジェクトのメタデータはPaidy Checkout経由でセットされます。
  • 決済オブジェクトのメタデータはPaidy Checkout経由でセットされ、Updateリクエストを行うことで更新できます。決済のメタデータは何度でも更新できますが、更新を行う度に既存のメタデータがすべて上書きされるという点にご注意ください。
  • capturesオブジェクトのメタデータをセットする際は、Captureリクエストを行います。また、データをセットした後は更新ができなくなります。
  • refundsオブジェクトのメタデータをセットする際は、Refundリクエストを行います。この払い戻しのメタデータは何度でも更新できますが、更新を行う度に既存のメタデータがすべて上書きされるという点にご注意ください(また、Refundリクエストを行う際に金額を指定しなければ、決済の全額を払い戻すよう求めるリクエストだとみなされる点もご留意ください)。

UTF-8でエンコード

日本語の文字をJSON形式で送信する際、意図しない文字(?や□)に文字化けすることがあります。送信時の文字化けを避け、テキストがPaidyのユーザーインターフェイスに正しく表示されるよう、送信前にテキストがUTF-8でエンコードされていることを必ず確認するようにしてください。

通常の決済を作成

通常の決済はPaidy Checkout経由でしか作成できません。開始した新規決済のステータスはAUTHORIZEDになっています。 決済をCaptureしなければコンシューマーへの請求が完了しません。コンシューマーに請求を行う準備ができたら、マーチャントはCaptureリクエストを送信します。

リクエストがAuthorizeされると、有効期間が自動的に設定されますのでご注意ください。決済の有効期限を確認するには、バックエンドシステムから/payments/{id}エンドポイント({id}の部分はPayment ID)にGETリクエストを送信します。このリクエストの処理が成功すると決済オブジェクト全体が返ってきます。expires_atフィールドは、その決済の有効期限を示します。

定期購入の決済を作成

定期購入の決済はAPI経由で開始し、Authorizeを行います。 その際、トークンとコンシューマーのstatusがどちらもACTIVEでなければなりません。決済データを作成する際は、/paymentsエンドポイントにPOSTリクエストを送信します。リクエストボディには以下のフィールドをすべて含めてください。

  • パラメーター

    説明

  • token_id

    string

    必須

    Paidyが生成する、「tok_」で始まるトークンID。

  • amount

    double

    必須

    税、送料を含み、値引きの対象であればさらにそれを適用した後の決済総額。

  • currency

    string

    必須

    決済で使用する通貨を示す、ISO4217通貨コードに準じた値(初期値はJPY)。

  • description

    string

    必須ではありません

    注文の概要。

  • store_name

    string

    必須ではありません

    Checkoutアプリケーションのヘッダー部分、MyPaidy、マーチャントダッシュボードに表示される店舗名。

  • buyer_data

    Buyer_data オブジェクト

    必須

    コンシューマーの購入履歴に関する情報を含むbuyer_dataオブジェクト

  • order

    Orderオブジェクト

    必須

    Orderデータ
    注意: 新規決済を開始するリクエストの場合は必須であり、トークンを作成するリクエストの場合は任意となるフィールドです。

  • shipping_address

    ShippingAddressオブジェクト

    必須

    Shipping addressデータ

  • metadata

    string

    必須ではありません

    マーチャントは自分で定義した決済に関する補足的なデータをこのフィールドに保存できます。このフィールドにはキーと値のセットを20件まで追加できます。

例:


curl -X "POST" "https://aapi.paidy.com/payments" \
  -H "Content-Type: application/json" \
  -H "Paidy-Version: 2016-07-01" \
  -H "Authorization: Bearer $secret_key" \
  -d $'{
         "token_id": "tok_WL0GoQwAAAoA1beX",
         "amount": 12500,
         "currency": "JPY",
         "description": "Description",
         "store_name": "Paidy sample store",
         "buyer_data": {
             "age": 29,
             "order_count": 1000,
             "ltv": 250000,
             "last_order_amount": 20000,
             "last_order_at": 20
         },
         "order": {
             "items": [ {
                   "id": "PDI001",
                   "quantity": 1,
                   "title": "Paidyスニーカー",
                   "unit_price": 12000,
                   "description": "Paidyスニーカー"
             } ],
             "order_ref": "your_order_ref",
             "shipping": "500",
             "tax": 300
         },
         "shipping_address": {
             "line1": "AXISビル 10F",
             "line2": "六本木4-22-1",
             "city": "港区",
             "state": "東京都",
             "zip": "106-2004"
         },
         "metadata": {}
      }'

トークンを使用して決済データを作成する際は、必ずPaidyがトークンとコンシューマーのstatusがACTIVEであるかどうかチェックした上で決済金額がAuthorizeされます。このチェックにすべて通過すれば、トークンを使用して新しい決済データが作成されます。コンシューマーに請求を行う準備ができたら、マーチャントはCaptureリクエストを送信します。

リクエストがAuthorizeされると、有効期間が自動的に設定されますのでご注意ください。決済の有効期限を確認するには、バックエンドシステムから/payments/{id}エンドポイント({id}の部分はPayment ID)にGETリクエストを送信します。このリクエストの処理が成功すると決済オブジェクト全体が返ってきます。expires_atフィールドは、その決済の有効期限を示します。

決済のCapture

コンシューマーに請求を行う準備ができたら、マーチャントはCaptureリクエストを送信します。

決済をCaptureしなければコンシューマーへの請求が完了しません。 つまり、マーチャントは自分たちの注文処理プロセスに合わせて請求を行うタイミングを決定できます。Authorizeの直後にCaptureを実行することも可能ですし、商品の配送が完了した時に実行することも可能です。

Captureリクエストが完了するとマーチャントへの支払いとコンシューマーへの請求が確定しますが、これはCaptureを実行する際に指定した金額だけが対象になります。

また、Captureはオープン状態の決済、つまりAuthorize済みで有効期間内の決済に対してのみ実行できます。(リクエストがAuthorizeされると、有効期間が自動的に設定されますのでご注意ください。この有効期間は利用規約に明記されており、期限が過ぎると注文をCaptureできなくなります。)

決済のCapture

決済のCaptureを行う際は、/payments/{id}/capturesエンドポイント({id}の部分はPayment ID)にPOSTリクエストを送信します。リクエストボディは空にしておくか、あるいはmetadataフィールドを含めることもできます。このフィールドには、captureオブジェクトについての補足的な情報を示す、キーと値のセットを20件まで追加できます。

例:


  curl -X "POST" "https://api.paidy.com/payments/pay_WD1KIj4AALQAIMtZ/captures" \
    -H "Content-Type: application/json" \
    -H "Paidy-Version: 2016-07-01" \
    -H "Authorization: Bearer $secret_key" \
    -d $'{"metadata": {"key1": "value1","key2": "value2"}}'

決済がAuthorize済みであればCaptureが実行されます。リクエストに成功した場合は決済オブジェクトが、失敗した場合は例外が返り、マーチャントはすぐに結果を知ることができます。 成功した場合、「cap_」で始まる一意のCapture IDといった払い戻しに関するデータが決済オブジェクトに追加されます。このCapture IDは必ずマーチャント側のシステムで保存しておいてください。Refundリクエストを送信する際にこのIDが必要になります。

注文金額の全額をCaptureした決済の状態は自動的にCLOSEDに更新されます。

例:


  {
    "id":"pay_WFDYLhEAAEQA42Dw",
    "created_at":"2016-11-14T05:27:10.063Z",
    "expires_at":"2016-12-13T05:28:32.143Z",
    "amount":39800,
    "currency":"JPY",
   "description":" ",
    "store_name":"Paidy sample store",
    "test":true,
    "status":"closed",
    ...,
    "captures":[
      {
        "id":"cap_WFIk5yIAACIAC6n3",
       "created_at":"2016-11-15T05:06:47.189Z",
       "amount":39800,
       "tax":300,
       "shipping":500,
       "items":[
         {
           "id":"PDI001",
           "title":"Paidyスニーカー",
           "description":" ",            
            "unit_price":10000,
           "quantity":1
         },{
           "id":"EXC002",
           "title":"エクスコスニーカー",
           "description":" ",
           "unit_price":15000,
           "quantity":2
         },{
           "id":"CPN001",
           "title":"Discount",
           "description":" ",
           "unit_price":-1000,
           "quantity":1
         }
       ],
       "metadata":{"key1":"value1","key2":"value2"}
     }
   ], 
   ...
 }

決済のRefund

Paidy APIを利用すれば支払いの一部あるいは全額を払い戻すことができます。Capture済みの支払いに対してRefundを実行できますが、リクエストを行うためにはCapture IDとPayment IDの両方が必要になります。また、Refundリクエストは特定のCaptureを指定して行います。

決済のRefund

決済のRefundを行う際は、/payments/{id}/refundsエンドポイント({id}の部分はPayment ID)にPOSTリクエストを送信します。その際、リクエストボディにCapture IDを含めてください。必須フィールドはこれだけですが、任意で以下のフィールドを送信することもできます。

  • amountフィールド:Paidy APIはこのフィールドの値をもとにしてリクエストがPartial Refund(一部払い戻し)なのかFull Refund(全額払い戻し)なのかを判断します。amountフィールドを指定しない場合、Capture済みの金額すべてが払い戻しの対象になります
  • reasonフィールド:払い戻しの理由を示すフィールドです。
  • metadataフィールド:払い戻しに関する補足的な情報をマーチャントが定義できるフィールドです。このフィールドにはキーと値のセットを20件まで追加できます。

例:


  curl -X "POST" "https://api.paidy.com/payments/pay_WD1KIj4AALQAIMtZ/refunds" \
    -H "Content-Type: application/json" \
    -H "Paidy-Version: 2016-07-01" \
    -H "Authorization: Bearer $secret_key" \
    -d "{\"capture_id\":\"cap_WFIk5yIAACIAC6n3\",\"amount\":10000}"

一つの決済に対してPartial RefundとFull Refundの両方を実行することも可能です。 例えば決済総額が10,000円の場合、amountフィールドを「3000」に指定してRefundリクエストを送信すれば、3,000円分のPartial Refundを実行できます。その後、amountフィールドを指定せずにリクエストを送ることで、Full Refundを実行して残りの7,000円をすべて払い戻すことが可能です。逆に、Full Refundリクエストの後からPartial Refundリクエストを実行することはできません。

Refundリクエストが成功すると、払い戻しに関するデータが含まれた決済オブジェクトが返ってきます。各Refundには「ref_」から始まる一意のRefund IDが割り当てられます。

例:


  {
    "id":"pay_WFDYLhEAAEQA42Dw",
    ...
    "refunds":[
      {
        "id":"ref_WFImZyIAAD8AC6pC",
        "created_at":"2016-12-15T05:13:11.800Z",
        "capture_id":"cap_WFIk5yIAACIAC6n3",
         "amount":10000,
        "reason":"unknown",
        "metadata":{}
       }
    ],
    ...
  }

RefundリクエストはCaptureを対象にして行うため、これにより決済のstatusが更新されることはありません。

決済データを取得

決済の詳細情報を確認する際はpaymentsエンドポイントを利用します。これは決済の現在の状態、実行したRefundについての情報など、決済の詳細情報をすべて取得できるエンドポイントです。決済のPayment IDが有効であればデータを取得できます。

決済オブジェクト全体を確認することで決済の状態を判断できます。

  • statusがAUTHORIZEDの場合、決済がAuthorize済みでCaptureが完了していない状態です。
  • statusがCLOSEDになっており、かつcapturesオブジェクトが含まれていない決済はキャンセル済みの状態です。
  • statusがCLOSEDになっているおり、かつcapturesオブジェクトが含まれている決済はCapture済みの状態です。さらにrefundsオブジェクトも含まれている場合は、Partial RefundあるいはFull Refundを実行済みの決済です。

決済データを取得

決済の詳細情報を取得するを行う際は、/payments/{id}エンドポイント({id}の部分はPayment ID)にリクエストボディが空のGETリクエストを送信します。

例:


  curl -X "GET" "https://api.paidy.com/payments/pay_WD1KIj4AALQAIMtZ" \
    -H "Content-Type: application/json" \
    -H "Paidy-Version: 2016-07-01" \
    -H "Authorization: Bearer $secret_key" \
    -d "{}"

このリクエストが成功すると、決済オブジェクトが返ってきます。

例:


  {
    "id":"pay_WFDYLhEAAEQA42Dw",
    "created_at":"2016-11-14T05:27:10.063Z",
     "expires_at":"2016-12-13T05:28:32.143Z",
    "amount":39800,
    "currency":"JPY",
    "description":" ",
    "store_name":"Paidy sample store",
    "test":true,
    "status":"closed",
    "tier":"classic",
    "buyer":{
      "name1":"山田 太郎",
      "name2":"ヤマダ タロウ",
      "email":"yamada@paidy.com",
      "phone":"818000000001"
    },
    "order":{
      "tax":300,
      "shipping":500,
      "order_ref":"20161214ato06",
      "items":[
        {
          "id":"PDI001",
          "title":"Paidyスニーカー",
          "description":" ",
          "unit_price":10000,
          "quantity":1
        },{
          "id":"EXC002",
          "title":"エクスコスニーカー",
          "description":" ",
          "unit_price":15000,
          "quantity":2
        },{
          "id":"CPN001",
          "title":"Discount",
          "description":" ",
          "unit_price":-1000,
          "quantity":1
        }
      ],
      "updated_at":" "
    },
    "shipping_address":{
      "line1":"AXISビル 10F",
      "line2":"六本木4-22-1",
      "city":"港区",
      "state":"東京都",
      "zip":"106-2004"
    },
    "captures":[
      {
        "id":"cap_WFIk5yIAACIAC6n3",
        "created_at":"2016-11-15T05:06:47.189Z",
        "amount":39800,
        "tax":300,
        "shipping":500,
        "items":[
          {
            "id":"PDI001",
            "title":"Paidyスニーカー",
            "description":" ",
            "unit_price":10000,
            "quantity":1
          },{
            "id":"EXC002",
            "title":"エクスコスニーカー",
            "description":" ",
            "unit_price":15000,
            "quantity":2
          }{
           "id":"CPN001",
           "title":"Discount",
           "description":" ",
           "unit_price":-1000,
           "quantity":1
         }
        ],
        "metadata":{}
      }
    ], 
    "refunds":[
      {
        "id":"ref_WFImZyIAAD8AC6pC",
        "created_at":"2016-12-15T05:13:11.800Z",
        "capture_id":"cap_WFIk5yIAACIAC6n3",
        "amount":10000,
        "reason":"unknown",
        "metadata":{}
      }
    ],
    "metadata":{}
  }

決済のアップデート

決済のorder_refdescriptionmetadataフィールドを更新する際は/payments/{id}エンドポイントを利用します。その際、決済のstatusはAUTHORIZEDでもCLOSEDでも構いません。これらのフィールドは決済オブジェクトが生成された時点ですでに設定されています。

  • order_refは必須フィールドであり、これにはマーチャントが定義する注文IDやリファレンスIDが含まれます。マーチャントはこのフィールドに一意のIDを格納し、Paidy決済とマーチャント側のシステムの間で管理番号を紐づけることができます。注文が行われた時点ではマーチャントが注文番号を割り当てられない場合があるため、決済データが作成されてAuthorizeが実行された後からでもマーチャントが更新を行えるよう、このエンドポイントをご用意しています。
  • descriptionは任意フィールドであり、これにはマーチャントが作成した説明文が含まれます。コンシューマーはこの説明文をMyPaidyで閲覧できます。MyPaidyやマーチャントダッシュボードには表示されないフィールドですので、ご注意ください。
  • 決済オブジェクトには任意のmetadataフィールドが含まれており、マーチャントは自分で定義した決済に関する補足的なデータをこのフィールドに保存できます。このフィールドにはキーと値のセットを20件まで追加できます。

このエンドポイントを利用して更新できるのは前述の3つのフィールドだけです。その他のフィールドがリクエストに含まれていても無視されます。

更新を行う決済のstatusはAUTHORIZEDでもCLOSEDでも構いません。

決済のアップデート

/payments/{id}エンドポイント({id}の部分はPayment ID)にPUTリクエストを送信します。その際、更新するorder_refdescription、あるいはmetadataフィールドをリクエストボディに含める必要があります。フィールドを更新すると、既存の値が上書きされます。そのため、metadataフィールドに含まれている既存のリストにキーと値のペアを追加する際は、元々あったキーと値のペアを含めた状態でUpdateリクエストを行うようにしてください。

1度のPUTリクエストで両方のフィールドを更新することも可能です。

例:


curl -X "PUT" "https://api.paidy.com/payments/pay_WD1KIj4AALQAIMtZ" \
  -H "Content-Type: application/json" \
  -H "Paidy-Version: 2016-07-01" \
  -H "Authorization: Bearer $secret_key" \
  -d "{\"order_ref":"88e021674",\"description":"スニーカーストア"\}"

このUpdateリクエストが成功すると、更新された決済オブジェクトが返ってきます。

例:


  {
    "id":"pay_WFDYLhEAAEQA42Dw",
    "created_at":"2016-11-14T05:27:10.063Z",
     "expires_at":"2016-12-13T05:28:32.143Z",
    "amount":39800,
    "currency":"JPY",
    "description":"スニーカーストア",
    "store_name":"Paidy sample store",
    "test":true,
    "status":"closed",
    ...,
    "order":{
      "tax":300,
      "shipping":500,
      "order_ref":"88e021674",
      "items":[
        {
          "id":"PDI001",
          "title":"Paidyスニーカー",
          "description":" ",
          "unit_price":10000,
          "quantity":1
        },{
          "id":"EXC002",
          "title":"エクスコスニーカー",
          "description":" ",
          "unit_price":15000,
          "quantity":2
       }{
          "id":"CPN001",
          "title":"Discount",
          "description":" ",
          "unit_price":-1000,
          "quantity":1
         }
      ],
      "updated_at":" "
    },
    ...
  }

決済のClose

注文金額の全額をCaptureすれば自動的に決済がクローズ状態(closed)になりますが、H手動で決済をクローズしたい場合はCloseエンドポイントにリクエストを送ることで、Authorize済みでCaptureが完了していない決済をクローズすることもできます。 手動でクローズできるのはstatusがAUTHORIZEDの決済だけですのでご注意ください。

コンシューマーが注文をキャンセルした際は、このエンドポイントを利用して可能な限り決済をクローズするようにしてください。 過去の決済が全額Captureされているかどうかという点は、Paidyがコンシューマーを審査する際の判断基準になります。そのため、コンシューマーが今後誤って決済を拒否されてしまわないように、決済をクローズしていただく必要があります。

Captureが完了している決済(statusがCLOSEDの決済)をキャンセルしたい場合はCloseエンドポイントを利用できません。 代わりにRefundエンドポイントをご利用ください。

決済のClose

手動で決済をクローズする際は、/payments/{id}/closeエンドポイント({id}の部分はPayment ID)にリクエストボディが空のPOSTリクエストを送信します。

例:


  curl -X "POST" "https://api.paidy.com/payments/pay_542e6dc6008a077a4de3/close" \
    -H "Content-Type: application/json" \
    -H "Paidy-Version: 2016-07-01"
    -H "Authorization: Bearer $secret_key" \
    -d "{}"

その後Paidyが決済データを取得し、決済がオープン状態かどうか確認します。 決済がクローズ状態だった場合はエラーを返します。 そうでなければ決済をクローズし、データ更新後の決済オブジェクトを返します。

例:


  {
    "id":"pay_WFDYLhEAAEQA42Dw",
    "created_at":"2016-11-14T05:27:10.063Z",
    "expires_at":"2016-12-13T05:28:32.143Z",
    "amount":40800,
    "currency":"JPY",
    "description":"スニーカーストア",
    "store_name":"Paidy sample store",
    "test":true,
    "status":"closed",
    ...
  }