継続課金
あなたのサブスクリプション製品またはサービスへの定期的な支払いをユーザーが許可することで、定期的な支払いを行うことができます。※法人のお客様のみご利用いただけます。
Integration
Overview
こちらはPayPay決済を導入する開発者向けドキュメントになります。こちらのPayment SDKを使うことで簡単に開発をできるように支援することを目的としています。こちらのPayment SDKを用いてビジネス要求を実現しつつPayPayのガイドラインに合わせた実装を行うことが可能になります。
継続課金を使用する場合
継続課金 は以下のような場合に採用することをお勧めしております
- ビデオストリーミングサービス、ゲームサービスなどのサブスクリプション製品またはサービスを持っている
- 短期間でサブスクリプションサービスの決済機能が必要である
支払いフローについて
次の図は、 継続課金 の統合フローを定義しています。
取引のステータスを確認するために、マーチャントは4〜5秒間隔でGet payment Details APIのポーリングを実装することをお勧めします。
でははじめていきましょう
実際の開発を開始する前に、
事前作業として以下の作業が完了しているか確認ください。
- PayPay for developer でマーチャントアカウントを 登録する
- developer dashboard より API key and secret を取得する
- sandboxむけの API key と Secret を使って開発する
継続課金を開発する
インストール
# If you love Python, you will love our pip installation package,
# simply run the following to ensure you have all the methods needed to make the integration
$ pip install paypayopa
クライアントをビルドする
以下に定義するようにapikeyとsecretを追加してクライアントを構築します。 APIでは、認証方式としてHMAC採用していますが、SDKで認証を処理することが可能です。 認証について詳しく知りたい場合は こちら を参照ください 。 Production_modeは、サンドボックス/本番環境の宛先を設定します。デフォルトのfalse設定は、サンドボックス環境に接続します。 Ture設定は、本番環境に接続します。
import paypayopa
''' production_mode : Set the connection destination of the sandbox environment / production environment.
The default false setting connects to the sandbox environment. The True setting connects to the production environment. '''
client = paypayopa.Client(auth=(API_KEY, API_SECRET), production_mode=False)
client.set_assume_merchant("MERCHANT_ID")
ユーザー認可を取得する
ユーザー認可を取得するためにはJWT を作成して頂く必要がございます。
Claim | Required | Type | Description |
---|---|---|---|
scopes | Yes | Array of string | Items Enum: 'direct_debit' 'cashback' 'get_balance' 'quick_pay' 'continuous_payments' 'merchant_topup' 'pending_payments' 'user_notification' 'user_topup' 'user_profile' 'preauth_capture_native' 'preauth_capture_transaction' 'push_notification' 'notification_center_ob' 'notification_center_ab' 'notification_center_tl' ユーザー認可のスコープ |
nonce | Yes | string | ランダムに生成された文字列。 |
redirectType | No | string | Default: 'WEB_LINK' Enum: 'APP_DEEP_LINK' 'WEB_LINK' 加盟店アプリまたはウェブページにリダイレクトするかどうかを決定するパラメーター。 |
redirectUrl | Yes | string | クライアントから提供されたコールバックエンドポイント。WEB_LINKの場合はHTTPSである必要があり、またドメインは事前に許可されたコールバックドメイン内になければなりません。 |
referenceId | Yes | string | マーチャントシステムでユーザーを識別するためのID。 再照合の目的でPayPayデータベースに格納されます |
phoneNumber | No | string | ユーザーの電話番号 |
deviceId | No | string | ユーザーの携帯電話デバイスID。提供されている場合は、より快適なUXを提供するために、この携帯電話デバイスIDを使って、ユーザーの確認とSMSの確認を省略できます。 |
userAgent | No | string | Webブラウザのユーザーエージェント。 redirectTypeが「WEB_LINK」の場合、ユーザー認可取得後に起動するWEBブラウザを指定する事が可能です。 |
payload = {
"scopes": [
"continuous_payments"
],
"nonce": "rtyuhghj7989",
"redirectType": "WEB_LINK",
"redirectUrl": "https://merchant.domain",
"referenceId": "uioiugf789",
"phoneNumber": "90999999999",
"deviceId": "qwertyuiopoiuytre54567",
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
}
client.Account.create_qr_session(payload)
ユーザーが認証を付与すると、認可ページの戻りパラメーターもしくはWebhookにてJWTトークンの一部としてUserAuthorizationIDを返します
# Calling the method to get user authorization status
response = client.User.get_authorization_status("<userAuthorizationId>")
# Printing if the method call was SUCCESS
print(response['resultInfo']['code'])
ユーザーのリンクを解除する
クライアントからユーザーのリンクを解除するには, 以下のパラメーターを使用してリクエストしてください
Field | Required | Type | Description |
---|---|---|---|
userAuthorizationId | Yes | string <= 64 characters | ユーザー認可フローで返却されたPayPayユーザー認可ID |
# Calling the method to unlink the user from the client
response = client.User.unlink_user_athorization("<userAuthorizationId>")
# Printing if the method call was SUCCESS
print(response['resultInfo']['code'])
Create a continuous payment
継続課金を実施する場合には、以下のパラメータを使用してリクエストしてください
Field | Required | Type | Description |
---|---|---|---|
merchantPaymentId | Yes | string <= 64 characters | 加盟店から提供された一意の支払い取引ID |
userAuthorizationId | Yes | string <= 64 characters | ユーザー認可フローで返却されたPayPayユーザー認可ID |
amount | Yes | integer <= 11 characters | 支払金額 |
orderDescription | No | string <= 255 characters | 取引の説明 |
# Creating the payload for a payment authorization request, additional parameters can be added basis the API Documentation
request_payload = {
"merchantPaymentId": "merchant_payment_id",
"userAuthorizationId": "my_user_authorization_id",
"orderDescription":"Mune's Favourite Cake",
"amount": {
"amount": 1,
"currency": "JPY"
}
}
# Calling the method to create a continuous payment authorization
response = client.Payment.create_continuous_payment(request_payload)
# Printing if the method call was SUCCESS, this does not mean the payment was a success
print(response['resultInfo']['code'])
上記のコンソール出力でSUCCESSが出力され、ステータスが'AUTHORIZED'である場合、APIの実行は成功しています。
レスポンス項目について詳細に知りたい 場合には、 [APIドキュメントガイド]をご確認ください。
Get Payment Details
決済情報を参照をすることができます。以下のパラメーターを使用してリクエストしてください。
Field | Required | Type | Description |
---|---|---|---|
merchantPaymentId | Yes | string <= 64 characters | 加盟店から提供された一意の支払い取引ID |
# Calling the method to get payment details
response = client.Payment.get_payment_details("<merchantPaymentId>")
# Printing if the method call was SUCCESS, this does not mean the payment was a success
print(response['resultInfo']['code'])
# Printing if the transaction status for the code has COMPLETED/ AUTHORIZED
print(response['data']['status'])
SUCCESS が返却された場合APIは正しく実行されています。支払いが完了すると、response.data.statusのステータスが CREATED から COMPLETED に変わります。 支払いの事前認証の場合、response.data.statusのステータスは CREATED から AUTHORIZED に変わります
レスポンス項目について詳細に知りたい 場合には、[APIドキュメントガイド]をご確認ください。
Cancel a payment
決済をキャンセルしたい場合にこちらを利用ください。通常の決済フローでは基本的には、Cancel a paymentを使いませんが以下の場合に利用ください。
- Get Payment Detailsを実行したが状態がわからない場合
注:Cancel a paymentは、支払いが行われた翌日の00:14:59まで使用できます。 00:15 AM以降の場合、Refund a paymentを呼び出して支払いを払い戻します。
処理を実施する場合には、以下のパラメーターを使用してリクエストしてください。
Field | Required | Type | Description |
---|---|---|---|
merchantPaymentId | Yes | string <= 64 characters | 加盟店から提供された一意の支払い取引ID |
# Calling the method to cancel a Payment
response = client.Payment.cancel_payment("<merchantPaymentId>")
# Printing if the method call was SUCCESS
print(response['resultInfo']['code'])
SUCCESS が返却された場合APIは正しく実行されています。
レスポンス項目について詳細に知りたい 場合には、 [APIドキュメントガイド]をご確認ください。
Refund payment
ユーザーがサブスクリプションを解約した場合など、返金する場合にRefund a paymentを使用ください。主要な項目を以下に記載しますので、以下のパラメーターを使用してリクエストしてください。
Field | Required | Type | Description |
---|---|---|---|
merchantRefundId | Yes | string <= 64 characters | 加盟店から提供された一意の払い戻し取引ID |
paymentId | Yes | string <= 64 characters | PayPayが決済後に発番する取引ID |
amount | Yes | integer <= 11 characters | 返金金額 |
reason | No | string <= 255 characters | 返金理由 |
# Creating the payload to refund a Payment, additional parameters can be added basis the API Documentation
payload = {
"assumeMerchant": "assume_merchant",
"merchantRefundId": "merchant_refund_id",
"paymentId": "paypay_payment_id",
"amount": {
"amount": 1,
"currency": "JPY"
},
"reason": "reason for refund"
}
# Calling the method to refund a Payment
response = client.Pending.refund_payment(payload)
# Printing if the method call was SUCCESS
print(response['resultInfo']['code'])
SUCCESS が返却された場合APIは正しく実行されています。
レスポンス項目について詳細に知りたい場合には、 [APIドキュメントガイド] を確認ください。
Fetch refund status and details
返金処理(`Refund a payment`)がタイムアウトをした場合には、このAPIを利用ください。処理を実施する場合には、以下のパラメーターを使用してリクエストしてください。
Field | Required | Type | Description |
---|---|---|---|
merchantRefundId | Yes | string <= 64 characters | 加盟店から提供された一意の返品取引ID |
# Calling the method to get Refund Details
response = client.Payment.refund_status("<merchantRefundId>")
# Printing if the method call was SUCCESS
print(response['resultInfo']['code'])
SUCCESS が返却された場合APIは正しく実行されています。
レスポンス項目について詳細に知りたい 場合には、 [APIドキュメントガイド]をご確認ください。
突合ファイル
PayPayでは取引明細ファイル(突合ファイル)を日次の処理で生成し、Webhookで通知します。
突合ファイル連携仕様
Category | Description | Note |
---|---|---|
ファイル連携方法 | Webhook | |
ファイル名 | transaction_<merchant_id>_<from>_<to>.csv | |
ファイル作成単位 | 加盟店(merchant_id)単位 | |
実行サイクル | Daily | PayPay側の取引日時が作成対象日の 00:00:00 – 23:59:59 の範囲 |
通知時間 | 毎日4:00 AM 以降 | |
フォーマット | CSV | |
ファイル保持期間 | 2週間 | |
Character Code(content) | SHIFT-JIS | |
Character Code(filename) | UTF-8 | |
newline code | CRLF |
ファイルレイアウト
Key | Value from | Note |
---|---|---|
決済番号 | paymentId | PayPayで採番された決済番号 |
加盟店ID | merchant_id | PayPayで採番された加盟店識別子 |
屋号 | brandName | PayPayで管理しているブランド名 |
店舗ID | storeId | リクエスト時にセットされたstoreId |
店舗名 | storeName | PayPayで管理している店舗名 |
端末番号/PosID | terminalId | リクエスト時にセットされたterminalId |
取引ステータス | "取引完了" , "取引失敗" , "返金完了" , "返金失敗" | |
取引日時 | acceptedAt | |
取引金額 | amount | 返金の場合はマイナス記号あり |
レシート番号 | "" | 当機能では設定不可 |
支払い方法 | "PayPay残高" , "PayPayカード" | |
マーチャント決済ID | merchantPaymentId | 加盟店で採番された決済番号 |
Webhooks
Webhookの設定
PayPayは、アカウントでイベントが発生したときにアプリケーションに通知するWebhookを送信します。 通知を受信するためには、POSTメソッドを使用してクライアントにデータを送信するWebhook URLを設定する必要があります。 すべての通知データには、どのイベントが発生したかを判断するためにクライアントサービスで使用できるnotification_typeフィールドがあります。 Webhook処理が正常に終了した場合、200 OK のHTTPステータスコードを返してください。 レスポンスボディは必須ではないですが、"OK"など、簡単な文字列を返していただくことを推奨します。
Webhookでの通知
Webhookで通知されたpathからファイルを取得してください。
{
"notification_type":"file.created",
"notification_id":"<UUID>",
"fileType":"transaction_recon",
"path":"https://<server_path>/<filename>?parameters",
"requestedAt":"<epoch time>"
}
下のボタンをクリックすると、Webhookの構成を確認できます
Error Handling
PayPayは、HTTP応答ステータスコードとエラーコードを使用して、リクエストの成功または失敗を示します。以下に、詳細のエラーコードごとの実装を詳細に記載致します。
HTTP 2xx
200 すべて正常に動作しています。
201 リクエストされたリソース(コードなど)が作成されたことを表します。
202 リクエストを受け付けたことを意味し、後に処理されます。
HTTP 4xx
400 このステータスコードは、リクエスト時にセットされた情報を処理できないことによるエラーを示します。 以下のOPAエラーコードが返される可能性があります。
- INVALID_PARAMS リクエスト時にセットされた情報に無効なデータが含まれています。例)サポートされていない通貨がセットされているなど。
- UNACCEPTABLE_OP リクエストが処理できません。
- LIMIT_EXCEEDED 支払い上限額を超えています。決済金額が事前承認された金額を超える場合、発生する可能性があります。 *1
- USER_DEFINED_DAILY_LIMIT_EXCEEDED ユーザ設定の支払い上限額(24時間)を超えています。 *1
- USER_DEFINED_MONTHLY_LIMIT_EXCEEDED ユーザ設定の支払い上限額(30日)を超えています。 *1
- NO_SUFFICIENT_FUND 支払のための残高が不足しています。
401 このステータスコードは、認証エラーを示します。 以下のOPAエラーコードが返される可能性があります。
- UNAUTHORIZED 有効なapi keyとsecretがセットされていません。
- OP_OUT_OF_SCOPE 対象APIを呼び出す権限がありません。
404 このステータスコードは、リクエストされたリソースがシステムに存在しないことを示しています。
429 このステータスコードは、クライアントが一定期間内に送信したリクエストが多すぎたため、速度制限に達したことを示します。 リクエストの送信を遅くするか、上限引き上げをご要望の旨を弊社までご連絡ください。
*1 : 2021年9月1日より本番環境に追加される予定です
HTTP 5xx
500 この状態コードは、PayPay側で何か問題が発生したことを示します。 下記のOPAエラーコードが返却される可能性があります。
- TRANSACTION_FAILED このコードは、PayPay側でトランザクションが失敗したことを意味します。 適切なバックオフ時間で、同様の新しいトランザクションの作成が可能です。
- INTERNAL_SERVER_ERROR このコードは何かがうまくいかなかったことを意味します。 しかし、トランザクションが発生したかどうか正確にはわからないため、不明な支払ステータスとして扱う必要があります。
502,503,504不明な支払いステータスとして扱われます。
Timeout
推奨されるタイムアウト設定は、各APIで指定されています。 最も重要なのは、支払いタイムアウトAPIで、読み取りタイムアウト値を30秒以上で設定してください。タイムアウトが発生した場合、不明な支払いステータスとして扱ってください。
Handle unknown payment status
ステータスが不明な場合、下記のいずれかの方法で対処してください:
- 取引のステータスを照会するため、照会APIを使用してください。 PayPayで取引が失敗になっている、または存在しない場合は、元取引と同様のリクエストを再度行なってください。
- キャンセルAPIを使用してください。 キャンセルAPIが提供されている場合は、取引をキャンセルすることもできます。 キャンセルが承認された後、元取引と同様のリクエストを再度行なってください。
Response code list
Common response code
Status | Code | Message |
---|---|---|
200 | SUCCESS | Success |
202 | REQUEST_ACCEPTED | Request accepted |
400 | INVALID_REQUEST_PARAMS | Invalid request params |
401 | OP_OUT_OF_SCOPE | The operation is not permitted |
400 | MISSING_REQUEST_PARAMS | |
401 | UNAUTHORIZED | Unauthorized request |
404 | OPA_CLIENT_NOT_FOUND | OPA Client not found |
429 | RATE_LIMIT | Too many requests |
500 | SERVICE_ERROR | |
500 | INTERNAL_SERVER_ERROR | Something went wrong on PayPay service side |
503 | MAINTENANCE_MODE | Sorry, we are down for scheduled maintenance |
Create a continuous payment
Status | Code | Message |
---|---|---|
400 | REQUEST_ORDER_NOT_FOUND | Request order not found |
400 | UNACCEPTABLE_OP | The requested operation is not able to be processed due to the current condition. E.g. the user is blacklisted by fraud check. |
400 | LIMIT_EXCEEDED | The payment amount exceeded upper limit. *1 |
400 | USER_DEFINED_DAILY_LIMIT_EXCEEDED | The payment amount exceeded user 24 hours defined limit. *1 |
400 | USER_DEFINED_MONTHLY_LIMIT_EXCEEDED | The payment amount exceeded user 30 days defined limit. *1 |
*1 : 2021年9月1日より本番環境に追加される予定です
Get payment details
Status | Code | Message |
---|---|---|
400 | DYNAMIC_QR_PAYMENT_NOT_FOUND | Dynamic QR payment not found |
400 | DYNAMIC_QR_BAD_REQUEST | Dynamic QR bad request error |
Cancel a Payment
Status | Code | Message |
---|---|---|
400 | ORDER_NOT_REVERSIBLE | Order cannot be reversed |
500 | INTERNAL_SERVER_ERROR | Request timed out |
Refund a Payment
Status | Code | Message |
---|---|---|
400 | INVALID_PARAMS | Invalid parameters received |
400 | UNACCEPTABLE_OP | Order cannot be refunded |
400 | UNACCEPTABLE_OP | Multiple refund not allowed |
400 | INVALID_PARAMS | Invalid refund amount |
400 | CANCELED_USER | Canceled user |
404 | RESOURCE_NOT_FOUND | Order not found |
500 | TRANSACTION_FAILED | Transaction failed |
500 | TRANSACTION_FAILED | Transaction failed |
500 | TRANSACTION_FAILED | Balance exceeded |
500 | INTERNAL_SERVER_ERROR | Request timed out |
Fetch refund status and details
Status | Code | Message |
---|---|---|
404 | NO_SUCH_REFUND_ORDER | Refund not found |
500 | INTERNAL_SERVER_ERROR | Request timed out |
本番展開の準備が整っているかどうかは、弊社推奨の チェックリストでご確認ください。