Integration Guide

This guide shows how to implement PayPal Checkout server-side using Node.js, Python, PHP, Java, .NET, or Ruby.

You'll learn how to:

  • Set up environment credentials

  • Authenticate your server with PayPal

  • Create and capture orders securely from your backend

Overview

PayPal Checkout uses a two-part integration:

  1. Client-side — Renders Smart Payment Buttons

  2. Server-side — Handles secure API calls (create and capture orders)

This guide focuses on the server-side logic using the Orders v2 API.

Prerequisites

Implement PayPal Checkout

1

Environment Setup

Log in to use your own API keys in these code examples.

Set these values as environment variables or securely in a config file:

PAYPAL_CLIENT_ID=your-sandbox-client-id
PAYPAL_CLIENT_SECRET=your-sandbox-client-secret
PAYPAL_API=https://api-m.sandbox.paypal.com
2

Authentication

Get an access token from PayPal

curl -X POST https://api-m.sandbox.paypal.com/v1/oauth2/token \
  -H "Accept: application/json" \
  -H "Accept-Language: en_US" \
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  -d "grant_type=client_credentials"
3

Create Order

Create a new PayPal order

curl -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  -d '{
    "intent": "CAPTURE",
    "purchase_units": [{
      "amount": {
        "currency_code": "USD",
        "value": "10.00"
      }
    }]
  }'
4

Capture Order

Capture payment for an approved order

curl -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID/capture \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ACCESS_TOKEN"
Complete Implementation Example (Node.js/Express)
const express = require('express');
const axios = require('axios');
require('dotenv').config();

const app = express();
app.use(express.json());

async function generateAccessToken() {
  const auth = Buffer.from(`${process.env.PAYPAL_CLIENT_ID}:${process.env.PAYPAL_CLIENT_SECRET}`).toString("base64");
  const response = await axios.post(
    `${process.env.PAYPAL_API}/v1/oauth2/token`,
    "grant_type=client_credentials",
    {
      headers: {
        Authorization: `Basic ${auth}`,
        "Content-Type": "application/x-www-form-urlencoded",
      },
    }
  );
  return response.data.access_token;
}

app.post("/api/orders", async (req, res) => {
  const accessToken = await generateAccessToken();
  const response = await axios.post(
    `${process.env.PAYPAL_API}/v2/checkout/orders`,
    {
      intent: "CAPTURE",
      purchase_units: [{ amount: { currency_code: "USD", value: "10.00" } }]
    },
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      }
    }
  );
  res.json({ id: response.data.id });
});

app.post("/api/orders/:orderID/capture", async (req, res) => {
  const accessToken = await generateAccessToken();
  const { orderID } = req.params;
  const response = await axios.post(
    `${process.env.PAYPAL_API}/v2/checkout/orders/${orderID}/capture`,
    {},
    {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "Content-Type": "application/json",
      }
    }
  );
  res.json(response.data);
});

app.listen(3000, () => console.log('Server running on port 3000'));

Next Steps

  • Validate payment status after capture

  • Store payment details in your database

  • Add webhook listeners to handle asynchronous events

  • Implement error handling and logging

  • Add order validation and security checks

Last updated

Was this helpful?