1 はじめに
1-1 Paidy決済とは?
Paidyは典型的なクレジットカード決済と似た構造になっています。 決済の実行には1回のAuthorizeと1回以上のCaptureが必要です。 Paidyが他の決済システムと異なる点は下記の通りです。
1. コンシューマーはクレジットカード番号の代わりに、メールアドレスと電話番号を入力します。
2. Paidyアカウント登録のためのコンシューマーによるサインアップは不要で、Paidyを使うためのアプリも必要ありません。あらゆる人がすでにPaidyのアカウントを所持し、利用できる状態です。
1-2 Authorize
全てのPaidy決済はAuthorizeのリクエストからはじまります。 Authorizeリクエストは顧客データと注文データによって構成されます。 各リクエストに含まれるこれらのデータをPaidy独自の詐欺探知と信用評価システムによって分析し、審査します。
Authorizeリクエストイメージ(画像をクリックすると拡大します)
ほとんどのAuthorizeリクエストは数秒以内に完了します。 Authorizeが成功すると、レスポンスとして、成功/失敗といった実行結果、Payment ID、有効期限を示す値が返されます。 Payment IDは、後のCaptureやStatus APIを実行する際に必要となります。 また、有効期限については、標準ではAuthorizeに成功した日から30日後に自動的に失効するようになっています。
Authorizeが成功した段階では、マーチャントに対する支払いやコンシューマーへの請求は確定していません。 それらを確定するためには、有効期限内の、マーチャントによるCaptureの実行が必要です。 また、Captureの実行には、Authorizeが成功したときに取得したPayment IDが必要です。
Paidy Checkoutは、ECサイトの支払いページに導入することができるJavascriptのアプリケーションです。 マーチャント側での実装を最小限におさえてAuthorize APIを使用できるため、時間も手間もかかりません。
Paidy Checkoutの最大の利点は、Paidy Checkoutそのものが、コンシューマーのコンバージョン率が上がるように最適化されていることです。 PaidyではECサイトのカートのコンバージョン率を上げるために日々取り組んでいます。 Paidy Checkoutによる支払いページから顧客が離脱することはありません。 そのためセッション管理やリダイレクト、売り上げ減少などを心配する必要はありません。 Paidy Checkoutは代表的なブラウザー、モバイル、タブレットに全て対応しています。
Paidy Checkoutを実装する際には、Authorize成功後に既存の支払いフォームを実行するよう、コールバック関数を設定してください。 後のCaptureの実行に備えて、取得したPayment IDをECサイトのバックエンドシステムに渡すよう構成してください。
1-3 決済のCapture
マーチャントに対する支払いとコンシューマーへの請求を確定するために、Captureを実行します。 Captureが成功すると、Paidyからマーチャントへのお支払いの保証と、コンシューマーへの請求が確定します。
マーチャントは、オープン状態の(Authorizeが成功した有効期限内の)決済であればCaptureすることができます。 マーチャントは、Authorize済決済の全額をCaptureすることもできますし、一部だけをCaptureすることも可能です。 Authorize済のPaidy決済が完全にCaptureされる(=Authorizeされた金額がすべてCaptureされる)か、もしくは有効期限を過ぎると、そのPayment IDの決済データは自動的にクローズします。
Paidy決済をCaptureするタイミングについてはマーチャントにお任せします。 Authorizeの直後に実行することも可能ですし、商品の配送が完了した時に実行することも可能です。
1-4 支払方法
コンシューマーによる支払方法は、毎月第1営業日に送信されるビリングURLおよびMyPaidyから確認可能です。
1-5 コンシューマーへの通知
Paidyでは、認証ならびに請求情報の通知のために、コンシューマーにSMSおよびEメールを送信します。 標準では下記のタイミングにて通知が送信されます。
コンシューマーへの通知トリガ(画像をクリックすると拡大します)
Authorizeがリクエストされ、PINコード認証が必要なとき
Type | Title or Message |
---|---|
SMS | 認証番号: XXXX をPaidy(ペイディー)の画面で入力してください。 |
Authorizeリクエストが成功したとき
Type | Title or Message |
---|---|
SMS | ようこそ、Paidyへ!お客様のPaidyご利用状況は[MyPaidyUrlHere]にてご確認いただけます。 (※1) |
お客様のmyPaidyアカウントオープンのお知らせ 《内容を表示│内容を別ウィンドウで表示》 (※1) | |
【利用速報】Paidyご利用のお知らせ 《内容を表示│内容を別ウィンドウで表示》 |
(※1) Paidy初回利用コンシューマーにのみ送信されます。 2回目以降は送信されません。
Captureリクエストが成功したとき
Type | Title or Message |
---|---|
【請求情報】Paidy請求情報登録のお知らせ 《内容を表示│内容を別ウィンドウで表示》 |
月に1回の請求額が確定したとき
Type | Title or Message |
---|---|
SMS | Paidyのご請求金額が ¥X,XXX に確定しました。お支払方法はこちら。[MyPaidyUrlHere] |
【Paidy】今月の請求金額が確定しました 《内容を表示│内容を別ウィンドウで表示》 |
コンシューマーがMyPaidyにログインするとき
Type | Title or Message |
---|---|
SMS | 認証番号: XXXX をPaidy(ペイディー)の画面で入力してください。 |
2 API エンドポイント
Paidy APIは、JSON型(Content-Type: application/json)のリクエストとレスポンスを使用するRESTエンドポイントです。 各リクエストは、マーチャントに一意のAPIキーとリクエストデータに対する一意なチェックサムによって認証されます。
Paidy決済には6つのAPIエンドポイントがあります。各エンドポイントは、下図のようなタイミングで実行することが可能です。 (下図は実行タイミングの一例です。マーチャントは任意のタイミングで各エンドポイントをリクエストできます。)
リクエストの認証
すべてのAPIリクエストは、下記の3種類で認証されます。
- APIキー : マーチャント識別のための公開鍵をチェックします。
- チェックサム : 各リクエストには、JSON属性のひとつとして必ずチェックサムが必要です。チェックサムは、マーチャントの秘密鍵によってのみ作成され、Paidy APIでは常にチェックサムの値を確認します。
- PINコード : Authorize APIのリクエスト実行時に、Paidyからコンシューマーの携帯電話にPINコードを送信し、認証します。
《APIキー》
マーチャントからのリクエストには必ず、HTTPリクエストの認証ヘッダに"Bearer"から始まるAPIキーを下記のように設定する必要があります。
Authorization: Bearer NTNlYAY0MDFjYTAxMyBlNDAzNDk2ZDE3
《チェックサム》
チェックサムの作成方法はリクエストのエンドポイント(URL)により異なります。 基本的には、マーチャントに固有の秘密鍵とリクエストとの連結文字列のハッシュ値をBase64もしくはHexでエンコードすることで作成できます。 Base64、Hexについてはどちらを使用してもかまいません。
《PINコード》
Paidy決済のAuthorizeにおいてコンシューマーの認証が必要な場合、PaidyシステムはSMSを利用してコンシューマーの携帯電話にPINコードを送信し、レスポンス内のステータスコードにauthenticate_consumer
をセットして返します。
このようなレスポンスが帰ってきた場合、Paidy Checkoutは、リクエストするJSONオブジェクトの中に、auth_code
属性に顧客(コンシューマー)が入力したPINコードをセットしたものを追加し、再度、Authorizeをリクエストします。
レスポンス
Paidy APIは、200 - OK、400 - 不正リクエスト、401 - 承認失敗、などといったHTTPレスポンスコードを使用してリクエストの結果を示します。 またレスポンスにJSONを含む場合は、"status" 属性の値でリクエストの結果を返します。
Paidyエンドポイントが返すJSONオブジェクトは下記の通りです。
Parameter | Description |
---|---|
payment_id | Payment ID - 詳細は後述のAPIエンドポイントをご確認ください |
capture_id | Capture ID - 詳細は後述のAPIエンドポイントをご確認ください |
status | ステータスコード - 詳細は後述のAPIエンドポイントならびに下表をご確認ください |
reason | 説明 |
message | 追加説明 |
全てのPaidyエンドポイントに共通するステータスコードは下記の通りです
Status Code | Description |
---|---|
bad_request | リクエストの実行に失敗しましました - JSONデータの欠損など |
request_failed | リクエストは拒絶されました - チェックサムの不一致など |
internal_error | 後でもう一度試してください |
リアクティブ
Paidyはリアクティブアプリケーションです。 APIを含むPaidyシステムはReactive Manifestoに準じて設計・開発されています。
例えば、AuthorizeにおけるPINコード追加送信や既存のPaidy決済データの更新など、追加データがPaidyエンドポイントに必要な場合は、変更部分のデータだけでなく、全てのデータを送信する必要があります。
セキュリティ
Paidy APIエンドポイントは、下記のSSL/TLS Protocolをサポートしています。 SSLv1〜v3についてはサポートしておりませんので、APIエンドポイントをリクエストする際は、下記のProtocolをサポートするよう、システムを適切に構成してください。
- TLS1.0
- TLS1.1
- TLS1.2
また、Paidy APIエンドポイントは、SHA-2署名アルゴリズムのSSL証明書を使用しています。
2-1 Authorize
Paidy決済データの作成のために、Authorizeをリクエストします。 リクエストの結果として、決済データに一意のPayment IDが発行されます。
Authorizeエンドポイントへのリクエストフローは下図のようになります。
HTTPリクエスト
Authorizeリクエストの内容はPaidy Checkouの章をご確認ください。
2-2 Update
HTTPリクエスト:
POST /pay/update HTTP/1.1
Host: api.paidy.com
Authorization: Bearer YourAccessTokenHere
Content-Type: application/json
{
"payment_id": "YourPaymentIdHere",
"order": {
"items": [{
"item_id": "1",
"title": "アイテム1",
"amount": 3000.0,
"quantity": 1
},{
"item_id": "2",
"title": "アイテム2",
"amount": 4500.0,
"quantity": 1
}],
"tax": 300.0,
"shipping": 500.0,
"total_amount": 8300.0,
"order_ref": "YourOrderRefHere"
},
"checksum": "YourChecksumHere"
}
レスポンス:
{
"payment_id":"YourPaymentIdHere",
"status":"update_success",
}
Authorize済のPaidy決済データの注文内容、合計金額を変更するために、Updateエンドポイントをリクエストします。
Updateエンドポイントを利用するには、Authorize済のPayment IDが必要です。
Updateエンドポイントは、CheckoutでJSONパラメータにセットしたorderオブジェクトを上書きするものです。決済データの、orderオブジェクトの内容全てをセットしてください。
Updateエンドポイントへのリクエストフローは下図のようになります。
HTTPリクエスト
POST https://api.paidy.com/pay/update
Parameter | Required | Type | Description |
---|---|---|---|
payment_id | YES | string | Authorize済のPayment ID |
order.items.item_id | - | string | 注文商品の商品ID |
order.items.title | YES | string | 注文商品の商品名 |
order.items.amount | YES | double | 注文商品の単価 |
order.items.quantity | YES | int | 注文商品の数 |
order.tax | - | double | 注文にかかる消費税 |
order.shipping | - | double | 注文にかかる配送料 |
order.total_amount | YES | double | 注文代金の総額 |
order.order_ref | ※1 | string | マーチャントが利用可能な、リファレンスID |
checksum | YES | string | チェックサム |
RequiredがYESとなっているパラメーターは、必須項目です。
(※1) Checkoutパラメータにorder_refをセットした場合は、確実に同じ値をセットしてください。なお、order_refの値を変更する場合は、下記「Payment ID取得後のorder_refをUpdateする場合」をご参照ください。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとPayment IDを組み合わせた文字列のハッシュ値をエンコードして作成してください。
例えばシークレットキーがIamSecret
、Payment IDがPaymentID0123456789
である場合、チェックサムのベースとなる文字列はIamSecretPaymentID0123456789
となります。
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
checksum = base64 ( sha256 ( secret + payment_id ) )
checksum = hex ( sha256 ( secret + payment_id ) )
レスポンス
レスポンス - 成功の場合:
{
"payment_id":"YourPaymentIdHere",
"status":"update_success",
}
レスポンス - 失敗の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "update_fail",
"reason": "closed",
"message": "Payment is closed or expired. No actions can be performed",
}
Updateリクエストの実行結果として、JSONオブジェクトが返ってきます。 それぞれが意味する内容は下記の通りです。 (SuccessがYESとなっているものは成功時に、FailureがYESとなっているものは失敗時に返ってくるオブジェクトです。)
Parameter | Success | Failure | Description |
---|---|---|---|
payment_id | YES | YES | リクエスト時に指定したAuthorize済のPayment ID |
status | YES | YES | ステータスコード - 詳細は後述のステータスコードをご確認ください |
reason | - | YES | リクエストが失敗した場合の理由 |
message | - | YES | リクエストが失敗した場合の理由の詳細 |
test | YES | YES | テストフラグ - テストコンシューマアカウントで作成されたものはtrue、それ以外はfalseとなります |
ステータスコード
Updateリクエスト実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status | Description |
---|---|
update_success | 指定されたPayment IDの更新に成功しました |
update_fail | 指定されたPayment IDの更新に失敗しました |
リクエストが失敗する場合
Updateリクエストが失敗する場合は、下記の原因が考えられます。 失敗の原因は実行結果として返ってくるJSONオブジェクトの"reason"、"message"に記載されます。
- チェックサムが誤っている
- 指定したPayment IDが既に全額Captureされている(=ステータスが"close"状態である)
- 指定したPayment IDの有効期限が超過している(=ステータスが"close"状態である)
- Authorizeした合計金額を大きく上回る金額にUpdateしようとした
Partial Capture済のPayment IDをUpdateする場合
Partial Capture済のPayment IDをUpdateする例:
{
"payment_id": "YourPaymentIdHere",
"order": {
"items": [{
"item_id": "1",
"title": "アイテム1",
"amount": 3000.0,
"quantity": 1
},{
"item_id": "2",
"title": "アイテム2",
"amount": 4500.0,
"quantity": 1
},{
"item_id": "999",
"title": "アイテム1に対する追加チャージ",
"amount": 1000.0,
"quantity": 1
}],
"tax": 300.0,
"shipping": 500.0,
"total_amount": 9300.0,
"order_ref": "YourOrderRefHere"
},
"checksum": "YourChecksumHere"
}
既にPartial Capture(Partial Captureについては、後述のCapture章をご確認ください)を実行してしまったPayment IDのデータをUpdateする必要がある場合は、既に登録済みのorder.items
を修正するのではなく、新規にorder.items
を追加する形式でUpdateエンドポイントをリクエストしてください。
たとえば、3,000円(アイテム1)
と4,500円(アイテム2)
というAuthorize済決済データに対し、3,000円(アイテム1)
をPartial Capture済のとき、3,000円(アイテム1)
の金額を4,000円
に変更する必要が発生した場合は、既にPartial Capture済の3,000円(アイテム1)
の金額をUpdateするのではなく、追加分の金額1,000円
のitems
データをorder
内に追加する形でUpdateをリクエストしてください。
リクエスト内容の詳細は、右記の例をご参照ください。
Payment ID取得後のorder_ref
をUpdateする場合
Payment ID取得後のorder_refをUpdateする例:
{
"payment_id": "YourPaymentIdHere",
"order": {
“order_ref": “YourUpdatedOrderRef"
},
"checksum": "YourChecksumHere"
}
ECプラットフォームの仕様上、Paidy Authorizeリクエストを送信する時点で、受注番号等の取引データの管理番号が発行されていない場合には、order_ref
に管理番号を割り当てることができない場合がございます。
そのような場合には、Paidy Autorizeリクエスト送信時に仮に文字列等を割り当てて、PaidyシステムよりPayment IDが発行された後で、Update APIを利用してorder_ref
を事後的に更新することができます。
order_ref
をPayment ID発行後に更新する際には、以下の2点が通常のUpdate APIと異なります。
- リクエストは/pay/updateReferenceあてに送信してください。
order_ref
のエントリーは必須です。
2-3 Close
HTTPリクエスト:
POST /pay/close HTTP/1.1
Host: api.paidy.com
Authorization: Bearer YourAccessTokenHere
Content-Type: application/json
{
"payment_id": "YourPaymentIdHere",
"checksum": "YourChecksumHere"
}
レスポンス:
{
"payment_id": "YourPaymentIdHere",
"status": "close_success",
}
ステータスがオープン状態のPaidy決済データを意図的にクローズするために、Closeエンドポイントをリクエストします。 Paidy決済データをクローズすると、そのPayment IDの決済データのUpdate、Captureは行うことができなくなります。 Closeエンドポイントは、Captureする必要がない決済データに対してリクエストしてください。
Closeエンドポイントを利用するには、Authorize済のPayment IDが必要です。
Closeエンドポイントへのリクエストフローは下図のようになります。
HTTP リクエスト
POST https://api.paidy.com/pay/close
Parameter | Reguired | Type | Description |
---|---|---|---|
payment_id | YES | string | Authorize済のPayment ID |
checksum | YES | string | チェックサム |
RequiredがYESとなっているパラメーターは、必須項目です。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとPayment IDを組み合わせた文字列のハッシュ値をエンコードして作成してください。
例えばシークレットキーがIamSecret
、Payment IDがPaymentID0123456789
である場合、チェックサムのベースとなる文字列はIamSecretPaymentID0123456789
となります。
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
checksum = base64 ( sha256 ( secret + payment_id ) )
checksum = hex ( sha256 ( secret + payment_id ) )
レスポンス
レスポンス - 成功の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "close_success",
}
レスポンス - 失敗の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "close_fail",
"reason": "closed",
"message": "Payment is closed or expired. No actions can be performed",
}
Closeリクエストの実行結果として、JSONオブジェクトが返ってきます。 それぞれが意味する内容は下記の通りです。 (SuccessがYESとなっているものは成功時に、FailureがYESとなっているものは失敗時に返ってくるオブジェクトです。)
Parameter | Success | Failure | Description |
---|---|---|---|
payment_id | YES | YES | リクエスト時に指定したAuthorize済のPayment ID |
status | YES | YES | ステータスコード - 詳細は後述のステータスコードをご確認ください |
reason | - | YES | リクエストが失敗した場合の理由 |
message | - | YES | リクエストが失敗した場合の理由の詳細 |
test | YES | YES | テストフラグ - テストコンシューマアカウントで作成されたものはtrue、それ以外はfalseとなります |
ステータスコード
Closeリクエスト実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status | Description |
---|---|
close_success | 指定されたPayment IDのクローズに成功しました |
close_fail | 指定されたPayment IDのクローズに失敗しました |
リクエストが失敗する場合
Closeリクエストが失敗する場合は、下記の原因が考えられます。
- チェックサムが誤っている
- 指定したPayment IDの決済データのステータスが"close"状態である
決済データのステータスが"close"状態となる理由は下記の通りです。
- 指定したPayment IDのもつ金額のすべてを既にCaptureしている
- 指定したPayment IDに設定されている有効期限が過ぎている
- 既に同一のPayment IDに対してCloseエンドポイントをリクエストし、それが成功済である
2-4 Capture
HTTPリクエスト:
POST /pay/capture HTTP/1.1
Host: api.paidy.com
Authorization: Bearer YourAccessTokenHere
Content-Type: application/json
{
"payment_id": "YourPaymentIdHere",
"checksum": "YourChecksumHere"
}
レスポンス:
{
"payment_id": "YourPaymentIdHere",
"capture_id": "YourCaptureIdHere",
"status": "capture_success",
}
Paidy決済の請求を確定するために、Captureをリクエストします。 Captureが成功すれば、その決済データに紐付いた請求番号Capture IDが発行されます。
Captureエンドポイントでは、下記の2種類のCaptureをリクエストできます。
- Partial Capture : Authorizeされた金額の一部のCapture
- Full Capture : Authorizeされた金額全てのCapture
Captureエンドポイントは、リクエストされたPaidy決済データがもつ一部、または全額のマーチャントへの支払いとコンシューマーへの請求を確定します。 Captureエンドポイントを利用するには、Authorize済のPayment IDが必要です。
Captureエンドポイントへのリクエストフローは下図のようになります。
HTTP リクエスト
POST https://api.paidy.com/pay/capture
Parameter | Reguired | Type | Description |
---|---|---|---|
payment_id | YES | string | Authorize済のPayment ID |
items.item_id | - | string | 注文商品の商品ID |
items.quantity | - | int | 注文商品の数 |
tax | - | double | 注文にかかる消費税 |
shipping | - | double | 注文にかかる配送料 |
checksum | YES | string | チェックサム |
RequiredがYESとなっているパラメーターは、必須項目です。
Partial CaptureとFull Capture
Partial Captureの例:
{
"payment_id": "YourPaymentIdHere",
"items": [{
"item_id": "1",
"quantity": 1
}],
"tax":100.0,
"shipping": 240.0,
"checksum": "YourChecksumHere"
}
Full Captureの例:
{
"payment_id": "YourPaymentIdHere",
"checksum": "YourChecksumHere"
}
Partial Captureとするか、Full Captureとするかは、CaptureエンドポイントへリクエストされるJSONオブジェクトの内容によって判断されます。
具体的には、リクエストされるJSONオブジェクトの中で、items.item_id
およびitems.quantity
や、tax
、shipping
の値が含まれている場合は、Partial CaptureとしてCaptureが実行されます。
一方、payment_id
およびchecksum
という必須項目のみをセットしてリクエストした場合は、Full CaptureとしてCaptureが実行されます。
Partial Captureは、指定されたPayment IDがもつ注文情報の商品を指定してリクエストしますが、
Payment IDがもつ注文情報とは、Authorizeリクエスト時のorder.items
、あるいはUpdateリクエスト時のorder.items
で設定した値です。
また、Partial Captureの場合は、指定されたPayment IDでAuthorizeされた決済金額がすべてCaptureされるまで、そのPayment IDのステータスは"open"状態を維持します。 ただし、そのPayment IDにセットされている有効期限を超過した場合は、すべての金額がCaptureされていなくても、ステータスは"close"状態へ変更されます。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとPayment IDを組み合わせた文字列のハッシュ値をエンコードして作成してください。
例えばシークレットキーがIamSecret
、Payment IDがPaymentID0123456789
である場合、チェックサムのベースとなる文字列はIamSecretPaymentID0123456789
となります。
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
checksum = base64 ( sha256 ( secret + payment_id ) )
checksum = hex ( sha256 ( secret + payment_id ) )
レスポンス
レスポンス - 成功の場合:
{
"payment_id":"YourPaymentIdHere",
"capture_id":"YourCaptureIdHere",
"status":"capture_success",
}
レスポンス - 失敗の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "capture_fail",
}
Captureリクエストの実行結果として、JSONオブジェクトが返ってきます。 それぞれが意味する内容は下記の通りです。 (SuccessがYESとなっているものは成功時に、FailureがYESとなっているものは失敗時に返ってくるオブジェクトです。)
Parameter | Success | Failure | Description |
---|---|---|---|
payment_id | YES | YES | リクエスト時に指定したAuthorize済のPayment ID |
capture_id | YES | - | 発行されたCapture ID |
status | YES | YES | ステータスコード - 詳細は後述のステータスコードをご確認ください |
test | YES | YES | テストフラグ - テストコンシューマアカウントで作成されたものはtrue、それ以外はfalseとなります |
ステータスコード
Captureリクエスト実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status | Description |
---|---|
capture_success | 指定されたPayment IDのCaptureに成功しました |
capture_fail | 指定されたPayment IDのCaptureに失敗しました |
リクエストが失敗する場合
Captureリクエストが失敗する場合は、下記の原因が考えられます。
- チェックサムが誤っている
- 指定したPayment IDの決済データのステータスが"close"状態である
- Partial Captureで、既にCapture済の
items.item_id
の値を指定している - Partial Captureで、
items.item_id
の値が指定したPayment IDの値と一致しない - Partial Captureで、
items.quantity
の値が指定したPayment IDの値と一致しない - Partial Captureで、
tax
の値が指定したPayment IDの値を超過している - Partial Captureで、
shipping
の値が指定したPayment IDの値を超過している
2-5 Status
HTTPリクエスト:
POST /pay/status HTTP/1.1
Host: api.paidy.com
Authorization: Bearer YourAccessTokenHere
Content-Type: application/json
{
"payment_id": "YourPaymentIdHere",
"checksum": "YourChecksumHere"
}
レスポンス:
{
"payment_id": "YourPaymentIdHere",
"status": "open",
"expires": "YYYY-MM-DD hh:mm:ss",
"amount": 4800,
}
Authorize済のPaidy決済データの状態を確認するために、Statusをリクエストします。 Statusエンドポイントを利用するには、Authorize済のPayment IDが必要です。
Statusエンドポイントへのリクエストフローは下図のようになります。
HTTP リクエスト
POST https://api.paidy.com/pay/status
Parameter | Reguired | Type | Description |
---|---|---|---|
payment_id | YES | string | Authorize済のPayment ID |
checksum | YES | string | チェックサム |
RequiredがYESとなっているパラメーターは、必須項目です。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecretPaymentID0123456789'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecretPaymentID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecretPaymentID0123456789'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecretPaymentID0123456789';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとPayment IDを組み合わせた文字列のハッシュ値をエンコードして作成してください。
例えばシークレットキーがIamSecret
、Payment IDがPaymentID0123456789
である場合、チェックサムのベースとなる文字列はIamSecretPaymentID0123456789
となります。
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
checksum = base64 ( sha256 ( secret + payment_id ) )
checksum = hex ( sha256 ( secret + payment_id ) )
レスポンス
レスポンス - “open"の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "open",
"expires": "2015-01-31 23:59:59",
"amount": 48000,
}
レスポンス - "close"の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "close",
"expires": "2015-01-31 23:59:59",
"amount": 48000,
}
Statusリクエストの実行結果として、下記のJSONオブジェクトがすべて返ってきます。 それぞれが意味する内容は下記の通りです。
Parameter | Description |
---|---|
payment_id | リクエスト時に指定したAuthorize済のPayment ID |
status | ステータスコード - 詳細は後述のステータスコードをご確認ください |
expires | リクエスト時に指定したAuthorize済Payment IDの有効期限 |
amount | リクエスト時に指定したAuthorize済Payment IDのAuthorize金額 |
order_ref | マーチャントが利用可能なリファレンスID |
test | テストフラグ - テストコンシューマアカウントで作成されたものはtrue、それ以外はfalseとなります |
ステータスコード
Statusリクエスト実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status | Description |
---|---|
open | 指定されたPayment IDは利用可能です |
close | 指定されたPayment IDは利用できません |
リクエストが失敗する場合
Statusリクエストが失敗する場合は、下記の原因が考えられます。
- チェックサムが誤っている
2-6 Refund
HTTPリクエスト:
POST /pay/refund HTTP/1.1
Host: api.paidy.com
Authorization: Bearer YourAccessTokenHere
Content-Type: application/json
{
"capture_id": "YourCaptureIdHere",
"checksum": "YourChecksumHere"
}
レスポンス:
{
"capture_id": "YourCaptureIdHere",
"status": "refund_success"
}
コンシューマーへの請求およびマーチャントへの支払いが確定済の金額に対して、一部、または全額の払い戻しを行うために、Refundエンドポイントをリクエストします。 Refundエンドポイントを利用するには、Capture済のCapture IDが必要です。
Refundエンドポイントでは、下記の2種類のRefundをリクエストできます。
- Partial Refund : Captureされた金額の一部のRefund
- Full Refund : Captureされた金額全てのRefund
Refundエンドポイントへのリクエストフローは下図のようになります。
HTTP リクエスト
POST https://api.paidy.com/pay/refund
Parameter | Reguired | Type | Description |
---|---|---|---|
capture_id | YES | string | Capture ID |
amount | - | double | 払戻金額 - 指定しない場合は指定されたCapture IDがもつ全額となります |
checksum | YES | string | チェックサム |
RequiredがYESとなっているパラメーターは、必須項目です。
Partial RefundとFull Refund
Partial Refundの例:
{
"capture_id": "YourCaptureIdHere",
"amount":2000.0,
"checksum": "YourChecksumHere"
}
Full Refundの例:
{
"capture_id": "YourCaptureIdHere",
"checksum": "YourChecksumHere"
}
Partial Refundとするか、Full Refundとするかは、RefundエンドポイントへリクエストされるJSONオブジェクトの内容によって判断されます。
具体的には、リクエストされるJSONオブジェクトの中で、amount
の値が含まれている場合は、Partial RefundとしてRefundが実行されます。
一方、capture_id
およびchecksum
の必須項目のみをセットしてリクエストした場合は、Full Refundとして指定されたCapture IDがもつすべての金額のRefundが実行されます。
Partial RefundとFull Refundを組み合わせて使用することも可能です。
Refundでは、指定されたCapture IDのRefund状況を必ずチェックしています。
例えば、Capture額10,000円
に対して、1.3,000円
のPartial Refundを実行した後、2.Full Refundを実行することができます。
この場合、2.のFull Refundでは、残りの7,000円
がRefundされることになります。
なお、Full Refundを実行した後、同一のCapture IDに対してPartial Refundを実行することはできません。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecretCaptureID0123456789'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecretCaptureID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecretCaptureID0123456789'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecretCaptureID0123456789';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecretCaptureID0123456789'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecretCaptureID0123456789'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecretCaptureID0123456789'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecretCaptureID0123456789';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとCapture IDを組み合わせた文字列のハッシュ値をエンコードして作成してください。
例えばシークレットキーがIamSecret
、Capture IDがCaptureID0123456789
である場合、チェックサムのベースとなる文字列はIamSecretCaptureID0123456789
となります。
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
checksum = base64 ( sha256 ( secret + capture_id ) )
checksum = hex ( sha256 ( secret + capture_id ) )
レスポンス
レスポンス - 成功の場合:
{
"capture_id":"YourCaptureIdHere",
"status":"capture_success"
}
レスポンス - 失敗の場合:
{
"capture_id": "YourCaptureIdHere",
"status": "refund_fail",
"reason": "invalid_amount",
"message": "Cannot refund more than authorized amount"
}
Refundリクエストの実行結果として、JSONオブジェクトが返ってきます。 それぞれが意味する内容は下記の通りです。 (SuccessがYESとなっているものは成功時に、FailureがYESとなっているものは失敗時に返ってくるオブジェクトです。)
Parameter | Success | Failure | Description |
---|---|---|---|
capture_id | YES | YES | リクエスト時に指定したCapture ID |
status | YES | YES | ステータスコード - 詳細は後述のステータスコードをご確認ください |
reason | - | YES | リクエストが失敗した場合の理由 |
message | - | YES | リクエストが失敗した場合の理由の詳細 |
ステータスコード
Refundリクエスト実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status | Description |
---|---|
refund_success | 指定されたCapture IDのRefundに成功しました |
refund_fail | 指定されたCapture IDのRefundに失敗しました |
リクエストが失敗する場合
Refundリクエストが失敗する場合は、下記の原因が考えられます。
- チェックサムが誤っている
- Partial Refundで、指定した
amount
の値が指定したCapture IDの値を超過している
3 Paidy Checkout
Paidy Checkoutは、全ての環境で容易に利用することができ、既存のユザーフローに変更を加える必要はありません。 コンシューマーはECサイトから離脱することなく、決済を実行できます。
Paidy CheckoutはPaidy APIのAuthorizeエンドポイントをコールし、Authorizeに必要な注文データをPaidyサーバに送信します。 Authorize実行後はマーチャントページに戻るため、任意のコールバック値を設定しておくことで、マーチャント独自の発注処理を継続して行うことができます。
Paidy CheckoutとPaidyエンドポイントとの接続イメージ(画像をクリックすると拡大します)
3-1 サンプルデモ
このデモにおいては以下のデモ用アカウントを入力してください。
- メールアドレス :
successful.payment@paidy.com
- 携帯電話番号 :
08000000001
- 認証コード :
8 8 8 8
3-2 Paidy Checkoutの導入
サンプルコード:
<script type="text/javascript" src="https://apps.paidy.com"></script>
<form method="post" name="hidden_form" id="hidden_form" action="YourActionHere">
<input type="hidden" name="paidy_payment_id" id="paidy_payment_id">
</form>
<button id="auth-btn">Paidyで支払う</button>
<script>
var paidy = Paidy.configure({
key: "YourAccessTokenHere",
logo_url: "YourLogoUrlHere",
callback: function(data){
$("#paidy_payment_id").val(data.payment_id);
$("#hidden_form").submit();
}
});
$("#auth-btn").click ( function () {
<!--以下のjsonオブジェクトがAuthorizeリクエストに利用されます-->
var data = {
"buyer": {
"name": "山田 太郎",
"name2": "ヤマダ タロウ",
"dob": "1990-10-25",
"email": {
"address": "taro.yamada@paidy.com"
},
"address": {
"address1": "3-16-26",
"address2": "六本木",
"address3": "港区",
"address4": "東京都",
"postal_code": "106-0032"
},
"phone": {
"number": "09087654321"
}
},
"order": {
"items": [{
"item_id": "1",
"title": "アイテム1",
"amount": 1000.0,
"quantity": 1
},{
"item_id": "2",
"title": "アイテム2",
"amount": 1500.0,
"quantity": 2
}],
"tax": 300.0,
"shipping": 500.0,
"total_amount": 4800.0,
"order_ref": "YourOrderrefHere"
},
"merchant_data": {
"store": "Test Store",
"customer_age": 2,
"last_order": 215,
"last_order_amount": 3500.0,
"known_address": false,
"num_orders": 2,
"ltv": 100.0,
"ip_address": "203.0.113.0"
},
"options": {
"authorize_type": "extended"
},
"checksum": "YourChecksumHere",
};
paidy.launch(data);
return false;
});
</script>
Paidy Checkoutは下記の手順で使用することが可能です。
STEP1 <script type="text/javascript" src="https://apps.paidy.com"></script>
をページの中にロードします。
STEP2 コールバック実行用のformをページ内に作成します。
STEP3 ページ内にPaidy Checkoutの設定オブジェクト(Paidy.configure)を作成し、STEP2で作成したformをPaidy Checkoutのコールバックとして設定します。
Parameter | Required | Type | Description |
---|---|---|---|
key | YES | string | APIキーを設定してください |
logo_url | - | string | Paidy Checkoutで表示するロゴのURL - 未設定の場合はPaidyのロゴが表示されます |
callback | - | N/A | Authorize APIからのレスポンスデータ処理する内容を設定してください |
RequiredがYESとなっているパラメーターは、必須項目です。
STEP4 ページ内にAuthorizeに必要なコンシューマーデータと注文データをJSON型で作成します。 Paidy Checkoutに表示されるデータ(メールアドレス、電話番号、氏名、住所)は、Paidy Checkoutを実行する際に設定されたコンシューマーデータから取得しています。 Authorizeに必要なJSONの詳細については後述します。
STEP5 前出のSTEP3で作成した設定オブジェクト、STEP4で作成したJSONデータ、および決済実行イベントをすべてバインドします。
例えば、Paidy Checkoutを導入するサイトの決済ページに、右記のようなコードを追加してください。 右記のサンプルコードでは、Paidyアプリケーションは、「#auth-btn」へのクリックイベントにバインドされています。 追加されたコードにより、ページの読み込み時に、Paidy Checkoutを起動する為のPaidyオブジェクトが作成されます。
Paidy Checkoutを実行する際に必要となるJSONパラメタは下記の通りです。
Parameter | Required | Type | Description |
---|---|---|---|
buyer.name | YES | string | コンシューマーの名前(漢字) - 性と名の間に半角スペースをいれてください |
buyer.name2 | YES | string | コンシューマーの名前(カタカナ) - 性と名の間に半角スペースをいれてください |
buyer.dob | - | string | コンシューマーの誕生日(※形式:YYYY-MM-DD) |
buyer.email.address | YES | string | コンシューマーのEメールアドレス (※1) |
buyer.phone.number | YES | string | コンシューマーの携帯電話番号 (※1)(※2) |
buyer.address.address1 | - | string | コンシューマーの住所(家/アパート/部屋/番号) |
buyer.address.address2 | YES | string | コンシューマーの住所(丁目、番地) |
buyer.address.address3 | YES | string | コンシューマーの住所(市区町村) |
buyer.address.address4 | YES | string | コンシューマーの住所(都道府県) |
buyer.address.postal_code | YES | string | コンシューマーの住所(郵便番号) |
order.items.item_id | YES | string | 注文商品の商品ID(※5) |
order.items.title | YES | string | 注文商品の商品名 |
order.items.amount | YES | double | 注文商品の単価 |
order.items.quantity | YES | int | 注文商品の数 |
order.tax | - | double | 注文にかかる消費税 |
order.shipping | - | double | 注文にかかる配送料 |
order.total_amount | YES | double | 注文代金の総額 |
order.order_ref | - | string | マーチャントが利用可能な、リファレンスID (※3) |
merchant_data.store | YES | string | マーチャントの名前(ストア・ショップ名) |
merchant_data.customer_age | YES | int | 決済方法に関係なく、コンシューマーの初回購入日からの経過日数 |
merchant_data.last_order | YES | int | 決済方法に関係なく、コンシューマーの直近の購入日からの経過日数 |
merchant_data.last_order_amount | YES | double | 決済方法に関係なく、コンシューマーの直近の購入金額 |
merchant_data.known_address | YES | boolean | 決済方法に関係なく、コンシューマの購入で以前に配送したことのある住所か否か |
merchant_data.num_orders | YES | int | 決済方法に関係なく、コンシューマが今まで利用した購入回数総計 |
merchant_data.ltv | YES | double | 決済方法に関係なく、コンシューマの今までの購入金額総計 |
merchant_data.ip_address | YES | string | コンシューマーの接続元IPアドレス |
checksum | YES | string | チェックサム |
options.authorize_type | - | string | Paidy Checkoutでの分割払い表示の有無 - simpleまたはextended (※4) |
RequiredがYESとなっているパラメーターは、必須項目です。
- ※1: このパラメータにセットされた値がPaidy Checkout画面に反映されます。
- ※2: 携帯電話番号が不明な場合は、このデータにデータをセットせずにPaidy Checkoutを実行してください。
- ※3: マーチャント側で独自に利用されるIDや、リファレンスデータとPaidyのpayment IDを紐付ける場合などにご利用ください。なお、このパラメータはすでに登録されている値を重複して設定することができます。ご注意ください。
- ※4: Paidy Checkoutにセットする、options.authorize_typeパラメータ(”simple”, “extended”)は加盟店様の契約に合致したパラメータを設定いただく必要があります。
・分割払いのできない加盟店様の場合:常に一括払いのみ表示されます。
・分割払いのできる加盟店様の場合:金額に応じ、一括または分割払いが表示されます。 - ※5: item_idは、order.items内において、ユニークである必要があります。
チェックサム
チェックサム作成例 - base64の場合:
#!/bin/bash
STRING='IamSecret7200Test Store22153500false21000.0.0.0'
CHECKSUM64=`echo -n ${STRING} | openssl dgst -sha256 -binary | base64`
echo ${CHECKSUM64}
//SORRY, NOW PRINTING.
require 'digest/sha1'
require 'base64'
$string = 'IamSecret7200Test Store22153500false21000.0.0.0'
$sha256 = Digest::SHA256.digest($string)
$checksum64 = Base64.encode64($sha256)
puts $checksum64
import hashlib
import base64
string = 'IamSecret7200Test Store22153500false21000.0.0.0'
sha256 = hashlib.sha256(string).digest()
checksum64 = base64.b64encode(sha256)
print(checksum64)
<?php
$string = 'IamSecret7200Test Store22153500false21000.0.0.0';
$sha256 = hash('sha256', $string, true);
$checksum64 = base64_encode($sha256);
echo $checksum64;
?>
チェックサム作成例 - hexの場合:
#!/bin/bash
STRING='IamSecret7200Test Store22153500false21000.0.0.0'
CHECKSUMHEX=`echo -n ${STRING} | openssl dgst -sha256 -binary | hexdump -e '"%0.0_ax" 32/1 "%02x" "\n"'`
echo ${CHECKSUMHEX}
//SORRY, NOW PRINTING.
require 'digest/sha1'
$string = 'IamSecret7200Test Store22153500false21000.0.0.0'
$sha256 = Digest::SHA256.digest($string)
$checksumhex = $sha256.each_byte.map{|b|b.to_s(16)}.join
puts $checksumhex
import hashlib
string = 'IamSecret7200Test Store22153500false21000.0.0.0'
sha256 = hashlib.sha256(string).digest()
checksumhex = sha256.encode('hex')
print(checksumhex)
<?php
$string = 'IamSecret7200Test Store22153500false21000.0.0.0';
$sha256 = hash('sha256', $string, true);
$checksumhex = array_shift(unpack('H*', $sha256));
echo $checksumhex;
?>
チェックサムは、マーチャント毎に固有のシークレットキーとリクエストするJSONのパラメーターを組み合わせた文字列のハッシュ値をエンコードして作成してください。
チェックサムの生成に使用するJSONパラメーターは下記の通りです。 double型のパラメータはint型に変換した後、すべてstringとしてつなぎあわせてください。
order.total_amount
merchant_data.store
merchant_data.customer_age
merchant_data.last_order
merchant_data.last_order_amount
merchant_data.known_address
merchant_data.num_orders
merchant_data.ltv
merchant_data.ip_address
エンコード方法は、base64を使用する方法とhexを使用する方法のどちらか一方を選択することができます。 ベースとなる文字列のハッシュ値をエンコードする方法は、右記のチェックサム作成例をご確認ください。
base64 ( sha256 ( secret + string(int(order.total_amount)) + merchant_data.store + string(merchant_data.customer_age) + string(merchant_data.last_order) + string(int(merchant_data.last_order_amount)) + string(merchant_data.known_address) + string(merchant_data.num_orders) + string(int(merchant_data.ltv)) + merchant_data.ip_address ) )
hex ( sha256 ( secret + string(int(order.total_amount)) + merchant_data.store + string(merchant_data.customer_age) + string(merchant_data.last_order) + string(int(merchant_data.last_order_amount)) + string(merchant_data.known_address) + string(merchant_data.num_orders) + string(int(merchant_data.ltv)) + merchant_data.ip_address ) )
例えばシークレットキーがIamSecret
、リクエストするJSONのパラメーターが下記である場合、
order.total_amount: 7200.0
merchant_data.store: "Test Store"
merchant_data.customer_age: 2
merchant_data.last_order: 215
merchant_data.last_order_amount: 3500.0
merchant_data.known_address: false
merchant_data.num_orders: 2
merchant_data.ltv: 100.0
merchant_data.ip_address: "203.0.113.0"
チェックサムのベースとなる文字列は
IamSecret7200Test Store22153500false2100203.0.113.0
となります。
レスポンス
レスポンス - 成功の場合:
{
"payment_id": "YourPaymentIdHere",
"status": "authorize_success",
}
レスポンス - 失敗の場合:
{
"status": "failed_request",
"reason": "bad_checksum",
"message": "Checksum doesn't match"
}
Authorizeリクエストの実行結果として、JSONオブジェクトが返ってきます。 それぞれが意味する内容は下記の通りです。 (SuccessがYESとなっているものは成功時に、FailureがYESとなっているものは失敗時に返ってくるオブジェクトです。)
Parameter | Success | Failure | Description |
---|---|---|---|
payment_id | YES | - | 新規に発行されたPaidyのPayment ID |
status | YES | YES | ステータスコード - 詳細は後述のステータスコードをご確認ください |
reason | - | YES | リクエストが失敗した場合の理由 |
message | - | YES | リクエストが失敗した場合の理由の詳細 |
test | YES | - | テストフラグ - テストコンシューマアカウントで作成されたものはtrue、それ以外はfalseとなります |
ステータスコード
Authorize実行結果のJSONオブジェクトに含まれる"status"の種類とそれが示す内容は下記の通りです。
Status Code | Description |
---|---|
authorize_success | Authorizeが成功しました |
authorize_fail | Authorizeが失敗しました |
決済データの有効期限とステータス
Authorizeに成功すると、Paidyで一意のPayment IDをもった決済データが作成されます。 作成された決済データは、Authorize時に送信された注文情報やコンシューマー情報以外に、
- 有効期限
- ステータス(決済の状態)
を含んでいます。
有効期限は、標準ではAuthorizeに成功した日を起算日として、30日です。 後述のUpdateエンドポイントをリクエストした場合であっても、有効期限は更新されません。
ステータスには、"open"または"close"のどちらかがセットされます。 Authorizeに成功し、新規で作成された決済データのステータスは常に"open"です。 作成された決済データのステータスは、
- Authorizeされた金額のすべてがCaptureされたとき
- 有効期限を過ぎたとき
- Closeエンドポイントをリクエストされたとき
をトリガにして、"close"に変更されます。 決済データのステータスが"close"の場合、そのPayment IDに対するUpdate、Close、Captureリクエストは失敗します。
Authorize済の決済データの有効期限、ならびにステータスは、後述のStatusエンドポイントをリクエストすることで確認できます。
合計金額からの値引きを設定する場合
合計金額からの値引きJSON設定例(一部のみ抽出):
"order": {
"items": [{
"item_id": "1",
"title": "アイテム1",
"amount": 2000.0,
"quantity": 1
}, {
"item_id": "2",
"title": "アイテム2",
"amount": 4500.0,
"quantity": 1
}, {
"item_id": "X",
"title": "値引き",
"amount": -1000.0,
"quantity": 1
}],
"tax": 200.0,
"shipping": 500.0,
"total_amount": 6200.0
}
クーポンやポイントの利用等、注文金額の合計から値引きを設定する必要がある場合は、order.item
の中に、値引きを示すマイナスのオブジェクトをセットしてください。
このとき、order.total_amount
は、値引き後の金額としてください。
たとえば、¥2,000
のアイテムひとつと、¥4,500
のアイテムひとつをカートに入れ、消費税¥200
、送料が¥500
であるとき、それら全体から¥1,000
を割引する場合は、リクエストするJSONのorderを右記のようにセットして、Paidy Checkoutを実行してください。
このとき、order.total_amount
には、値引き分の¥1,000
を引いた金額をセットしてください。
このAuthorizeが成功しCaptureがリクエストされた時に、コンシューマーは自身のMyPaidyから割引額を確認することができます。
ロゴの準備とロゴURLの設定
Paidy Checkout上に表示される丸ロゴをサイト独自のロゴに設定することが可能です。 Paidy Checkout上に表示するロゴは、Paidy Checkoutを利用するページと同じドメインに設置してください。 最適画像サイズならびに推奨画像形式は下記の通りです。
最適画像サイズ: 184px x 184px (正方形)
推奨画像形式: .png
, .jpg
, .gif
画像サンプル
画像は、Paidy Checkoutでは円形のフレーム内に表示されます。 上記画像サンプルの場合、正方形の外枠部分が用意された画像で、点線で円形に囲まれた部分が実際にPaidy Checkoutに表示される部分となります。 グレー部分は、Paidy Checkout画面で非表示となる部分です。 また、縦横が同じ長さでないロゴの場合、長辺がフレームの大きさを満たすように画像が表示されます。
分割払いオプションの表示・非表示
加盟店様の契約に従って分割払いオプションが表示・非表示にされます。
画面遷移イメージ(画像をクリックすると拡大します)
ブラウザ対応状況
対応しているWebブラウザー、デバイスに関しては以下のページを参照ください。
ブラウザ対応状況および推奨されるプラットフォーム
3-3 ベストプラクティス
Paidy Checkoutを使用する際のベストプラクティスは下記の通りです。
システムの構成
Paidy Checkoutを実装すると、AuthroizeエンドポイントからのPayment ID等のレスポンスデータをマーチャントシステムのフロントエンド側で(= コンシューマーのブラウザーで)受け取ることになります。 マーチャントのフロントエンドから取得したレスポンスデータの信頼性を担保するためには、後述のWebhookの利用してフロントエンドで取得するレスポンスデータと同じデータをシステムバックエンドで取得するか、あるいは下図のように、Payment IDをマーチャントシステムのデータベースに保存する前に、Statusエンドポイントをリクエストするようシステムを構成してください。
Paidy Checkoutを使用したシステム構成(画像をクリックすると拡大します)
1. マーチャントECサイトのチェックアウトページでロードされたPaidy CheckoutからAuthorize APIをリクエストします。
2. Authorizeが成功し、Payment IDがレスポンスデータとして戻ってきます。
3. マーチャントECサイトのフロントエンドで取得したPayment IDをバックエンドシステムにPOSTします。
4. マーチャントECサイトのバックエンドシステムで、フロントエンドから取得したPayment IDを使って、PaidyのStatusエンドポイントをリクエストします。
5. Payment IDが正規のものであると確認できた場合は、Statusエンドポイントから、そのPayment IDのステータス、合計金額等がレスポンスととして返ってきます。
6. 前述の5.で正しいレスポンスが返ってきたことが確認できたら、自身のデータベースにPayment IDをストアします。
スマートフォンでのPaidy Checkoutの起動
Paidy Checkoutはポップアップを使用しているため、一部のスマートフォンではポップアップにおいて問題が生じる場合があります。 しかしこの問題は、Paidy Checkoutの起動方法を制御することによって回避することができます。
<iOSの場合>
iOS safariは、ユーザのクリックアクションによって開かれたポップアップはブロックしない、という仕様です。 従って、Paidy Checkoutはユーザアクション(クリックイベント等)とひも付けて起動するようシステムを構成してください。 なお、本ドキュメントのサンプルデモは、クリックイベントからPaidy Checkoutを起動しています。
<Androidの場合>
Androidについては、デフォルトでポップアップがブロック設定となっているデバイスとそうでないデバイスがあります。 しかしたとえデフォルトでブロック設定となっている場合であっても、「許可してもいいですか」という旨のメッセージが表示され、ユーザが「許可」とした場合は、以後、許可を促すメッセージは表示されることはなく、先に進めます。
4 Webhook
Webhookは、Paidyのイベントが発生した際に、Paidyのシステムからマーチャントが指定したURLにデータを受け取る手段を提供するものです。
Webhookは、イベントオブジェクト(Authorize、Update, Close, Capture、Refund)が作成されたタイミングに、指定されたURLへHTTP(S)リクエストを送信します。
APIやCheckoutなどのレスポンスから直接処理を実装する以外に、Webhookにより指定したURLにイベントを受け取ることで、マーチャントが用途に応じた処理を実装することが可能になります。
Webhookを利用することで、主に以下の二つの利点があります。
- Paidyマーチャント画面の処理をマーチャント様側のシステムへ同期
Paidyマーチャント画面にて処理を実行した場合に、マーチャント様側のシステムへ変更を通知することで、自動的にPaidy-マーチャント間のデータを同期することが可能になります。
- コンシューマデバイス - マーチャント間の通信に発生する問題の回避
コンシューマーが実行する、Paidy Checkoutとマーチャントシステムの間に発生しうる問題を解決する手段として有効です。Paidy Checkoutのページを途中で終了してしまったり、通信状況が悪い環境からCheckoutを実行すると、まれに、マーチャント側へデータの受け渡しが失敗することがあります。WebHookにより、確実に処理を同期し、完了することが可能となります。
4-1 利用方法
Webhookを送る先のURLはマーチャントの管理画面から設定できます。Webhook用のURLを設定すると、次に発生するイベントからWebhookの送信が行われます。
Webhookの送信元IPアドレス
更新:2016/10/28
送信元IPアドレスは2016/11/17以降
以下に変更されます。ご注意ください。
2016/11/17まで
- 54.64.193.188
- 54.64.149.166
の2つです。
2016/11/17以降
- 52.199.50.20
- 52.199.62.26
の2つに変更されます。
以前のIPアドレスは利用されません。
Webhookによる通知へのレスポンス
マーチャント側のエンドポイントがWebhookを受信したら、200 HTTP Statusコードをレスポンスする必要があります。レスポンスが200 HTTP Statusコード以外だった場合、または10秒以内にレスポンスが得られなかった場合、Paidyは継続してリクエストを送信し続けます。
遅延と再試行
Webhookの通知はイベントが発生した時点で作成されますが、以下のような原因で通知の受信が遅れる場合があります。
- Webhookの通知は作成後にキューに並べられ、順番に処理されていきます。その際、キューに並んでいる通知の数が多いと処理に時間がかかります。
- 決済を高速で処理できるよう、システムはまず決済の処理を優先的に行ってからキューを更新するため、ここで遅延が生じる場合があります。
発生したイベントの種類(決済のAuthorizeなど)を問わず、どのイベントでも遅延が生じる可能性があります。遅延の長さは1秒~数時間程度です。
なお、ネットワークの遅延によりWebhookが失敗(タイムアウト)する可能性があり、その場合は再試行が行われます。この再試行は最大で9回繰り返されます(合計で10回メッセージを送信することになります)。まずは10秒間隔で再試行を3回行い、それ以降は指数関数的に徐々に間隔を広げていき、最終的に10分の間隔を空けて最後の再試行が行われます。処理成功を知らせるレスポンスをAPIが受信しないまま再試行が終了しても、この通知が再び送信されることはありません。
また、再試行中に後から他の決済イベントが発生した場合、そのイベントに関する通知も引き続き処理され、Webhook経由で送信され続けます。
実装の注意点
必要に応じて以下のようにシステムを構成してください。
- Webhookを実装すると自動的にすべてのイベントが通知の対象になります。必要なWebhookのみを処理したい場合は、通知をフィルタリングするようにシステムを構成してください。
- Webhookは必ず一定の順序で送信されるというわけではありません。例えば、ある決済で発生したAuthorizeイベントの通知を、Captureイベントのものよりも後に受け取る可能性があります。そのため、例えば有限オートマトンなどのロジックを利用してシステムがこれに対処できるようにしておくことが推奨されます。
- 同じ通知のコピーを複数回受信する可能性があります。そのため、すでに処理を済ませたWebhookを破棄するようにシステムを構成しておくことが推奨されます。
4-2 リクエストボディ
例 - authorize の場合:
{
"payment_id":"YourPaymentIdHere",
"status":"authorize_success",
"event_type": "payment",
"order_ref":"abc123",
"event_datetime":"2015-01-29 18:28:37"
}
例 - capture の場合:
{
"payment_id":"YourPaymentIdHere",
"capture_id":"YourCaptureIdHere",
"status":"capture_success",
"event_type": "payment",
"event_datetime":"2015-01-29 18:28:37"
}
例 - refund(success) の場合:
{
"payment_id":"YourPaymentIdHere",
"capture_id":"YourCaptureIdHere",
"status":"refund_success",
"event_type": "payment",
"event_datetime":"2015-01-29 18:28:37"
}
Webhookの内容はPOSTリクエストで、リクエストボディは、Paidy APIのリクエスト内容とほぼ同じJSONです。 Paidy APIのリクエスト内容に加えて、イベントオブジェクトを識別するためのorder_refのような追加の情報が含まれます。具体的には、右記の例をご参照ください。
リクエストボディパラメタ
Parameter | Description |
---|---|
payment_id | 決済(ペイメント)ID |
capture_id | 回収(キャプチャー)ID |
status | (詳細は下記ステータスコードを参照してください) |
order_ref | マーチャントが利用可能なリファレンスID |
reason | 失敗した場合の原因(払い戻しの場合のみ) |
event_type | イベントタイプ |
event_datetime | イベントオブジェクトが作成された日時 |
timestamp | イベントオブジェクトが作成された日時。UTC時間で、以下のフォーマットとなります。"yyyy-mm-ddThh:mm:ss.fffZ" (例: “2016-12-05T02:18:48.616Z") |
ステータスコード
Status Code | Description |
---|---|
authorize_success | Paidy決済の認証が成功しました |
capture_success | 指定された決済IDの回収(キャプチャー)が成功しました |
refund_success | 払い戻し処理が成功しました |
update_success | 指定されたPayment IDの更新に成功しました |
close_success | 指定されたPayment IDのクローズに成功しました |
※ updateReferenceリクエストはwebhookを返しません。
※ キャプチャーできなくなった時点で、クローズのwebhookが常に送信されます。これは、クローズリクエストが実行された場合に加え、決済に対し、すべてキャプチャーされた場合(capture_success、およびclose_successのステータスの2つが送信されます。)においても送信されます。
5 テストアカウント
開発・検証のためのテスト方法に関しては、加盟店様管理画面、「設定」ページをご確認ください。