PayPay Open Payment API (OPA) is designed to be used by our payment partners to make payment-related operations in different scenarios, so as to deliver the best payment experience to end users. After being onboarded as a PayPay OPA client, depending on the contract, you will have the capability on one or more of the below:
This document will be focusing on APIs that support the last solution to grant cashback to users.
The PayPay Open Payment API requires that you use TLS 1.2 or higher as a security measure. Note that you cannot connect with TLS1.0 and TLS1.1.
To start utilizing our Open Payment API platform, at first the business needs to be onboarded onboard as a PayPay merchant. This process usually consists of information collection, manual verification, contract confirmation and credentials issuance.
After becoming a merchant on PayPay, the following items would be setup for the client:
This setup can be managed using our merchant panel/ getting in touch with the sales representative.
Everything related to OPA API Authorization is described here.
Every time an API is called, the merchant identifier needs to be passed along with the request. There are two ways to pass the merchant identifier:
In a query string parameter:
?assumeMerchant={MerchantId}
Or in HTTP headers:
X-ASSUME-MERCHANT: {MerchantId}
If both are provided, the query string parameter would take precedence.
PayPay OPA uses HTTP response status codes and OPA error code to indicate the success or failure of the requests. With these information, you can decide what error handling strategy to use. In general, PayPay OPA return the following http status codes.
Status | Code | Message |
---|---|---|
200 | SUCCESS | Success |
202 | REQUEST_ACCEPTED | Request accepted |
400 | INVALID_REQUEST_PARAMS | The information provided by the request contains invalid data, e.g., unsupported currency. |
401 | OP_OUT_OF_SCOPE | The operation is not permitted |
400 | MISSING_REQUEST_PARAMS | The set parameter is invalid. |
401 | UNAUTHORIZED | No valid api key and secret provided. |
404 | OPA_CLIENT_NOT_FOUND | OPA Client not found |
429 | RATE_LIMIT | Too many requests |
500 | SERVICE_ERROR | A service error has occurred. |
500 | INTERNAL_SERVER_ERROR | This code indicates that something went wrong, but we don't know exactly if the transaction has happened or not. It should be treated as unknown payment status. |
503 | MAINTENANCE_MODE | Sorry, we are down for scheduled maintenance. |
Status | Code | Message |
---|---|---|
400 | VALIDATION_FAILED_EXCEPTION | Error occurs while handling request params. For example, this error code will be thrown if merchantCashbackId same as the one in requests which failed granting cashback in the past is set. |
400 | FAILURE | Duplicate transaction error |
401 | INVALID_USER_AUTHORIZATION_ID | The specified user authorization ID is invalid |
401 | EXPIRED_USER_AUTHORIZATION_ID | The user authorization ID expired |
404 | RESOURCE_NOT_FOUND | Campaign id not found |
500 | UNAUTHORIZED_ACCESS | Unauthorized access to resource server |
Status | Code | Message |
---|---|---|
200 | NOT_ENOUGH_MONEY* | Not enough balance in the campaign budget to complete the cashback transaction |
200 | BALANCE_OUT_OF_LIMIT* | The receiver(PayPay user)'s balance exceeds limit. |
200 | INTERNAL_SERVICE_ERROR* | Internal service error while processing the cashback transaction |
404 | TRANSACTION_NOT_FOUND | Transaction not found |
500 | UNAUTHORIZED_ACCESS | Unauthorized access to resource server |
*Note : Give cashback API is async process, merchant can call Check Cashback Details API to know the status of the cashback transaction. For some error scenarios listed above will return reason for the failure as error code in the response with HTTP status 200. Check here for details.
Status | Code | Message |
---|---|---|
400 | VALIDATION_FAILED_EXCEPTION | Error handling request params or trying to cancel PayPay Money Lite which is not cancelable. |
404 | TRANSACTION_NOT_FOUND | Transaction not found |
500 | UNAUTHORIZED_ACCESS | Unauthorized access to resource server |
Status | Code | Message |
---|---|---|
404 | TRANSACTION_NOT_FOUND | Transaction not found |
500 | UNAUTHORIZED_ACCESS | Unauthorized access to resource server |
Status | Code | Description |
---|---|---|
200 | SUCCESS | Cashback is granted successfully |
200 | NOT_ENOUGH_MONEY | Not enough balance in the campaign budget to complete the cashback transaction |
200 | BALANCE_OUT_OF_LIMIT | The receiver(PayPay user)'s balance exceeds limit |
200 | INTERNAL_SERVICE_ERROR | Internal service error while processing the cashback transaction |
Status | Code | Message |
---|---|---|
400 | CANCELED_USER | The user has canceled PayPay account. |
401 | INVALID_USER_AUTHORIZATION_ID | The specified user authorization ID is invalid. |
Status | Code | Message |
---|---|---|
401 | INVALID_USER_AUTHORIZATION_ID | The specified user authorization ID is invalid. |
Status | Code | Description |
---|---|---|
401 | INVALID_USER_AUTHORIZATION_ID | The specified user authorization ID is invalid. |
The recommended timeout setting is specified in each API. The most important one is for the payment creation api, where the read timeout should not be less than 30 seconds. When timeout happens, it should be treated as unknown payment status.
There are two ways to react with this situation
Use the query api to query the transaction status. If the original transaction was failed or not found in PayPay, you can start a new transaction for the same purpose.
Or, you can cancel the transaction, if the cancel api is provided. After the cancellation is accepted, you can start a new transaction for the same purpose.
Please check here for additional FAQs for OPA
PayPay merchant can know user's cashback balance using Get user wallet balance api by passing productType
as POINT
(please reach out to your Sales Representative and Integration Manager to add this configuration at PayPay’s end) in the request.
PayPay merchant can use user's cashback balance for making a payment using Create a payment api by passing productType
as POINT
(please reach out to your Sales Representative and Integration Manager to add this configuration at PayPay’s end) in the request.
Everything related to user wallet balance, Give Cashback to user and Check Cashback Details process is shown here
Please note that, Reverse Cashback and Check Cashback Reversal Details process same as above.
Gives the balance to the user. This API only accepts cashback and grants them by asynchronous processing on the PayPay side.
Please see Check Cashback Details for the results of the cashback.
Timeout: 30s
CreateCashback
merchantCashbackId required | string <= 64 characters The unique cashback transaction id provided by merchant. |
userAuthorizationId required | string (UserAuthorizationId) <= 64 characters The PayPay user reference id returned by the user authorization flow |
required | object (MoneyAmount) |
requestedAt required | integer (EpochTimeWithValidation) Epoch timestamp in seconds |
orderDescription | string <= 255 characters Description of the order |
walletType | string Enum: "CASHBACK" "PREPAID" Specify the balance type to be given to the user. |
metadata | object This parameter is obsolete. |
{- "merchantCashbackId": "string",
- "userAuthorizationId": "string",
- "amount": {
- "amount": 0,
- "currency": "JPY"
}, - "requestedAt": 1704112496,
- "orderDescription": "string",
- "walletType": "CASHBACK",
- "metadata": { }
}
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": { }
}
Check the cashback details of the cashback given
Timeout: 10s
merchantCashbackId required | string (MerchantCashbackId) <= 64 characters The unique cashback transaction id provided by merchant. |
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": {
- "cashbackId": "string",
- "status": "ACCEPTED",
- "acceptedAt": 1704112496,
- "merchantAlias": "string",
- "merchantCashbackId": "string",
- "userAuthorizationId": "string",
- "amount": {
- "amount": 0,
- "currency": "JPY"
}, - "requestedAt": 1704112496,
- "orderDescription": "string",
- "walletType": "CASHBACK",
- "metadata": { }
}
}
Transfer money back from user wallet to merchants campaign wallet.
This API only accepts cashback cancellations, and cancels them through asynchronous processing on the PayPay side.
Only PayPay Point(walletType="CASHBACK") cancellations are allowed, and grantings on PayPay Money Lite(walletType="PREPAID") are not cancelable.
Please see to the Check Cashback Reversal Details for the results of canceling the cashback.
Timeout: 40s
CreateCashbackReversal
merchantCashbackReversalId required | string (MerchantCashbackReversalId) <= 64 characters The unique cashback reversal transaction id provided by merchant. |
merchantCashbackId required | string (MerchantCashbackId) <= 64 characters The unique cashback transaction id provided by merchant. |
required | object (MoneyAmount) |
requestedAt required | integer (EpochTimeWithValidation) Epoch timestamp in seconds |
reason | string <= 255 characters Reason for reversing the cashback |
metadata | object This parameter is obsolete. |
{- "merchantCashbackReversalId": "string",
- "merchantCashbackId": "string",
- "amount": {
- "amount": 0,
- "currency": "JPY"
}, - "requestedAt": 1704112496,
- "reason": "string",
- "metadata": { }
}
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": { }
}
Check the cashback reversal details of the cashback reversed
Timeout: 10s
merchantCashbackReversalId required | string (MerchantCashbackReversalIdSimple) <= 64 characters The unique cashback reversal transaction id provided by merchant. |
merchantCashbackId required | string (MerchantCashbackId) <= 64 characters The unique cashback transaction id provided by merchant. |
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": {
- "cashbackReversalId": "string",
- "status": "ACCEPTED",
- "acceptedAt": 1704112496,
- "merchantAlias": "string",
- "merchantCashbackReversalId": "string",
- "merchantCashbackId": "string",
- "amount": {
- "amount": 0,
- "currency": "JPY"
}, - "requestedAt": 1704112496,
- "reason": "string",
- "metadata": { }
}
}
Get the authorization status of a user
Timeout: 15s
userAuthorizationId required | string (UserAuthorizationId) <= 64 characters The PayPay user reference id returned by the user authorization flow |
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": {
- "userAuthorizationId": "string",
- "referenceIds": [
- "string"
], - "status": "ACTIVE",
- "scopes": [
- "direct_debit"
], - "expireAt": 0,
- "issuedAt": 0
}
}
Get the masked phone number of the user
userAuthorizationId required | string (UserAuthorizationId) <= 64 characters The PayPay user reference id returned by the user authorization flow |
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": {
- "phoneNumber": "*******1234"
}
}
Unlink a user from the client
Timeout: 15s
userAuthorizationId required | string (UserAuthorizationId) <= 64 characters The PayPay user reference id returned by the user authorization flow |
{- "resultInfo": {
- "code": "string",
- "message": "string",
- "codeId": "string"
}, - "data": { }
}
PayPay can send webhook events that notify your application at the time
when event happens on your account. To receive the notification,
the client needs to set up a webhook url where we will use HTTP POST to
send data to the client. Each notification event will have one
notification_type
field which can be used by clients to determine
which event has happened.
When your application receives the notification via webhook, it should respond with a HTTP 200 OK
status code.
Although not required, a response body with a short text description (like "OK") is recommended.
PayPay will try to resend the notification if no response back or response back with high delay, which means the notification can possibly have more than one times.
Three endpoints for webhook, as shown in the following table.
No. | name | purpose |
---|---|---|
1 | accountLinkCallbackUrl | Receives account linking and revoking event notifications |
2 | giveCashbackCallbackUrl | Receives give cashback notifications |
3 | reverseCashbackCallbackUrl | Receives reverse cashback notifications |
Please keep reading to learn for which events we currently send webhook notifications.
This notification is sent after the client successfuly acuqired the user's authorization.
{
"notification_type": "customer.authroization.succeeded",
"notification_id": "evt_aXnbdeFt2Ke",
"createdAt": "1349654313",
"referenceId": "yyyy",
"nonce": "12345",
"scopes": "cashback",
"userAuthorizationId": "xxxxx",
"profileIdentifier": "*******5678",
"expiry": 1234567 // the authorization id expiration epoch timestamp in seconds
}
This notification is sent after the client failed to acuqire after going through the user authorization flow.
{
"notification_type": "customer.authroization.failed",
"notification_id": "evt_aXnbdeFt2Ke",
"createdAt": "1349654313",
"referenceId": "yyyy",
"nonce": "12345",
"result": "declined", // or bad_request
"reason": "invalid scope"
}
The result
in the payload could be either declined
if the the request
is rejected by user, or bad_request
if there are invalid info in the
request.
This notification is sent after a user revoked the ever granted authorization from the PayPay app.
{
"notification_type": "customer.authroization.revoked",
"notification_id": "evt_aXnbdeFt2Ke",
"createdAt": "1349654313",
"userAuthorizationId": "xxxxx",
"referenceId": "yyyy"
}
In order to ease third party account linking experience, we will increase user authorization expiry from the date of last transaction/ grant. So merchants and users will have to give authorization less often.
This notification is sent after user's authorization is extended from PayPay side.
{
"notification_type": "customer.authroization.extended",
"notification_id": "evt_aXnbdeFt2Ke",
"createdAt": "1349654313",
"scopes": "cashback",
"userAuthorizationId": "xxxxx",
"expiry": 1234567 // the authorization id expiration epoch timestamp in seconds
}
This notification will be sent after a user has been deleted.
sample event:
{
"notification_type": "customer.authroization.canceled",
"notification_id": "evt_aXnbdeFt2Ke",
"createdAt": "1349654313",
"userAuthorizationId": "xxxxx"
}
This notification is sent to notify the cashback result to a merchant.
The request body is same as the response body of the Check Cashback Details
API.
{
"resultInfo": {
"code": "SUCCESS",
"codeId": "08100001",
"message": "SUCCESS"
},
"data": {
"cashbackId": "12345-test10",
"status": "SUCCESS",
"acceptedAt": 1566278399,
"merchantAlias": "testMerchant",
"merchantCashbackId": "test10",
"userAuthorizationId": "de9f3b76-3820-4136-a54c-8068c9b7d03d",
"amount": {
"amount": 10,
"currency": "JPY"
},
"requestedAt": 1566278399,
"orderDescription": "Description of the order",
"walletType": "CASHBACK",
"metadata": {}
}
}
If cashback fails, the following WEBHOOK will be sent. Error codes are mentioned in Cashback Event under Error Handling section.
{
"resultInfo": {
"code": "NOT_ENOUGH_MONEY",
"message": "Not enough balance in the campaign budget to complete the cashback transaction",
"codeId": "WAL_500017"
},
"data": {
"status": "FAILURE",
"acceptedAt": 1566278399,
"merchantAlias": "266952919408074752",
"amount": {
"amount": 10,
"currency": "JPY"
},
"requestedAt": 1601962499,
"cashbackId": "12345-test10",
"merchantCashbackId": "test10",
"userAuthorizationId": "de9f3b76-3820-4136-a54c-8068c9b7d03d",
"orderDescription": "Description of the order",
"walletType": "CASHBACK",
"metadata": {}
}
}
This notification is sent to notify the cashback reverse result to a merchant.
The request body is same as the response body of the Check Cashback Reversal Details
API and error codes are mentioned in Cashback Event under Error Handling section.
{
"resultInfo": {
"code": "SUCCESS",
"codeId": "08100001",
"message": "SUCCESS"
},
"data": {
"cashbackReversalId": "121904701032398848-rc_31922956-8e06-45aa-9a3a-bb6ba1e1b0d8_1_cancel",
"status": "SUCCESS",
"acceptedAt": 1566278399,
"merchantAlias": "testMerchant",
"merchantCashbackReversalId": "rc_31922956-8e06-45aa-9a3a-bb6ba1e1b0d8_1_cancel"
"merchantCashbackId": "c_31922956-8e06-45aa-9a3a-bb6ba1e1b0d8_1",
"userAuthorizationId": "null",
"amount": {
"amount": 10,
"currency": "JPY"
},
"requestedAt": 1566278399,
"reason": "reversing reason",
"metadata": {}
}
}
PayPay generates a transaction file by daily processing and notifies it by Webhook.
Category | Description | Note |
---|---|---|
File linkage method | Webhook | |
File Name | cashback_<merchant_id>_<from>_<to>.csv | |
File creation unit | merchant_id | |
Processing cycle | 4 times a day. | Transactions for the time periods of 18:00-23:59, 0:00-05:59, 06:00-11:59, 12:00-17:59 are included. |
Notification time | See the right column. | A file is created for each execution cycle and notified after completion. The standard is 2 to 4 hours after the execution cycle, but the notification time varies depending on the volume of transactions. Notification is made in units of execution cycles; a day's worth of notifications cannot be made at once. |
format | CSV | |
File acquisition period | 2hours | |
File retention period | 1 week | If the recon file cannot be obtained due to a merchant failure, etc., PayPay will be able to resend the webhook. Please contact us if you would like to be notified again. |
character code(Contents) | UTF-8 | |
character code(file name) | UTF-8 | |
newline code | CRLF |
Key | Value from | Note |
---|---|---|
merchant_cashback_id | merchantCashbackId | merchantCashbackId issued by Mercahnt. |
merchant_cashback_reversal_id | merchantCashbackReversalID | Only if cashback is reversal. |
cashback_id | cashback_id | cashback_id issued by PayPay. |
transaction_type | CASHBACK / CASHBACK_REVERSAL | |
merchant_id | MerchantID issued by PayPay. | |
amount | amount | Amount |
currency | currency | JPY |
wallet_type | wallet_type | CASHBACK / PREPAID |
status | SUCCESS/FAILURE | |
expiry_date | expiryDate | Only if expiryDate is specified. |
order_description | orderDescription | Order description. |
requested_at | requestedAt | YYYY-MM-DDTHH:MM:SS+09:00 (UTC, ISO8601) |
accepted_at | acceptedAt | YYYY-MM-DDTHH:MM:SS+09:00 (UTC, ISO8601) |
Get the file from the path
notified by the webhook.
{
"notification_type":"file.created",
"notification_id": "<UUID>",
"fileType":"cashback_recon",
"path":"https://<server_path>/<filename>?parameters",
"requestedAt":"<epoch time>"
}
Click here for the latest FAQ.
Date of Documentation Update | Date of Release | Type of Change | Section | Updates |
---|---|---|---|---|
2024.07.09 | 2024.08.01 | Documentation Fix | API name | Specified the name of the API as "PayPay Points API". |
2023.01.12 | 2023.01.13 | Description | Get Cashback Balance and Deduct Cashback Balance | Updated the description of these sections to reach PayPay team to update the configuration |
2023.01.19 | Released | Feature | Reverse a given cashback | Changed the descriptions of MerchantCashbackReversalId and MerchantCashbackId. |
2023.01.19 | Released | Feature | Check Cashback Reversal Details | Changed the description of the ACCEPTED status. |
2023.04.07 | Released | Feature | File-linkage-specifications | Changed the description of notification time. |
2023.07.04 | Released | Documentation Fix | Give Cashback to User, Check Cashback Details, Reverse a given cashback, Check Cashback Reversal Details | Updated the description of metadata. |
2023.08.16 | Released | Documentation Fix | Changed the description of VALIDATION_FAILED_EXCEPTION. | |
2023.11.10 | 2023.11.13 | Feature | Add character validation for merchantCashbackId and merchantCashbackReversalId |
|
2024.03.12 | Released | Documentation Fix | Give Cashback to User, Check Cashback Details, Reverse a given cashback, Check Cashback Reversal Details | Added that the metadata is obsolete. |
2024.09.17 | 2024.10.21 | Feature | Give Cashback to User, Reverse a given cashback | Added description about validation of requestedAt |
2024.10.08 | TBD | Description | Webhook Setup | Add description about webhook retries. |