SDK Version: PayPal JS SDK v6 Framework: Next.js 16 + React 19 + TypeScript Frontend Package: @paypal/react-paypal-js v9.0.1 Backend Package: @paypal/paypal-server-sdk v2.2.0 (shared Express server) Payment Methods: PayPal, Venmo, Pay Later, BCDC (Guest) Demo: 3-page checkout flow (Product → Cart → Checkout)
This Next.js sample application demonstrates how to integrate the PayPal JS SDK using @paypal/react-paypal-js with the App Router. The clientId is fetched from the server via a Server Action.
- PayPal — Standard one-time payment via
PayPalOneTimePaymentButton - Venmo — Venmo one-time payment via
VenmoOneTimePaymentButton - Pay Later — Pay Later one-time payment via
PayLaterOneTimePaymentButton - BCDC (Guest) — Card payment via
PayPalGuestPaymentButton
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16.x | Full-stack React framework (App Router) |
| React | 19.x | UI framework |
| TypeScript | 5.8.x | Type safety |
| Tailwind CSS | 4.x | Styling |
| @paypal/react-paypal-js | 9.0.1 | React components and hooks for PayPal V6 SDK |
| @paypal/paypal-server-sdk | 2.2.0 | Server-side PayPal API calls (shared Express server) |
- Node.js — Version 20 or higher
- PayPal Developer Account — Required for sandbox credentials
- Environment Configuration — See the root README for instructions on setting up your
.envfile withPAYPAL_SANDBOX_CLIENT_IDandPAYPAL_SANDBOX_CLIENT_SECRET
This sample requires two servers running concurrently: the shared Node.js backend API and the Next.js frontend.
Terminal 1 — Start the backend server:
cd server/node
npm install
npm startTerminal 2 — Start the Next.js application:
npm install
npm run dev- Frontend: http://localhost:3000
- Backend: http://localhost:8080
All PayPal API calls are handled via Server Actions that communicate directly with the backend server.
| Route | Description |
|---|---|
/ |
Product page with quantity selector and "Add to Bag" button |
/cart |
Cart page to review item, update quantity, and proceed |
/checkout |
Checkout page with order summary and PayPal payment buttons |
nextjs/
├── src/
│ ├── actions/
│ │ └── paypal.ts # Server Actions (clientId, createOrder, captureOrder)
│ ├── app/
│ │ ├── layout.tsx # Root layout with metadata
│ │ ├── globals.css # Tailwind CSS and design tokens
│ │ ├── page.tsx # Product page with quantity selector
│ │ ├── cart/
│ │ │ └── page.tsx # Cart page with item review
│ │ └── checkout/
│ │ └── page.tsx # Checkout page with PayPal buttons
│ ├── components/
│ │ └── Nav.tsx # Shared navigation component
│ └── lib/
│ ├── config.ts # Shared configuration (API_BASE)
│ └── product.ts # Product data and cart helpers (sessionStorage)
├── public/ # Static assets
├── next.config.ts # Next.js configuration
├── package.json
├── tsconfig.json
├── postcss.config.mjs
└── README.md
PayPalProvider from @paypal/react-paypal-js handles loading the PayPal V6 SDK. The clientId is fetched from the Express server via a Server Action (src/actions/paypal.ts), then passed to the provider:
<PayPalProvider
clientId={clientId}
components={["paypal-payments", "venmo-payments", "paypal-guest-payments"]}
pageType="checkout"
>
<PaymentButtons cart={cart} onStatusChange={setStatus} />
</PayPalProvider>The components prop specifies which payment methods to load:
paypal-payments— PayPal and Pay Later buttonsvenmo-payments— Venmo buttonpaypal-guest-payments— BCDC (card) button
- User selects quantity on the product page (
/) and clicks "Add to Bag" - Cart is saved to
sessionStorageand user navigates to the cart page (/cart) - User reviews the item and clicks "Check Out" to navigate to checkout (
/checkout) PayPalProviderinitializes withclientIdfetched via Server ActionuseEligibleMethodschecks payment method eligibility- User clicks a payment button (PayPal, Venmo, Pay Later, or Card)
createOrderServer Action creates an order via the backend API- PayPal opens the checkout experience
- On approval,
onApprovecaptures the order via thecaptureOrderServer Action onCompletecallback logs the payment session state- Inline success message replaces the checkout form
All PayPal API calls are consolidated in src/actions/paypal.ts as Server Actions that call the shared Express server. See getBrowserSafeClientId, createOrder, and captureOrder.
The Node.js backend handles sensitive PayPal API interactions. This template reuses the shared Express server from the repository root.
Location: server/node/
Package: @paypal/paypal-server-sdk v2.2.0
| Endpoint | Method | Description |
|---|---|---|
/paypal-api/auth/browser-safe-client-id |
GET | Returns the PayPal sandbox client ID |
/paypal-api/checkout/orders/create-order-for-one-time-payment |
POST | Creates a PayPal order for one-time payment |
/paypal-api/checkout/orders/{orderId}/capture |
POST | Captures the approved payment |
- PayPal JS SDK V6 Documentation
- @paypal/react-paypal-js on npm
- @paypal/paypal-server-sdk on GitHub
- PayPal Developer Dashboard
- PayPal Sandbox Test Accounts
- PayPal Sandbox Card Testing
All SDK components and hooks are imported from @paypal/react-paypal-js/sdk-v6. See src/app/checkout/page.tsx for the full integration example.