Integrate card payments with JS SDK for direct merchants

PayPal Checkout plus customized card fields

SDKCurrentAdvancedLast updated: December 15th 2023, @ 12:11:35 pm


Important: This is version 2 of the JavaScript SDK integration guide for direct merchants. Version 1 is a legacy integration.

How it works

Advanced Checkout lets you offer the PayPal payment button and custom credit and debit card fields. This guide covers integrating the PayPal button, card payments, and customized credit card fields that handle input from the following payment fields:

  • Card number
  • CVV
  • Expiration date
  • Optional: Cardholder name

You can find more ways to extend your integration in our customization doc.

After you integrate advanced Checkout, you can also offer options like Pay Later, Venmo, and other payment methods with some additional configuration.

Visit the GitHub repo to download a sample integration.

Which integration to use

There are 2 versions of card payment integrations for direct merchants using the JavaScript SDK:

  • Recommended: Version 2 uses the PayPal-hosted CardFields component to accept and save cards without handling card information. PayPal handles all security and compliance issues associated with processing cards. The CardFields component is the recommended integration method and receives ongoing enhancements and improvements.
  • Version 1 is a legacy integration that uses the HostedFields component. This integration is no longer under active development and won’t receive further updates.

Other elements of the JavaScript SDK integration for direct merchants remain the same.

Get up and running in GitHub Codespaces

GitHub Codespaces are cloud-based development containers where you can code and test your PayPal integrations. Learn more

Know before you code

  • You need a developer account to get sandbox credentials:
    • PayPal uses REST API credentials, which you can get from the developer dashboard.
    • Client ID: authenticates your account with PayPal and identifies an app in your sandbox.
    • Client secret: authorizes an app in your sandbox. Keep this secret safe and don’t share it.
  • You need the following PayPal tools for this integration:
    • JavaScript SDK: Adds PayPal-supported payment methods.
    • Orders v2 REST API: Create, update, retrieve, authorize, and capture orders.
    • You can use Postman to explore and test PayPal APIs.

1. Before you begin your integration

Check your account setup for advanced card payments

This integration requires a sandbox business account with the Advanced Credit and Debit Card Payments capability. Your account should automatically have this capability.

To confirm that Advanced Credit and Debit Card Payments are enabled for you, check your sandbox business account as follows:

  1. Log into the PayPal Developer Dashboard, toggle Sandbox, and go to Apps & Credentials.
  2. In REST API apps, select the name of your app.
  3. Go to Features > Accept payments.
  4. Select the Advanced Credit and Debit Card Payments checkbox and select Save Changes.

Note: If you created a sandbox business account through sandbox.paypal.com, and the Advanced Credit and Debit Card Payments status for the account is disabled, complete the sandbox onboarding steps.

Check 3D Secure requirements

Add 3D Secure to reduce the risk of fraud and improve the payment experience by authenticating a cardholder through their card issuer.

Visit our 3D Secure page to see if 3D Secure is required in your region and learn more about implementing 3D Secure in your app.

2. Initialize JavaScript SDK

Add the JavaScript SDK to your web page and include the following:

  • Your app's client ID.
  • A div to render the PayPal buttons.
  • A div to render each of the card fields.

In the included JavaScript file, there are reference routes on the server that you’ll add in the next step.

Tip: Test your PayPal button transactions in the developer dashboard by creating sandbox accounts.

3. Add PayPal buttons and card fields

This integration includes a full-stack Node.js example. The /client/checkout.ejs, /public/app.js, and /server/server.js file samples show how to render the PayPal buttons and the card fields component:

  • Use PayPal buttons to process PayPal payments.
  • Use card fields to process card payments.

You'll need to:

  • Save the checkout.ejs file in a folder named /client.
  • Save the app.js file in a folder named /public.
  • Save the server.js file in a folder named /server.
  1. /client/checkout.ejs
  2. /public/app.js
  3. /server/server.js
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <!-- To be replaced with your own stylesheet -->
7 <link
8 rel="stylesheet"
9 type="text/css"
10 href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"
11 />
12 <!-- Express fills in the clientId variable -->
13 <script src="https://www.paypal.com/sdk/js?components=buttons,card-fields&client-id=<%= clientId %>"></script>
14 </head>
15 <body>
16 <div id="paypal-button-container" class="paypal-button-container"></div>
17 <div id="checkout-form">
18 <!-- Containers for Card Fields hosted by PayPal -->
19 <div id="card-name-field-container"></div>
20 <div id="card-number-field-container"></div>
21 <div id="card-expiry-field-container"></div>
22 <div id="card-cvv-field-container"></div>
23 <!-- To be replaced with your own Billing Address Fields -->
24 <div>
25 <label for="card-billing-address-line-1">Billing Address</label>
26 <input
27 type="text"
28 id="card-billing-address-line-1"
29 name="card-billing-address-line-1"
30 autocomplete="off"
31 placeholder="Address line 1"
32 >
33 </div>
34 <div>
35 <input
36 type="text"
37 id="card-billing-address-line-2"
38 name="card-billing-address-line-2"
39 autocomplete="off"
40 placeholder="Address line 2"
41 >
42 </div>
43 <div>
44 <input
45 type="text"
46 id="card-billing-address-admin-area-line-1""
47 name="card-billing-address-admin-area-line-1""
48 autocomplete="off"
49 placeholder="Admin area line 1"
50 >
51 </div>
52 <div>
53 <input
54 type="text"
55 id="card-billing-address-admin-area-line-2"
56 name="card-billing-address-admin-area-line-2"
57 autocomplete="off"
58 placeholder="Admin area line 2"
59 >
60 </div>
61 <div>
62 <input
63 type="text"
64 id="card-billing-address-country-code"
65 name="card-billing-address-country-code"
66 autocomplete="off"
67 placeholder="Country code"
68 >
69 </div>
70 <div>
71 <input
72 type="text"
73 id="card-billing-address-postal-code"
74 name="card-billing-address-postal-code"
75 autocomplete="off"
76 placeholder="Postal/zip code"
77 >
78 </div>
79 <br><br>
80 <button id="card-field-submit-button" type="button">
81 Pay now with Card Fields
82 </button>
83 </div>
84 <script src="./public/app.js"></script>
85 </body>
86</html>

Modify the code

This section explains how to customize the PayPal buttons and card fields for your integration.

PayPal buttons

  1. Copy a complete set of sample integration code from the GitHub repo.
  2. The CSS file in the head section is a sample for demo purposes. Instead, you should use styles that align with your brand using the CSS properties supported by this integration.
  3. Optional: Customize JavaScript configurations, such as currency and intent.
  4. Optional: Change the layout, width, height, and outer styling of the PayPal buttons, such as border, box-shadow, and background.

Card fields

  1. Copy and paste both examples of card field style objects into your existing /client/checkout.ejs and /public/app.js files.
  2. Include the required card form elements: card number, security code, and expiration date. To learn about the available card form elements, see Card fields.
  3. Add your own fields to accept billing address information.
  4. A complete set of sample integration code is available from the GitHub repo.
  5. Optional: Change the layout, width, height and outer styling of the card fields, such as border, box-shadow, and background. You can modify the elements you supply as containers.

4. Call Orders API for PayPal buttons and card fields

Create API endpoints on your server that communicate with the Orders v2 API to create an order and capture payment for an order.

Important: If you process payments that require Strong Customer Authentication, you need to provide additional context with payment indicators.

Server-side example (Node.js)

The paypal-api.js and /server/server.js code samples show how to integrate back-end code for advanced payments. The code adds routes to an Express server to create orders and capture payments using the Orders v2 API.

You'll need to:

  • Save the paypal-api.js file in your app's main folder.
  • Save the server.js file in a folder named /server.
  1. /server/server.js
  2. paypal-api.js
1import * as paypal from "./paypal-api.js";
2
3// create order
4app.post("/api/orders", async (req, res) => {
5 const order = await paypal.createOrder(req.body.paymentSource);
6 res.json(order);
7});

5. Capture order

Set up your server-side code to capture the order when a payer uses a credit or debit card. The paypal-api.js and /server/server.js files show how using server-side code prevents exposing your access token on the client side.

You'll need to:

  • Save the server.js file in a folder named /server.
  • Save the paypal-api.js file in your app's main folder.
  1. /server/server.js
  2. paypal-api.js
1// capture payment
2app.post("/api/orders/:orderID/capture", async (req, res) => {
3 const { orderID } = req.params;
4 const captureData = await paypal.capturePayment(orderID);
5 res.json(captureData);
6});

6. Handle payment responses

PayPal returns a status code and payment status for all authorize and capture calls.

Use the following API responses to handle errors and declined payments in your system:

Sample capture response

1{
2 "id": "8UV51279W51319843",
3 "status": "COMPLETED",
4 "payment_source": {
5 "card": {
6 "name": "Firstname Lastname",
7 "last_digits": "1234",
8 "expiry": "2026-11",
9 "brand": "VISA",
10 "available_networks": ["VISA"],
11 "type": "UNKNOWN",
12 "bin_details": {}
13 }
14 },
15 "purchase_units": [{
16 "reference_id": "default",
17 "payments": {
18 "captures": [{
19 "id": "76R688678R689884Y",
20 "status": "COMPLETED", // This is where the capture statuses appear.
21 "amount": {
22 "currency_code": "USD",
23 "value": "100.00"
24 },
25 "final_capture": true,
26 "seller_protection": {
27 "status": "NOT_ELIGIBLE"
28 },
29 "seller_receivable_breakdown": {
30 "gross_amount": {
31 "currency_code": "USD",
32 "value": "100.00"
33 },
34 "paypal_fee": {
35 "currency_code": "USD",
36 "value": "3.00"
37 },
38 "net_amount": {
39 "currency_code": "USD",
40 "value": "97.00"
41 },
42 "receivable_amount": {
43 "currency_code": "CAD",
44 "value": "124.99"
45 },
46 "exchange_rate": {
47 "source_currency": "USD",
48 "target_currency": "CAD",
49 "value": "1.28856"
50 }
51 },
52 "links": [{
53 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/76R688678R689884Y",
54 "rel": "self",
55 "method": "GET"
56 }, {
57 "href": "https://api-m.sandbox.paypal.com/v2/payments/captures/76R688678R689884Y/refund",
58 "rel": "refund",
59 "method": "POST"
60 }, {
61 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/8UV51279W51319843",
62 "rel": "up",
63 "method": "GET"
64 }],
65 "create_time": "2023-10-27T17:37:56Z",
66 "update_time": "2023-10-27T17:37:56Z",
67 "network_transaction_reference": {
68 "id": "746206625503785",
69 "network": "VISA"
70 },
71 "processor_response": {
72 // Check this section for processor response specifics.
73 "avs_code": "Y",
74 "cvv_code": "S",
75 "response_code": "0000"
76 }
77 }]
78 }
79 }],
80 "links": [{
81 "href": "https://api-m.sandbox.paypal.com/v2/checkout/orders/8UV51279W51319843",
82 "rel": "self",
83 "method": "GET"
84 }]
85}

Check processor response

In response to an an authorize or capture request, payment processor codes are returned in the processor_response of the payment object.

For a complete list of responses, refer to the Orders v2 processor response definitions.

1"processor_response": {
2 "avs_code": "Y",
3 "cvv_code": "S",
4 "payment_advice_code": "",
5 "response_code": "0000"
6}

7. Test integration

Before going live, test your integration in the sandbox environment.

Learn more about the following resources on the Card Testing page:

Note: Refer to the Card testing guide to test credit cards for sandbox testing.

8. Go live

If you have fulfilled the requirements for accepting Advanced Credit and Debit Card Payments for your business account, review the Move your app to production page to learn how to test and go live.

If this is your first time testing in a live environment, follow these steps:

  1. Log into the PayPal Developer Dashboard with your PayPal business account.
  2. Complete production onboarding so you can process card payments with your live PayPal business account.
  3. Request Advanced Credit and Debit Card Payments for your business account.

Important: The code for the integration checks eligibility requirements, so the payment card fields only display when the production request is successful.