PayPal Checkout

Add the Buttons

Add Smart Payment Buttons to your website. This integration guide helps you:

  • Render a click-able set of PayPal Smart Payment Buttons
  • Set up a transaction and immediately capture the funds into your account
  • Test the button and take it live on your site

Note: This integration uses the PayPal JavaScript SDK. If you're looking for the checkout.js integration, see the archived Checkout integration guide.

1. Set Up Your Development Environment

Before you can integrate Checkout, you must set up your development environment. After you get a token that lets you access protected REST API resources, you create sandbox accounts to test your web and mobile apps. For details, see Get Started.

Then, return to this page to integrate Checkout.

2. Add the PayPal script to your web page

Add the PayPal script to your web page, then add your sandbox client-id to the script tag:

<!DOCTYPE html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>

<body>
  <script
    src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID">
  </script>
</body>

Important: If you already added the PayPal script from the Try the buttons demo, swap client-id=SB_CLIENT_ID for your own client ID that you created in step one.

Make sure you:

  • Add the <!DOCTYPE html> tag for optimal browser compatibility.
  • Add the <meta http-equiv="X-UA-Compatible" content="IE=edge" /> meta tag to the page for optimal Internet Explorer compatibility.
  • Add the <meta name="viewport" content="width=device-width, initial-scale=1"> tag to the page to ensure optimal rendering on mobile devices.

You can customize your integration by passing different query parameters to https://www.paypal.com/sdk/js

Option Example value Default Description
client-id sb required Your PayPal REST client ID. This identifies your PayPal account and determines where transactions are paid to. While you're testing in sandbox, you can use client-id=sb as a shortcut.
currency USD CAD EUR USD The currency of the transaction. See Currencies for a full list of available currencies.

See Customize the SDK for a complete list of available parameters and values.

3. Render the Smart Payment Buttons

Next, render the PayPal Smart Payment Buttons to a container element on your page:

<body>
  <script
    src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID">
  </script>

  <div id="paypal-button-container"></div>

  <script>
    paypal.Buttons().render('#paypal-button-container');
  </script>
</body>

Important: If you already added the PayPal script from the Try the buttons demo, swap .render('body') for the element into which you want to render the PayPal buttons.

Button placement

To create the best checkout process for your customers and increase your conversion rates, consider where you'll place the PayPal Checkout button on your site. See Choose the optimal button location to learn more.

4. Set up the transaction

Next, implement the createOrder function, which is called when the buyer clicks the PayPal button. This step:

  • Calls PayPal using actions.order.create() to set up the details of the transaction, including the amount, line item details, and more.
  • Launches the PayPal Checkout window so the buyer can log in and approve the transaction on paypal.com.

Note: For the basic integration, you'll do this step on the client. For advanced use cases, you can also call from your server to set up a transaction.

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      // Set up the transaction
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    }
  }).render('#paypal-button-container');
</script>

For the full list of parameters you can pass to actions.order.create() to set up the transaction, and example responses, see the Orders Create API reference.

Note: To change the currency and other parameters, see Customize the SDK.

5. Capture the transaction

Next, implement the onApprove function, which is called after the buyer approves the transaction on paypal.com. This function:

  • Optionally calls PayPal using actions.order.get() to get the transaction details and display them to the buyer.
  • Calls PayPal using actions.order.capture() to capture the funds from the transaction.
  • Shows a message to the buyer to let them know the transaction is successful.

Note: For the basic integration, you'll do this step on the client. For advanced use cases, you can also call from your server to capture a transaction.

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {
      // Capture the funds from the transaction
      return actions.order.capture().then(function(details) {
        // Show a success message to your buyer
        alert('Transaction completed by ' + details.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');
</script>

For the full list of order details you receive from actions.order.capture(), see the Orders Capture API reference.

6. Verify the transaction

Next, your server verifies the transaction, saves it to your database, and dispatches the purchased item to the buyer.

1. Client side

On the client, call your server and pass the orderID that is passed from the onApprove callback:

<script>
  paypal.Buttons({
    createOrder: function(data, actions) {
      return actions.order.create({
        purchase_units: [{
          amount: {
            value: '0.01'
          }
        }]
      });
    },
    onApprove: function(data, actions) {
      return actions.order.capture().then(function(details) {
        alert('Transaction completed by ' + details.payer.name.given_name);
        // Call your server to save the transaction
        return fetch('/paypal-transaction-complete', {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            orderID: data.orderID
          })
        });
      });
    }
  }).render('#paypal-button-container');
</script>

2. Server side

Use this fully-annotated code sample to:

  1. Set up your server to make calls to PayPal
  2. Set up your server to receive a call from the client with the order ID
  3. Call PayPal to get the transaction details
  4. Handle any errors from the call
  5. Validate the transaction details are as expected
  6. Save the transaction in your database
  7. Return a successful response to the client

Note: To install the PayPal SDK on your server, see the Set up Server-Side SDK guide. If you are calling the API directly, you do not need to install the SDK.

// Note: This code is intended as a *pseudocode* example. Each server platform and programming language has a different way of handling requests, making HTTP API calls, and serving responses to the browser.

// 1. Set up your server to make calls to PayPal

// 1a. Add your client ID and secret
PAYPAL_CLIENT = 'PAYPAL_SANDBOX_CLIENT';
PAYPAL_SECRET = 'PAYPAL_SANDBOX_SECRET';

// 1b. Point your server to the PayPal API
PAYPAL_OAUTH_API = 'https://api.sandbox.paypal.com/v1/oauth2/token/';
PAYPAL_ORDER_API = 'https://api.sandbox.paypal.com/v2/checkout/orders/';

// 1c. Get an access token from the PayPal API
basicAuth = base64encode(`${ PAYPAL_CLIENT }:${ PAYPAL_SECRET }`);
auth = http.post(PAYPAL_OAUTH_API {
  headers: {
    Accept:        `application/json`,
    Authorization: `Basic ${ basicAuth }`
  },
  data: `grant_type=client_credentials`
});

// 2. Set up your server to receive a call from the client
function handleRequest(request, response) {

  // 2a. Get the order ID from the request body
  orderID = request.body.orderID;

  // 3. Call PayPal to get the transaction details
  details = http.get(PAYPAL_ORDER_API + orderID, {
    headers: {
      Accept:        `application/json`,
      Authorization: `Bearer ${ auth.access_token }`
    }
  });

  // 4. Handle any errors from the call
  if (details.error) {
    return response.send(500);
  }

  // 5. Validate the transaction details are as expected
  if (details.purchase_units[0].amount.value !== '5.77') {
    return response.send(400);
  }

  // 6. Save the transaction in your database
  database.saveTransaction(orderID);

  // 7. Return a successful response to the client
  return response.send(200);
}
// 1. Set up your server to make calls to PayPal

// 1a. Import the SDK package
const checkoutNodeJssdk = require('@paypal/checkout-server-sdk');

// 1b. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
/**
 *
 * PayPal HTTP client dependency
 */
const payPalClient = require('../Common/payPalClient');

// 2. Set up your server to receive a call from the client
module.exports = async function handleRequest(req, res) {

  // 2a. Get the order ID from the request body
  const orderID = req.body.orderID;

  // 3. Call PayPal to get the transaction details
  let request = new checkoutNodeJssdk.orders.OrdersGetRequest(orderID);

  let order;
  try {
    order = await payPalClient.client().execute(request);
  } catch (err) {

    // 4. Handle any errors from the call
    console.error(err);
    return res.send(500);
  }

  // 5. Validate the transaction details are as expected
  if (order.result.purchase_units[0].amount.value !== '220.00') {
    return res.send(400);
  }

  // 6. Save the transaction in your database
  // await database.saveTransaction(orderID);

  // 7. Return a successful response to the client
  return res.send(200);
}
<?php

namespace Sample;

require __DIR__ . '/vendor/autoload.php';
//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;

class GetOrder
{

  // 2. Set up your server to receive a call from the client
  /**
   *You can use this function to retrieve an order by passing order ID as an argument.
   */
  public static function getOrder($orderId)
  {

    // 3. Call PayPal to get the transaction details
    $client = PayPalClient::client();
    $response = $client->execute(new OrdersGetRequest($orderId));
    /**
     *Enable the following line to print complete response as JSON.
     */
    //print json_encode($response->result);
    print "Status Code: {$response->statusCode}\n";
    print "Status: {$response->result->status}\n";
    print "Order ID: {$response->result->id}\n";
    print "Intent: {$response->result->intent}\n";
    print "Links:\n";
    foreach($response->result->links as $link)
    {
      print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
    }
    // 4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    print "Gross Amount: {$response->result->purchase_units[0]->amount->currency_code} {$response->result->purchase_units[0]->amount->value}\n";

    // To print the whole response body, uncomment the following line
    // echo json_encode($response->result, JSON_PRETTY_PRINT);
  }
}

/**
 *This driver function invokes the getOrder function to retrieve
 *sample order details.
 *
 *To get the correct order ID, this sample uses createOrder to create a new order
 *and then uses the newly-created order ID with GetOrder.
 */
if (!count(debug_backtrace()))
{
  GetOrder::getOrder('REPLACE-WITH-ORDER-ID', true);
}
?>
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
from sample import PayPalClient
from paypalcheckoutsdk.orders import OrdersGetRequest

class GetOrder(PayPalClient):

  #2. Set up your server to receive a call from the client
  """You can use this function to retrieve an order by passing order ID as an argument"""   
  def get_order(self, order_id):
    """Method to get order"""
    request = OrdersGetRequest(order_id)
    #3. Call PayPal to get the transaction
    response = self.client.execute(request)
    #4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    print 'Status Code: ', response.status_code
    print 'Status: ', response.result.status
    print 'Order ID: ', response.result.id
    print 'Intent: ', response.result.intent
    print 'Links:'
    for link in response.result.links:
      print('\t{}: {}\tCall Type: {}'.format(link.rel, link.href, link.method))
    print 'Gross Amount: {} {}'.format(response.result.purchase_units[0].amount.currency_code,
                       response.result.purchase_units[0].amount.value)

"""This driver function invokes the get_order function with
   order ID to retrieve sample order details. """
if __name__ == '__main__':
  GetOrder().get_order('REPLACE-WITH-VALID-ORDER-ID')
# 1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
require_relative '../paypal_client'
require 'json'
require 'ostruct'

include PayPalCheckoutSdk::Orders

module Samples
  class GetOrder

  #2. Set up your server to receive a call from the client
  # You can use this function to retrieve an order by passing order ID as an argument
  def get_order(order_id)
    request = OrdersGetRequest::new(order_id)
    #3. Call PayPal to get the transaction
    response = PayPalClient::client::execute(request)
    #4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    puts "Status Code: " + response.status_code.to_s
    puts "Status: " + response.result.status
    puts "Order ID: " + response.result.id
    puts "Intent: " + response.result.intent
    puts "Links:"
    for link in response.result.links
    # You could also call this link.rel or link.href, but method is a reserved keyword for RUBY. Avoid calling link.method.
    puts "\t#{link["rel"]}: #{link["href"]}\tCall Type: #{link["method"]}"
    end
    puts "Gross Amount: " + response.result.purchase_units[0].amount.currency_code + response.result.purchase_units[0].amount.value
  end
  end
end

# This driver function invokes the get_order function
# with order ID to retrieve sample order details.
if __FILE__ == $0
   Samples::GetOrder::new::get_order('REPLACE-WITH-VALID-ORDER-ID')
end
package com.paypal;

import java.io.IOException;

import org.json.JSONObject;

import com.braintreepayments.http.HttpResponse;
import com.braintreepayments.http.serializer.Json;
import com.paypal.orders.Order;
import com.paypal.orders.OrdersGetRequest;

/*
*
*1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
*This step extends the SDK client.  It's not mandatory to extend the client, you can also inject it.
*/
public class GetOrder extends PayPalClient {

  //2. Set up your server to receive a call from the client
  /**
   *Method to perform sample GET on an order
   *
   *@throws IOException Exceptions from the API, if any
   */
  public void getOrder(String orderId) throws IOException {
    OrdersGetRequest request = new OrdersGetRequest(orderId);
    //3. Call PayPal to get the transaction
    HttpResponse<Order> response = client().execute(request);
    //4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
    System.out.println("Full response body:");
    System.out.println(new JSONObject(new Json().serialize(response.result())).toString(4));
  }

  /**
   *This driver method invokes the getOrder function with
   *order ID to retrieve order details.
   *
   *To get the correct order ID, this sample uses createOrder to create
   *a new order and then uses the newly-created order ID as a
   *parameter to getOrder.
   *
   *@param args
   *@throws IOException
   */
  public static void main(String[] args) throws IOException {
    new GetOrder().getOrder("REPLACE-WITH-VALID-ORDER-ID");
  }
}
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

//1. Import the PayPal SDK client that was created in `Set up Server-Side SDK`.
using BraintreeHttp;
using PayPalCheckoutSdk.Core;
using PayPalCheckoutSdk.Orders;

namespace Samples
{
  public class GetOrderSample
  {

    //2. Set up your server to receive a call from the client
    /*
      You can use this method to retrieve an order by passing the order ID.
     */
    public async static Task<HttpResponse> GetOrder(string orderId, bool debug = false)
    {
      OrdersGetRequest request = new OrdersGetRequest(orderId);
      //3. Call PayPal to get the transaction
      var response = await PayPalClient.client().Execute(request);
      //4. Save the transaction in your database. Implement logic to save transaction to your database for future reference.
      var result = response.Result<Order>();
      Console.WriteLine("Retrieved Order Status");
      Console.WriteLine("Status: {0}", result.Status);
      Console.WriteLine("Order Id: {0}", result.Id);
      Console.WriteLine("Intent: {0}", result.Intent);
      Console.WriteLine("Links:");
      foreach (LinkDescription link in result.Links)
      {
        Console.WriteLine("\t{0}: {1}\tCall Type: {2}", link.Rel, link.Href, link.Method);
      }
      AmountWithBreakdown amount = result.PurchaseUnits[0].Amount;
      Console.WriteLine("Total Amount: {0} {1}", amount.CurrencyCode, amount.Value);

      return response;
    }

    /*
      This driver method invokes the getOrder function with
      order ID to retrieve order details.

      To get the correct order ID, this sample uses createOrder to create
      a new order and then uses the newly-created order ID with GetOrder.
     */
    static void Main(string[] args)
    {
      GetOrder("REPLACE-WITH-VALID-ORDER-ID").Wait();
    }
  }
}

For the full list of keys you can retrieve from /v2/checkout/orders/, see the Orders Get API reference.

7. Test the integration

To test your buttons, complete these steps.

Run test transactions

  1. Log in to the developer dashboard and create a new sandbox test account.
  2. Click your PayPal Checkout button.
  3. Log in to PayPal using the test buyer account you created.
  4. Complete a transaction.

Verify test transactions

Verify your test transactions from both the merchant's and buyer's perspective:

  1. Log in to the sandbox using your sandbox merchant account to confirm that the funds have been received (minus any processing fees). merchant summary
  2. Log in to the sandbox using your sandbox buyer account to confirm that the funds have been sent. buyer summary

When your test is complete and you're satisfied with the results, you can launch your new button into production.

8. Go live

To launch your button into production, complete these steps:

Create a PayPal business account

Note: If you already have a PayPal business account, skip to Replace sandbox credentials with live credentials.

  1. Go to the PayPal home page and click Sign Up.
  2. Select Business Account and follow the on-screen instructions.

Replace sandbox credentials with live credentials

  1. Change the https://www.paypal.com/sdk/js script tag to use your live client ID.

      <script
        src="https://www.paypal.com/sdk/js?client-id=LIVE_CLIENT_ID">
      </script>
    
  2. Change any API calls from https://api.sandbox.paypal.com to https://api.paypal.com and use your production client ID and secret for these calls.

      // Add your client ID and secret
        var PAYPAL_CLIENT = 'PAYPAL_LIVE_CLIENT';
        var PAYPAL_SECRET = 'PAYPAL_LIVE_SECRET';
    
      // Point your server to the PayPal API
        var PAYPAL_ORDER_API = 'https://api.paypal.com/v2/checkout/orders/';
    

Test a live transaction

  1. Click your PayPal Checkout button.
  2. Log in to the PayPal window using a real buyer account. If you don’t have a real PayPal buyer account, go to the PayPal website and click Sign Up.
  3. Complete a transaction.

Verify live transactions

Verify your live transactions from both the merchant's and buyer's perspective:

  1. Log in to PayPal using your real PayPal business account to confirm that the funds have been received (minus any processing fees).
  2. Log in to PayPal using a real PayPal buyer account to confirm that the funds have been sent.

Congratulations. You have completed the basic PayPal Smart Payment Buttons integration. Your new buttons will set up and capture simple, one-time payments.

Next

When you've completed this basic integration, add these essential features to your integration:

See the full list of features you can add to your integration.

Feedback