Standard payments with JavaScript frameworks
DocsCurrentLast updated: March 16th 2023, @ 11:23:55 am
Use this guide if your website uses a library or framework such as React, Vue, or Angular.
Know before you code
Complete the steps in Get started to get the following sandbox account information from the Developer Dashboard:
- Client ID
- Access token
- Business account credentials
Use Postman to explore and test PayPal APIs.
How it works
Add payment buttons to your library or framework:
- React
- Angular
- Angular 2
- Vue
1const PayPalButton = paypal.Buttons.driver("react", { React, ReactDOM });
1. Add the JavaScript SDK
The JavaScript SDK displays payment methods on your checkout page.
Place the following script
tag in your index.html
page based on how you plan to render payment buttons, so the paypal
object is available when you need it in the checkout flow.
To render payment buttons immediately:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
To render payment buttons after user action, navigation, or page change, include the
defer
object in the JavaScript SDK script:<script defer src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID" ></script>
Add and modify the code
Note: This sample code is optimized for JavaScript performance. To learn more about optimization considerations, see JavaScript SDK performance optimization.
- Copy the sample JavaScript SDK code and paste it into your checkout page.
- In the SDK code, replace
YOUR_CLIENT_ID
with your client ID. - Pass parameters to replace default values, such as
USD
forcurrency
. To learn more about the default values, see the JavaScript SDK script configuration.
2. Add the code
Choose your JavaScript library or framework:
React
Component implementation and functional implementation.
Component implementation
1import React from "react";2import ReactDOM from "react-dom"3const PayPalButton = paypal.Buttons.driver("react", { React, ReactDOM });4class YourComponent extends React.Component {5 createOrder(data) {6 // Order is created on the server and the order id is returned7 return fetch("/my-server/create-paypal-order", {8 method: "POST",9 headers: {10 "Content-Type": "application/json",11 },12 // use the "body" param to optionally pass additional order information13 // like product skus and quantities14 body: JSON.stringify({15 cart: [16 {17 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",18 quantity: "YOUR_PRODUCT_QUANTITY",19 },20 ],21 }),22 })23 .then((response) => response.json())24 .then((order) => order.id);25 }26 onApprove(data) {27 // Order is captured on the server28 return fetch("/my-server/capture-paypal-order", {29 method: "POST",30 headers: {31 "Content-Type": "application/json",32 },33 body: JSON.stringify({34 orderID: data.orderID35 })36 })37 .then((response) => response.json());38 }39 render() {40 return (41 <PayPalButton42 createOrder={(data, actions) => this.createOrder(data)}43 onApprove={(data, actions) => this.onApprove(data)}44 />45 );46 }47}
Functional implementation
1import React from "react";2import ReactDOM from "react-dom"3const PayPalButton = paypal.Buttons.driver("react", { React, ReactDOM });4function YourComponent() {5 const createOrder = (data) => {6 // Order is created on the server and the order id is returned7 return fetch("/my-server/create-paypal-order", {8 method: "POST",9 headers: {10 "Content-Type": "application/json",11 },12 // use the "body" param to optionally pass additional order information13 // like product skus and quantities14 body: JSON.stringify({15 cart: [16 {17 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",18 quantity: "YOUR_PRODUCT_QUANTITY",19 },20 ],21 }),22 })23 .then((response) => response.json())24 .then((order) => order.id);25 };26 const onApprove = (data) => {27 // Order is captured on the server and the response is returned to the browser28 return fetch("/my-server/capture-paypal-order", {29 method: "POST",30 headers: {31 "Content-Type": "application/json",32 },33 body: JSON.stringify({34 orderID: data.orderID35 })36 })37 .then((response) => response.json());38 };39 return (40 <PayPalButton41 createOrder={(data) => createOrder(data, actions)}42 onApprove={(data) => onApprove(data, actions)}43 />44 );45}
Angular
1paypal.Buttons.driver("angular", window.angular);2angular3 .module("app", ["paypal-buttons"])4 .controller("appController", function ($scope) {5 $scope.opts = {6 createOrder: function (data) {7 // Order is created on the server and the order id is returned8 return fetch("/my-server/create-paypal-order", {9 method: "POST",10 headers: {11 "Content-Type": "application/json",12 },13 // use the "body" param to optionally pass additional order information14 // like product skus and quantities15 body: JSON.stringify({16 cart: [17 {18 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",19 quantity: "YOUR_PRODUCT_QUANTITY",20 },21 ],22 }),23 })24 .then((response) => response.json())25 .then((order) => order.id);26 },27 onApprove: function (data) {28 // Order is captured on the server29 return fetch("/my-server/capture-paypal-order", {30 method: "POST",31 headers: {32 "Content-Type": "application/json",33 },34 body: JSON.stringify({35 orderID: data.orderID36 })37 })38 .then((response) => response.json());39 },40 };41 });
1<body ng-app="app" ng-controller="appController">2 <paypal-buttons props="opts"></paypal-buttons>3</body>
Angular 2
1(function () {2 const PayPalButton = paypal.Buttons.driver("angular2", ng.core);3 const appComponent = ng.core4 .Component({5 selector: "my-app",6 template:7 <div id="app">8 <paypal-buttons [props]="{9 createOrder: createOrder,10 onApprove: onApprove11 }"></paypal-buttons>12 </div>13 ,14 })15 .Class({16 constructor: function () {17 this.createOrder = (function(data) {18 // Order is created on the server and the order id is returned19 return fetch("/my-server/create-paypal-order", {20 method: "POST",21 headers: {22 "Content-Type": "application/json",23 },24 // use the "body" param to optionally pass additional order information25 // like product skus and quantities26 body: JSON.stringify({27 cart: [28 {29 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",30 quantity: "YOUR_PRODUCT_QUANTITY",31 },32 ],33 }),34 })35 .then((response) => response.json())36 .then((order) => order.id);37 }).bind(this);38 this.onApprove = (function(data, actions) {39 // Order is captured on the server40 return fetch("/my-server/capture-paypal-order", {41 method: "POST",42 headers: {43 "Content-Type": "application/json",44 },45 body: JSON.stringify({46 orderID: data.orderID47 })48 })49 .then((response) => response.json())50 }).bind(this);51 });52 }});53 const appModule = ng.core54 .NgModule({55 imports: [ng.platformBrowser.BrowserModule, PayPalButton],56 declarations: [appComponent],57 bootstrap: [appComponent],58 })59 .Class({60 constructor: function () {},61 });62 document.addEventListener("DOMContentLoaded", function () {63 ng.platformBrowserDynamic64 .platformBrowserDynamic()65 .bootstrapModule(appModule);66 });67})();
1(function () {2 const PayPalButton = paypal.Buttons.driver("angular2", ng.core);3 const appComponent = ng.core4 .Component({5 selector: "my-app",6 template:7 <div id="app">8 <paypal-buttons [props]="{9 createOrder: createOrder,10 onApprove: onApprove11 }"></paypal-buttons>12 </div>13 ,14 })15 .Class({16 constructor: function () {17 this.createOrder = (function(data) {18 // Order is created on the server and the order id is returned19 return fetch("/my-server/create-paypal-order", {20 method: "POST",21 headers: {22 "Content-Type": "application/json",23 },24 // use the "body" param to optionally pass additional order information25 // like product skus and quantities26 body: JSON.stringify({27 cart: [28 {29 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",30 quantity: "YOUR_PRODUCT_QUANTITY",31 },32 ],33 }),34 })35 .then((response) => response.json())36 .then((order) => order.id);37 }).bind(this);38 this.onApprove = (function(data) {39 // Order is captured on the server40 return fetch("/my-server/capture-paypal-order", {41 method: "POST",42 headers: {43 "Content-Type": "application/json",44 },45 body: JSON.stringify({46 orderID: data.orderID47 })48 })49 .then((response) => response.json())50 }).bind(this);51 });52 }});53 const appModule = ng.core54 .NgModule({55 imports: [ng.platformBrowser.BrowserModule, PayPalButton],56 declarations: [appComponent],57 bootstrap: [appComponent],58 })59 .Class({60 constructor: function () {},61 });62 document.addEventListener("DOMContentLoaded", function () {63 ng.platformBrowserDynamic64 .platformBrowserDynamic()65 .bootstrapModule(appModule);66 });67})();
Angular 2 using TypeScript
1@ng.core.Component({2 selector: 'my-app',3 template:4 <div id="app">5 <paypal-buttons [props]="{6 createOrder: createOrder,7 onApprove: onApprove8 }"></paypal-buttons>9 </div>10 ,11})12class AppComponent {13 createOrder(data) {14 // Order is created on the server and the order id is returned15 return fetch("/my-server/create-paypal-order", {16 method: "POST",17 headers: {18 "Content-Type": "application/json",19 },20 // use the "body" param to optionally pass additional order information21 // like product skus and quantities22 body: JSON.stringify({23 cart: [24 {25 sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",26 quantity: "YOUR_PRODUCT_QUANTITY",27 },28 ],29 }),30 })31 .then((response) => response.json())32 .then((order) => order.id);33 }34 onApprove(data, actions) {35 // Order is captured on the server36 return fetch("/my-server/capture-paypal-order", {37 method: "POST",38 headers: {39 "Content-Type": "application/json",40 },41 body: JSON.stringify({42 orderID: data.orderID43 })44 })45 .then((response) => response.json())46 }47}48@ng.core.NgModule({49 imports: [50 ng.platformBrowser.BrowserModule,51 paypal.Buttons.driver('angular2', ng.core)52 ],53 declarations: [54 AppComponent55 ],56 bootstrap: [57 AppComponent58 ]59})60class AppModule {}61ng.platformBrowserDynamic62 .platformBrowserDynamic()63 .bootstrapModule(AppModule);
Vue
<div id="container">
<app></app>
</div>
<script>
const PayPalButton = paypal.Buttons.driver('vue', window.Vue)
Vue.component('app', {
// The style prop for the PayPal button should be passed in as `style-object` or `styleObject` to avoid conflict with Vue's `style` reserved prop.
template: `
<paypal-buttons :on-approve="onApprove" :create-order="createOrder" :on-shipping-change="onShippingChange" :on-error="onError" :style-object="style" />
`,
components: {
'paypal-buttons': PayPalButton,
},
computed: {
createOrder: function () {
return (data) => {
// Order is created on the server and the order id is returned
return fetch("/my-server/create-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// use the "body" param to optionally pass additional order information
// like product skus and quantities
body: JSON.stringify({
cart: [
{
sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
})
.then((response) => response.json())
.then((order) => order.id);
}
},
onApprove: function () {
return (data) => {
// Order is captured on the server
return fetch("/my-server/capture-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
orderID: data.orderID
})
})
.then((response) => response.json());
}
},
onShippingChange: function () {
return (data, actions) => {
if (data.shipping_address.country_code !== 'US') {
return actions.reject()
}
return actions.resolve()
}
},
onError: function () {
return (err) => {
console.error(err)
window.location.href = '/your-error-page-here'
}
},
style: function () {
return {
shape: 'pill',
color: 'gold',
layout: 'horizontal',
label: 'paypal',
tagline: false,
}
},
},
})
const vm = new Vue({
el: '#container',
})
</script>
Next steps
Test in PayPal sandbox, then go live in PayPal's live environment.