alt

Important information

The API reference is now available here.
The deprecated API reference is available here.

Unzer

Integrate using Link Pay Page

Accept payments through a customizable, ready-made Link Pay page hosted on your server.

Overview

Link Pay is an all-in-one solution that displays the configured payment methods on a Unzer-hosted webpage. You do not have to manually implement individual payment methods on your website. Instead, you only need to call Unzer API once and create a common URL (unlike unique URL created via Hosted Payment Page) that you will use to redirect your users to finalize their payments.

icon
The link is usually not created by visiting a webpage. Paylinks are mostly sent in mails on invoice to pay for something afterwards.

User interface

Depending on your requirements, you can render the Link Pay UI in different ways.

If you have a basket with various items, it is displayed with a list of all your configured payment methods on the right hand side. You can also choose not to display any basket items at all and only render the payment method list. These two options are identical to the Hosted Payment Page.

In addition, you will have an option to show a box containing amount and currency input fields. These fields can (but don’t have to) be editable by the end users. The box will be visible only in case amount or currency values are not passed when creating an instance of Link Pay.

All these options are fully responsive on tablets and phones.

Different scenarios for using Link Pay:

  • Use Link Pay with a fixed amount if the customer should pay a fixed amount. You can also provide basket information to show what the customer is purchasing. Alternatively, you can also skip the amount. In this case the customer has to enter the amount themselves.
  • Specify the orderId or invoiceId if you want the customer to enter an order ID or invoice ID so that you can clearly assign the payment to the order of one customer.
  • You can also specify an alias. The alias is also used within the URL. This is good in case you want to provide the customer a human readable link. For example, here is the view of a Link Pay page with amount and currency box:

Link Pay page

Before you begin

Check the basic integration requirements.

How it works

  1. First, you need to set up the Link pay page – create customer and basket resources.
  2. Now initialize the Link pay page on the server side by making a Link Pay POST request to the Unzer API that returns a Link Pay URL.
  3. Once you have the URL, you can send your customers to this link where they will be able to finalize a purchase.
    • With basketId When the basket exists, the customer can verify the list of items in the basket that they are buying. The basket is rendered on the left side of the page.
    • Without basketId and amount or currency When the basket does not exist, and either amount or currency are not set when making a POST/PUT request, the users will see the amount and currency box, and will be able to add the values themselves.
  4. The customer makes the payment using this link.
  5. After the payment is made you should check its status on the server side and display the result to the customer on the client side.
  6. You can perform more operations on the server side once the payment has been made – most common example would be cancelling the payment.

Once your customer gets redirected to the Link Pay Page, there are a few possible cases:

icon info
In case one of the two key has a pre-set value, but the other does not, the input field with the set value (either amount or currency) will be disabled, and the end-user will not be able to change its value.
icon info
The URL created is not unique and has an expiration date, which you set when creating the instance of Link Pay (you can also choose that the link never expires). In contrast, the URL for the Hosted Payment Page can be used by a specific customer only and expires after the payment is made.

Another difference between Link Pay and Hosted or Embedded Payment Pages is that there are no keys required when initializing a Link Pay page.

First, you should prepare resources needed when initializing the Link Pay page on the server side—customer, basket (recommended), and the metadata (optional) resources.

The customer resource contains information about the customer and is required for card, Unzer Invoice, Direct Debit Secured, Unzer Installment, and Klarna payment methods.

The customer resource is also required for the deprecated payment methods.

icon
  • When you provide a customerId when crating the link, you should only send the link to the customer that was specified when creating the linkpay resource.
  • We recommend that you always provide the customer resource.

To use an existing customer resource, you need its corresponding customerId. If you don’t have an existing customer resource, you can create it on the server side.

icon
Requests to the API must be authenticated using your public or private key. For more details, see Authentication.
POST https://api.unzer.com/v1/customers

{
  "lastname": "Mustermann",
  "firstname": "Max",
  "salutation": "mr",
  "customerId": "51222",
  "birthDate": "1970-01-01",
  "email": "info@unzer.com",
  "phone": "+49 6221 - 64 71 100",
  "mobile": "+49 172 123 456",
  "billingAddress": {
    "name": "Max Mustermann",
    "street": "Vangerowstr. 18",
    "zip": "69115",
    "city": "Heidelberg",
    "country": "DE"
  },
  "shippingAddress": {
    "name": "Max Mustermann",
    "street": "Vangerowstr. 18",
    "zip": "69115",
    "city": "Heidelberg",
    "country": "DE"
  }
}
Linkpay currently not supported.
Address address = new Address();
address
  .setName("Max Mustermann")
  .setStreet("Vangerowstr. 18")
  .setCity("Heidelberg")
  .setZip("69115")
  .setCountry("DE");
      
Customer customer = new Customer("Max", "Mustermann");
customer
  .setCustomerId(customerId)
  .setSalutation(Salutation.mr)
  .setEmail("max.mustermann@unzer.com")
  .setMobile("+49123456789")
  .setBirthDate(getDate("12.12.2000"))
  .setBillingAddress(address)
  .setShippingAddress(address);

Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
customer = unzer.createCustomer(customer);
icon info
For Unzer Direct debit, Direct Debit Secured, and Unzer Invoice, if there is no existing customer resource available, built-in customer forms are displayed on the Link Pay page.

If you want to pass a customerId to your Link Pay page, add it to the resources object within the request body:

The basketId contains all the product information relevant to the transaction. It is required for Unzer Invoice, Direct Debit Secured, Unzer Installment, and Klarna . We recommend that you always create a basket resource.

icon info
Note that you must send the basket resource with the with the payment request.
POST https://api.unzer.com/v1/baskets

{
  "amountTotalGross" : 200.00,
  "amountTotalDiscount" : 10.00,
  "amountTotalVat" : 33.33,
  "currencyCode" : "EUR",
  "orderId" : "Order-12345",
  "note" : "Test Basket",
  "basketItems" : [ {
    "basketItemReferenceId" : "Item-d030efbd4963",
    "unit" : "m",
    "quantity" : 10,
    "amountDiscount" : 10.00,
    "vat" : 0.2,
    "amountGross" : 200.00,
    "amountVat" : 33.33,
    "amountPerUnit" : 16.667,
    "amountNet" : 166.67,
    "title" : "SDM 6 CABLE",
    "subTitle" : "This is brand new Mid 2019 version",
    "imageUrl" : "https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg",
    "type": "goods"
  } ]
}
Linkpay currently not supported.
BasketItem basketItem = new BasketItem()
        .setBasketItemReferenceId("Item-d030efbd4963")
        .setQuantity(BigDecimal.valueOf(10))
        .setUnit("m")
        .setAmountPerUnitGross(BigDecimal.valueOf(20.00))
        .setAmountDiscountPerUnitGross(BigDecimal.valueOf(1.00))
        .setVat(BigDecimal.valueOf(19.0))
        .setTitle("SDM 6 CABLE")
        .setSubTitle("This is brand new Mid 2019 version")
        .setImageUrl(new URL("https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg"))
        .setType(BasketItem.Type.GOODS);

Basket basket  = new Basket()
        .setTotalValueGross(BigDecimal.valueOf(190.00))
        .setCurrencyCode(Currency.getInstance("EUR"))
        .setOrderId("Order-12345")
        .setNote("Test Basket")
        .addBasketItem(basketItem);

Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
unzer.createBasket(basket);

Once you have the basketId, you can pass it to the Link Pay request body.

For a full description of basket resource, check the relevant server-side-integration documentation page: Manage basket (direct API calls), Manage basket (PHP SDK), Manage basket (Java SDK).

If chose to pass a basketId to Link Pay, add it to the resources object within the request body:

{
...
"resources": {
  "basketId": "s-bsk-1"
}
...
}

(Optional) Create metadata

Metadata is the additional information you can append to each payment. By adding metadata, you can store important information about the order or the payment. You can append additional information for each payment. Add the metadata by adding it in the additional resources.

{
...
"resources": {
  "basketId": "s-bsk-1",
  "customerId": "s-cst-1",
  "metadataId": "s-mtd-1",
},
...
}

You can initialize the Link Pay page to support either charge or authorize transactions. For a description of charge and authorize transactions, refer to relevant server-side integration documentation page: Manage API resources (direct API calls), Manage API resources (PHP SDK), Manage API resources (Java SDK).

POST - https://api.unzer.com/v1/linkpay/charge

Request body:
{
  "amount": "100",
  "alias": "unique-alias",
  "currency": "EUR",
  "returnUrl": "https://www.unzer.com",
  "expires": "2200-10-20",
  "card3ds": "true",
  "billingAddressRequired": "false",
  "shippingAddressRequired": "false",
  "orderIdRequired":"false",
  "invoiceIdRequired":"false",
  "fullPageImage": "https://www.any.ed/photos/302743/pexels-photo-302743.jpeg",
  "shopDescription": "Your purchase",
  "logoImage": "https://insights.unzer.com/static/unzerLogo.svg",
  "tagline": "Established 1862",
  "shopName": "Company XYZ",
  "helpUrl": "https://www.unzer.com",
  "contactUrl": "https://www.unzer.com",
  "termsAndConditionUrl": "https://www.unzer.com",
  "privacyPolicyUrl": "https://www.unzer.com",
  "imprintUrl": "https://www.unzer.com",
  "intention": "Checkout",
  "additionalAttributes": {
    "exemptionType": "lvp"
  },
  "resources": {
    "customerId": "s-cst-1",
    "basketId": "s-bsk-1",
    "metadataId": "s-mtd-1"
  }
}
Linkpay currently not supported.

// Currently only available for charge.
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
Linkpay linkpay = new Linkpay();

linkpay.setAmount("100");
linkpay.setAlias("unique-alias");
linkpay.setCurrency("EUR");
linkpay.setReturnUrl(unsafeUrl("https://www.unzer.com"));
linkpay.setExpires("2200-10-20");
linkpay.setCard3ds("true");
linkpay.setBillingAddressRequired("false");
linkpay.setShippingAddressRequired("false");
linkpay.setOrderIdRequired("false");
linkpay.setInvoiceIdRequired("false");
linkpay.setFullPageImage(unsafeUrl("https://www.any.ed/photos/302743/pexels-photo-302743.jpeg"));
linkpay.setShopDescription("Your purchase");
linkpay.setLogoImage("http://www.any.ed/images/page/info-img.png");
linkpay.setTagline("Established 1862");
linkpay.setShopName("Company XYZ");
linkpay.setHelpUrl("https://www.unzer.com");
linkpay.setContactUrl("https://www.unzer.com");
linkpay.setTermsAndConditionUrl(unsafeUrl("https://www.unzer.com"));
linkpay.setPrivacyPolicyUrl(unsafeUrl("https://www.any.ed/policy"));
linkpay.setImprintUrl(unsafeUrl("https://www.any.ed/impressum"));

Map<String, String> additionalAttributes = new HashMap<>();
additionalAttributes.put("exemptionType", "lvp");
linkpay.setAdditionalAttributes(additionalAttributes);

linkpay.setCustomerId("s-cst-1");
linkpay.setBasketId("s-bsk-1");
linkpay.setMetadataId("s-mtd-1");

// Initialize the linkpay
linkpay = unzer.linkpay(linkpay);

The response looks similar to the following example:

POST - https://api.unzer.com/v1/linkpay/charge

Request body:
{
  "id": "s-lpy-xyz",
  "redirectUrl": "https://sbx-payment.heidelpay.com/v1/paypage/linkpay/s-lpy-xyz",
  "version": "1",
  "alias": "unique-alias",
  "orderId": "",
  "invoiceId": "",
  "amount": "100",
  "currency": "EUR",
  "returnUrl": "https://www.unzer.com",
  "logoImage": "http://www.any.ed/images/page/info-img.png",
  "shopName": "Company XYZ",
  "shopDescription": "Your purchase",
  "tagline": "Established 1862",
  "css": {},
  "termsAndConditionUrl": "https://www.unzer.com",
  "privacyPolicyUrl": "https://www.unzer.com",
  "imprintUrl": "http://www.any.ed/impressum",
  "helpUrl": "https://www.unzer.com",
  "contactUrl": "https://www.unzer.com",
  "card3ds": "true",
  "billingAddressRequired": "false",
  "shippingAddressRequired": "false",
  "expires": "2200-10-20",
  "intention": "Checkout",
  "paymentReference": "",
  "additionalAttributes": {
      "effectiveInterestRate": "3",
      "exemptionType": "lvp"
  },
  "orderIdRequired":"false",
  "invoiceIdRequired":"false",
  "oneTimeUse": "false",
  "excludeTypes": [],
  "resources": {
      "paymentId": "",
      "customerId": "s-cst-1",
      "basketId": "s-bsk-1",
      "metadataId": "s-mtd-1"
  },
  "action": "CHARGE"
}
icon
  • You need to request a new payment page every time your customer pays. That also includes failed transactions.
  • Each payment page expires after 60 minutes.
  • Each payment page becomes invalid after a successful payment.
  • Each payment page becomes invalid if an unrecoverable error occurs. i.e. payment type creation successful but payment transaction failed.

Set additional attributes

Depending on the use case of your pay page integration, you might need to set the following additionalAttributes:

ParameterDescriptionExample value
effectiveInterestRateFor Unzer Installment you need to provide the effectiveInterestRate parameter in the Authorize call. Positive floating point value allowed."4.99"
exemptionTypeExemption type is used for card payment method. Allowed values: "lvp" . See more Low Value Exemptions"lvp"
disabledCOFAllows disabling COF for defined payment types.

Possible values to be passed as a coma separated string.
"card"

"card, sepa-direct-debit"

icon info
recurrenceType is not supported by Linkpay.

When using the Google Pay payment method, make sure to set required additionalAtributes as listed below.

ParameterTypeDescriptionExample values
googlepay.countryCode

(required)
stringThe countryCode must be set to the one submitted to Merchant upfront in the contract or in a separated email. Currently supported values are CH and DKCH or DK
googlepay.buttonColorstringThe buttonColor might be set to change the color of the buttonwhite

When using the Apple Pay payment method, make sure to set required additionalAtributes as listed below.

ParameterTypeDescriptionExample values
applepay.countryCode

(required)
stringThe merchant’s two-letter ISO 3166 country code. For more information, see countryCode"DE"
applepay.merchantCapabilitiesstringComma separated string of the payment capabilities that the merchant supports, such as credit or debit. For more information, see merchantCapabilities"supports3DS, supportsCredit"

alias

When creating a Link Pay page, you can pass a unique value for the alias key. The value of this key can be used to replace a long ID that you receive by default as the last part of the redirectUrl value. An alias can not be used in combination with orderId or invoiceId.

Using this feature, you can customize the Link Pay URL according to your corporate image requirements.

icon
The value for the alias can only be set during the initial POST call.

expires

You can choose whether you wish your Link Pay instance to expire after a certain time frame. Accepted formats are YYYY-mm-dd or YYYY-mm-dd hh:mm:ss.

If you don’t add any value, your Link Pay instance will never expire.

oneTimeUse

With oneTimeUse you can set the Link Pay instance to only be usable for one payment. After a successful payment Link Pay resource will contain a paymentId as linked resource. You can not set oneTimeUse directly. To create a Link Pay page with oneTimeUse, it is required to set the orderId or invoiceId in your initialization request. The created resource will then have set oneTimeUse to “true”, which can be found in the response.

orderIdRequired

The default value of this property is false. If this property is set as true, users always have to pass orderId in any transaction request (authorize or charge) using the Link Pay. If the orderId is not already defined, an input field is displayed for the customer to add this value themselves.

invoiceIdRequired

The default value of this property is false. If this property is set as true, users always have to pass invoiceId in any transaction request (authorize or charge) via Link Pay. In case invoiceId is not already defined, an input field is displayed for the customer to add this value themselves.

The update option is one of the unique features of Link Pay (on contrary, it is not possible to update an instance of Hosted Payment Page).

This step includes making a PUT request to our API, and sending a JSON object with correct values. You can use your Link Pay page’s ID or alias values for creating a PUT request.

In case all data is valid, the Link Pay instance that you have already created will be updated.

PUT - https://api.unzer.com/v1/linkpay/{{linkpayId}}
// Linkpay can also be updated using {{alias}} instead of {{linkpayId}}

Request body:
{ 
  // request body can contain the same keys as in the POST request
}
Currently not supported.

If you want, you can delete the instance of your Link Pay. To delete, make a DELETE request to our API and pass either a valid ID or alias.

DELETE - https://api.unzer.com/v1/linkpay/{{linkpayId}}
// Linkpay can also be deleted using {{alias}} instead of {{linkpayId}}
Currently not supported.

Optional: Exclude payment methods

If you want to exclude some of the payment methods from the Embedded Payment Page, add the arrayexcludeTypes when initializing on the server side. Put all payment types you want to exclude from the page in an array:

POST https://api.unzer.com/v1/linkpay/{authorize|charge}
Body:
{
  ...
  "excludeTypes": ["paypal", "sepa-direct-debit"],
  ...
}
...
String[] excludeTypes = {"paypal", "sepa-direct-debit"};
linkpay.setExcludeTypes(excludeTypes);
...

For a list of all possible excludeTypes array values, see Payment methods.

After validating the data, the response containing a redirectUrl key is created. Use the redirectUrl to send the customer to the instance of your Link Pay, where they can finalize the payment.

If a redirect payment method is selected, the customer is redirected to the third party payment page, where the payment is finalized. After the customer finalizes the payment, they are redirected back to the returnUrl that you have provided when you created or updated your Link Pay page.

After the redirect, fetch the payment resource using the GET method and handle the order depending on its status, that is redirect to success if it is successful or show a failure message if there was an error.

If any other payment method is selected, the customer is redirected to the returnUrl that you passed. In case you did not pass any value to returnUrl, the user is redirect to the Unzer-hosted success page.

Customization

You can customize the following elements of the Link Pay Page:

  • Images
  • Colors
  • UI text

Customize the images

You can define some of the images that appear on the Link Pay page. To do that, set the following properties when initializing the Link Pay page in Step 2:

  • fullPageImage
  • logoImage

Unlike the Hosted Pay Page, Link Pay cannot be customized by passing URL-encoded parameters (except for language). All customization for Link Pay is done by passing key-value pairs to the css object in the request body.

For each customizable element, you can choose to change its backgroundColor, fontColor and fontSize.

Basket image

If you want to set individual basket images on the Link Pay page, you can do so by specifying the image URL in the imageURL property of each basketItems entity.

Customize the header

To customize the header section, you can choose one of the following:

  • Pass the style values to the options object as the second parameter of the checkout method (in Step 3).
  • Pass a CSS key when initializing payment page on the server side (in Step 2).

For Link Pay, you can choose to pass values for shopDescription, header, shopName, tagline, helpUrl, contactUrl, orderId, invoiceId and backToMerchantLink.

Another way to customize the header section is to pass a CSS object. This option is more flexible and lets you select individual elements. You can pass values for:

  • header
  • tagline
  • shopName

For each element, you can change:

  • backgroundColor
  • fontColor
  • fontSize

To use this option, add the CSS object when initializing payment page on the server side in Step 2:

POST https://api.unzer.com/v1/linkpay/{authorize|charge}
{
  ...
  "css": {
    "shopDescription": "color: blue; font-size: 30px",
    "tagline": "color: yellow; font-size: 10px",
    "header": "background-color: white",
    "shopName": "color: white; font-size: 24px",
    "contactUrl": "color: green; font-size: 10px",
    "helpUrl": "background-color: black",
    "invoiceId": "color: rgb(230, 185, 64)",
    "orderId": "color: rgb(230, 185, 64)",
    "backToMerchantLink": "color: rgb(230, 185, 64)"
  },
  ...
}
...
Map<String, String> cssMap = new HashMap<String, String>();

cssMap.put("shopDescription", "color: blue; font-size: 30px");
cssMap.put("tagline", "color: yellow; font-size: 10px");
cssMap.put("header", "background-color: white");
cssMap.put("shopName", "color: white; font-size: 24px");
cssMap.put("contactUrl", "color: green; font-size: 10px");
cssMap.put("helpUrl", "background-color: black");
cssMap.put("invoiceId", "color: rgb(230, 185, 64)");
cssMap.put("orderId", "color: rgb(230, 185, 64)");
cssMap.put("backToMerchantLink", "color: rgb(230, 185, 64)");

linkpay.setCss(cssMap);
...
icon
  • When creating CSS that you send to the backend, use vanilla CSS with camel cased key names.
  • If you send several values for an individual element, separate these values with a semicolon ;.
  • We recommend testing the UI changes for all device sizes, especially when passing font-size values.
  • When you pass styles for the same element through the checkout method and the CSS object, the latter takes precedence.
icon info
Backend CSS customization
The CSS sent to the backend should look exactly the same as when writing vanilla CSS (except for the names of the keys, which follow camel case naming convention). If you choose to send more than one value for an individual element, you will have to separate the values with a colon ;.

Manage payment

After you have made a transaction, you can perform additional operations on it. A common example is the cancel operation which is applicable for most of the payment methods.

Cancel before money receipt (reversal)

To reduce or cancel a reservation on the customer account you need to perform a cancel on the initial transaction. An example of reversal would be unblocking reserved amount on customer account after they returned a rented car.

POST https://api.unzer.com/v1/payments/s-pay-1/authorize/cancels

{
  "amount" : "100.00"
}
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
Authorization authorization = unzer.fetchAuthorization('s-pay-1');
Cancel cancel = authorization.cancel();
POST https://api.unzer.com/v1/payments/s-pay-1/authorize/cancels

{
  "amount" : "100.00"
}

Cancel after money receipt (refund)

To refund a payment you need to perform a cancel on a successful charge transaction. This transfers the money back to the customer.

POST https://api.unzer.com/v1/payments/s-pay-1/charges/s-chg-1/cancels
{
  "amount" : "12.450",
  "paymentReference": "Test cancel transaction"
}
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
Cancel cancel = unzer.cancelCharge("s-pay-1", "s-chg-1");
{
    "id": "s-cnl-1",
    "isSuccess": true,
    "isPending": false,
    "isError": false,
    "message": {
        "code": "COR.000.100.112",
        "merchant": "Request successfully processed in 'Merchant in Connector Test Mode'",
        "customer": "Your payments have been successfully processed in sandbox mode."
    },
    "amount": "12.450",
    "currency": "EUR",
    "date": "2021-06-10 10:42:31",
    "resources": {
        "customerId": "",
        "paymentId": "s-pay-1",
        "basketId": "",
        "metadataId": "",
        "linkPayId": "",
        "traceId": "980df34e485a2dac0019e998b1b044cb",
        "typeId": "s-sdd-ixdcookaqpzu"
    },
    "paymentReference": "",
    "processing": {
        "uniqueId": "31HA07BC8174FCB9564040C4B8564729",
        "shortId": "4872.4815.1981",
        "traceId": "980df34e485a2dac0019e998b1b044cb"
    }
}

To learn about payment management for specific payment methods, go to the relevant payment method page.

To learn about payment management for specific payment methods, go to the relevant payment method page.

<h2 id="error-handling">Error handling</h2>

All requests to the API can result in an error that should be handled. Refer to the Error handling guide to learn more about Unzer API (and other) errors and handling them.

<h2 id="test--go-live">Test &amp; go live</h2>

You should always test your integration before going live. First perform test transactions using test data. Next, check against Integration checklist and Go-live checklist to make sure the integration is complete and you’re ready to go live.

See also