The Payment Request API provides a seamless mobile checkout experience on the web without the need to optimize the web page for mobile. This guide explains what WePay partners need to know to support the Payment Request API.

Chrome, like many browsers, has for some time allowed payers to store credit card and billing info, and then prefill into checkout forms. The Payment Request API allows website developers a better way to ask for stored cards, present options, and get the payer’s approval.


Summary and Limitations

Payer & Device

  • Android device running Chrome v53 or higher.

Platform Integration

  • Custom checkout (aka tokenization) only. WePay hosted checkout (iframe) is coming soon.

Transactions

  • Cards become a tokenized payment method, much like a credit card.
  • Browser-stored cards can be used for any purpose normally accepted on WePay.

Geographies

Merchants must be in the United States, Canada, or United Kingdom.

Processing Fees

  • Cards tokenized with the Payment Request API are treated like any other card not present payment. Fees will be a partner’s standard or negotiated card-not-present rate. Browser-stored cards are naturally card not present.
  • App fees must be payee or payee-from-app - amount payer pays must be known and final up front.

Platform Integration with the Payment Request API

Processing Summary - platform perspective

  1. Platform website code calls WePay JavaScript SDK to verify that Payment Request API is available.
    1. Note that this does not mean a card has been setup, only that the browser and device support is present.
  2. Platform website code shows “Express Checkout” button.
    1. Partners are free to use whatever language or button they wish.
  3. Payer chooses “Express Checkout”.
  4. Platform website code triggers WePay JavaScript, which triggers Google’s JavaScript.
  5. The Payment Request payment sheet is shown.
    1. Amount must be known at this point, though things like tax and shipping can be added based on choices on the payment sheet.
  6. Payer fills out required information.
  7. Payer chooses an available payment method.
  8. Payer presses “PAY”. The user will be asked to verify the CVC of the card.
  9. The payment sheet shows a spinning cursor while processing is in progress.
  10. If successful, WePay creates a credit card ID compatible with /checkout/create and returns it from the JavaScript to the platform website code.
  11. Platform processing from here is the same as any other tokenized credit card:
    1. Website submits token to platform server
    2. Platform server calls /checkout/create with the credit card ID
    3. Amount must match what was set on the payment sheet
  12. Partner tells WePay JavaScript that checkout is successful (or not) - will dismiss the payment sheet

The following sections provide more details on these steps.

Verifying payers are ready for the Payment Request API

This function only verifies that the payer is using a device that can use the Payment Request API:

WePay.wallet.canMakePaymentRequestAPIPayments()

  • This call returns true if the payer’s device supports the Payment Request API, false otherwise.

Initiating Payment via Payment Request API

To initiate the Payment Request API payment sheet, the platform browser code calls WePay.wallet.beginTokenization() in the WePay JavaScript SDK. To make this call, the platform must capture the amount. In addition, there are options that can be set such as contact email but the payer can also make changes on the payment sheet such as the following:

  • Shipping options
  • Shipping address which can drive tax decisions
  • Email
  • Phone number

The WePay.wallet.beginTokenization() call performs the following:

  1. Displays the payment sheet directly in the Chrome browser.
  2. If payment sheet is shown.
  3. The payment sheet will expand to include the details provided to the beginTokenization() call in the paymentRequest parameter.
  4. If the user completes the payment flow, then the credit card ID will be provided to the supplied callback.

Partner Expectations while the Payment Sheet is Showing

The payer can change shipping and payment method options as well as add/edit their email address and phone number on the payment sheet.

If the payer makes changes to shipping contact or shipping method, WePay’s JavaScript SDK will inform the platform browser code of the update. The platform browser code can then change the total amount, line items, or shipping options in response and update through the WePay JavaScript SDK. The user will then see an updated payment sheet.

These steps can happen any number of times before the payer approves payment.

The 2 update calls are the following:

  • WePay.wallet.updateAfterShippingContactSelected()
  • WePay.wallet.updateAfterShippingMethodSelected()

Payment Sheet Outcomes

When satisfied, the payer approves the payment. WePay’s JavaScript SDK hides all of the details of getting the payment information from Google and tokenizing it, and returns a standard credit card ID to the platform website code.

There are various reasons why the payment sheet can return an error:

  • The user cancels the transaction
  • Improperly configured payment request

If any of these occur, the platform website code needs to restart the payment sheet using the beginTokenization() call (there is no need to re-verify that a device is ready to use the Payment Request API).

Finalizing from Server with /checkout/create

From this point on, the platform browser and server code process a credit card ID the same as for a credit card.

  • Browser code sends the ID to the platform server, with any other details collected from the payer
  • Platform server calls WePay with /checkout/create

Note:

  • The amount must match what was finally shown on the payment sheet
  • Application fee settings, if used at all, must be payee or payee-from-app

The final step is to dismiss the payment sheet. Best practice is to do this after the payment is successfully authorized, thus waiting until /checkout/create succeeds. Dismissing the payment sheet is done by calling WePay.wallet.completePayment() from the WePay JavaScript SDK.


Payer Email Information

WePay requires a payer email address. Partners can decide how to collect it:

  • Partner’s own UX: ideal when the platform naturally already has or collects the payer’s email prior to the point where the Express Checkout button would be clicked.
  • Via the payment sheet: The payment sheet will prompt the user for the payer’s email address.

Partners can decide to use either path.

Email is supplied by partner Email is not supplied by partner
Email is collected via payment sheet Email supplied by partner will be ignored. Payer will still have to type in an email if none already saved. Payer will see email field on payment sheet - may be prefilled by device or may be blank - payer must fill in if blank.
Email is not collected via payment sheet Payer will not see email field on payment sheet - partner supplied email will be used as is Not allowed - if email is not supplied by partner, the SDK will automatically ask for email via payment sheet.

To enable partner-supplied email: provide an email address on the ‘emailAddress’ attribute of the PaymentRequest object used in the beginTokenization() call.

To collect / edit email via the payment sheet: set the requestPayerEmail attribute of the PaymentRequest object used in the beginTokenization() call to true.

See the JavaScript SDK details below for more info.


Transaction Rules

The intent is that payers approve each transaction, or a plausible series of related transactions that were understood at the time of the initial transaction.

Examples that are acceptable:

  • Individual transactions: a complete payment sheet, new credit card ID, and a corresponding /checkout/create
  • Recurring: these are considered acceptable:
    • Paying $X/month, e.g. a gym membership
    • Paying a varying amount each month for the same basic service, e.g. a phone bill
    • Paying a set amount each time for a specific good or service, but on an irregular basis (e.g. tennis lessons)

Note

For recurring-type use cases, using the credit card ID for additional calls to /checkout/create is acceptable, and works like it does with credit cards.


Testing

Stage Environment

The testing details for the stage environment are as follows:

  • The website must be using WePay’s stage environment.
  • The payment sheet will display in test mode. There is no visible difference between test and production mode, however in test mode the real card payment info is not sent to our servers (dummy data is provided instead).
  • If the tester taps the “Express Checkout” button on any website, the payment sheet will be shown.
  • The payer can go through the payment flow
  • WePay will return a credit card ID
  • Partners can send the credit card ID to their server and call /checkout/create on stage (https://stage.wepay.com/)
  • Partners can use WePay’s existing online processing magic numbers for simulated results

Production Environment

To use production, set the WePay environment to production. Please be aware that WePay does not support test scenarios once production is live, so partners will not be able to simulate errors/successes in production.


WePay JavaScript SDK Calls for Payment Request API

Test for Payment Request API Availability

This call operates synchronously, and will return with a boolean.

WePay.wallet.canMakePaymentRequestAPIPayments()

Begin a Payment Request API Transaction

This method will open the payment sheet.

WePay.wallet.beginTokenization(clientId, accountId, merchantId, paymentRequest, callback, onShippingContactSelected, onShippingMethodSelected)

  • clientId (number): the WePay client ID
  • accountId (number): the WePay account ID
  • merchantId (string): the merchant ID (for use with Android Pay only)
  • paymentRequest (PaymentRequest): A PaymentRequest object containing the info required to initialize the Payment Request API payment sheet.
  • callback (function): the callback function that accepts a PaymentResponse object.

If the platform wants to request shipping information (by supplying true on the requestShipping attribute of PaymentRequest), then the corresponding callbacks below must be provided.

  • onShippingContactSelected(shippingContact): The callback function that accepts a {PaymentContact} object as a parameter. If provided, this function should finish by calling WePay.wallet.updateAfterShippingContactSelected().
  • onShippingMethodSelected(shippingMethod): The callback function that accepts a {ShippingItem} object as a parameter. If provided, this function should finish by calling WePay.wallet.updateAfterShippingMethodSelected().

After any updates, these must call the functions below to update the payment sheet.

Updating the Payment Sheet

If your website code made use of the payment sheet update callbacks in the previous section, they must use these functions to actually update the payment sheet:

WePay.wallet.updateAfterShippingContactSelected (status, newShippingMethods, newTotal, newItems)

  • status (number): The status code of the update
  • newShippingMethods (array): An array of ShippingItem objects representing shipping costs (if any).
  • newTotal (LineItem): a LineItem object representing the new adjusted total. Amount must be greater than zero.
  • newItems (array): An array of Item objects representing all other costs or discounts

WePay.wallet.updateAfterShippingMethodSelected (status, newTotal, newItems)

  • status (number): The status code of the update details
  • newTotal (LineItem): a LineItem object representing the new adjusted total. Amount must be greater than zero.
  • newItems(array): An array of Item objects representing all other costs or discounts.

Dismissing the Payment Sheet

Once a transaction is successfully processed via the platform’s (and WePay’s) server, use this to dismiss the payment sheet.

WePay.wallet.completePayment (status)

  • status (number): The status code of the transaction

Dismissing the Payment Request

Use this to abort the payment request and dismiss the payment sheet.

WePay.wallet.abort()

Supporting Objects

Amount

  • currency (String) - The three-letter ISO 4217 currency code for the payment.
  • value (String) - The decimal-notation currency amount.

LineItem < Item

  • label (String) - The label for the line item.
  • amount (Amount) - The amount for the line item

ShippingItem < Item

  • label (String) - The label for the shipping item.
  • amount (Amount) - The amount for the shipping item.
  • id (String) - A unique identifier for the shipping options.
  • selected (Boolean) - set to true to mark the ShippingItem selected.

PaymentContact

  • country (String) - The CLDR (Common Locale Data Repository) region code. ex: US, GB, CN, or JP.
  • addressLine (Array(String)> - The most specific part of address. Street name, house #, P.O. Box, etc.
  • region (String) - The top level administrative subdivision of the country. ex: State, Province, etc.
  • city (String) - The city/town portion of the address.
  • dependentLocality (String) - The dependent locality or sublocality within a city. For example, used for neighborhoods, boroughs, * districts, or UK dependent localities.
  • postalCode (String) - The postal code or ZIP code, also known as PIN code in India.
  • sortingCode (String) - The sorting code as used in, for example, France.
  • languageCode (String) - The BCP-47 language code for the address.
  • organization (String) - The organization, firm, company, or institution at this address.
  • recipient (String) - The name of the recipient or contact person.
  • careOf (String) - The name of an intermediary party or entity responsible for transferring packages.
  • phone (String) - The phone number of the recipient or contact person.

PaymentRequest

  • emailAddress (String) - The prefilled email address. Optional, but requestPayerEmail will be set to true if not provided.
  • lineItems (Array(Item)) - The items to show in the detailed total view.
  • publicKey (String) - The public key WePay has provided for you for use with Android Pay (for use with Android Pay only).
  • requestShipping (Boolean) - Set to true to request payer shipping contact information.
  • requestPayerEmail (Boolean) - Set to true to request payer’s email address.
  • requestPayerPhone (Boolean) - Set to true to request payer’s phone number.
  • shippingMethods (Array(ShippingItem)) - The shipping method options for the shipment. Do not mark any ShippingItem selected in the PaymentRequest if you provide more than one option.
  • total (LineItem) - The total amount LineItem for the payment. Required.

PaymentResponse

  • creditCardId (Number) - The ‘token’ for the payment. For use with a /checkout/create call.
  • billingContact (PaymentContact) - the billing contact information of the payer.
  • methodName (String) - The method used for payment. Can be visa, amex, discover, or mastercard
  • methodDetails (String) - The details of the method used for payment. ex: ‘VISA 1441’.
  • payerEmail (String) - The email address of the payer (if requested).
  • payerPhone (String) - The phone number of the payer. Format: (XXX) XXX-XXXX
  • shippingContact (PaymentContact - the shipping contact information of the payer (if requested).
  • shippingOptionId (String) - The id of the shipping option that was selected (if requested).
  • state (String) - The state of the card (generally, ‘new’)
  • error (String) - The name of the error. Only exists if an error occurred. The above attributes will not be present in case of an error.
  • error_description (String) - The error description. Only exists if error exists.

Status Codes

  • WePay.wallet.STATUS_SUCCESS
  • WePay.wallet.STATUS_FAILURE
  • WePay.wallet.STATUS_INVALID_SHIPPING_POSTAL_ADDRESS

Sample Code

Sample JavaScript for Payment Request API integration.


Sample Objects

Sample objects for Payment Request API integration.