NAV
json

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)
EMAIL お客様のmyPaidyアカウントオープンのお知らせ 《内容を表示内容を別ウィンドウで表示》 (※1)
EMAIL 【利用速報】Paidyご利用のお知らせ 《内容を表示内容を別ウィンドウで表示

(※1) Paidy初回利用コンシューマーにのみ送信されます。 2回目以降は送信されません。

Captureリクエストが成功したとき

Type Title or Message
EMAIL 【請求情報】Paidy請求情報登録のお知らせ 《内容を表示内容を別ウィンドウで表示

月に1回の請求額が確定したとき

Type Title or Message
SMS Paidyのご請求金額が ¥X,XXX に確定しました。お支払方法はこちら。[MyPaidyUrlHere]
EMAIL 【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キー》

マーチャントからのリクエストには必ず、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をサポートするよう、システムを適切に構成してください。

また、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"に記載されます。

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と異なります。

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リクエストが失敗する場合は、下記の原因が考えられます。

決済データのステータスが"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をリクエストできます。

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や、taxshippingの値が含まれている場合は、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リクエストが失敗する場合は、下記の原因が考えられます。

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をリクエストできます。

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リクエストが失敗する場合は、下記の原因が考えられます。

3 Paidy Checkout

Paidy Checkoutは、全ての環境で容易に利用することができ、既存のユザーフローに変更を加える必要はありません。 コンシューマーはECサイトから離脱することなく、決済を実行できます。

Paidy CheckoutはPaidy APIのAuthorizeエンドポイントをコールし、Authorizeに必要な注文データをPaidyサーバに送信します。 Authorize実行後はマーチャントページに戻るため、任意のコールバック値を設定しておくことで、マーチャント独自の発注処理を継続して行うことができます。

Paidy CheckoutとPaidyエンドポイントとの接続イメージ(画像をクリックすると拡大します)

3-1 サンプルデモ

このデモにおいては以下のデモ用アカウントを入力してください。

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となっているパラメーターは、必須項目です。

チェックサム

チェックサム作成例 - 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としてつなぎあわせてください。

エンコード方法は、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のパラメーターが下記である場合、

チェックサムのベースとなる文字列は 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"です。 作成された決済データのステータスは、

をトリガにして、"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 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"
}

例 - refund(fail) の場合:

{
    "payment_id":"YourPaymentIdHere",
    "capture_id":"YourCaptureIdHere",
    "status":"refund_fail",
    "reason":"Cannot refund more than authorized amount",
    "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の回収(キャプチャー)が成功しました
capture_fail 指定された決済IDの回収(キャプチャー)に失敗しました
refund_success 払い戻し処理が成功しました
refund_fail 払い戻し処理に失敗しました
update_success 指定されたPayment IDの更新に成功しました
update_fail 指定されたPayment IDの更新に失敗しました
close_success 指定されたPayment IDのクローズに成功しました
close_fail 指定されたPayment IDのクローズに失敗しました

※ updateReferenceリクエストはwebhookを返しません。

※ キャプチャーできなくなった時点で、クローズのwebhookが常に送信されます。これは、クローズリクエストが実行された場合に加え、決済に対し、すべてキャプチャーされた場合(capture_succes、およびclose_successのステータスの2つが送信されます。)においても送信されます。

5 テストアカウント

開発・検証のためのテスト方法に関しては、加盟店様管理画面、「設定」ページをご確認ください。

6 変更履歴