Direct Integration to PayPal JS SDK
This guide describes how to add PayPal Smart Button to your payment page by integrating directly to PayPal's JavaScript SDK.
Prerequisites
To offer the PayPal Smart Button as a checkout option to your payers by using PayPal's JavaScript SDK:
- Ensure your payment service provider has an account with PayPal and has created an application with their PayPal account. Your payment service provider should have received the client ID from PayPal and stored it against your merchant profile in Merchant Manager.
- Ensure you have configured the PayPal integration in Merchant Administration and have granted the third-party permission to the gateway to transact on your behalf.
Information flow
The following steps describe the information flow for a direct integration to PayPal JS SDK:
- Payer clicks PayPal Smart Button on your payment page.
- Javascript in the payer's browser sends a request to your server.
- Your server performs the Initiate Browser Payment operation on the gateway to start the payment process with PayPal.
- Gateway returns the interaction ID from PayPal to your server.
- Your server returns the interaction ID to the Javascript that is running in the payer's browser.
- The payer's browser then displays the PayPal UI.
- The Javascript in the payer's browser interacts with your server to proceed with the payment process.
- Your server performs the Confirm Browser Payment operation on the gateway to complete the payment.
Add smart button using PayPal's JavaScript SDK
Follow the steps outlined below to build your integration to PayPal's JavaScript SDK.
Step 1: Get the client ID
Get the client ID by submitting the Payment Options Inquiry request to the gateway. The response returns a client ID that you must use in the subsequent steps.
https://<your_host_name>/api/rest/version/<api_version>/merchant/<your_gateway_merchantId>/paymentOptionsInquiry
{ "merchant": "TESTPP_V2_MER33;", "paymentTypes": { "paypal": { "currencies": [ { "currency": "AUD" }, ], "transactionSources": [ { "transactionSource": "INTERNET" } ] "clientId": "ARLDC7ynAfGNlnJy8PuLanMRQvteg9RsfxAMLK-43amD5_urCn0Jl1APryAyWEvIm_GY1ippISEwsoza", "accountId": "RMU2YU3VN8SUL" } }, "result": "SUCCESS", "supportedPaymentOperations": [ { "supportedPaymentOperation": "AUTHORIZE" } ] }
Step 2: Add the PayPal JavaScript SDK to your web page
To enable the PayPal Smart Button functionality, add the PayPal JavaScript SDK to your web page. Use the client ID that you have received in the response of Payment Options Inquiry in step 1 as the value of the client-id query parameter.
<!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=PayPal_CLIENT_ID and merchant-id=PayPal_MERCHANT_ID"> </script> </body>
For more details on this step, see step 2 in the PayPal Developer guide.
Step 3: Render PayPal Smart Button on your web page
To render the PayPal Smart Button on your webpage, add the below code to your webpage. Use the client ID that you have received in the response of Payment Options Inquiry in step 1.
<body> <script src="https://www.paypal.com/sdk/js?client-id=PayPal_CLIENT_ID and merchant-id=PayPal_MERCHANT_ID"> </script> <div id="paypal-button-container"></div> <script> paypal.Buttons().render('#paypal-button-container'); // This function displays Smart Payment Buttons on your web page. </script> </body>
For more details on this step, see step 3 in the PayPal Developer guide.
Step 4: Set up a transaction
You have to set the createOrder callback to inform your host to submit the Initiate Browser Payment request to the gateway. To set up a transaction from your server or client, see the Set up a Transaction section in the PayPal Developer guide.
The sequence of events differ based on the PayPal Checkout flow.
- For Checkout with PayPal, see the Sequence of Events during Checkout with PayPal section.
- For Pay with PayPal, see the Sequence of Events during Pay with PayPal section.
Sequence of Events during Checkout with PayPal
- Submit the Initiate Browser Payment request to the gateway with
browserPayment.paypal.paymentconfirmation = CONFIRM_AT_MERCHANT
Example Request{ "apiOperation": "INITIATE_BROWSER_PAYMENT", "browserPayment": { "operation": "PAY", "paypal": { "paymentConfirmation": "CONFIRM_AT_MERCHANT" } }, "order": { "amount": "679.99", "currency": "USD" }, "sourceOfFunds": { "type": "PAYPAL" } }
Example Response"browserPayment.paypal.interactionId": "EC-8AT72418NV353182U"
- Implement a callback handler that gets invoked when a payer clicks the PayPal Smart Button (shown as
createOrderCallbackHandler
in the example in Step 4). This handler must interact with your server to submit the Initiate Browser Payment request to the gateway. - Submit the Initiate Browser Payment request from your server, and then return
browserPayment.paypal.interactionId
.The Initiate Browser Payment response contains the express checkout token in the
browserPayment.paypal.interactionId
field.Example RequestcreateOrder: function() { return fetch('/my-server/create-paypal-transaction', { method: 'post', headers: { 'content-type': 'application/json' } }).then(function(res) { return res.json(); }).then(function(data) { return data.interactionId; // Return the interactionId as provided by the gateway to your server }); }
- The PayPal JavaScript gets the payment form from PayPal, and then it renders the form on the payer's browser.
- Payer logs in to PayPal and submits the payment details to PayPal.
- Register the onApprove handler with PayPal.
- After the transaction on the PayPal UI is successful, the onApprove handler gets invoked. Now, submit the Update Browser Payment request from your server to the gateway to get the latest payment details.
approveCallback handler
onApprove: function (data, actions) { // CALL TO UPDATE_BROWSER_PAYMENT from your server; };
Sample Update Browser Payment Request//URL https://<your_host_name>/api/rest/version/latest/merchant/<your_merchant_id>/transaction/151109242cvbnv //Body { "apiOperation": "UPDATE_BROWSER_PAYMENT" }
Sample Update Browser Payment Response{ "device": { "browser": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36", "ipAddress": "66.159.204.102" }, "gatewayEntryPoint": "WEB_SERVICES_API", "merchant": "TESTMAN1234", "order": { "amount": 679.99, "chargeback": { "amount": 0, "currency": "USD" }, "creationTime": "2020-09-17T09:38:41.924Z", "currency": "USD", "id": "421d49456789012345678909234527890", "lastUpdatedTime": "2020-09-17T09:40:11.894Z", "merchantAmount": 679.99, "merchantCurrency": "USD", "status": "CAPTURED", "totalAuthorizedAmount": 679.99, "totalCapturedAmount": 679.99, "totalRefundedAmount": 0 }, "response": { "acquirerCode": "Success", "gatewayCode": "APPROVED" }, "result": "SUCCESS", "shipping": { "address": { "city": "Market City", "country": "AUS", "postcodeZip": "4322", "stateProvince": "Queensland", "street": "35 Rainbow street", "street2": "Floor 5, Apartment 34" }, "contact": { "firstName": "John", "lastName": "Smith", "phone": "0745231111" } }, "timeOfLastUpdate": "2020-09-17T09:40:11.894Z", "timeOfRecord": "2020-09-17T09:38:41.945Z", "transaction": { "acquirer": { "date": "2020-09-17", "id": "PAYPAL", "merchantId": "m.m@g.com", "time": "09:40:11", "transactionId": "SVE2APDYOXKMA7RY0" }, "amount": 679.99, "currency": "USD", "id": "151109242cvbnv", "receipt": "SVE2APDYOXKMA7RY0", "source": "INTERNET", "stan": "0", "type": "PAYMENT", "update": [ { "gatewayCode": "SUBMITTED", "time": "2020-09-17T09:38:42.054Z" }, { "gatewayCode": "APPROVED", "time": "2020-09-17T09:40:11.896Z" } ] }, "version": "59" }
- If there is any change to the amount due to a change in the shipping amount, you display the delta amount to the payer.
- Once the payer confirms the payment, submit the CONFIRM_BROWSER_PAYMENT request to finalize the transaction.
Example Request
{ "apiOperation": "CONFIRM_BROWSER_PAYMENT", "order": { "amount": "779.99", // amount updated as a result of updated shipping and handling charges "shippingAndHandlingAmount": "100.00" // updated shipping and handling charges ... } }
Sequence of Events during Pay with PayPal
- Submit the Initiate Browser Payment request to the gateway with
browserPayment.paypal.paymentconfirmation = CONFIRM_AT_PROVIDER
Example Request{ "apiOperation": "INITIATE_BROWSER_PAYMENT", "browserPayment": { "operation": "PAY", "paypal": { "paymentConfirmation": "CONFIRM_AT_PROVIDER" } }, "order": { "amount": "679.99", "currency": "USD" }, "sourceOfFunds": { "type": "PAYPAL" } }
Example Response"browserPayment.paypal.interactionId": "EC-8AT72418NV353182U"
- Implement the
createOrder
callback in the PayPal Smart Button code. When a payer clicks the PayPal Smart Button, PayPal will execute this code. - Submit the Initiate Browser Payment request, from your server and then return
browserPayment.paypal.interactionId
.The Initiate Browser Payment response contains the field
browserPayment.paypal.interactionId
.ExamplecreateOrder: function() { return fetch('/my-server/create-paypal-transaction', { method: 'post', headers: { 'content-type': 'application/json' } }).then(function(res) { return res.json(); }).then(function(data) { return data.interactionId; // Return the interactionId as provided by the gateway to your server }); }
- The PayPal JavaScript gets the payment form from PayPal, and then it renders the form on the payer's browser.
- Payer logs in to PayPal and submits the payment details to PayPal.
- Register the onApproveCallback handler with PayPal.
- After the transaction on the PayPal UI is successful, the
onApprove
handler gets invoked. Now, submit the CONFIRM_BROWSER_PAYMENT request from your server to the gateway to finalize the payment.approveCallback handleronApprove: function (data, actions) { // CALL TO CONFIRM_BROWSER_PAYMENT from your server; };
Example Request{ "apiOperation": "CONFIRM_BROWSER_PAYMENT" }
- (Optional) If the instrument is declined, PayPal sends the
INSTRUMENT_DECLINED
response to the Execute Payment request.A payer gets three attempts in total to make the payment. For more information, see Decline Recovery.
You must do
action.restart()
to support DECLINE_RECOVERY.
Decline Recovery
Decline recovery is supported only using PayPal. During the transaction process if
the instrument gets declined then the payer gets two more attempts to make the payment.
For all the three attempts, a payer can use the same or any another instrument which is registered with PayPal to
proceed with the payment. If it is a new instrument, a payer must register it with PayPal before proceeding wth the
payment. A payer gets three attempts in total to make the payment. If even after the third attempt the
instrument gets declined, your payment service provider will send the TRANSACTION_REFUSED
or the
INSTRUMENT_DECLINED
response. Henceforth, the payer will not be able to proceed with the transaction
process.
Sequence of Events during Decline Recovery
- Submit the Initiate Browser Payment request to the gateway with browserPayment.paypal.paymentconfirmation = CONFIRM_AT_PROVIDER.
The PayPal's payment form is displayed.
- A payer logs in to the PayPal's payment form, selects the payment instrument, and then clicks Pay Now.
- Submit the CONFIRM_BROWSER_PAYMENT request to invoke the PayPal's Execute Payment request.
- If the instrument is declined, PayPal sends the
INSTRUMENT_DECLINED
response to the Execute Payment request.A payer gets three attempts in total to make the payment.
- After the onApprove event handler receives the INSTRUMENT_DECLINED response, call the actions.restart() function to allow a payer to choose a different instrument.
const restartPaymentOnInstrumentDeclined = (resp, actions) => { if (isInstrumentDeclined(resp)) { return actions.restart(); } else { gatewaySuccessCallbackBP(resp); } }
{ "browserPayment": { "interaction": { "status": "INITIATED", "timeInitiated": "2021-07-15T07:10:16.176Z" }, "operation": "PAY", "paypal": { "displayShippingAddress": true, "interactionId": "EC-9SH774983H4356451", "overrideShippingAddress": true, "paymentConfirmation": "CONFIRM_AT_PROVIDER" } }, "gatewayEntryPoint": "WEB_SERVICES_API", "merchant": "PP_POI_1", "order": { "amount": 931, "chargeback": { "amount": 0, "currency": "USD" }, "creationTime": "2021-07-15T07:10:16.152Z", "currency": "USD", "id": "vcc-206", "item": [ { "brand": "MC", "category": "NA", "detail": { "unitDiscountRate": 0 }, "name": "name", "quantity": 1, "sku": "sku", "unitDiscountAmount": 0, "unitPrice": 931 } ], "itemAmount": 931, "lastUpdatedTime": "2021-07-15T07:12:19.571Z", "merchantAmount": 931, "merchantCurrency": "USD", "reference": "my order", "status": "INITIATED", "taxAmount": 0, "totalAuthorizedAmount": 0, "totalCapturedAmount": 0, "totalDisbursedAmount": 0, "totalRefundedAmount": 0 }, "response": { "acquirerCode": "INSTRUMENT_DECLINED", "acquirerMessage": "", "debugInformation": "INSTRUMENT_DECLINED, The instrument presented was either declined by the processor or bank, or it can't be used for this payment., e5a837ee6834", "gatewayCode": "SUBMITTED" }, "result": "SUCCESS", "shipping": { "address": { "city": "Los Angeles", "company": "Google", "country": "USA", "postcodeZip": "90001", "stateProvince": "CA", "street": "2nd Main", "street2": "lane 2" }, "contact": { "email": "ramakanth@gmail.com", "firstName": "Ramakanth", "lastName": "Kulkarni", "mobilePhone": "9999999999", "phone": "9999999999" } }, "sourceOfFunds": { "provided": { "paypal": { "accountEmail": "johnsmith@paypal.com", "accountHolder": "Paul Levetsky", "payerId": "LM9AM5Y34N3X8" } }, "type": "PAYPAL" }, "timeOfLastUpdate": "2021-07-15T07:12:19.571Z", "timeOfRecord": "2021-07-15T07:10:16.171Z", "transaction": { "acquirer": { "date": "15 Jul 2021", "id": "PAYPAL", "merchantId": "NDXE9MFKNPCUA", "time": "07:12:19" }, "amount": 931, "currency": "USD", "id": "1", "source": "INTERNET", "stan": "0", "type": "PAYMENT", "update": [ { "gatewayCode": "SUBMITTED", "time": "2021-07-15T07:10:17.280Z" } ] }, "version": "62" }
{ "browserPayment": { "interaction": { "status": "COMPLETED", "timeCompleted": "2021-07-20T09:17:27.128Z", "timeInitiated": "2021-07-20T09:15:56.313Z" }, "operation": "PAY", "paypal": { "displayShippingAddress": true, "interactionId": "EC-74C02380KE247305K", "overrideShippingAddress": true, "paymentConfirmation": "CONFIRM_AT_PROVIDER" } }, "gatewayEntryPoint": "WEB_SERVICES_API", "merchant": "PP_POI_1", "order": { "amount": 1.28, "chargeback": { "amount": 0, "currency": "USD" }, "creationTime": "2021-07-20T09:15:56.278Z", "currency": "USD", "description": "Ordered goods", "id": "testsdkhco33", "item": [ { "brand": "MC", "category": "NA", "name": "name", "quantity": 1, "sku": "sku", "unitPrice": 1.28 } ], "itemAmount": 1.28, "lastUpdatedTime": "2021-07-20T09:17:27.136Z", "merchantAmount": 1.28, "merchantCurrency": "USD", "reference": "my order", "status": "FAILED", "taxAmount": 0, "totalAuthorizedAmount": 0, "totalCapturedAmount": 0, "totalDisbursedAmount": 0, "totalRefundedAmount": 0 }, "response": { "acquirerCode": "TRANSACTION_REFUSED", "acquirerMessage": "", "debugInformation": "TRANSACTION_REFUSED, The request was refused, cae635b964420", "gatewayCode": "DECLINED" }, "result": "FAILURE", "shipping": { "address": { "city": "Los Angeles", "country": "USA", "postcodeZip": "90001", "stateProvince": "CA", "street": "2nd Main", "street2": "lane 2" }, "contact": { "firstName": "Ramakanth", "lastName": "Kulkarni" } }, "sourceOfFunds": { "provided": { "paypal": { "accountEmail": "CCREJECT-REFUSED@paypal.com", "accountHolder": "Paul Levetsky", "payerId": "LM9AM5Y34N3X8" } }, "type": "PAYPAL" }, "timeOfLastUpdate": "2021-07-20T09:17:27.136Z", "timeOfRecord": "2021-07-20T09:15:56.308Z", "transaction": { "acquirer": { "date": "20 Jul 2021", "id": "PAYPAL", "merchantId": "NDXE9MFKNPCUA", "time": "09:17:27" }, "amount": 1.28, "currency": "USD", "id": "1", "source": "INTERNET", "stan": "0", "type": "PAYMENT", "update": [ { "gatewayCode": "SUBMITTED", "time": "2021-07-20T09:15:57.482Z" }, { "gatewayCode": "DECLINED", "time": "2021-07-20T09:17:27.128Z" } ] }, "version": "62" }
Testing your integration
When you have completed your integration with the PayPal, you can test it by using the PayPal sandbox.
To begin the test, create an account with PayPal and use those credentials while setting up your merchant profile with your payment service provider. Ensure you use the non-TEST merchant for these transactions.
- Use the aforementioned steps for the integration.
- Ensure you submit the Payment Options Inquiry request to receive the client ID of your payment service provider in the response.
- Ensure you have configured the PayPal integration in Merchant Administration, and have granted the third-party permission to the gateway to transact on your behalf.