Paypal - SDK Flow 

PayPal v2 introduces the PayPal Checkout, featuring a RESTful API solution that includes standard checkout, PayPal Express, and the innovative PayPal Vault functionality. These versatile and powerful payment solutions are designed to enhance the e-commerce experience for both merchants and their customers. By allowing customers to quickly complete transactions using their PayPal accounts, this integration helps reduce cart abandonment and speeds up the payment process.


PayPal v2 streamlines authentication and approval steps, ensuring a secure, efficient, and user-friendly checkout experience for your e-commerce platform. Beyond the standard checkout, the platform also offers the flexibility to use the JavaScript SDK to render PayPal buttons and respond to various PayPal events.

StandarD vs PayPal SDK 

With the standard PayPal implementation, the user is expected to be redirected to a new window / tab by the integrating partner and this flow is explained in details: PayPal Redirect Flow

PayPal Checkout v2 with PayPal SDK , provides a more easy end-user handling approach by simplifying the redirection process  and customer's return to merchant's page. In principle, the merchant’s site renders the PayPal Button and delegates most of the user handling to PayPal, reducing checkout complexity and dropouts.

  • Partner displays PayPal Button  ( along other payment methods )

  • Customer selects and presses PayPal Button

 

  • A new window opens in the same view where user authenticates and approves transaction with PayPal

  • User is returned to the partner 's website where the completion information is provided immediately  via SDK callback
  • Partner is expected to continue with the Order Completion and Delivery

Mode details on PayPal SDK can be found here PayPal information  

Configure your Initiation script

PayPal allows the configuration of the initiation script via Query parameters to help define specific content or actions based on the data being passed. Each piece of data sent contains:

  • A key-value pair: Keys define the piece of information needed, and the value provides that information. The key is separated from the value by an equal sign (=).
  • A question mark (?): Preceding the key-value pair to annotate that a question for a piece of information is being asked.
  • Ampersands (&): Used if more than one set of values needs to be provided at a time.
  • Information that PayPal needs to handle your request.
     

In this example, the script includes the following query parameters:

  • client-id: Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • merchant-id: YYYYYYYYYYYYYY
  • currency: EUR
  • intent: authorize 
  • locale: de_DE the country list is published here
  • commit: true
  • vault: false
  • disable-funding: card, sepa ( these are not implemented)
  • enable-funding: paylater

 <script src="https://www.paypal.com/sdk/js?client-id=Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&merchant-id=LXXXXXXXXXXXXX&currency=EUR&intent=authorize&locale=de_DE&commit=true&vault=false&disable-funding=card,sepa,bancontact&enable-funding=paylater"></script>

 

For debug purpose you can also add the parameter

debug:  true/false

Rendering the PayPal Button

Merchants have two options for rendering the PayPal button: they can opt for a dynamic PayPal button or use the standard JavaScript SDK to create buttons and respond to key events (such as onApprove, onError, onCancel, and onShippingChange).

The JavaScript Button Renderer offers a simple and efficient way to integrate the PayPal button into your website, enhancing both functionality and user experience. To ensure the PayPal button operates smoothly and provides a seamless checkout process, you'll need to prepare the following components:

When rendering the Payone button, it's essential to use the Payone client ID.

PAYONE client ID (LIVE):
AVNBj3ypjSFZ8jE7shhaY2mVydsWsSrjmHk0qJxmgJoWgHESqyoG35jLOhH3GzgEPHmw7dMFnspH6vim
Merchant ID/ Account ID:
Your Merchant ID (for the Javascript SDK only, see below)
Test Data (fixed): 
PAYONE client ID:
AUn5n-4qxBUkdzQBv6f8yd8F4AWdEvV6nLzbAifDILhKGCjOS62qQLiKbUbpIKH_O2Z3OL8CvX7ucZfh
Merchant ID/ Account ID: 3QK84QGGJE5HW (for the Javascript SDK only, see below)

Example: Render PayPal Button
<body>
    <script>
        paypal.Buttons({

            style: {
                layout: 'vertical', // vertical or horizontal
                color: 'gold', // gold, blue, black, silver, white
                shape: 'rect', // rect, pill
                label: 'checkout', // paypal, pay, subscribe, checkout, buynow
                height: 40 // 25 - 55, a value around 40 is recommended
            },

            createOrder: function(data, actions) {
                // call your own serverside script for pre-/authorization call to payone
                return fetch('create_order.php', {
                    method: 'post'
                }).then(function(res) {
                    return res.json();
                }).then(function(orderID) {
                    return orderID;
                });
            },

            onApprove: function(data, actions) {
                // redirect to your serverside success handling script/page
                window.location = 'handle_on_approve.php';
            },

            onCancel: function(data, actions) {
                console.log("Customer cancelled the PayPal Checkout Flow");
                // add your actions on cancellation
            },

            onError: function() {
                console.log("An Error occurred as part of the PayPal JS SDK");
                // add your actions if error occurs
            },

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

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

Information on Order Request  implementation using our SDKs can be found here : Server SDK Documentation 

Where to find your Merchant ID (live and Sandbox)
Live Account

Log in to your PayPal account and click on Account Settings under your profile.


Click on Business Information, and you will see your Merchant ID on the right-hand side.

PRocessing flow

Simple example flow for a PayPal SDK payment via Commerce Platform

  • Creating a checkout ( either together with Commerce Case or in distinct calls ) 
  • Render the PayPal Button using the PayPal Javascript SDK ,explained above.
  • Customer selects PayPal button and a callback function is triggered by the SDK to your server to generate a PayPal OrderID. 
  • On the server side, you will generate an Order Request against the previously generated Checkout , retrieve the payPalTransactionId (also called across documentation as OrderId ) from the response and respond with it to the SDK initial call.
  • PayPal Javascript SDK will open a new pop-up window where consumer will be asked to login, approve and finalize PayPal order
  • PayPal will close the pop-up window and give back user control to you 
  • You will be notified via a callback on the payment status ( e.g.: onApprove , onCancel or onError )
  • You need to  generate a complete request to update the order process in Commerce Platform
  • Finalize the process by Initialization of delivery process to capture the amount and deliver the services / goods. 

Parameters for PayPal SDK Payments

Structure redirectPaymentMethodSpecificInput - ORDER CALL

paymentProductId

840

requiresApproval

boolean

  • true = the payment requires approval before the funds will be captured using the Deliver or Capture endpoint of the API
  • false = the payment does not require approval, and the funds will be captured automatically
redirectionData.returnUrl

For SDK Flow , user will not be redirected to this URL but due to legacy and interoperability between flows, this URL still needs to be passed in the request. 

tokenize

boolean

  • true =  the payment would tokenize / store PayPal account and a an id ( token )  will be received 
  • false = the payment does not require tokenization / account storage 
paymentProcessingToken

  The unique Id which needed to facilitate payments against a stored account. Usable for speeding up checkout process by asking customer to complete transaction using his stored PayPal account or , when customer is not present, to complete a transaction. ( e,g. : Subscription charge ) . 

   Please notice that if tokenize = "true", the paymentProcessingToken will not be considered, and a new process to store consumer account will be initiated. 

   To initiate a payment against a stored account, paymentProcessingToken has to contain the Token ID and tokenize = "false".

paymentProduct840SpecificInput.fraudNetId

A unique ID determined by the merchant, to link a Paypal transaction to a FraudNet PayPal risk session. Only applicable to customer-initiated transactions, when the FraudNet SDK is used, and to be passed in the API request the same tracking ID value (FraudNet Session Identifier). This SDK is available here https://developer.paypal.com/docs/checkout/apm/pay-upon-invoice/fraudnet/

 paymentProduct840SpecificInput.javaScriptSdkFlow 

 Required parameter which defines how PayPal is being integrated inside the checkout page.  

boolean

  true =  the current integration uses PayPal SDK
  false = classic usage with PayPal Redirect flow 

Structure redirectPaymentMethodSpecificInput - Complete CALL

 paymentProduct840SpecificInput.javaScriptSdkFlow 

 Required parameter which defines how PayPal is being integrated inside the checkout page.  

boolean

  true =  the current integration uses PayPal SDK
  false = classic usage with PayPal Redirect flow 

 paymentProduct840SpecificInput.action

 Required parameter which one value "CONFIRM_ORDER_STATUS" it signals process is finished on merchant side. 

Create CommerceCase/Checkout

Creating a Commerce Case with the initial Checkout including a reference, information about the customer and the items in the shopping cart.

POST Commerce Case
Request
/v1/{merchantId}/commerce-cases
{
        "customer": {
            "merchantCustomerId": "PayPalTest-12121983",
            "billingAddress": {
                "additionalInfo": "Nice Garden infront ",
                "city": "TEst",
                "countryCode": "DE",
                "houseNumber": "16",
                "state": "NRW",
                "street": "TestStreet",
                "zip": "50858"
            },
            "contactDetails": {
                "emailAddress": "test.user@payone.com",
                "phoneNumber": "+491740000000"
            },
            "fiscalNumber": "",
            "businessRelation": "B2C",
            "locale": "de",
            "personalInformation": {
                "dateOfBirth": "19830404",
                "gender": "MALE",
                "name": {
                "firstName": "Test",
                "surname": "User",
                "title": "Ing."
                }
            }
        },
        "merchantReference": `yourReference-123`,
       "checkout": {
            "amountOfMoney": {
                "amount": 61600,
                "currencyCode": "EUR"
            },
           "references": {
                    "merchantReference": `paypalReference-123
            },
            "shipping": {
                "address": {
                "additionalInfo": "Apartment 203",
                "city": "Test",
                "countryCode": "DE",
                "houseNumber": 3,
                "state": "NRW",
                "street": "TestStreet 16",
                "zip": 50838,
                "name": {
                "firstName": "Wile",
                "surname": "E. Coyote",
                "title": "Dr."
                }
                }
            },
            "shoppingCart": {
                "items": [
                    {
                        "invoiceData": {
                            "description": "Test Product 1"
                        },
                        "orderLineDetails": {
                            "productCode": "CB314-2H-K7E8",
                            "productPrice": 16900,
                            "productType": "GOODS",
                            "quantity": 1,
                            "taxAmount": 2698
                        }
                    },
                    {
                        "invoiceData": {
                            "description": "Test Product 2"
                        },
                        "orderLineDetails": {
                            "productCode": "A-943238",
                            "productPrice": 14900,
                            "productType": "GOODS",
                            "quantity": 3,
                            "taxAmount": 7187
                        }
                    }

                ]
            },
        "autoExecuteOrder":"false"
    }

Response
{
  "commerceCaseId": "0affb53f-fe38-4331-9765-xxx123",
  "merchantReference": "PayPalTest-12121983",
  "customer": {
            "merchantCustomerId": "PayPalTest-12121983",
            "billingAddress": {
                "additionalInfo": "Nice Garden infront ",
                "city": "TEst",
                "countryCode": "DE",
                "houseNumber": "16",
                "state": "NRW",
                "street": "TestStreet",
                "zip": "50858"
            },
            "contactDetails": {
                "emailAddress": "test.user@payone.com",
                "phoneNumber": "+491740000000"
            },
            "fiscalNumber": "",
            "businessRelation": "B2C",
            "locale": "de",
            "personalInformation": {
                "dateOfBirth": "19830404",
                "gender": "MALE",
                "name": {
                "firstName": "Test",
                "surname": "User",
                "title": "Ing."
                }
            }
        },
  "checkout": {
    "checkoutId": "d8cedd0a-ac95-4b3c-8e77-xxxx123",
    "shoppingCart": {
                "items": [
                    {
                        "invoiceData": {
                            "description": "Test Product 1"
                        },
                        "orderLineDetails": {
                            "productCode": "CB314-2H-K7E8",
                            "productPrice": 16900,
                            "productType": "GOODS",
                            "quantity": 1,
                            "taxAmount": 2698
                        }
                    },
                    {
                        "invoiceData": {
                            "description": "Test Product 2"
                        },
                        "orderLineDetails": {
                            "productCode": "A-943238",
                            "productPrice": 14900,
                            "productType": "GOODS",
                            "quantity": 3,
                            "taxAmount": 7187
                        }
                    }

                ]
            },
            "amountOfMoney": {
                "amount": 61600,
                "currencyCode": "EUR"
            },
           "references": {
                    "merchantReference": `paypalReference-123
            },
            "shipping": {
                "address": {
                "additionalInfo": "Apartment 203",
                "city": "Test",
                "countryCode": "DE",
                "houseNumber": 3,
                "state": "NRW",
                "street": "TestStreet 16",
                "zip": 50838,
                "name": {
                "firstName": "Wile",
                "surname": "E. Coyote",
                "title": "Dr."
                }
                }
            },
    "checkoutStatus": "OPEN",
    "statusOutput": {
      "paymentStatus": "WAITING_FOR_PAYMENT",
      "isModifiable": true,
      "openAmount": 0,
      "collectedAmount": 0,
      "cancelledAmount": 0,
      "refundedAmount": 0,
      "chargebackAmount": 0
    },
    "creationDateTime": "2025-08-10T10:03:35.417776675Z",
    "allowedPaymentActions": [
      "ORDER_MANAGEMENT",
      "PAYMENT_EXECUTION"
    ]
  },
  "creationDateTime": "2025-08-10T10:03:35.417776675Z"
}

Order with PayPal payment

This call, will be initiated by the PayPal SDK when the user clicks the button and the SDK's createOrder function, will call an endpoint from your server where the PayPal ID is expected to be responded with.  When this happens, create an Order Request following the standard API implementation API Order Request. You can find the PayPal required ID  it in the response under payPalTransactionId and return it to the SDK.

POST Order
Request
/v1/{merchantId}/commerce-cases/{commerceCaseId}/checkout/{checkoutId}/order
{
    "orderType": "FULL",
    "orderReferences": {
        "descriptor": "PayPal payment",
        "merchantReference": "PayPal-2234521243"
    },
      "paymentMethodSpecificInput": {

                    "redirectPaymentMethodSpecificInput": {
                        "paymentProductId": 840,
                        "requiresApproval": true,
                        "paymentProduct840SpecificInput":
                        {
                            "addressSelectionAtPayPal":false,
                            "javaScriptSdkFlow":true
                        },      
                       "redirectionData": {
                        "returnUrl": "https://secure.ogone.com/ncol/test/displayparams.asp"
                    }
                    },

                "paymentChannel": "ECOMMERCE"
            }
}

Response
{
  "createPaymentResponse": {
    "merchantAction": {
      "actionType": "REDIRECT",
      "redirectData": {
        "redirectURL": "https://www.sandbox.paypal.com/checkoutnow?token=4UJ17366069442530"
      }
    },
    "payment": {
      "paymentOutput": {
        "amountOfMoney": {
          "amount": 61600,
          "currencyCode": "EUR"
        },
        "references": {
          "merchantReference": "PayPal-2234521243"
        },
        "paymentMethod": "redirect",
        "redirectPaymentMethodSpecificOutput": {
          "paymentProductId": 840,
          "paymentProduct840SpecificOutput": {
            "payPalTransactionId": "4UJ17366069442530"
          }
        }
      },
      "status": "REDIRECTED",
      "statusOutput": {
        "isCancellable": false,
        "statusCategory": "PENDING_PAYMENT",
        "isAuthorized": false,
        "isRefundable": false
      },
      "id": "PP2AAYBJ6HKLJY5X"
    },
    "paymentExecutionId": "af8cc429-d334-479b-af7a-xxxx123"
  },
  "shoppingCart": {
    "items": [
      {
        "invoiceData": {
          "description": "Test Product 1"
        },
        "orderLineDetails": {
          "id": "d868f4d3-9067-418a-96c1-xxx123",
          "status": [
            {
              "cartItemStatus": "WAITING_FOR_PAYMENT",
              "quantity": 1
            }
          ],
          "productCode": "CB314-2H-K7E8",
          "productPrice": 16900,
          "productType": "GOODS",
          "quantity": 1,
          "taxAmount": 2698,
          "taxAmountPerUnit": false
        }
      },
      {
        "invoiceData": {
          "description": "Test Product 2"
        },
        "orderLineDetails": {
          "id": "3f96a88d-412a-4aa8-9a7e-xxx123",
          "status": [
            {
              "cartItemStatus": "WAITING_FOR_PAYMENT",
              "quantity": 3
            }
          ],
          "productCode": "A-943238",
          "productPrice": 14900,
          "productType": "GOODS",
          "quantity": 3,
          "taxAmount": 7187,
          "taxAmountPerUnit": false
        }
      }
    ]
  }
}

Complete Order Request with PayPal

After onEvent notification is received from PayPal with transaction status  ( either onApproved ,  onCancel or onError ) , a Complete request is needed before any other Order ( retry )  can be initiated ( for the same checkout ). This will allow for the status to be propagated across the Commerce platform and facilitate a new order if needed. 

POST Order
Request
/v1/{merchantId}/commerce-cases/{commerceCaseId}/checkout/{checkoutId}/complete-order
{
        "completePaymentMethodSpecificInput": 
        {
            "paymentProduct840SpecificInput": 
            {
                "javaScriptSdkFlow": true,
                "action": "CONFIRM_ORDER_STATUS"
            }       

        }
      }

Response
{
  "payment": {
    "paymentOutput": {
      "amountOfMoney": {
        "amount": 61600,
        "currencyCode": "EUR"
      },
      "references": {
        "merchantReference": "PayPal-2234521243"
      },
      "paymentMethod": "redirect",
      "redirectPaymentMethodSpecificOutput": {
        "paymentProductId": 840
      }
    },
    "status": "PENDING_COMPLETION",
    "id": "PP2AAYBJ6DF3LL56"
  }
}

Webhook after successful confirmation on PayPal portal by end customer

You can identify the corresponding transaction by the field createPaymentResponse.payment.id in the order response. The status PENDING_CAPTURE shows that the amount is authorized and the payment gateway is waiting for a capture.

Webhook
{
    "apiVersion": "v1",
    "created": "2023-11-15T09:54:18.097694888+00:00",
    "id": "88ec52d6-bd59-47bf-b21e-147508d85b02",
    "merchantId": "P1_18323_2013224",
    "payment": {
        "paymentOutput": {
            "amountOfMoney": {
                "amount": 2995,
                "currencyCode": "EUR"
            },
            "references": {
                "merchantReference": "Order-2234521243"
            },
            "redirectPaymentMethodSpecificOutput": {
                "paymentProductId": 840
            },
            "paymentMethod": "redirect"
        },
        "status": "PENDING_CAPTURE",
        "statusOutput": {
            "isCancellable": true,
            "statusCategory": "PENDING_MERCHANT",
            "isAuthorized": true,
            "isRefundable": false
        },
        "id": "PP2AAD9QHE48KG0E"
    },
    "type": "payment.pending_capture"
}

Deliver

Full Deliver to capture the complete order amount.

POST Deliver
Request
/v1/{merchantId}/commerce-cases/{commerceCaseId}/checkout/{checkoutId}/deliver
{
    "deliverType": "FULL",
    "isFinal": true
}

Response
{
    "capturePaymentResponse": {
        "captureOutput": {
            "amountOfMoney": {
        "amount": 61600,
        "currencyCode": "EUR"
      },
            "references": {
                "merchantReference": "PayPal-2234521243"
            },
            "paymentMethod": "redirect"
        },
        "status": "CAPTURED",
        "id": "PP2AAYBJ6DF3LL56"
    },
     "shoppingCart": {
    "items": [
      {
        "invoiceData": {
          "description": "Test Product 1"
        },
        "orderLineDetails": {
          "id": "d868f4d3-9067-418a-96c1-xxx123",
          "status": [
            {
              "cartItemStatus": "WAITING_FOR_PAYMENT",
              "quantity": 1
            }
          ],
          "productCode": "CB314-2H-K7E8",
          "productPrice": 16900,
          "productType": "GOODS",
          "quantity": 1,
          "taxAmount": 2698,
          "taxAmountPerUnit": false
        }
      },
      {
        "invoiceData": {
          "description": "Test Product 2"
        },
        "orderLineDetails": {
          "id": "3f96a88d-412a-4aa8-9a7e-xxx123",
          "status": [
            {
              "cartItemStatus": "WAITING_FOR_PAYMENT",
              "quantity": 3
            }
          ],
          "productCode": "A-943238",
          "productPrice": 14900,
          "productType": "GOODS",
          "quantity": 3,
          "taxAmount": 7187,
          "taxAmountPerUnit": false
        }
      }
    ]
  }
}

Webhook after successful Deliver

The payment gateway informs you via webhook about the successful capture.

Webhook
{
    "apiVersion": "v1",
    "created": "2023-11-14T17:25:17.996829148+00:00",
    "id": "74e4fe0e-ee75-4c02-9b80-a3e3df8140d4",
    "merchantId": "P1_18323_2013224",
    "payment": {
        "paymentOutput": {
            "amountOfMoney": {
                "amount": 1998,
                "currencyCode": "EUR"
            },
            "references": {
                "merchantReference": "Order-1234521244"
            },
            "redirectPaymentMethodSpecificOutput": {
                "paymentProductId": 990
            },
            "paymentMethod": "redirect"
        },
        "status": "CAPTURED",
        "statusOutput": {
            "isCancellable": false,
            "statusCategory": "COMPLETED",
            "isAuthorized": true,
            "isRefundable": true
        },
        "id": "PP2AAD9B9UAW8BBD"
    },
    "type": "payment.captured"
}