This site requires javascript to be enabled.

PayPal

Results for

Results for Searching

Integration

Description

This is a product specific integration guide that will go over all the available features and how to use them.

Features or customization options that are not strictly required for PayPal Payments may be skipped in this guide, pages with extra information will be hyperlinked where appropriate.

Prerequisites

To follow along with this guide, please ensure that you have the following ready:

MyCheckout hosted payment pages

The fastest way to start accepting PayPal Payments is to make use of the MyCheckout hosted payment pages.

To start using the MyCheckout hosted payment pages, you only need to make a POST /v1/{merchantId}/hostedcheckouts API call with an order object containing a amountOfMoney object and a customer object. The customer object has a lot of options but only the billingAddress object with a countryCode property is required for a basic checkout.

This is how a minimum payload would look like:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    }
}

This will return a response like this:


{
   "RETURNMAC" : "33893c8a-1e6f-4e02-9015-9d4e34b08d41",
   "hostedCheckoutId" : "0634e88f-7255-71ff-860e-3f55f70978cc",
   "partialRedirectUrl" : "pay1.preprod.secured-by-ingenico.com/checkout/1010-e6e2e548a8024375a3c22ae4cea99f59:0634e88f-7255-71ff-860e-3f55f70978cc:80152ac992ea431ea1da027d1c3e6df4"
}

From the response, the important properties are hostedCheckoutId and partialRedirectUrl.

The hostedCheckoutId can be used in subsequent API calls such as GET /v1/{merchantId}/hostedcheckouts/{hostedCheckoutId} which will allow you to retrieve details regarding the transaction.

The partialRedirectUrl is used to create the URL where the customer needs to be redirected to. By default, we configure every account with the subdomain payment so you can always concatenate https://payment. with the partialRedirectUrl, which will result in URL such as:

https://payment.pay1.preprod.secured-by-ingenico.com/checkout/1010-e6e2e548a8024375a3c22ae4cea99f59:0634e88f-7255-71ff-860e-3f55f70978cc:80152ac992ea431ea1da027d1c3e6df4

More detailed information on how to customize the MyCheckout hosted payment pages (e.g. subdomains, design, languages etc.) can be found here.

At its core, this is all you need to start accepting PayPal Payments, more complex options will be covered later.

The hostedCheckoutId is only valid for 2 hours, please ensure to store the createdPaymentOutput.payment.id from the GET /v1/{merchantId}/hostedcheckouts/{hostedCheckoutId} response in order to be able to retrieve data after 2 hours have elapsed via the GET /v1/{merchantId}/payments/{paymentId} API call.
Alternatively, we can also optionally send a Webhooks event which will contain it. Please refer to this page for further information regarding Webhooks.

Server to Server

If you choose to not use the MyCheckout hosted payment pages option, perhaps that you require more styling customization options, or already have an existing payment page, you can build a direct integration using our SDKs (or integrate our API from scratch).

Within this option, you have variations depending on how you wish to integrate.

Client Encryption

The Client API can be used for a variety of purposes, it allows you to perform actions such as collecting card data from your customers without needing to be PCI SAQ-D compliant, while also not requiring the usage of our checkout.

All you need is to be able to create a session via the POST /v1/{merchantId}/sessions API call. This will grant you access to the Client API.

It is highly recommended that you use our Client SDKs.

This guide only describes generally what steps you need to go through, the in-depth SDK pages describe how to perform the steps with SDK specific examples.

We provide these Client SDKs for:

These pages include detailed information on how to use the SDKs with language specific examples.

We also have references implementations showing how to use these SDK on GitHub.

If you choose to not use our Client SDKs, at the very least, please use the encryption methods we provide in these SDKs as it can be a bit tricky to do a custom implementation.

Raw Data

If you wish to do a direct server to server API call, you can elect to go for this option.

After the customer has chosen to pay with PayPal, you need to perform a POST /v1/{merchantId}/payments API call, similar to the last step in the Client Encryption option. The difference being that you do not need to submit a encryptedCustomerInput property.

The payload in this case requires the same order object as described in the last step of 3.1 Client Encryption, and a redirectPaymentMethodSpecificInput object, this object needs to contain a paymentProductId property and a redirectionData object.

Just as before, the redirectionData object needs to contain a returnUrl property.

This will result in a payload looking like this:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}
Customer Redirection

If you use POST /v1/{merchantId}/payments, you will also need to care of the customer redirection (in the case of POST /v1/{merchantId}/hostedcheckouts, we will handle it).

We will return a merchantAction object. There are various different actionType values but in the case of PayPal, we will always return the actionType value REDIRECT. This is accompanied with a redirectData object that contains a redirectURL that you need to direct your customer to in order for them to complete the PayPal payment.

Be aware that the merchantAction is only returned in the response to POST /v1/{merchantId}/payments and will look like this:

Expand example response

{
    "creationOutput": {
        "additionalReference": "01010100000750700001",
        "externalReference": "0101010000075070000100001"
    },
    "merchantAction": {
        "actionType": "REDIRECT",
        "redirectData": {
            "RETURNMAC": "eec8bcfc-e591-4619-9d12-99128ef9dacb",
            "redirectURL": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=EC-52K66531PE2909031"
        },
        "showData": []
    },
    "payment": {
        "id": "000000101010000075070000100001",
        "paymentOutput": {
            "amountOfMoney": {
                "amount": 100,
                "currencyCode": "SEK"
            },
            "references": {
                "paymentReference": "101000008219"
            },
            "paymentMethod": "redirect",
            "redirectPaymentMethodSpecificOutput": {
                "paymentProductId": 840,
                "paymentProduct840SpecificOutput": {
                    "customerAccount": {
                        "surname": "NONAME"
                    },
                    "customerAddress": {
                        "city": "NOCITY",
                        "countryCode": "NL"
                    }
                }
            }
        },
        "status": "REDIRECTED",
        "statusOutput": {
            "isCancellable": false,
            "statusCategory": "PENDING_PAYMENT",
            "statusCode": 50,
            "statusCodeChangeDateTime": "20221102141354",
            "isAuthorized": false,
            "isRefundable": false
        }
    }
}


The merchantAction is omitted from the GET /v1/{merchantId}/payments/{paymentId} API call and will return a response like this:

Expand example response

{
    "id": "000000101010000075070000100001",
    "paymentOutput": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "references": {
            "paymentReference": "101000008219"
        },
        "paymentMethod": "redirect",
        "redirectPaymentMethodSpecificOutput": {
            "paymentProductId": 840,
            "paymentProduct840SpecificOutput": {
                "customerAccount": {
                    "surname": "NONAME"
                },
                "customerAddress": {
                    "city": "NOCITY",
                    "countryCode": "NL"
                }
            }
        }
    },
    "status": "REDIRECTED",
    "statusOutput": {
        "isCancellable": false,
        "statusCategory": "PENDING_PAYMENT",
        "statusCode": 50,
        "statusCodeChangeDateTime": "20221102141354",
        "isAuthorized": false,
        "isRefundable": false
    }
}


Additional Features

There are several additional features that can be used depending on your needs.

Billing Agreement

The Billing Agreement is used when you need to perform recurring payments (e.g. your monthly music streaming service).

To initiate a new recurring sequence you need to submit a few extra properties in redirectPaymentMethodSpecificInput. By setting the isRecurring property to true, the transaction will be considered Recurring and PayPal will provide a Billing Agreement. The recurringPaymentSequenceIndicator will indicate whether this is the first payment or a subsequent one in the sequence.

Do note that this does not work the same way for the POST /v1/{merchantId}/hostedcheckouts and POST /v1/{merchantId}/payments API calls.

The difference is that the isRecurring property will need to be submitted in the hostedCheckoutSpecificInput object instead of the redirectPaymentMethodSpecificInput.

To give an example of the difference, this is the example payload for the POST /v1/{merchantId}/hostedcheckouts API call:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "recurringPaymentSequenceIndicator": "first"
    },
    "hostedCheckoutSpecificInput": {
        "isRecurring": true
    }
}

And this is how it would look like for the POST /v1/{merchantId}/payments API call:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "isRecurring": true,
        "recurringPaymentSequenceIndicator": "first",
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

Here is an example of the output of GET /v1/{merchantId}/hostedcheckouts/{hostedCheckoutId} after the payment has been completed (it may look different based on your Merchant ID configuration):

Expand example response

{
    "createdPaymentOutput": {
        "payment": {
            "id": "000000101010000075060000100001",
            "hostedCheckoutSpecificOutput": {
                "hostedCheckoutId": "063626ad-34dc-71ff-bb57-3f919033eb91"
            },
            "paymentOutput": {
                "amountOfMoney": {
                    "amount": 100,
                    "currencyCode": "SEK"
                },
                "references": {
                    "paymentReference": "101000008209"
                },
                "paymentMethod": "redirect",
                "redirectPaymentMethodSpecificOutput": {
                    "paymentProductId": 840,
                    "paymentProduct840SpecificOutput": {
                        "customerAccount": {
                            "accountId": "gcsstag@outlook.com",
                            "billingAgreementId": "B-4KF96505WT315842S",
                            "companyName": "d",
                            "countryCode": "NL",
                            "customerAccountStatus": "verified",
                            "customerAddressStatus": "Confirmed",
                            "firstName": "asd",
                            "payerId": "NKH8H8V2TJP5Q",
                            "surname": "adsf"
                        },
                        "customerAddress": {
                            "additionalInfo": "15",
                            "city": "MILANO",
                            "countryCode": "IT",
                            "state": "MI",
                            "street": "VIA FRANCESCO SOAVE",
                            "zip": "20136"
                        }
                    },
                    "token": "aa66c3e7-b90b-4604-969e-4d11d0e808ac"
                }
            },
            "status": "CAPTURED",
            "statusOutput": {
                "isCancellable": false,
                "statusCategory": "COMPLETED",
                "statusCode": 800,
                "statusCodeChangeDateTime": "20221102140451",
                "isAuthorized": true,
                "isRefundable": false
            }
        },
        "paymentCreationReferences": {
            "additionalReference": "01010100000750600001",
            "externalReference": "0101010000075060000100001"
        },
        "paymentStatusCategory": "SUCCESSFUL",
        "tokenizationSucceeded": true,
        "tokens": "aa66c3e7-b90b-4604-969e-4d11d0e808ac"
    },
    "status": "PAYMENT_CREATED"
}


Similarly, GET /v1/{merchantId}/payments/{paymentId} will return a response like this:

Expand example response

{
    "id": "000000101010000075060000100001",
    "hostedCheckoutSpecificOutput": {
        "hostedCheckoutId": "063626ad-34dc-71ff-bb57-3f919033eb91"
    },
    "paymentOutput": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "references": {
            "paymentReference": "101000008209"
        },
        "paymentMethod": "redirect",
        "redirectPaymentMethodSpecificOutput": {
            "paymentProductId": 840,
            "paymentProduct840SpecificOutput": {
                "customerAccount": {
                    "accountId": "gcsstag@outlook.com",
                    "billingAgreementId": "B-4KF96505WT315842S",
                    "companyName": "d",
                    "countryCode": "NL",
                    "customerAccountStatus": "verified",
                    "customerAddressStatus": "Confirmed",
                    "firstName": "asd",
                    "payerId": "NKH8H8V2TJP5Q",
                    "surname": "adsf"
                },
                "customerAddress": {
                    "additionalInfo": "15",
                    "city": "MILANO",
                    "countryCode": "IT",
                    "state": "MI",
                    "street": "VIA FRANCESCO SOAVE",
                    "zip": "20136"
                }
            },
            "token": "aa66c3e7-b90b-4604-969e-4d11d0e808ac"
        }
    },
    "status": "CAPTURED",
    "statusOutput": {
        "isCancellable": false,
        "statusCategory": "COMPLETED",
        "statusCode": 800,
        "statusCodeChangeDateTime": "20221102140451",
        "isAuthorized": true,
        "isRefundable": false
    }
}


As can be seen in above examples, we will also return a token or tokens property, you will need to use the token for future payments, for further information regarding tokenization, please refer to this page.

In order to initiate a subsequent payment in the recurring sequence, you need to perform a POST /v1/{merchantId}/payments API call with the token.

This is an example payload using a token, the redirectionData object is no longer necessary as the customer is not present and thus, does not need to be redirected.:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "token": "aa66c3e7-b90b-4604-969e-4d11d0e808ac",
        "isRecurring": true,
        "recurringPaymentSequenceIndicator": "recurring"
    }
}

In this case, the response to the POST /v1/{merchantId}/payments API call will not show a pending status and there will not be a merchantAction object either:


{
    "creationOutput": {
        "additionalReference": "01010100000750900002",
        "externalReference": "0101010000075090000200001"
    },
    "payment": {
        "id": "000000101010000075090000200001",
        "paymentOutput": {
            "amountOfMoney": {
                "amount": 100,
                "currencyCode": "SEK"
            },
            "references": {
                "paymentReference": "101000008239"
            },
            "paymentMethod": "redirect",
            "redirectPaymentMethodSpecificOutput": {
                "paymentProductId": 840,
                "paymentProduct840SpecificOutput": {
                    "customerAccount": {
                        "surname": "NONAME"
                    },
                    "customerAddress": {}
                },
                "token": "aa66c3e7-b90b-4604-969e-4d11d0e808ac"
            }
        },
        "status": "CAPTURED",
        "statusOutput": {
            "isCancellable": false,
            "statusCategory": "COMPLETED",
            "statusCode": 800,
            "statusCodeChangeDateTime": "20221102141818",
            "isAuthorized": true,
            "isRefundable": false
        }
    }
}
Express Checkout

If you wish to offer the customers to option to not have to go through your full checkout and enter their data manually, and instead use the details from their PayPal account, you can use the Express Checkout feature.

You will need to add a paymentProduct840SpecificInput object containing a isShortcut property in the redirectPaymentMethodSpecificInput object.

An example of the POST /v1/{merchantId}/payments payload:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "paymentProduct840SpecificInput": {
            "isShortcut": true
        },
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

The difference starts after the customer finalizes their actions on the PayPal website.

Either through GET /v1/{merchantId}/payments/{paymentId} or Webhooks, you will see that the status moves to PENDING_COMPLETION if the customer successfully finished paying:


{
    "id": "000000101010000075110000100001",
    "paymentOutput": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "references": {
            "paymentReference": "101000008259"
        },
        "paymentMethod": "redirect",
        "redirectPaymentMethodSpecificOutput": {
            "paymentProductId": 840,
            "paymentProduct840SpecificOutput": {
                "customerAccount": {
                    "accountId": "gcsstag@outlook.com",
                    "companyName": "d",
                    "countryCode": "NL",
                    "customerAccountStatus": "verified",
                    "customerAddressStatus": "Confirmed",
                    "firstName": "asd",
                    "payerId": "NKH8H8V2TJP5Q",
                    "surname": "adsf"
                },
                "customerAddress": {
                    "additionalInfo": "15",
                    "city": "MILANO",
                    "countryCode": "IT",
                    "state": "MI",
                    "street": "VIA FRANCESCO SOAVE",
                    "zip": "20136"
                }
            }
        }
    },
    "status": "PENDING_COMPLETION",
    "statusOutput": {
        "isCancellable": true,
        "statusCategory": "PENDING_MERCHANT",
        "statusCode": 70,
        "statusCodeChangeDateTime": "20221102143307",
        "isAuthorized": false,
        "isRefundable": false
    }
}

These are the customer details that are returned by PayPal.

At this point, the payment will stay at this status until you are ready to charge the customer. To do that, you need to submit the POST /v1/{merchantId}/payments/{paymentId}/complete API call.

Invoice ID

Whenever a customer finishes a PayPal payment, they will receive an email with a few details regarding the transaction, one of those is the Invoice ID. This can be customized by you.

To specify a custom Invoice ID, you need to submit a references object with an invoiceData object which contains an invoiceNumber property. This references object needs to be placed within the order object, this applies to both the POST /v1/{merchantId}/hostedcheckouts and POST /v1/{merchantId}/payments API calls, as example:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        },
        "references": {
            "invoiceData": {
                "invoiceNumber": 744349993
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

If you do not submit this, we will generate a random string to use instead.

Pre-authorization

The Pre-authorization feature allows you to (either through the API or via configuration) choose when to capture. In order to be able to do this, you need to submit another property, namely the requiresApproval property.

You can also contact us to make this a fixed setting so that you do not need to send requiresApproval in the request.

If you do choose to send it in the request, it should look like this:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "requiresApproval": true,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

After the customer finishes the payment, GET /v1/{merchantId}/payments/{paymentId} will return a response like this:

Expand example response

{
    "id": "000000101010000075150000100001",
    "paymentOutput": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "references": {
            "paymentReference": "101000008299"
        },
        "paymentMethod": "redirect",
        "redirectPaymentMethodSpecificOutput": {
            "paymentProductId": 840,
            "paymentProduct840SpecificOutput": {
                "customerAccount": {
                    "accountId": "gcsstag@outlook.com",
                    "companyName": "d",
                    "countryCode": "NL",
                    "customerAccountStatus": "verified",
                    "customerAddressStatus": "Confirmed",
                    "firstName": "asd",
                    "payerId": "NKH8H8V2TJP5Q",
                    "surname": "adsf"
                },
                "customerAddress": {
                    "additionalInfo": "15",
                    "city": "MILANO",
                    "countryCode": "IT",
                    "state": "MI",
                    "street": "VIA FRANCESCO SOAVE",
                    "zip": "20136"
                }
            }
        }
    },
    "status": "PENDING_APPROVAL",
    "statusOutput": {
        "isCancellable": true,
        "statusCategory": "PENDING_MERCHANT",
        "statusCode": 600,
        "statusCodeChangeDateTime": "20221102160445",
        "isAuthorized": true,
        "isRefundable": false
    }
}


And here is how the equivalent GET /v1/{merchantId}/hostedcheckouts/{hostedCheckoutId}:

Expand example response

{
    "createdPaymentOutput": {
        "payment": {
            "id": "000000101010000075160000100001",
            "hostedCheckoutSpecificOutput": {
                "hostedCheckoutId": "06362876-270e-71ff-8f2a-8dbfda4ebb12"
            },
            "paymentOutput": {
                "amountOfMoney": {
                    "amount": 100,
                    "currencyCode": "SEK"
                },
                "references": {
                    "paymentReference": "101000008309"
                },
                "paymentMethod": "redirect",
                "redirectPaymentMethodSpecificOutput": {
                    "paymentProductId": 840,
                    "paymentProduct840SpecificOutput": {
                        "customerAccount": {
                            "accountId": "gcsstag@outlook.com",
                            "companyName": "d",
                            "countryCode": "NL",
                            "customerAccountStatus": "verified",
                            "customerAddressStatus": "Confirmed",
                            "firstName": "asd",
                            "payerId": "NKH8H8V2TJP5Q",
                            "surname": "adsf"
                        },
                        "customerAddress": {
                            "additionalInfo": "15",
                            "city": "MILANO",
                            "countryCode": "IT",
                            "state": "MI",
                            "street": "VIA FRANCESCO SOAVE",
                            "zip": "20136"
                        }
                    }
                }
            },
            "status": "PENDING_APPROVAL",
            "statusOutput": {
                "isCancellable": true,
                "statusCategory": "PENDING_MERCHANT",
                "statusCode": 600,
                "statusCodeChangeDateTime": "20221102160635",
                "isAuthorized": true,
                "isRefundable": false
            }
        },
        "paymentCreationReferences": {
            "additionalReference": "00000010101000007516",
            "externalReference": "000000101010000075160000100001"
        },
        "paymentStatusCategory": "SUCCESSFUL"
    },
    "status": "PAYMENT_CREATED"
}


As can be seen above, the status will be changed to PENDING_APPROVAL (as opposed to CAPTURED which is the usual status of a successful PayPal payment) which indicates that it is waiting for your approval to continue.

In order to instruct us to perform the capture, you need to send the approval with the POST /v1/{merchantId}/payments/{paymentId}/approve API call.

This API call is also used to modify the amount to be captured, in order to set an amount, simply submit the amount property with any value lower than the original authorization amount.

The payload should look like this:


{
    "amount": 50
}

After we receive your approval to capture, we will proceed with the transaction after which the status will change to CAPTURED.

Shopping Cart

Just like when you use our checkout, you can also show an order overview on PayPal’s website.

Depending on which properties you submit, a different style of overview will be displayed to the customer.

If you do not send any order overview related properties, we will simply show the Merchant ID and Order ID.

The merchantReference will be displayed if you submit one. The merchantReference property needs to be send within the references object if you choose to use it.

If you submit this:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        },
         "references": {
            "merchantReference": "A Shirt"
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "requiresApproval": true,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

It will show this to the customer:

You can further enrich this by submitting various Shopping Cart related properties.

For example, you can add a break down of amounts by submitting this:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        },
         "references": {
            "merchantReference": "A Shirt"
        },
        "shoppingCart": {
            "amountBreakdown": [
                {
                    "amount": 8,
                    "type": "HANDLING"
                },
                {
                    "amount": 40,
                    "type": "SHIPPING"
                },
                {
                    "amount": 2,
                    "type": "TAX"
                }
            ]
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "requiresApproval": true,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

Which will show this break down to the customer:

While you can submit all the type values in the amountBreakdown array as mentioned in the usage guide, only HANDLING, SHIPPING, and TAX are used for PayPal.

Lastly, if you submit objects in the items array, this will replace the merchantReference mentioned earlier:


{
    "order": {
        "amountOfMoney": {
            "amount": 100,
            "currencyCode": "SEK"
        },
        "customer": {
            "billingAddress": {
                "countryCode": "NL"
            }
        },
        "references": {
            "merchantReference": "Clothing Order #1"
        },
        "shoppingCart": {
            "amountBreakdown": [
                {
                    "amount": 8,
                    "type": "HANDLING"
                },
                {
                    "amount": 40,
                    "type": "SHIPPING"
                },
                {
                    "amount": 2,
                    "type": "TAX"
                }
            ],
            "items": [
                {
                    "amountOfMoney": {
                        "amount": 25,
                        "currencyCode": "SEK"
                    },
                    "invoiceData": {
                        "nrOfItems": 1,
                        "pricePerItem": 25,
                        "description": "A Shirt",
                        "merchantLinenumber": 1,
                        "merchantPagenumber": 1
                    }
                },
                {
                    "amountOfMoney": {
                        "amount": 25,
                        "currencyCode": "SEK"
                    },
                    "invoiceData": {
                        "nrOfItems": 1,
                        "pricePerItem": 25,
                        "description": "A Jacket",
                        "merchantLinenumber": 2,
                        "merchantPagenumber": 1
                    }
                }
            ]
        }
    },
    "redirectPaymentMethodSpecificInput": {
        "paymentProductId": 840,
        "requiresApproval": true,
        "redirectionData": {
            "returnUrl": "https://example.org/return"
        }
    }
}

This will display the following to the customer:

Refunds and Cancellations

If you wish to cancel a payment, you have 2 opportunities to do so; before the capture and after the capture, depending on the situation, you need to send a separate API call.

The first one we will cover is POST /v1/{merchantId}/payments/{paymentId}/cancel.

This can be only be performed when the status is PENDING_APPROVAL and statusOutput.isCancellable is true

Next is the POST /v1/{merchantId}/payments/{paymentId}/refund API call, this is only possible if status is PAID.

You may refund any amount equal or lower to the captured amount, and may do this up till the total captured amount has been refunded.

A basic refund payload only requires the amountOfMoney object specifying the amount and currencyCode:


{
    "amountOfMoney": {
        "amount": 25,
        "currencyCode": "SEK"
    }
}

If you wish to see the details of your refund, you may use the GET /v1/{merchantId}/refunds/{refundId} API call.

Next Process flows