PayPay
このページで扱うトピック
PayPayを有効化することで、加盟店のお客様はPayPayによる決済が利用できるようになります。PayPayは、登録ユーザーが日本全国で5,700万人以上おり、スマートフォンでアプリを立ち上げる、もしくはQRコードを読み取るだけで簡単に決済ができるサービスです。このガイドでは、決済の流れやPayPayを導入するための手順を説明します。
決済手数料
3.4%
お申し込み方法
サポートされる国: 日本
対象となるAPIバージョン: 2017-11-02版以降
既にOpn Paymentsで他の決済手段をご利用の場合
こちらのページから申請を行ってください。申請には、Opn Paymentsに登録しているメールアドレスが必要です。
弊社からPayPayに審査依頼を行い、審査完了次第、弊社からご連絡致します。
新たにOpn Paymentsの利用申し込みをされる場合
Opn Paymentsの利用申し込み時に、利用する決済手段としてPayPayにチェックを入れてください。
弊社からPayPayに審査依頼を行い、審査完了次第、弊社からご連絡致します。
決済フロー
PayPayはスマートフォンとパソコンでの決済に対応しています。PayPayでの決済を選択したお客様は、app_redirectと呼ばれる決済フローを経由します。
スマートフォンの場合、お客様はPayPayアプリを使用して決済を完了させます。パソコンの場合、お客様がウェブサイト上のQRコードをスマートフォンのPayPayアプリを使用してスキャンするか、PayPayのウェブサイトにログインして決済を完了させます。
スマートフォンを利用した場合とパソコンを利用した場合について、具体的なフローをご説明します。
※画面遷移のイメージについては、PayPayサイトも参照ください。
スマートフォンの場合
加盟店サイトで、お客様が決済方法としてPayPayを選択します。
PayPayアプリが立ち上がり、お支払い内容を確認し、支払いを行います。
PayPayアプリで決済終了の確認画面が表示され、5秒後に加盟店サイトの確認画面にリダイレクトされます。
パソコンの場合~QRコードスキャン~
加盟店サイトで、お客様が決済方法としてPayPayを選択します。
QRコードが表示され、スマートフォンのPayPayアプリでスキャンします。
PayPayアプリでお支払い内容を確認し、支払いを行います。
PayPayアプリで決済終了の確認画面が表示され、5秒後に加盟店サイトの確認画面にリダイレクトされます。
パソコンの場合~PayPayログイン~
加盟店サイトで、お客様が決済方法としてPayPayを選択します。
PayPayの画面に切り替わるので、PayPayに登録している携帯電話番号、パスワードを入力してログインします。
SMSで送信された4桁の認証コードを入力します。
お支払い内容を確認し、支払いを行います。
5秒後に加盟店の確認画面にリダイレクトされます。
実装
PayPayを使用して課金を作成するには、次のようにAPIリクエストを作成します。
Omise.js、モバイルSDK (iOS、Android)、APIコールのいずれかを使用して、新しい課金ソース (
type: paypay
) を作成します。ステップ1で作成したソースの識別子を使用して、新しい課金を作成します。
webhookイベントの課金完了の通知を受信した後、課金を取得してそのステータス(オプションだが推奨)を確認します。
実装には、以下の二つの方法があります。
ソースと課金を個別に作成する
a. まずパブリックキーを利用して、プログラムでPayPayソースを作成する。
b. 次にシークレットキーを利用して、加盟店のシステム側でPayPay課金を作成する。
ソースと課金を同時に作成する
a. シークレットキーを利用して、加盟店のシステム側でソースと課金を作成する。
b. 加盟店のシステム側で、ソースの作成と課金の両方を行う必要がある場合等にこの方法を用いる。
ソースと課金を個別に作成する場合
ソースの作成
ソースの作成で必要なパラメーターは以下の通りです。
Parameter | Type | Description |
---|---|---|
amount |
integer | (required) In Subunits |
currency |
string | (required) JPY |
type |
string | (required) paypay |
phone_number |
string | (optional) 10桁の電話番号 (例: 0812345678) |
name |
string | (optional) 名前 |
email |
string | (optional) メールアドレス |
items |
Item | (optional) |
shipping |
Address | (optional) |
billing |
Address | (optional) |
次の例は、新たに1000円のPayPayの課金ソースを作成する場合の実装を示しています。
omise_public_key
と$OMISE_PUBLIC_KEY
変数をダッシュボードのテストパブリックキーに置き換えます
type
パラメーターはOmise.jsを利用して、createSourceメソッドの最初の引数として提供されます。
Omise.setPublicKey(omise_public_key);
Omise.createSource('paypay', {
"amount": 1000,
"currency": "JPY",
"items",
[
{
"name": "water bottle",
"amount": "500",
"quantity: "2"
}
],
}, function(statusCode, response) {
console.log(response)
});
テストとして、curlを利用し同じリクエストを作成できます。
curl https://api.omise.co/sources \
-u $OMISE_PUBLIC_KEY: \
-d "amount=1000" \
-d "currency=JPY" \
-d "type=paypay" \
-d "items[0][name]=water bottle" \
-d "items[0][quantity]=2" \
-d "items[0][amount]=500"
{
"object": "source",
"id": "src_test_5xawkiqz6boyxaf8gg0",
"livemode": false,
"location": "/sources/src_test_5xawkiqz6boyxaf8gg0",
"amount": 1000,
"barcode": null,
"bank": null,
"created_at": "2023-10-02T12:11:47Z",
"currency": "JPY",
"email": null,
"flow": "app_redirect",
"installment_term": null,
"ip": null,
"absorption_type": null,
"name": null,
"mobile_number": null,
"phone_number": null,
"platform_type": null,
"scannable_code": null,
"billing": null,
"shipping": null,
"items": [
{
"sku": null,
"name": "water bottle",
"brand": null,
"category": null,
"amount": 500,
"quantity": 2,
"item_uri": null,
"image_uri": null
}
],
"references": null,
"provider_references": null,
"store_id": null,
"store_name": null,
"terminal_id": null,
"type": "paypay",
"zero_interest_installments": null,
"charge_status": "unknown",
"receipt_amount": null,
"discounts": []
}
id
属性はソース識別子です(src
で始まります)。
課金の作成
先ほど作ったソースとパラメーターreturn_uri
、amount
、currency
を指定して課金を作成します。
return_uri
は、決済承認後にお客様がリダイレクトされるウェブサイトのアドレスを指定します。source
はソース識別子を指定します。amount
とcurrency
は、ソースのamount
とcurrency
と一致する必要があります。
手動売上化と自動売上化の両方に対応しています。
以下では、curlを使用した課金を新規で作成する方法を例示しています。 $OMISE_SECRET_KEY
をダッシュボードにあるテストシークレットキーに置き換えます。$SOURCE_ID
をソースのid
に置き換えます。
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=1000" \
-d "currency=JPY" \
-d "return_uri=http://example.com/orders/345678/complete" \
-d "source=$SOURCE_ID"
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=1000" \
-d "currency=JPY" \
-d "source[items][0][name]=water bottle" \
-d "source[items][0][quantity]=2" \
-d "source[items][0][amount]=500" \
-d "return_uri=http://example.com/orders/345678/complete" \
-d "source=$SOURCE_ID"
{
"object": "charge",
"id": "chrg_test_5xawkivme2kkynlspkx",
"location": "/charges/chrg_test_5xawkivme2kkynlspkx",
"amount": 1000,
"net": 967,
"fee": 30,
"fee_vat": 3,
"interest": 0,
"interest_vat": 0,
"funding_amount": 1000,
"refunded_amount": 0,
"transaction_fees": {
"fee_flat": "0.0",
"fee_rate": "2.95",
"vat_rate": "10.0"
},
"platform_fee": {
"fixed": null,
"amount": null,
"percentage": null
},
"currency": "JPY",
"funding_currency": "JPY",
"ip": null,
"refunds": {
"object": "list",
"data": [],
"limit": 20,
"offset": 0,
"total": 0,
"location": "/charges/chrg_test_5xawkivme2kkynlspkx/refunds",
"order": "chronological",
"from": "1970-01-01T00:00:00Z",
"to": "2023-10-02T12:11:48Z"
},
"link": null,
"description": null,
"metadata": {},
"card": null,
"source": {
"object": "source",
"id": "src_test_5xawkid6180h5oba6xg",
"livemode": false,
"location": "/sources/src_test_5xawkid6180h5oba6xg",
"amount": 1000,
"barcode": null,
"bank": null,
"created_at": "2023-10-02T12:11:45Z",
"currency": "JPY",
"email": null,
"flow": "app_redirect",
"installment_term": null,
"ip": null,
"absorption_type": null,
"name": null,
"mobile_number": null,
"phone_number": null,
"platform_type": null,
"scannable_code": null,
"billing": null,
"shipping": null,
"items": [
{
"sku": null,
"name": "water bottle",
"brand": null,
"category": null,
"amount": 500,
"quantity": 2,
"item_uri": null,
"image_uri": null
}
],
"references": null,
"provider_references": null,
"store_id": null,
"store_name": null,
"terminal_id": null,
"type": "paypay",
"zero_interest_installments": null,
"charge_status": "pending",
"receipt_amount": null,
"discounts": []
},
"schedule": null,
"customer": null,
"dispute": null,
"transaction": null,
"failure_code": null,
"failure_message": null,
"status": "pending",
"authorize_uri": "https://pay.omise.co/payments/pay2_test_5xawkivo0trgt11nc5w/authorize",
"return_uri": "http://example.com/orders/345678/complete",
"created_at": "2023-10-02T12:11:48Z",
"paid_at": null,
"expires_at": "2023-11-01T12:11:48Z",
"expired_at": null,
"reversed_at": null,
"zero_interest_installments": false,
"branch": null,
"terminal": null,
"device": null,
"authorized": false,
"capturable": false,
"capture": true,
"disputable": false,
"livemode": false,
"refundable": false,
"partially_refundable": false,
"reversed": false,
"reversible": false,
"voided": false,
"paid": false,
"expired": false
}
ソースと課金を同時に作成する場合
シングルAPIリクエストでソースを作成し課金する場合は、以下の方法で行います。
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=1000" \
-d "currency=JPY" \
-d "return_uri=http://example.com/orders/345678/complete" \
-d "source[type]=paypay"
課金の完了
ここまでの手順で、新しい課金が作成されstatus
がpending
に設定されました。課金status
のその他の可能な値は successful
(成功)、failed
(失敗)、およびexpired
(期限切れ)です。
次のセクションでは、課金を承認する方法、webhook
イベントを受け取る方法、およびステータスを更新する方法について詳しく説明します。
課金の承認
お客様が課金を承認するため、authorize_uri
で指定された場所にリダイレクトします。
テストモードでこの承認フェーズをシミュレートするには、authorize_uri
にアクセスして、手動で課金をSuccessful
またはFailed
としてマークします。お客様が承認フェーズを完了すると、return_uri
で指定した場所にリダイレクトされます。
課金完了イベントの受信
課金の完了を通知するために最適な方法は、webhookイベントを利用することです。サーバー上の場所を設定して、webhookイベントを受信し、この場所をwebhookエンドポイントとしてダッシュボード上に追加します。
課金が完了すると、課金レスポンスが埋め込まれたPOSTリクエストがこのエンドポイントに送信されます。
イベントオブジェクトのkey
属性にはcharge.complete
が含まれ、data
属性には課金オブジェクトが含まれます。イベントオブジェクトの構造については、イベントAPIをご覧ください。
課金ステータスの確認
このイベントを受信した後、id
を使用して課金を取得し、このstatus
がイベントに含まれる課金のstatus
と一致することを確認してください。
status
の値が successful
に更新されると決済を受領したことになります。status
の値がfailed
に更新された場合、課金オブジェクトの failure_code
とfailure_message
から詳細を確認してください。
考えられるエラーコードは以下の通りです。
エラーコード | 説明 |
---|---|
payment_expired |
決済が失効した |
payment_rejected |
加盟店側で決済を拒否した |
failed_processing |
一般的な決済処理の失敗 |
注意点
以下、PayPay決済を実装する際の注意事項となります。
課金完了を確実に確認するための実装方法
PayPayアプリでの支払い完了後、お客様がreturn_uriで指定した加盟店の確認画面にリダイレクトされた場合、webhookイベントで課金完了を確認することができます。
一方、お客様がリダイレクト前にPayPayアプリを閉じてしまった等でリダイレクトされなかった場合は、webhookイベントで課金完了を確認することが出来ません。
課金情報の取得APIをコールし、対象となる課金について一定の頻度で支払いステータスを確認することで、上記のようなケースについても課金完了を確認することができます。
課金のステータスは、こちらのページのAttributesに記載がありますので、ご確認ください。
確認画面にお客様情報、購入情報などを表示する場合
PayPay支払い完了後に遷移する加盟店の確認画面(return_uri)で、お客様の名前、購入金額、購入履歴等を表示する場合には、以下のような方法で、購入時のID等をパラメーターとして引き継ぐ設定を行ってください。
- ローカルストレージを用いる
- return_uriにパラメーターを埋め込む
なお、PayPayアプリから加盟店の確認画面に遷移する際、購入時とは別タブやブラウザが立ち上がるため、セッションストレージではパラメーターを引き継ぐことができません。
(セッションストレージでは、同一タブ、ブラウザ内でのみ、セッションデータが引き継がれます。セッションストレージを用いてパラメーターを引き継ぐ設定を行った場合、ウェブシミュレータでのテストでは、同一タブ/ウィンドウで画面が遷移するため、一見正常に作動するように見えますが、スマートフォンでは別タブ/ウィンドウが開き、パラメーターが引き継がれません。)
決済の有効期限
PayPay決済の有効期限は、以下のタイミングから5分間となります。
スマートフォンの場合:お客様がPayPayアプリに遷移してから
パソコンの場合:QRコードとPayPayログインフォームの画面が表示されてから
5分間経つと失効し、決済が行えなくなります。
重複決済
PayPay決済では、外部アプリに遷移するため、以下のようなイレギュラーなケースにおいては、他の決済手段と重複して決済が行われる可能性があります。
お客様が加盟店サイトで支払方法としてPayPayを選択する。
PayPayアプリが立ち上がり、支払画面が表示されるが、決済を行わない。
加盟店サイトに戻り、支払方法を変更し、他の支払方法で決済を行う。
5分以内にステップ2のPayPay支払い画面を再度表示し、支払いを行う。
万が一、お客様から重複して決済を行ったというお問い合わせがありましたら、ダッシュボードから支払い履歴をご確認頂き、重複決済が確認できた場合、返金手続きを行ってください。
テスト
テストについては、APIキーを用い、ウェブシミュレーターで行うことが可能です。
スマートフォンの実機を用いたテストについては、support@opn.oooにお問い合わせください。
返金
PayPayで行われた課金は、取引日から1年間以内であれば、一部または全額の返金が可能です。
なお、課金日の清算タイミング前(日本時間の翌日午前0時15分)までにご返金いただいた場合、該当課金は無効(VOIDED)となり、PayPayの明細では「支払い失敗」と表示されます。
決済金額の上下限
最低金額: ¥100
最高金額: ¥1,000,000
関連するAPIドキュメント
パブリックキーとシークレットキーの確認方法
パブリックキーとシークレットキーの取得・確認方法については、こちらを参照してください。