PayPay

Topics covered on this page

By activating PayPay, merchants enable customers to use PayPay for payments. PayPay has more than 57 million registered users across Japan, and is a service that allows the customer to easily make payments by launching the app on their smartphone and scanning a QR code. This guide explains the payment flow and the steps for implementing PayPay.

Payment fee

3.4%

How to apply

  • Supported countries: Japan

  • Target API version: 2017-11-02 version or later

If the merchant already uses other payment methods with Opn Payments:

  1. The merchant must apply from the page here. To apply, the merchant will need the email address registered with Opn Payments.

  2. Opn will request a review from PayPay, and will contact the merchant once the review is complete.

When applying as a new user of Opn Payments:

  1. When applying for Opn Payments usage, the merchant must select PayPay as the payment method to use.

  2. Opn will request a review from PayPay, and will contact the merchant once the review is complete.

Payment flow

PayPay supports payments using smartphones and computers. Customers who choose to pay with PayPay will go through a payment flow called app_redirect.

For smartphones, customers use the PayPay app to complete payments. For computers, customers scan the QR code on the website using the PayPay app on their smartphones, or log in to the PayPay website to complete the payment.

This guide explains the specific flow when using a smartphone and when using a computer.

Please refer to the PayPay site for images of screen transitions.

For smartphones

  1. On the merchant site, the customer selects PayPay as the payment method.

  2. The PayPay app will launch. The customer confirms the payment details, and makes the payment.

  3. The PayPay app displays the payment confirmation screen. After five (5) seconds, the customer is redirected to the confirmation screen on the merchant site.

For PC using QR code scan

  1. On the merchant site, the customer selects PayPay as the payment method.

  2. The system displays a QR code. The customer scans it with the PayPay app on their smartphone.

  3. The customer checks the payment details on the PayPay app and makes the payment.

  4. The PayPay app displays the payment confirmation screen. After five (5) seconds, the customer is redirected to the confirmation screen on the merchant site.

For PC using PayPay login

  1. On the merchant site, the customer selects PayPay as the payment method.

  2. The customer is redirected to the PayPay screen, and logs in using their mobile phone number and password registered with PayPay.

  3. The customer enters the 4-digit verification code sent via SMS.

  4. The customer confirms the payment details and makes the payment.

  5. After five (5) seconds, the customer is redirected to the merchant confirmation screen.

Create a charge

To create a charge using PayPay, make an API request as follows:

  1. Omise.js, Mobile SDK (iOS, Android), use one of the API calls to create a new charge source (type: paypay )

  2. Create a charge using the source identifier created in step 1.

  3. After receiving the charge completion notification for the webhook event, retrieve the charge and check its status (optional but recommended).

There are two ways to implement it:

  1. Create source and charge separately

    a. First, create the PayPay source programmatically using the public key.

    b. Next, use the secret key to create a PayPay charge on the merchant's system.

  2. Create source and charge at the same time

    a. Create source and charge on the merchant's system using the secret key.

    b. Use this method when it is necessary to perform both source creation and charge on the merchant's system.

When creating source and charge separately

Creating the source

The parameters required to create the source are as follows.

Parameter Type Description
amount integer (required) In Subunits
currency string (required) JPY
type string (required) paypay
phone_number string (optional) 10 digit mobile number starting with 0 (example: 0812345678)
name string (optional) Customer Name
email string (optional) Customer Email
items Item (optional)
shipping Address (optional)
billing Address (optional)

The following examples demonstrate the creation of a new PayPay source for ¥1000. Replace the omise_public_key and $OMISE_PUBLIC_KEY variables with the test public key found on your dashboard.

Using Omise.js, the type parameter is supplied as the first argument to the createSource method.

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)
});

For testing, you can create the same request using 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_5xb5275a1af4h42ufwk",
  "livemode": false,
  "location": "/sources/src_test_5xb5275a1af4h42ufwk",
  "amount": 1000,
  "barcode": null,
  "bank": null,
  "created_at": "2023-10-03T02:40:09Z",
  "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": []
}

The id attribute is the source identifier (begins with src).

Creating a charge

Create a charge specifying the parameters return_uri, source, amount, and currency.

  • return_uri specifies the location on your website to which the customer should be redirected after completing the payment authorization step.

    URL must be in HTTPS format.

  • source specifies the source identifier.

  • amount and currency must match amount and currency of the source.

Can support both manual and automatic capture.

The following example demonstrates how to create a new charge using curl. Replace $OMISE_SECRET_KEY with your test secret key found on your dashboard. Replace $SOURCE_ID with the id of the source.

The capturable field in the charge response indicates whether the charge can be captured or not. The three possibilities are as follows:

  • capturable=false: charge cannot be captured.

  • capturable=true and capture=true: charge is automatically captured.

  • capturable=true and capture=false: charge is not automatically captured but can be captured manually.

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_5xb5279nqmrmkx96ulo",
  "location": "/charges/chrg_test_5xb5279nqmrmkx96ulo",
  "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_5xb5279nqmrmkx96ulo/refunds",
    "order": "chronological",
    "from": "1970-01-01T00:00:00Z",
    "to": "2023-10-03T02:40:09Z"
  },
  "link": null,
  "description": null,
  "metadata": {},
  "card": null,
  "source": {
    "object": "source",
    "id": "src_test_5xb526ur6c08tfsy96n",
    "livemode": false,
    "location": "/sources/src_test_5xb526ur6c08tfsy96n",
    "amount": 1000,
    "barcode": null,
    "bank": null,
    "created_at": "2023-10-03T02:40:07Z",
    "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_5xb5279pdpuzvsugcvd/authorize",
  "return_uri": "http://example.com/orders/345678/complete",
  "created_at": "2023-10-03T02:40:09Z",
  "paid_at": null,
  "expires_at": "2023-11-02T02:40:09Z",
  "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
}

Creating a source and charge

Alternatively, you can create and charge a source in a single API request.

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"

Completing the charge

At this point, you have created a new charge with its status set to pending. Other possible values for charge status are successful, failed, and expired.

The following sections detail how to authorize a charge, receive its completion webhook event, and update its status.

Authorizing the charge

Redirect the customer to the location specified in authorize_uri so that they can authorize the charge.

The merchant can simulate this authorization phase in test mode by visiting authorize_uri to manually mark the charge as Successful or Failed.

After the customer has completed the authorization phase, they will be redirected to the location specified in return_uri.

Receiving the charge completion event

The best way to be notified about the completion of a charge is using webhook events.

Set up a location on the merchant server to receive webhook events, and add this location as a webhook endpoint on the dashboard.

Checking the charge status

After receiving this event, retrieve the charge using its id and confirm that its status matches the status of the charge contained in the event.

If the value of status is successful, the merchant got paid.

If the value of status is failed, check the failure_code and failure_message in the charge object for an explanation.

Possible failure codes are as follows.

Failure Code Description
payment_expired Payment expired.
payment_rejected Payment rejected by issuer.
failed_processing General payment processing failure.

Important points

Note the following points when implementing the PayPay payment method.

How to implement to ensure payment completion

After completing the payment with the PayPay app, if the customer is redirected to the confirmation screen of the merchant specified in return_uri, the merchant can confirm the completion of the payment with a webhook event.

However, if the customer is not redirected because they closed the PayPay app before being redirected, it will not be possible to confirm the completion of the charge using the webhook event.

By calling the charge retrieval API and checking the payment status of the applicable charges at a certain frequency, the merchant can confirm that the charge is successful.

Please check the charge status, which is listed on the Attributes page.

When displaying customer information, purchase information, etc. on the confirmation screen

To display the customer's name, purchase amount, purchase history, etc. on the merchant confirmation screen (return_uri) that displays after PayPay payment is completed, use the following method to set the ID at the time of purchase, to be passed on as a parameter.

  1. Use local storage
  2. Embed parameters in return_uri

Note that when transitioning from the PayPay app to the merchant's confirmation screen, a separate tab or browser will open from the one used at the time of purchase, so parameters cannot be carried over using session storage.

With session storage, session data is inherited only within the same tab or browser. If the merchant configures parameters to be inherited using session storage, when testing with a web simulator, the screen transitions in the same tab/window. Therefore, although it appears to work normally, a separate tab/window opens on the smartphone and the parameters are not inherited.

Payment expiration period

PayPay payment links expire five(5) minutes from the following timing.

  1. For smartphones: After the customer transitions to the PayPay app

  2. For PC: After the QR code and PayPay login form screen are displayed

Payment links expire after five(5) minutes and the customer will no longer be able to make a payment.

Duplicate payment

PayPay payments transfer to an external application, so in rare cases such as the following, payments may be made in duplicate with other payment methods.

  1. The customer selects PayPay as the payment method on the merchant site.

  2. The PayPay app launches and the payment screen is displayed, but the customer does not make the payment.

  3. The customer returns to the merchant site, changes the payment method, and makes the payment using another payment method.

  4. Within 5 minutes, the customer redisplays the PayPay payment screen mentioned in step 2 and makes the payment.

In the unlikely event that a customer inquires about a duplicate payment, please check the payment history from the dashboard, and on confirming the duplicate payment, please complete the refund procedure.

Test

To test, use a web simulator with an API key.

To test using an actual smartphone, please contact support@opn.ooo.

Voids and refunds

Charges made with PayPay can be partially or fully refunded within one year from the date of transaction.

In addition, if the merchant receives a refund before the settlement timing on the billing date (12:15 a.m. the next day Japan time), the charge will be invalidated (VOIDED) and Payment Failed will be displayed on their PayPay statement.

Minimum and maximum limits of payment amount

  • Minimum amount: ¥100

  • Maximum amount: ¥1,000,000

How to check the public key and secret key

For information on how to obtain and check the public and secret keys, please refer to this document.

Omise uses cookies to improve your overall site experience and collect information on your visits and browsing behavior. By continuing to browse our website, you agree to our Privacy Policy. Learn more