alt

Important information

There was an update of Unzer TLS/SSL certificates. Learn more

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.

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 user will be able to double-check the list of items in the basket that he/she is purchasing. The basket box will be rendered on the left side of the page.
    • Without basketId and amount or currency When the basket does not exists, 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 and basket resource (recommended) as well as metadata resource (optional).

The customer resource contains information about the customer and is required by card payment method as well as Unzer Invoice, Unzer Direct Debit Secured and Unzer Installment.

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"
  }
}
$address = (new Address())
            ->setName('Max Mustermann')
            ->setStreet('Vangerowstr. 18')
            ->setZip('69115')
            ->setCity('Heidelberg')
            ->setCountry('DE');

$customer = (new Customer())
            ->setFirstname('Max')
            ->setLastname('Mustermann')
            ->setSalutation(Salutations::MR)
            ->setCompany('Unzer GmbH')
            ->setBirthDate('1972-12-24')
            ->setEmail('Max.Mustermann@unzer.com')
            ->setMobile('+49 123456789')
            ->setPhone('+49 123456789')
            ->setBillingAddress($address)
            ->setShippingAddress($address);

$unzer = new Unzer('s-priv-xxxxxxxxxx');
$unzer->createCustomer($customer);
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, Unzer Direct Debit Secured, and Unzer Invoice Secured, 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, Unzer Direct Debit Secured and Unzer Installment. We recommend that you always create a basket resource.

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"
  } ]
}
$basketItem = (new BasketItem())
    ->setBasketItemReferenceId('Item-d030efbd4963')
    ->setQuantity(10)
    ->setUnit('m')
    ->setAmountPerUnitGross(20.00)
    ->setAmountDiscountPerUnitGross(1.00)
    ->setVat(19.0)
    ->setTitle('SDM 6 CABLE')
    ->setSubTitle('This is brand new Mid 2019 version')
    ->setImageUrl('https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg')
    ->setType(BasketItemTypes::GOODS);

$basket  = (new Basket())
    ->setTotalValueGross(190.00)
    ->setCurrencyCode('EUR')
    ->setOrderId('Order-12345')
    ->setNote('Test Basket')
    ->addBasketItem($basketItem);

$unzer = new Unzer('s-priv-xxxxxxxxxx');
$unzer->createBasket($basket);
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",
},
...
}

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

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.

POST - https://api.unzer.com/v1/linkpay/charge
// Link Pay can also be initialized using /authorize call

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",
  // other info
  "fullPageImage": "https://www.any.ed/photos/302743/pexels-photo-302743.jpeg",
  "shopDescription": "Your purchase",
  // header
  "logoImage": "http://www.any.ed/images/page/info-img.png",
  "tagline": "Established 1862",
  "shopName": "Company XYZ",
  "helpUrl": "http://www.any.ed/help",
  "contactUrl": "http://www.any.ed/contact",
  // footer
  "termsAndConditionUrl": "https://www.the-alley.vn/",
  "privacyPolicyUrl": "http://www.any.ed/policy",
  "impressumUrl": "http://www.any.ed/impressum",
  // customization (button text)
  "intention": "Checkout",
  // resources
  "resources": {
    "customerId": "s-cst-1",
    "basketId": "s-bsk-1",
    "metadataId": "s-mtd-1"
  }
}

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.

This feature can make the Link Pay URL shorter and customizable, following your needs and/or corporate image.

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

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.

OrderId (required)

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.

InvoiceId (required)

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
}

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}}

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

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 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.

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"],
  ...
}
...
$linkpay->setExcludeType(['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.

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:

{
...
"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)"
},
...
}
POST https://api.unzer.com/v1/linkpay/{authorize|charge}

{
  ...
    "css": {
      "shopName": "color: #fff; font-size: 24px",
      "tagline": "color: green; font-size: 10px"
    },
  ...
}
...
$styles = [
  'shopName' => 'color: #fff; font-size: 24px',
  'tagline' => 'color: green; font-size: 10px',
];
$linkpay->->setCss($styles);
...
...
Map<String, String> cssMap = new HashMap<String, String>();
cssMap.put("tagline", "color: blue; font-size: 30px");
cssMap.put("shopName", "color: blue; font-size: 30px");

linkpay.setCss(cssMap);
...
icon
  • When creating CSS that you send to the backend, use vanilla CSS with camelCase in the names of the keys.
  • 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 camelCase 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 = new Unzer('s-priv-xxxxxxxxxx');
$payment = $unzer->fetchPayment('s-pay-1');
$unzer->cancelAuthorizationByPayment($payment, 100.00);
Unzer unzer = new Unzer("s-priv-xxxxxxxxxx");
Authorization authorization = unzer.fetchAuthorization('s-pay-1');
Cancel cancel = authorization.cancel();
{
  "id": "s-cnl-1",
  "isSuccess": true,
  "isPending": false,
  "isError": false,
  "card3ds": 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": "100.0000",
  "currency": "EUR",
  "date": "2021-06-10 10:47:43",
  "resources": {
    "customerId": "",
    "paymentId": "s-pay-1",
    "basketId": "",
    "metadataId": "",
    "payPageId": "",
    "traceId": "d9763d2fdd7830bdd73f76957423f351",
    "typeId": "s-crd-e6f2yo8ggwhg"
  },
  "paymentReference": "",
  "processing": {
    "uniqueId": "31HA07BC8174FCB9564077FB19AEF03B",
    "shortId": "4872.4846.3345",
    "traceId": "d9763d2fdd7830bdd73f76957423f351"
  }
}

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 = new Unzer('s-priv-xxxxxxxxxx');
$charge = $unzer->fetchChargeById('s-pay-1', 's-chg-1');
$cancel = $charge->cancel();
Unzer unzer = new Unzer(new HttpClientBasedRestCommunication(), "s-priv-xxxxxxxxxx");
Charge charge = unzer.fetchChargeById("s-pay-1", "s-chg-1");
Cancel cancel = charge.cancel();

The response will look similar to the following example:

{
  "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.

Error handling

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.

Test & go live

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