決済の流れ
コンシューマーがメールアドレスと携帯番号だけで手軽に、安全に決済を行えるのがペイディの大きな特徴です。
決済について
通常の決済
通常の決済とは、定期購入の決済と区別される一度限りの決済のことを示します。通常の決済はPaidy Checkout経由でコンシューマーが開始し、ペイディのAPI経由でマーチャントが管理していきます。
通常の決済の典型的な流れ
- Paidy Checkoutの流れに従って数回クリックするだけで、コンシューマーが手軽に注文を行います。
- ペイディがSMSを通じてコンシューマーを認証し、決済をAuthorizeして決済データを作成します。
- 次にマーチャントが既存の注文管理システムを使って注文処理と発送を行い、コンシューマーに請求できる段階になったらAPI経由で決済をCaptureします。
また、API経由で決済をキャンセルしたり、払い戻しを行ったりすることもできます。
トークンの決済
トークン決済は、加盟店サイトで定期購入を実現するための方法の1つです。トークンは、Checkoutを実行することで作成されます。トークンが作成されると、加盟店はそのトークンを利用し、ペイディのAPIで決済を作成することができます。トークンとはペイディのコンシューマーアカウントを識別するものです。
トークンの決済の典型的な流れ(トークンの作成を含む)
- コンシューマーがPaidy Checkoutを使って注文を行います。
- ペイディがコンシューマーを認証し、トークンを作成します。
- 加盟店がトークンを利用してCreateリクエストを行うと、ペイディはAuthorizeを行い決済を作成します。
- コンシューマーに請求を行う準備ができたら、マーチャントがAPI経由で決済をCaptureします。
- 以後、API経由でCreateリクエストやCaptureリクエストを送信するだけで、前述のトークンを使用する決済を簡単に開始できるようになります。
開始した決済は、通常の決済の場合と同様にペイディAPI経由で管理していきます。
決済のライフサイクル
-
ステータス
説明
-
AUTHORIZED
正常に開始された新規決済に付与されるステータスです。
ステータスがAUTHORIZEDである決済に対して行えるリクエストは、Capture、Close、Retrieve、Updateです。 -
REJECTED
Authorizeに失敗した決済に付与されるステータスです。
ステータスがREJECTEDである決済に対して行えるリクエストは、Retrieveだけです。 -
CLOSED
CaptureあるいはCloseが完了した決済に付与されるステータスです。
ステータスがCLOSEDである決済に対して行えるリクエストは、Refund、Retrieve、Updateです。
決済のAPIについて
ペイディAPIを使って簡単かつ安全に決済を管理できます。APIはJSON型のリクエストとレスポンスを使用するRESTエンドポイントです。API経由で行える操作は次の通りです。
- 決済を作成:決済はAPI経由で開始し、Authorizeを行います。
- 決済のCapture:コンシューマーに請求する準備が整っていれば、支払いを回収できます。
- 決済のRefund:回収した金額の一部または全額を払い戻せます。
- 決済データの取得(Retrieve): 決済オブジェクトを指定して取得できます。
- 決済のUpdate: 決済オブジェクトのorder_ref、description、metadataフィールドを更新できます。
- 決済のClose: Authorize済みでCaptureが完了していない決済をクローズできます。
安全な通信
ネットワーク通信を暗号化し、インターネット上に存在するウェブサイトが本物であることを確認するために業界で標準的に採用されているプロトコルが、TLSです。ペイディはこのTLSのバージョン1.1以降をサポートしています。さらに、あらゆるデータを安全にやり取りするために、HTTPS通信を利用しています。
APIのバージョン
現行のAPIのバージョンは2018-04-10です。このバージョン番号はAPIリクエストを行う毎にヘッダーで指定できます。
APIのバージョンがヘッダーで指定されていない場合、マーチャントダッシュボードで設定されているバージョンに基づいて処理が行われます。 さらにマーチャントダッシュボードでもこの設定を行っていない場合は、現行のAPIのバージョンが自動的に適用されます。
Metadataフィールド
オブジェクトに関する補足的な情報をmetadataフィールドに保存できます。このmetadataフィールドは、tokenオブジェクト、決済オブジェクト、capturesオブジェクト、refundsオブジェクトのすべてに含まれています。例えば、マーチャントが保存しておかなければならないデータを割り当てるためのフィールドがペイディAPIに存在しない場合、このフィールドにキーと値のペアを保存することができます。また、各フィールドにセットできるキーは20件までです。
例:
"metadata": {
"key1": "value1",
"key2": "value2"
}
- tokenオブジェクトのメタデータはPaidy Checkout経由でセットされます。
- 決済オブジェクトのメタデータはPaidy Checkout経由でセットされ、Updateリクエストを行うことで更新できます。決済のメタデータは何度でも更新できますが、更新を行う度に既存のメタデータがすべて上書きされるという点にご注意ください。
- capturesオブジェクトのメタデータをセットする際は、Captureリクエストを行います。また、データをセットした後は更新ができなくなります。
- refundsオブジェクトのメタデータをセットする際は、Refundリクエストを行います。この払い戻しのメタデータは何度でも更新できますが、更新を行う度に既存のメタデータがすべて上書きされるという点にご注意ください(また、Refundリクエストを行う際に金額を指定しなければ、決済の全額を払い戻すよう求めるリクエストだとみなされる点もご留意ください)。
UTF-8でエンコード
日本語の文字をJSON形式で送信する際、意図しない文字(?や□)に文字化けすることがあります。送信時の文字化けを避け、テキストがペイディのユーザーインターフェイスに正しく表示されるよう、送信前にテキストが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
必須
ペイディが生成する、「tok_」で始まるトークンID。
-
amount
double
必須
税、送料を含み、値引きの対象であればさらにそれを適用した後の決済総額。
-
currency
string
必須
決済で使用する通貨を示す、ISO4217通貨コードに準じた値(初期値はJPY)。
-
description
string
必須ではありません
注文の概要。
-
store_name
string
必須ではありません
Checkoutアプリケーションのヘッダー部分、MyPaidy、マーチャントダッシュボードに表示される店舗名。
-
buyer_data
object
必須
コンシューマーの購入履歴に関する情報を含むbuyer_dataオブジェクト。
-
order
object
必須
Orderデータ。
注意: 新規決済を開始するリクエストの場合は必須であり、トークンを作成するリクエストの場合は任意となるフィールドです。 -
shipping_address
object
必須
-
metadata
object
必須ではありません
マーチャントは自分で定義した決済に関する補足的なデータをこのフィールドに保存できます。このフィールドにはキーと値のセットを20件まで追加できます。
例:
curl -X "POST" "https://api.paidy.com/payments" \
-H "Content-Type: application/json" \
-H "Paidy-Version: 2018-04-10" \
-H "Authorization: Bearer $secret_key" \
-d $'{
"token_id": "tok_WL0GoQwAAAoA1beX",
"amount": 12800,
"currency": "JPY",
"description": "Description",
"store_name": "Paidy sample store",
"buyer_data": {
"user_id": "yamada_taro",
"age": 29,
"age_platform": 50,
"days_since_first_transaction": 29,
"ltv": 250000,
"order_count": 1000,
"last_order_amount": 20000,
"last_order_at": 20,
"order_amount_last3months": 15000,
"order_count__last3months": 5,
"additional_shipping_addresses": [{
"line1": "AZABUビル 2F",
"line2": "東麻布2-10-1",
"city": "港区",
"state": "東京都",
"zip": "106-0023"
}],
"billing_address": {
"line1": "AXISビル 10F",
"line2": "六本木4-22-1",
"city": "港区",
"state": "東京都",
"zip": "106-2004"
},
"delivery_locn_type": "office",
"gender": "Male",
"subscription_counter": 2,
"previous_payment_methods": {
"credit_card_used": false,
"cash_on_delivery_used": true,
"convenience_store_prepayment_used": true,
"carrier_payment_used": false,
"bank_transfer_used": false,
"rakuten_pay_used": true,
"line_pay_used": false,
"amazon_pay_used": false,
"np_postpay_used": false,
"other_postpay_used": false
},
"number_of_points": 8023,
"order_item_categories": ["sunglasses", "contact lenses"]
},
"order": {
"items": [ {
"id": "PDI001",
"quantity": 1,
"title": "Paidyスニーカー",
"unit_price": 12000,
"description": "Paidyスニーカー"
} ],
"order_ref": "88e021674",
"shipping": 500,
"tax": 300
},
"shipping_address": {
"line1": "AXISビル 10F",
"line2": "六本木4-22-1",
"city": "港区",
"state": "東京都",
"zip": "106-2004"
},
"metadata": {}
}'
トークンを使用して決済データを作成する際は、必ずペイディがトークンとコンシューマーの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を行う際は、/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: 2018-04-10" \
-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":"2018-06-14T05:27:10.063Z",
"expires_at":"2018-07-13T05:28:32.143Z",
"amount":39800,
"currency":"JPY",
"description":" ",
"store_name":"Paidy sample store",
"test":true,
"status":"closed",
...,
"captures":[
{
"id":"cap_WFIk5yIAACIAC6n3",
"created_at":"2018-06-15T05:06:47.189Z",
"amount":39800,
"tax":300,
"shipping":500,
"items":[
{
"id":"PDI001",
"title":"スニーカー",
"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
ペイディAPIを利用すれば支払いの一部あるいは全額を払い戻すことができます。Capture済みの支払いに対してRefundを実行できますが、リクエストを行うためにはCapture IDとPayment IDの両方が必要になります。また、Refundリクエストは特定のCaptureを指定して行います。
決済のRefundを行う際は、/payments/{id}/refunds
エンドポイント({id}の部分はPayment ID)にPOSTリクエストを送信します。その際、リクエストボディにCapture IDを含めてください。必須フィールドはこれだけですが、任意で以下のフィールドを送信することもできます。
- amountフィールド:ペイディ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: 2018-04-10" \
-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":"2018-06-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: 2018-04-10" \
-H "Authorization: Bearer $secret_key" \
-d "{}"
このリクエストが成功すると、決済オブジェクトが返ってきます。
例:
{
"id":"pay_WFDYLhEAAEQA42Dw",
"created_at":"2018-06-14T05:27:10.063Z",
"expires_at":"2018-07-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":"88e021674",
"items":[
{
"id":"PDI001",
"title":"スニーカー",
"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":"2018-06-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":"2018-06-15T05:13:11.800Z",
"capture_id":"cap_WFIk5yIAACIAC6n3",
"amount":10000,
"reason":"unknown",
"metadata":{}
}
],
"metadata":{}
}
決済のアップデート
決済のorder_refとdescriptionとmetadataフィールドを更新する際は/payments/{id}
エンドポイントを利用します。その際、決済のstatusはAUTHORIZEDでもCLOSEDでも構いません。これらのフィールドは決済オブジェクトが生成された時点ですでに設定されています。
- order_refは必須フィールドであり、これにはマーチャントが定義する注文IDやリファレンスIDが含まれます。マーチャントはこのフィールドに一意のIDを格納し、ペイディとマーチャント側のシステムの間で管理番号を紐づけることができます。注文が行われた時点ではマーチャントが注文番号を割り当てられない場合があるため、決済データが作成されてAuthorizeが実行された後からでもマーチャントが更新を行えるよう、このエンドポイントをご用意しています。
- descriptionは任意フィールドであり、これにはマーチャントが作成した説明文が含まれます。コンシューマーはこの説明文をMyPaidyで閲覧できます。MyPaidyやマーチャントダッシュボードには表示されないフィールドですので、ご注意ください。
- 決済オブジェクトには任意のmetadataフィールドが含まれており、マーチャントは自分で定義した決済に関する補足的なデータをこのフィールドに保存できます。このフィールドにはキーと値のセットを20件まで追加できます。
このエンドポイントを利用して更新できるのは前述の3つのフィールドだけです。その他のフィールドがリクエストに含まれていても無視されます。
更新を行う決済のstatusはAUTHORIZEDでもCLOSEDでも構いません。
/payments/{id}
エンドポイント({id}の部分はPayment ID)にPUTリクエストを送信します。その際、更新するorder_ref、description、あるいはmetadataフィールドをリクエストボディに含める必要があります。フィールドを更新すると、既存の値が上書きされます。そのため、metadataフィールドに含まれている既存のリストにキーと値のペアを追加する際は、元々あったキーと値のペアを含めた状態でUpdateリクエストを行うようにしてください。
1度のPUTリクエストで両方のフィールドを更新することも可能です。
例:
curl -X "PUT" "https://api.paidy.com/payments/pay_WD1KIj4AALQAIMtZ" \
-H "Content-Type: application/json" \
-H "Paidy-Version: 2018-04-10" \
-H "Authorization: Bearer $secret_key" \
-d "{\"order_ref":"88e021674",\"description":"スニーカーストア"\}"
このUpdateリクエストが成功すると、更新された決済オブジェクトが返ってきます。
例:
{
"id":"pay_WFDYLhEAAEQA42Dw",
"created_at":"2018-06-14T05:27:10.063Z",
"expires_at":"2018-07-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":"スニーカー",
"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)になりますが、手動で決済をクローズしたい場合はCloseエンドポイントにリクエストを送ることで、Authorize済みでCaptureが完了していない決済をクローズすることもできます。 手動でクローズできるのはstatusがAUTHORIZEDの決済だけですのでご注意ください。
コンシューマーが注文をキャンセルした際は、このエンドポイントを利用して可能な限り決済をクローズするようにしてください。 過去の決済が全額Captureされているかどうかという点は、ペイディがコンシューマーを審査する際の判断基準になります。そのため、コンシューマーの今後の決済が否決されないように、決済をクローズしていただく必要があります。
Captureが完了している決済(statusがCLOSEDの決済)をキャンセルしたい場合はCloseエンドポイントを利用できません。 代わりにRefundエンドポイントをご利用ください。
手動で決済をクローズする際は、/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: 2018-04-10"
-H "Authorization: Bearer $secret_key" \
-d "{}"
その後ペイディが決済データを取得し、決済がオープン状態かどうか確認します。 決済がクローズ状態だった場合はエラーを返します。 そうでなければ決済をクローズし、データ更新後の決済オブジェクトを返します。
例:
{
"id":"pay_WFDYLhEAAEQA42Dw",
"created_at":"2018-06-14T05:27:10.063Z",
"expires_at":"2018-07-13T05:28:32.143Z",
"amount":40800,
"currency":"JPY",
"description":"スニーカーストア",
"store_name":"Paidy sample store",
"test":true,
"status":"closed",
...
}