Full Redirect

In full redirect flow customer (aka account owner) will be directly redirected from your website or app to PayPal.
For such reason you will need to send integrationData containing the success (RETURN_URL) and failure URL (FAILURE_RETURN_URL) in the request to the Gateway, so that the Gateway can forward this information to PayPal.
requestType can be either 'ApmSaleTransaction' for purchase (sale) or 'ApmPreAuthTransaction' for pre-authorization.

Sequence Flow

Steps

Step 1 - ORDER CREATION - Create a transaction to retrieve the redirect url to PayPal

Details

Endpoint: POST | .../ipgrestapi/v2/services/payments

{
    "requestType": "ApmSaleTransaction",
    "transactionAmount": {
        "total": "13",
        "currency": "EUR"
    },
    "paymentMethod": {
        "type": "PAYPAL"
    },
    "storeId": "54180618061806",
    "order": {
        "shipping": {//mandatory for PayPal seller protection program
            "name": "John Doe",
            "address": {
                "company": "Test Company",
                "address1": "House No: 2, street -5",
                "address2": "Weberstr",
                "city": "BONN",
                "postalCode": "53113",
                "region": "Nordrhein-Westfalen",
                "country": "India"
            }
        },
        "basket": { //mandatory for PayPal seller protection program
            "items": [
                {
                    "id": "item-1",
                    "description": "World cup",
                    "quantity": 1,
                    "subTotal": 8,
                    "valueAddedTax": 2,
                    "deliveryAmount": 0,
                    "chargeTotal": 10,
                    "currency": "EUR"
                },
                {
                    "id": "item-2",
                    "description": "cup",
                    "quantity": 1,
                    "subTotal": 2,
                    "valueAddedTax": 0.15,
                    "deliveryAmount": 0.85,
                    "chargeTotal": 3,
                    "currency": "EUR"
                }
            ]
        }
    },
    "transactionOrigin": "ECOM",
    "integrationData": [
        {
            "item": "RETURN_URL",
            "value": "https://www.fiserv.com"
        },
        {
            "item": "FAILURE_RETURN_URL",
            "value": "https://www.google.com"
        }
    ]
}
{
    "clientRequestId": "7cb6183e-f20b-4033-9ca1-fdc3ee40d0b6",
    "apiTraceId": "ZNCzr4CHgPxce6hdk77CegAAA0A",
    "ipgTransactionId": "84445951290",
    "orderId": "R-e8c80e57-50d0-47c6-a82b-ce632993268e",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1691399087,
    "transactionAmount": {
        "total": 13.00,
        "currency": "EUR",
        "components": {}
    },
    "transactionStatus": "WAITING",
    "approvalCode": "?:waiting PAYPAL",
    "processor": {
        "referenceNumber": "6JB86214PU121700R",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    },
    "requiredActions": {
        "requiredRedirectionData": {
            "target": "https://www.sandbox.paypal.com/checkoutnow?token=6JB86214PU121700R",
            "method": "GET"
        }
    }
}

Now the user should get redirected to the URL mentioned in requiredActions.requiredRedirectData.target (part of response). The order identifier by PayPal will be included inreferenceNumber.

Step 2 - STATUS INQUIRY - Get the order status after the successful redirect

Details

After the successful redirect back to the success URL of your webpage, you need to perform an inquiry towards our gateway. For the inquiry you need to use the IPGtransactionID (and not the orderID). If the orderID is used for the inquiry, you will only see the status of the transaction but not the change of the transaction to a final status.

The inquiry should only be triggered if the user was successfully redirected back to your RETURN_URL.

Endpoint: GET | .../ipgrestapi/v2/services/payments

GET https://test3.ipg-online.com/ipgrestapi/v2/services/payments/{ipgTransactionID}
{
    "clientRequestId": "a9d7e808-f5af-4970-86f7-1673ad59abf4",
    "apiTraceId": "ZNC2fYCHgPxce6hdk77ExgAAAzs",
    "ipgTransactionId": "84445951290",
    "orderId": "R-e8c80e57-50d0-47c6-a82b-ce632993268e",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1691399087,
    "approvedAmount": {
        "total": 13,
        "currency": "EUR",
        "components": {
            "subtotal": 13
        }
    },
    "transactionAmount": {
        "total": 13,
        "currency": "EUR",
        "components": {
            "subtotal": 13
        }
    },
    "transactionResult": "APPROVED",
    "approvalCode": "Y:000000:4445951290:PP X:5VB67358LM390583H",
    "transactionState": "CAPTURED",
    "processor": {
        "referenceNumber": "5VB67358LM390583H",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    }
}

transactionState should now be either CAPTURED or DECLINED.

Smart Buttons

Configuration and Functions

Paypal's Software Development Kit (SDK) offers a variety of functions that can be easily integrated into your website or app. For more information please see: https://developer.paypal.com/sdk/js/reference/

Before you using the PayPal's SDK you need to set the correct configuration.

The commit status of the transaction. Determines whether to show a Pay Now or Continue button in the Checkout flow.

PayPal query parameter 'commit'Implementation use caseBehavior on PayPal sidePayPal Button Visual
falseShow order review page before finalizing payment'False' shows a Continue button in the PayPal Checkout flow. The final amount might change after the buyer returns from PayPal to your site due to shipping, taxes, or other fees, the final amount. (Only possible in the Express Checkout Flow)Continue
trueOrder will be finalized after user approved payment'True' shows a Pay Now button in the PayPal Checkout flow. The final amount doesn't change after the buyer returns from PayPal to your site.Pay Now

The intent for the transaction. This determines whether the funds are captured immediately while the buyer is present on the page. Defaults to capture.

Transaction typePayPal query parameter 'intend'requestType
pre-authorizationauthorizeApmPreAuthTransaction
sale (purchase)captureApmSaleTransaction

For more information please see: https://developer.paypal.com/sdk/js/configuration/

Below table shows the linkage between the PayPal function used in the Smart buttons and the Gateway's API endpoints:

Details
Function (PayPal JS SDK)Request in Fiserv RESTful payments APIComment
createOrder - authorize only
(Link to PayPal Developer side)
POST | .../payments with
requestType: ApmPreAuthTransaction
(Link to Fiserv Postman collection
(Link to API Reference)
Use this requestType if you want to authorize only. Separate capture required.
In order to complete the order you will need to perform a second transaction against our API with requestType:PostAuthTransaction
(Link to Fiserv Postman Collection)
(Link to API Reference)
createOrder - capture
(Link to PayPal Developer side) - capture
POST | .../payments with
requestType: ApmSaleTransaction
(Link to Fiserv Postman collection
Use this requestType if you want to capture the transaction directly.
onApprove
(Link to PayPal Developer side)
GET | .../payments/{ipgTransactionId}
(Link to Fiserv Postman collection
(Link to API Reference)
After the User approved the transaction in the PayPal pop up, the SDK onApprove function is called which has to call the Fiserv inquiry endpoint.

Only the IPGtransactionID can be inquired and not the orderID. If the orderID is inquired, then you will only see the status of the transaction but not the change of the transaction to a final status such as CAPTURED or DECLINED.
onCancel
(Link to PayPal Developer side)
POST | .../payments/{transaction-id}
(Link to Fiserv Postman collection
When an account owner cancels a payment, they typically return to the main page of website. Instead, you can use the onCancel function to show a cancellation page or return to the shopping cart. At the same time you should send a cancelation to the Gateway.
onError
(Link to PayPal Developer side)
POST | .../payments/{transaction-id}
(Link to Fiserv Postman collection
If an error prevents checkout, you can alert the user that an error has occurred with the buttons using the onError callback. At the same time you should send a cancelation to the Gateway.
onShippingAddressChange
(Link to PayPal Developer side)
Transaction status inquiry with body
POST | .../payments/{transaction-id}
Can be used to retrieve the updated shipping address the customer selected or updated on PayPal side. Needed in Express Checkout flow
onShippingOptionsChange
(Link to PayPal Developer side)
Transaction status inquiry with body
POST | .../payments/apm/{transaction-id}
Can be used to retrieve the updated shipping options the customer selected or updated on PayPal side. Needed in Express Checkout flow.

Below diagram shows how to integrate the createOrder and onApprove functions.


Express Checkout Shortcut (ECS)

PayPal ECS is essentially another PayPal button that can be used outside of the normal payment flow. Means, the customer can directly switch to the payment process on PayPal side without entering the shopping cart. The flow is only implemented in our RESTful payments API and slightly varies from the standard flow. It allows you to handle overcharges for updated shipping costs and amounts.

(Link to PayPal documentation: https://www.paypal.com/mu/webapps/mpp/express-checkout )

🚧

ECS requires a different Client ID and PayPal ID

The ECS flow supports the following transaction types:

  • sale
  • pre-authorization and post-authorization (completion)

Steps

Step 1 - Create an transaction order without shipping details

Details

Endpoint: POST | .../ipgrestapi/v2/services/payments

{
    "requestType": "ApmSaleTransaction",
    "transactionAmount": {
        "total": "13",
        "currency": "EUR",
        "components": {
            "subtotal": 10,
            "vatAmount": 2.15,
            "shipping": 0.85
        }
    },
    "paymentMethod": {
        "type": "PAYPAL"
    },
    "order": {
        "additionalDetails": {
            "merchantParameters": {
                "shippingPreference": "GET_FROM_FILE"
            }
        },
        "basket": {
            "items": [
                {
                    "id": "item-3",
                    "description": "World cup",
                    "quantity": 1,
                    "subTotal": 8,
                    "valueAddedTax": 2,
                    "deliveryAmount": 0,
                    "chargeTotal": 10,
                    "currency": "EUR",
                    "category": "category",
                    "detailedCategory": "detailedCategory",
                    "options": [
                        {
                            "name": "optionName",
                            "choice": "choice"
                        }
                    ]
                },
                {
                    "id": "item-2",
                    "description": "cup",
                    "quantity": 1,
                    "subTotal": 2,
                    "valueAddedTax": 0.15,
                    "deliveryAmount": 0.85,
                    "chargeTotal": 3,
                    "currency": "EUR",
                    "category": "category",
                    "detailedCategory": "detailedCategory",
                    "options": [
                        {
                            "name": "optionName",
                            "choice": "choice"
                        }
                    ]
                }
            ]
        }
    },
    "transactionOrigin": "ECOM",
    "integrationData": [
        {
            "item": "RETURN_URL",
            "value": "https://www.fiserv.com"
        },
        {
            "item": "FAILURE_RETURN_URL",
            "value": "https://www.google.com"
        }
    ]
}'
{
    "type": "transactionResponse",
    "clientRequestId": "55d712e2-c2ad-497f-ba96-f7786dff09be",
    "apiTraceId": "ZkRttN3doTrrJ-7cduFvwAAAA6M",
    "ipgTransactionId": "84499620335",
    "orderId": "R-3c7f81c5-60f8-4ee0-8e7b-8e614c88c49d",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1715760564,
    "transactionAmount": {
        "total": 13.00,
        "currency": "EUR",
        "components": {
            "subtotal": 10.00,
            "vatAmount": 2.15,
            "shipping": 0.85
        }
    },
    "transactionStatus": "WAITING",
    "approvalCode": "?:waiting PAYPAL",
    "processor": {
        "referenceNumber": "4YK73210A4055194X",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    },
    "requiredActions": {
        "requiredRedirectionData": {
            "target": "https://www.sandbox.paypal.com/checkoutnow?token=4YK73210A4055194X",
            "method": "GET"
        }
    }
}

In case of a preauth use requestType = "ApmPreAuthTransaction".

Step 2 - Get the details of sale transaction with updated shipping address

Details

Endpoint: POST| .../ipgrestapi/v2/services/payments/apm/

{
"requestType":"RefreshOrder"
}
{
    "type": "orderResponse",
    "clientRequestId": "gstzzs6578, 25c84e1f-e0a5-4fcb-b7f1-9b4f05135cad",
    "apiTraceId": "ZkRvD2GAFBFP81lDrk2dwAAAAtc",
    "shipping": {
        "name": "John Doe",
        "address": {
            "address1": "Nelson-Mandela-Platz 10",
            "address2": "Mitte",
            "city": "Nürnberg",
            "postalCode": "90459",
            "country": "DE"
        }
    },
    "transactions": [
        {
            "type": "transactionResponse",
            "ipgTransactionId": "84499620336",
            "orderId": "R-292166bf-b103-4e02-926f-3711fce93839",
            "paymentToken": {
                "reusable": true,
                "declineDuplicates": false
            },
            "transactionTime": 1715760793,
            "transactionAmount": {
                "total": 13,
                "currency": "EUR",
                "components": {
                    "subtotal": 10,
                    "vatAmount": 2.15,
                    "shipping": 0.85
                }
            },
            "transactionResult": "WAITING",
            "approvalCode": "?:waiting PAYPAL",
            "transactionState": "WAITING",
            "processor": {
                "referenceNumber": "82D56455543349520",
                "responseCode": "200",
                "responseMessage": "SUCCESS"
            },
            "requiredActions": {
                "requiredIntegrationData": [
                    {
                        "hint": "10",
                        "key": "UPDATED_AMOUNT_VALUE"
                    },
                    {
                        "hint": "EURO",
                        "key": "UPDATED_AMOUNT_CURRENCY"
                    },
                    {
                        "hint": "0",
                        "key": "UPDATED_SHIPPING_AMOUNT"
                    }
                ]
            }
        }
    ]
}

Step 3 - Update the amount and currency after recalculation of shipping and order costs

Details

Once you have received the updated shipping details, you can recalculate the shipping and order costs and send the updated details through our gateway to PayPal. If the total amount is below a specific amount, then the transaction is finalized. Otherwise, the customer will need to approve the transaction once more on PayPal side. It's up to PayPal whether an additional customer approval is needed.

Endpoint: PATCH | .../ipgrestapi/v2/services/payments/apm/

{
    "requestType": "UpdateTransaction",
    "integrationData": [
        {
            "item": "UPDATED_AMOUNT_VALUE",
            "value": "10"
        },
        {
            "item": "UPDATED_SHIPPING_AMOUNT",
            "value": "2"
        },
        {
            "item": "UPDATED_AMOUNT_CURRENCY",
            "value": "EUR"
        }
    ],
    "comments": "comments"
}
{
    "type": "transactionResponse",
    "clientRequestId": "gstzzs6578, 8f5d7a3f-d606-4969-be26-8d32e7523fd1",
    "apiTraceId": "ZkRvcA93MqlGypdPv0skgAAAAe8",
    "ipgTransactionId": "84499620336",
    "orderId": "R-292166bf-b103-4e02-926f-3711fce93839",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1715761008,
    "approvedAmount": {
        "total": 14.15,
        "currency": "EUR",
        "components": {
            "subtotal": 10.00,
            "vatAmount": 2.15,
            "shipping": 2.00
        }
    },
    "transactionAmount": {
        "total": 14.15,
        "currency": "EUR",
        "components": {
            "subtotal": 10.00,
            "vatAmount": 2.15,
            "shipping": 2.00
        }
    },
    "transactionStatus": "APPROVED",
    "approvalCode": "Y:000000:4499620336:PP X:7J077052N8584004D",
    "processor": {
        "referenceNumber": "7J077052N8584004D",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    }
}

Step 4 - OPTIONAL: Complete the pre-authorization

Details

In case of pre-authorization (aka authorize only via PayPal) you will need to perform another call to our RESTful payments API with requestType= "PostAuthTransaction"

Endpoint: POST | .../ipgrestapi/v2/services/payments/

{
    "requestType": "PostAuthTransaction",
    "transactionAmount": {
        "total": 12,
        "currency": "EUR",
        "components": {
            "subtotal": 10,
            "shipping": 2
        }
    }
}
{
    "type": "transactionResponse",
    "clientRequestId": "7c14338f-147f-47ee-81da-ade069adb60c",
    "apiTraceId": "ZkRwfGGAFBFP81lDrk2e9wAAAtw",
    "ipgTransactionId": "84499620338",
    "orderId": "R-896e2676-c477-4b26-984d-82c24480f9c2",
    "transactionType": "POSTAUTH",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1715761276,
    "transactionStatus": "APPROVED",
    "approvalCode": "Y:000000:4499620338:PP X:7T121574CX5509539",
    "processor": {
        "referenceNumber": "7T121574CX5509539",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    }
}

Step 5 - Get the tx status after the successful redirect

Details

Endpoint: GET | .../ipgrestapi/v2/services/payments/apm/

---body absent---
{
    "type": "transactionResponse",
    "clientRequestId": "667efafe-c239-4659-b121-66443ec6780c",
    "apiTraceId": "ZkRxsMzPZicTYiBaEqInfAAAAcE",
    "ipgTransactionId": "84499620337",
    "orderId": "R-896e2676-c477-4b26-984d-82c24480f9c2",
    "paymentToken": {
        "reusable": true,
        "declineDuplicates": false
    },
    "transactionTime": 1715761090,
    "approvedAmount": {
        "total": 12,
        "currency": "EUR",
        "components": {
            "subtotal": 10,
            "shipping": 2
        }
    },
    "transactionAmount": {
        "total": 12,
        "currency": "EUR",
        "components": {
            "subtotal": 10,
            "shipping": 2
        }
    },
    "transactionResult": "APPROVED",
    "approvalCode": "Y:000000:4499620337:PP X:7W1705579A463220H",
    "transactionState": "AUTHORIZED",
    "processor": {
        "referenceNumber": "7W1705579A463220H",
        "responseCode": "200",
        "responseMessage": "SUCCESS"
    }
}

Important parameters

Shipping and Basket Items

Field nameType*Description
shippingCTo be entitled to retain the full purchase amount as part of the PayPal’s Seller Protection program you have to ensure items/goods shipping to the shipping address presented on the transaction details page in your PayPal account for the transaction. To meet this eligibility requirement for PayPal’s Seller Protection you must submit the shipping address details as part of your request to be forwarded to PayPal. See more on https://www.paypal.com/ke/webapps/mpp/ua/seller-protection#what-eligible.

Presence of address data in PayPal overlay:
If you send a complete set of shipping element to our gateway (i.e.: name, address1, zip, city and country), then these values will be forwarded to PayPal. At the same time our gateway will set purchase_units.shipping_preference to ‘SET_PROVIDED_ADDRESS’ in the request to PayPal. This happens automatically whenever a shipping address is present. Your customers will be able see these address details inside the PayPal wallet (but cannot change it), and you will be provided with the address details as part of the gateway’s response.

If you submit invalid shipping address details (such as invalid country code) within your request to our gateway, then these values will be forwarded to PayPal and your transaction will be declined with an error (in this case: invalid country name for shipping).

In case you don't submit shipping element to our gateway, then no address data will be forwarded to PayPal and our gateway will set purchase_units.shipping_preference to ‘NO_SHIPPING’ in the request to PayPal. This allows you to control the address details selection inside the PayPal wallet (switch it off). Your customers won't see the address details inside the PayPal wallet, and you will not be provided with the address details as part of the gateway’s response. This is case is especially relevant if you're selling digital goods.
basket.itemsM?Can contain a list of the sold items/goods in order to show them in the PayPal wallet

*(M)=Mandatory (O)=Optional (C)=Conditional

STC-Content and Client-Meta-data

The following elements can be sent under the element additionalDetails.MerchantParameters (part of order)

Field nameDescription
client-meta-idIf required by PayPal (depending on individual use case), then you can set in your request to our gateway a value for the client-meta-id which will be passed on to PayPal as a specific risk tracking id (Risk Session Correlation ID / Client Metadata ID).
stc-contentIf required by PayPal, use this parameter to provide content for the PayPal Set Transaction Context (STC) with sufficient data for the PayPal Risk Services analysis which will be passed to PayPal before the transaction is authorized. (PayPal documentation https://developer.paypal.com/api/limited-release/raas/v1/#transaction-contexts_set)

Shipping Preference

Field nameDescription
shippingPreferenceThis element can be used to determine the shipping preference. If no value is provided in the request to our gateway, then the below behavior will be applied.

Behavior if elements are not given

ValueDescriptionBehavior if value is absent
GET_FROM_FILEUse the customer-provided shipping address on the PayPal site.
Warning: Only Possible in combination with IPG express checkout flow.
Default
Use the customer-provided shipping address on the PayPal site.
Warning: Only Possible in combination with IPG express checkout flow.
LINK to Express Checkout documentation
NO_SHIPPINGRecommended for digital goods.Our gateway assumes that the item is a digital good and uses use the shipping address provided by the customer on PayPal site. The customer cannot change this on the PayPal site.
SET_PROVIDED_ADDRESSUse the merchant-provided address. The customer cannot change this address on the PayPal site.Our gateway sets SET_PROVIDED_ADDRESS in the request to PayPal under the assumption the item is a digital good. The customer cannot change this address on the PayPal site

Example:

...
"additionalDetails": {
            "merchantParameters": {
                "stc-content": "{'name': 'jan', 'id':'1234'}",
                "client-meta-id": "meta-value-0342",
                "shippingPreference":"SET_PROVIDED_ADDRESS"
            }
        }

...

Want a quick overview?