User Account Link (1.0)

Introduction

On PayPay, to have smooth account linking process QR code based flow is added. Here merchant will create a ACCOUNT LINK QR and display it to the user. User will have to scan QR code with login to his/her PayPay account or login with credentials to authorise OPA client.

Detailed design flow described here

Download Account Link Flow

TLS implementation

The PayPay Open Payment API requires that you use TLS 1.2 or higher as a security measure. Note that you cannot connect with TLS 1.0 and TLS 1.1.

Onboard merchant

To start utilizing our Open Payment API platform, at first the business needs to be onboarded 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:

  • api key and secret
  • webhook endpoints
  • client IP whitelist

This setup can be managed using our merchant panel/ getting in touch with the sales representative.

Access from users to the PayPay app and PayPay web screen from outside Japan is restricted. Please contact us for details.

Acquire user authorization

To be able to collect payment from PayPay user’s wallet, you need to obtain user’s authorization explicitly.

For each attempt to acquirer user authorization, merchant is required to make a request to "Create Account Link QR Code" API and generate a URL of PayPay permission screen on which user gives his/her consent.

In special cases when a client chooses to enable mandate KYC setting in the authorization process, user might need to go through a few more steps on the permission screen such as KYC data match. If KYC data match fails, user will be given the options either to complete KYC at PayPay or to go back to merchant's page.

Upon successful authorization, a user authorization id will be issued to you per user. You should store this id in your backend and link it to your internal user. Please ensure this user authorization id is not stored on the client side. This id will be used as the user identifier in the Payment, Cashback and Topup requests.

Every user authorization has limited validity time. It will be automatically extended each time you make a payment, grant a balance or re-authorize. You can check the expiry date of the user authorization ID with expiry in the customer event webhook or expireAt in the response data of Get user authorization status. A PayPay user can also revoke the authorizations from PayPay's App without notifying to merchant. In both these cases the user authorization id has to be acquired again. Depending on the user environment, redirects may occur multiple times. Please check here and take appropriate action.

App Invoke flow

sequence diagram

Merchant desktop site with PayPay scan

sequence diagram

Merchant desktop site with PayPay web login

sequence diagram

Receive the user authorization result

On PayPay's authorization page the user can choose to accept/decline giving the merchant the authorization. Depending on the user action, the request to acquire user authorization could succeed or fail.

3 methods to fetch the account linking status

There are three ways to receive the result of account linking:

  • Payload appended in redirect URL
  • Payload of webhook notification
  • Polling from "Fetch Status of Account Link QR Code" API

The first two are the recommended way to implement, and the last one is optional. Since the first two options are reactive, they are much more likely to update information. In the case all the redirects and webhook failed, polling is provided as the fallback method to retrieve the status.

If all three methods failed, the situation means that the session of account linking has failed and is unrecoverable. Merchants are requested to initiate a new attempt on your side and inform the user that the account linking has failed.

1. Payload appended in redirect URL

We will encode the result into the JWT token and pass it to the redirect URL provided in the Create Account Link QR Code API (/v1/qr/sessions). The specific parameters we will pass to the redirect URL are as follows:

  • apiKey is the api key issued during the onboarding process.
  • responseToken is a JWT token signed with the Base64-decoded value of apiKeySecret corresponding to apiKey.
{
  "typ": "JWT",
  "alg": "HS256",
}
.
{
  "aud" : "<merchant organization id>",
  "iss" : "paypay.ne.jp",
  "exp" : 1638198000,
  "result": "succeeded",
  "profileIdentifier": "*******5678",
  "nonce" : "<the same nonce in the request>",
  "userAuthorizationId" : "<PayPay user reference id>",
  "referenceId": "<merchant user reference id>"
}
.
signature
claim type description
iss string PayPay is the issuer. The value is paypay.ne.jp.
aud string Merchant is the audience. The value is merchant's client ID
exp number expiration time of the responseToken, set with epoch timestamp in seconds
result string succeeded, declined
profileIdentifier string Masked phone number or email e.g. "*******5678", "abc*******@example.com"
nonce string set the nonce of API request parameter to validate the response.
userAuthorizationId string PayPay user reference id which you should store in your db and use it in the api calls. Max length: 64 characters
referenceId string the same referenceId in the request

Please note that, profileIdentifier and userAuthorizationId are not part of jwt response if user declines the account link process.

So, after the user accepted or declined the authorization request, we will redirect the webview to the following URL.

https://<redirect url>?apiKey={apiKey}&responseToken={jwtToken}

When the authentication screen expires, redirect to the following URL.

https://<redirect url>

2. Payload of webhook notification

See Webhook section.

See Fetch Status of Account Link QR Code.

OPA API Authorization

Everything related to OPA API Authorization is described here.

Error Handling

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.

Response code list

Common response codes

status code message
400 INVALID_REQUEST_PARAMS the information provided by the request contains invalid data, e.g., unsupported currency.
401 UNAUTHORIZED no valid api key and secret provided.
429 RATE_LIMIT too many requests
500 INTERNAL_SERVER_ERROR this code indicates that something went wrong during account link qr code creation, can be tried once again.
status code message
201 SUCCESS success for creation
400 EXPECTATION_FAILED when the scopes passed or callback url is invalid
Status Code Message
200 SUCCESS Success
404 SESSION_NOT_FOUND The requested resource is not found in the case given a wrong URL or the session get expired already.

Timeout

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.

User

Create Account Link QR Code

Create an ACCOUNT LINK QR and display it to the user.

Timeout: 10s

Request Body schema: application/json

Create account link QR

scopes
required
Array of strings

Scope of the user authorization.Please select only the required SCOPEs.
For SCOPE, specify the SCOPE described in "Acquire user authorization" in the API documentation of the API to be used.
If you do not know which SCOPE to specify, please contact us.

nonce
required
string <= 255 characters

Random generated string

redirectType
string
Default: "WEB_LINK"
Enum: "APP_DEEP_LINK" "WEB_LINK"

Parameter to decide whether to redirect to merchant app or merchant web application

redirectUrl
required
string <= 255 characters

The callback endpoint provided by client. For WEB_LINK it must be HTTPS, and its domain should be in the allowed authorization callback domains

referenceId
string <= 255 characters

The id used to identify the user in merchant system. It will be stored in the PayPay db for reconsilliation purpose

phoneNumber
string

The user mobile phone number. When you open the login screen with a browser, it will be set as the initial value of the phone number.

deviceId
string <= 255 characters

This parameter is obsolete.
The item is retained for backward compatibility and will be removed in a future release.

userAgent
string <= 255 characters

The User agent of the web browser. When redirectType is WEB_LINK this parameter is provided, on mobile devices PayPay tries to open the browser that the merchant website is using.

object (KYCData)

KYC data to be verified during account link

Responses

Request samples

Content type
application/json
{
  • "scopes": [
    ],
  • "nonce": "string",
  • "redirectType": "APP_DEEP_LINK",
  • "redirectUrl": "string",
  • "referenceId": "string",
  • "phoneNumber": "string",
  • "deviceId": "string",
  • "userAgent": "string",
  • "kycData": {
    }
}

Response samples

Content type
application/json
{
  • "resultInfo": {
    },
  • "data": {
    }
}

Fetch Status of Account Link QR Code

Fetch the status of a ACCOUNT LINK QR code. This endpoint is intended to be used for polling, and the interval should be 2–3 seconds. Before start polling, wait half a minute so that the user can complete the linking process.

The polling itself is an optional solution and not required to use. See the "3 methods to get the account linking status" section below for detail.

Timeout: 10s

query Parameters
linkQRCodeURL
required
string <urlencoded>
Example: linkQRCodeURL=https://www.paypay-corp.co.jp/app/opa/web/link?code=https%3A%2F%2Fqr-stg.paypay-corp.co.jp%2F2818010757vFsOLzaglGjvtE

The URL retrieved from the linkQRCodeURL created by /v1/qr/sessions. It must be URL encoded.

Responses

Response samples

Content type
application/json
{
  • "resultInfo": {
    },
  • "data": {
    }
}

Webhook Setup

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.

For security, it is highly recommended that clients whitelist PayPay IP address to receive notifications.

Please keep reading to learn for which events we currently send webhook notifications.

Customer Events

Events related to user state changes. The authroization comes as is.

attribute type is_required? description
notification_type string yes Type of the notification. Possible values: customer.authroization.succeeded, customer.authroization.failed, customer.authroization.revoked, customer.authroization.extended, customer.authroization.canceled
notification_id string yes The ID used to identify the notification
createdAt number yes The time at which the notification is created, epoch timestamp in seconds
referenceId string no The ID used to identify the user on the merchant's system
nonce string yes if notification_type is customer.authroization.succeeded, customer.authroization.failed The same nonce in the request for client side to validate the response
scopes string yes if notification_type is customer.authroization.succeeded, customer.authroization.extended Scopes of the user authorization
userAuthorizationId string yes if notification_type is customer.authroization.succeeded, customer.authroization.revoked, customer.authroization.canceled, customer.authroization.extended PayPay user reference id which you should store in your db and use it in the api calls. Max length: 64 characters
profileIdentifier string yes if notification_type is customer.authroization.succeeded Masked phone number or email e.g. "5678", "abc@example.com"
expiry number yes if notification_type is customer.authroization.extended, customer.authroization.succeeded The authorization ID's expiration epoch timestamp in seconds
result string yes if notification_type is customer.authroization.failed The result of the operation that the client is trying to do. Possible values: declined, kyc_not_completed, kyc_data_mismatch
reason string yes if notification_type is customer.authroization.failed The reason for the result of the operation

The following are examples of the possible notification types:

customer.authroization.succeeded

This notification is sent after the client successfully acquired the user's authorization.

{
  "notification_type": "customer.authroization.succeeded",
  "notification_id": "evt_aXnbdeFt2Ke",
  "createdAt": 1349654313,
  "referenceId": "yyyy",
  "nonce": "12345",
  "scopes": "direct_debit",
  "userAuthorizationId": "xxxxx",
  "profileIdentifier": "*******5678",
  "expiry": 1669734000  
}

customer.authroization.failed

This notification is sent after the client failed to acquire after going through the user authorization flow.

{
  "notification_type": "customer.authroization.failed",
  "notification_id": "evt_aXnbdeFt2Ke",
  "createdAt": 1349654313,
  "referenceId": "yyyy",
  "nonce": "12345",
  "result": "declined",
  "reason": "invalid scope"
}

The result will have declined, kyc_not_completed or kyc_data_mismatch.

  • declined if the request is rejected by user
  • kyc_not_completed if user has not completed kyc
  • kyc_data_mismatch if user kyc data is mismatched

customer.authroization.revoked

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"
}

customer.authroization.extended

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": "direct_debit",
  "userAuthorizationId": "xxxxx",
  "expiry": 1669734000  
}

customer.authroization.canceled

This notification will be sent after a user has been deleted.

sample event:

{
  "notification_type": "customer.authorization.canceled",
  "notification_id": "evt_aXnbdeFt2Ke",
  "createdAt": 1349654313,
  "userAuthorizationId": "xxxxx"
}

FAQ

Click here for the latest FAQ.

Changelog

Date of Change Date of Release Type of Change Section Updates
2022.12.21 Released Feature Receive-the-user-authorization-result Added redirect when authentication screen expires.
2023.01.19 Released Feature Create Account Link QR Code Added that the deviceId is obsolete.
2023.03.28 Released Feature Receive-the-user-authorization-result Changed the description of nonce.
Changed signature description for JWT tokens.
2023.03.28 Released Feature Create Account Link QR Code Changed the description of scopes.
2023.03.28 Released Feature Response code list Changed the message of EXPECTATION_FAILED.
2023.04.28 2023.05.25 Feature Create Account Link QR Code Changed referenceId to optional
2023.09.11 Released Feature Receive the user authorization result Changed signature description for JWT tokens.
Changed the description of exp.