alt

Important information

Please be advised that there will be a scheduled downtime across our API network on November 05 and November 07, 2024. For more information, visit our platform status portal.:
- Scheduled maintenance on November 5, 2024
- Scheduled maintenance on November 7, 2024

Unzer

Integrate using LinkPay Page (v2)

Beta

Accept payments by seamlessly integrating a LinkPay page for sending a payment link, messenger payment, or in-store QR code payments.

Overview

LinkPay 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 link with a defined validity (unlike unique URL created via Hosted Payment Page) that you will use to redirect your customers to finalize their payments.

Depending on the use case, this can be an email link, a messenger payment, or in-store QR code payment.

icon
The link is usually not created by visiting a webpage. Pay links are mostly sent in mails for invoice to pay for goods or services afterwards.

Using LinkPay Payment Page, you can support multiple payment methods with one simple integration.

User interface

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

If you have a basket with various items, it is displayed on the right side of the list of all your configured payment methods.

LinkPay page

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.

LinkPay page

In addition, you will have an option to display a box containing the amount input field. This field can be edited by the end users. The box is displayed only when the amount is not passed and amountSettings object is passed instead when creating an instance of LinkPay. This use case is used for example for donations. For more details, go to use cases.

LinkPay page

All these options are fully responsive on tablets and phones.

Use cases

Different scenarios for using LinkPay:

  • Single-use fixed amount: An example for single-use fixed amount is invoice payments for goods and services that the customer purchased. A link with the dedicated amount/currency can be created and sent out to the customer. The customer has to only follow the link and initiate the payment. The merchant will be notified about the payment status via the webhooks.

You can specify several attributes for multiuse which are described below.

AttributeDescription
shopnameDefines the name of the shop which is visible in the payment page.
orderIdThe order ID for the payment.
invoiceIdThe invoice ID for the payment.
paymentReferenceThe payment reference will be displayed in the bank statement.
expiresAtThe time stamp when the link expires. The format must be YYYY-MM-DDTHH:MM:SS.SSSZ, example: 2024-11-30T08:41:39.916Z
If the expiresAt is not defined, the default validity of 7 days is applicable.
  • Multiple-use variable amount: For donations and such other use cases where the amount is not fixed, you can use the multiple use functionality from LinkPay. Therefore, you have to set the flag multiUse to true. You can specify several attributes for multiuse which are described below.
AttributeDescription
aliasThe alias is also used within the URL in case you want to provide the customer a human-readable link. For example, the following is the view of a LinkPay page with amount box.
multiuseThis must be set to true if the multiuse of the link is required, for example, donations.
amountSettingsThis allows you to set a minimum and a maximum amount for multiuse payment links.
expiresAtThe time stamp when the link expires. The format must be YYYY-MM-DDTHH:MM:SS.SSSZ, example: 2024-11-30T08:41:39.916Z
If the expiresAt is not defined, the default validity of 7 days is applicable.

The orderId and invoiceID can’t be used for multiuse payments.

Read this guide for a general overview on how to accept payments with LinkPay Page. For a list of all payment methods supported by LinkPay Page, go to Supported Payment methods.

Before you begin

Check the basic integration requirements

How it works

To integrate payments using LinkPay, you need to perform steps on both client and server side.

  1. First, you need to set up the LinkPay page – create customer and basket resources.
  2. Now initialize the LinkPay page on the server side by making a LinkPay POST request to the Unzer API that returns a LinkPay 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 right 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 customers will see the amount box, and will be able to add the value themselves.
    • With the customerID, all the details from the customer are displayed. For example, in-store payments.
  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.

Step 1: Set up the payment page
server side

First, you should prepare resources required when initializing the payment page on the server side – customer (recommended), basket (recommended), and the metadata resource (optional).

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

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

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": "Schöneberger Str. 21a",
    "zip": "10963",
    "city": "Berlin",
    "country": "DE"
  },
  "shippingAddress": {
    "name": "Max Mustermann",
    "street": "Schöneberger Str. 21a",
    "zip": "10963",
    "city": "Berlin",
    "country": "DE"
  }
}
LinkPay is currently not supported.
Address address = new Address();
address
  .setName("Max Mustermann")
  .setStreet("Schöneberger Str. 21a")
  .setCity("Berlin")
  .setZip("10963")
  .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);

Payment types which require customer resource will not be available if neither customer ID nor customer form is provided (for example, payment page is set to payment_only).

For a full description of customer resource, please refer to relevant server-side integration documentation page: Manage customer (direct API calls), Manage customer (PHP SDK), Manage customer (Java SDK).

The basket resource stores information about the purchased products, used vouchers, and shipment costs. It is required for Unzer Invoice, Direct Debit Secured, and Klarna payment methods. We recommend that you always create a basket resource.

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

{
  "totalValueGross": 190.0,
  "currencyCode": "EUR",
  "note": "Test Basket",
  "orderId": "Order-12345",
  "basketItems": [
    {
      "amountDiscountPerUnitGross": 1.0,
      "amountPerUnitGross": 20.0,
      "basketItemReferenceId": "Item-d030efbd4963",
      "imageUrl": "https://a.storyblok.com/f/91629/x/1ba8deb8cc/unzer_primarylogo__white_rgb.svg",
      "quantity": 10,
      "subTitle": "This is brand new Mid 2019 version",
      "title": "SDM 6 CABLE",
      "type": "goods",
      "unit": "m",
      "vat": 19.0
    }
  ]
}
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);

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

(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. Please refer to the following page for more information: Metadata.

Step 2: Create the payment page
server side

Now you can combine the resources with the data about the transaction and payment page configuration options to make an initialization call for the payment page. However, before you initialize the Payment Page, you need to issue a new bearer token for authentication against the Payment Page API.

Issue a new bearer token for authentication

As long as a token is valid, it can be used multiple times for calls to Payment Page API.

To keep the token authentication mechanism safe and secure, there are some measures that need to be taken into account:

  1. A requested token is valid for 7 minutes‚ after which it expires, and you need to request a new one.
  2. There is a rate limit in place that allows 2 token creations per second.
icon
If you are using one of our SDKs, the token handling is done automatically as long as you are reusing the Unzer instance.

Authorization: Basic auth with your merchant private key.

GET https://token.upcgw.com/v1/auth/token

{
  "accessToken": "eyJraWQiOiJhbGlhcy9jb25uZWN0aXZpdHktdjItdG9rZW4ta21zIiwiYWxnIjoiUlMyNTY..."
}

To learn more, go to the Authentication page.

Initialize a new Payment Page

You can initialize the payment page to support either charge or authorize transactions. For a more detailed 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).

Some payment methods support Two-step payments (both authorize and charge) transactions. For these payment methods, you can choose the transaction type during the payment page creation.

However, some payment methods only support One-step payments (charge). In such a case if the payment page is called with type authorize (Two-step flow), the One-Step payment methods will be displayed as well. A charge will be automatically executed for the One-Step only payment methods if one of these is selected for payment.

To learn more about which payment methods support One-step or Two-step flows, go to Support payment methods.

You need to save the paypageId contained in the create paypage response. The paypageId will be required to open the LinkPay Payment Page and to check the payment status later.

To create an LinkPay Payment Page, in the create payment request, set the type flag linkpay.

{
  "mode": "charge",
  "amount": "84.9000",
  "currency": "EUR",
  "type": "linkpay",
  "checkoutType": "full",
  "paymentMethodsConfigs": {
    "default": {
      "enabled": true
    },
    "twint": {
      "enabled": true,
      "order": 0
    }
  },
  "urls": {
    "returnSuccess": "https://example.com/success",
    "returnPending": "https://example.com/pending",
    "returnFailure": "https://example.com/error",
    "returnCancel": "https://example.com/error"
  },
  "resources": {
    "customerId": "{{customerId}}",
    "basketId": "{{basketId}}",
    "metadataId": "{{metadataId}}"
  }
}
$unzer = new Unzer('s-priv-xxxxxxxxxx');
$paypage = new Paypage(9.99, 'EUR'); // charge as default type.
//or if authorize is preferred:
//$paypage = new Paypage(9.99, 'EUR', 'authorize');

$paypage->setType("linkpay");

//it is recommended to add a customer object.
$customer = $unzer->createCustomer(CustomerFactory::createCustomer('Max', 'Mustermann'));

$resources = new Resources($customer->getId(), null, null);
$paypage->setResources($resources);

$unzer->createPaypage($paypage);
// Redirect to the paypage
redirect($paypage->getRedirectUrl());
Coming Soon!

The response looks similar to the following example:

{
  "paypageId": "01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c",
  "redirectUrl": "https://static-v2.unzer.com/v2/paypage/#/01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c?publicKey=cy1wdWItmed3123MmExMAAAAE41dESE9mQT48kVUM3E=",
  "qrCodeSvg": "PHN2ZyB4bWxucz0naHR0cDovL..."
}

For a complete list of parameters, see the Payment Page Reference.

Optional: LinkPay features

amountSettings

In case you need the amount to be given by the customer (e.g for donations), then you have to send the amountSettings object, with min and max values. In this case amount (and basketId) is not allowed.

{
  "mode": "charge",
  "currency": "EUR",
  "amountSettings": {
    "minimum": 2,
    "maximum": 10
  },
  "type": "linkpay",
  "checkoutType": "full",
  "paymentMethodsConfigs": {
    "default": {
      "enabled": true
    }
  },
  "urls": {
    "returnSuccess": "https://example.com/success",
    "returnPending": "https://example.com/pending",
    "returnFailure": "https://example.com/error",
    "returnCancel": "https://example.com/error"
  },
  "resources": {
  }
}
Coming Soon!
Coming Soon!

The response looks similar to the following example:

{
  "paypageId": "01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c",
  "redirectUrl": "https://static-v2.unzer.com/v2/paypage/#/01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c?publicKey=cy1wdWItmed3123MmExMAAAAE41dESE9mQT48kVUM3E=",
  "qrCodeSvg": "PHN2ZyB4bWxucz0naHR0cDovL..."
}

multiUse

In case you need the LinkPay link to be used many times (e.g for donations), then you have to set the flag multiUse to true. In this case none of the resource Ids is allowed.

{
  "mode": "charge",
  "currency": "EUR",
  "type": "linkpay",
  "multiUse": true,
  "checkoutType": "full",
  "paymentMethodsConfigs": {
    "default": {
      "enabled": true
    }
  },
  "urls": {
    "returnSuccess": "https://example.com/success",
    "returnPending": "https://example.com/pending",
    "returnFailure": "https://example.com/error",
    "returnCancel": "https://example.com/error"
  },
  "resources": {
  }
}
Coming Soon!
Coming Soon!

The response looks similar to the following example:

{
  "paypageId": "01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c",
  "redirectUrl": "https://static-v2.unzer.com/v2/paypage/#/01016b49-6f11-7a10-8208-9ea91bcd0d70-681ebed7-638d-44c6-9cbe-d7248da4c60c?publicKey=cy1wdWItmed3123MmExMAAAAE41dESE9mQT48kVUM3E=",
  "qrCodeSvg": "PHN2ZyB4bWxucz0naHR0cDovL..."
}

Optional: Common features

Recurring payments

To create a Payment Page for recurring payments, you need to provide the recurrenceType flag in the create Payment Page call.

icon
The recurrenceType flag is optional and only needed if you want to create a Payment Page with recurring payments.

The following recurrence types are supported by our payment pages: unscheduled and scheduled.

The recurrence type oneclick is automatically set whenever a previously stored One-click payment type is used or the customer enables the checkbox to store the payment type for future payments.

icon
Currently, the recurrence types scheduled and unscheduled are only supported for the card payment method. This means that the list of payment methods will be reduced to this payment method and the other payment methods will be hidden.

For more information, go to the recurring payments page.

{
  "mode": "authorize",
  "amount": "84.9000",
  "currency": "EUR",
  "recurrenceType": "scheduled",
  "resources": {
    "customerId": "{{customerId}}",
    "basketId": "{{basketId}}"
  }
}
$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setRecurrenceType("scheduled");
$unzer->createPaypage($paypage);
Coming Soon!

Select a checkout type

Payment pages support different checkout types. The following checkout types are supported:

  • full: Customer-related data, like billing and shipping address, are required and corresponding form fields are rendered. If a customerId is set in the initial request, the forms will be preloaded.
  • payment_only: Customer-related forms are not rendered.
  • no_shipping: Only the billing address form are rendered. This is useful for digital goods or services.

If you create a payment page with disabled customer form, keep in mind that some payment methods require a customer object. In these cases, the customerId needs to be provided in the create payment page call, otherwise those payment methods will not be available.

{
  "mode": "authorize",
  "amount": "84.9000",
  "currency": "EUR",
  "checkoutType": "payment_only",
  "resources": {
    "customerId": "{{customerId}}",
    "basketId": "{{basketId}}"
  }
}
$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setCheckoutType("payment_only");
$unzer->createPaypage($paypage);
Coming Soon!

Create a payment page with custom return URLs

icon
The returnURL is only required for LinkPay and Hosted Payment Page.

To redirect the end customer to the correct result URL in your system, you can set the following URLs.

If no URL is set, the payment page will render default result pages instead.

{
  ...
  "urls": {
    "returnSuccess": "https://example.com/success",
    "returnPending": "https://example.com/pending",
    "returnFailure": "https://example.com/failure",
    "returnCancel": "https://example.com/cancel"
  }
  ...
}
$urls = new Urls();
$urls->setReturnSuccess('https://returnsuccess.com');
$urls->setReturnPending('https://returnpending.com');
$urls->setReturnFailure('https://returnfailure.com');
$urls->setReturnCancel('https://returncancel.com');

$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setUrls($urls);

$unzer->createPaypage($paypage);
Coming Soon!

To redirect the end customer to the correct informational pages of your shop, such as imprint, contact, help, you can set the corresponding URLs in the urls section of the request body.

icon
If no URL is set, the corresponding link will not be rendered.
{
  ...
  "urls": {
    "termsAndCondition": "https://example.com",
    "privacyPolicy": "https://example.com",
    "imprint": "https://example.com",
    "help": "https://example.com",
    "contact": "https://example.com"
  },
  ...
}
$urls = new Urls();
$urls->setTermsAndCondition('https://termsandcondition.com');
$urls->setPrivacyPolicy('https://privacypolicy.com');
$urls->setImprint('https://imprint.com');
$urls->setHelp('https://help.com');
$urls->setContact('https://contact.com');

$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setUrls($urls);

$unzer->createPaypage($paypage);
Coming Soon!

Exclude payment methods

You can configure payment methods so that a subset of the available payment methods is displayed or is available during checkout. In such cases, you can either disable single payment methods to limit the list by setting specific payment method related enabled flag to false, or disable all of them using the default.enabled flag and enable only the ones you want to offer in the checkout.

You can specify the order or sort the payment methods in the payment form by setting the order as described in the example here.

icon
By default, all payment methods configured in your account are enabled and displayed on your payment pages.
{
  "mode": "charge",
  "amount": "84.9000",
  "currency": "EUR",
  "paymentMethodsConfigs": {
    "default": {
      "enabled": false
    },
    "cards": {
      "enabled": true,
      "order": 0
    },
    "bancontact": {
      "enabled": true,
      "order": 1
    },
    "googlepay": {
      "enabled": true,
      "order": 2
    }
  },
  "resources": {
    "customerId": "{{customerId}}",
    "basketId": "{{basketId}}"
  }
}
$enabledConfig = new PaymentMethodConfig(true, 1);
$paylaterConfig = (new PaymentMethodConfig(true, 1))
    ->setLabel('Paylater');
$cardConfig = (new PaymentMethodConfig(true, 1))
    ->setCredentialOnFile(true)
    ->setExemption(ExemptionType::LOW_VALUE_PAYMENT);

$configs = (new PaymentMethodsConfigs())->setPreselectedMethod('cards')
    ->setDefault((new PaymentMethodConfig())->setEnabled(false)) //enable or disable all payment methods by default
    ->addMethodConfig(Card::class, $cardConfig)
    ->addMethodConfig(PaylaterInstallment::class, $enabledConfig)
    ->addMethodConfig(Googlepay::class, $enabledConfig)
    ->addMethodConfig(Applepay::class, $enabledConfig)
    ->addMethodConfig(PaylaterInvoice::class, $paylaterConfig);

$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setPaymentMethodsConfigs($configs);
$unzer->createPaypage($paypage);
Coming Soon!

Risk settings

The following risk related settings can be passed and may increase the acceptance rate.

ParameterTypeDescriptionExample values
risk.customerGroupstringCustomer classification for the customer if known. Valid values:
TOP: Customers with more than 3 paid transactions
GOOD: Customers with more than 1 paid transactions
BAD: Customers with defaulted/fraudulent orders
NEUTRAL: Customers without paid transactions
"GOOD"
risk.confirmedAmountintThe amount/value of the successful transactions paid by the end customerPositive number: 891
risk.confirmedOrdersintThe number of successful transactions paid by the end customerPositive number: 10
risk.registrationLevelstringCustomer registration level
0=guest, 1=registered
"0"
risk.registrationDatestringCustomer registration date in your shop
(YYYYMMDD)
"2019-01-01"
{
  "mode": "authorize",
  "amount": "84.9000",
  "currency": "EUR",
  "risk": {
    "registrationLevel": "string",
    "registrationDate": "string",
    "customerGroup": "top",
    "confirmedOrders": 0,
    "confirmedAmount": 0
  },
  "resources": {
    "customerId": "{{customerId}}",
    "basketId": "{{basketId}}"
  }
}
$risk = new RiskData();
$risk->setCustomerGroup('TOP')
    ->setConfirmedAmount(1234)
    ->setConfirmedOrders(42)
    ->setRegistrationLevel('1')
    ->setRegistrationDate('20160412');

$paypage = new Paypage(9.99, 'EUR', 'charge');
$paypage->setRisk($risk);
$unzer->createPaypage($paypage);
Coming Soon!

Credentials on file (COF)

You can enable storing payment methods on your payment page to make it easier for returning customers to pay.
This feature is called Credentials on File (COF) and is supported by the following payment methods:

  1. card
  2. sepa-direct-debit
  3. paypal

Enable the feature for a payment method by use of the flag credentialOnFile in the corresponding object within paymentMethodConfigs.

icon
  • COF payments in combination with cards automatically triggers a One-click payment.
  • Because the payment methods related to the customer are presented in the frontend, this feature requires the customerId to be set.
{
  "mode": "authorize",
  "amount": "84.9000",
  "currency": "EUR",
  "paymentMethodsConfigs": {
    "card": {
      "credentialOnFile": true
    }
  },
  "resources": {
    "customerId": "p-cst-1234"
  }
}
$paypage = new Paypage(9.99, 'EUR', 'charge');

$cardConfig = (new PaymentMethodConfig())->setCredentialOnFile(true);
$config = (new PaymentMethodsConfigs())->addMethodConfig(Card::class, $cardConfig);
$paypage->setPaymentMethodsConfigs($config);

$unzer->createPaypage($paypage);
Coming Soon!

Step 3: Initialize payment page
client side

Load the JS script

Add Unzer’s JavaScript to your application where you will initiate the payment link. You should always load the script directly from https://static-v2.unzer.com:

<script type="text/javascript" src="https://static-v2.unzer.com/v2/ui-components/index.js"></script>
icon
Faster load time
To make your website load faster, insert the JavaScript at the bottom of your HTML document.

Step 4: Check payment status
server side, client side

For payment methods that don’t require the customer to redirect to an external site to complete the payment, the checkout.success() or checkout.error() events will be triggered after the customer follows the payment link and finalizes the payment by clicking the Pay button.

Check all possible payment states here.

For redirect payment methods the customer gets redirected to an external payment site to finalize their payment.
Once the payment is done, they are redirected to one of the return URLs, that you set in Step 2.
Now you can fetch the payment resource and check its status.

There are a few ways the payment can be verified after the return URL is called:

  • Via a GET call and the paypageId here, which returns paymentId and transaction status.
  • Via a GET call and the paymentId here, which returns paypageId and payment details.
  • Via Webhook: Subscribe to the payment webhook and receive the paymentId.
icon
  • Don’t forget to verify that the paymentId that you receive in the returnUrl belongs to the paypageId.
  • For security reasons, we recommend that you always check that the payment ID that you received in the return URL matches the paypage ID. This is because of the risk when the browsers allow their users to manipulate any query parameters.

Get payments via Paypage ID

This endpoint can be called after the payment page is finished and the customer has returned to the shop. It will contain the paymentId, status and information about failures. For LinkPay with multiuse, this endpoint will contain all payments.

The current status of the payment can be seen in the response.

GET https://paypage.unzer.com/v2/merchant/paypage/{paypageId}
{
  "payments": [
    {
      "paymentId": "s-pay-1",
      "transactionStatus": "success",
      "creationDate": "2024-08-22T14:42:57.944Z",
      "messages": [
        {
          "code": "string",
          "customer": "string",
          "merchant": "string"
        }
      ]
    }
  ],
  "total": 0
}

Get Payment via Payment ID

This endpoint can be called after the payment page is finished and the customer has returned to the shop with the paymentId parameter passed in the URL. Keep in mind to verify that the paymentId received in the returnUrl belongs to the paypageId.

GET https://api.unzer.com/v1/payments/{paymentId}
{
    "id": "s-pay-131937",
    "state": {
        "id": 1,
        "name": "completed"
    },
    "amount": {
        "total": "20.0000",
        "charged": "20.0000",
        "canceled": "0.0000",
        "remaining": "0.0000"
    },
    "currency": "EUR",
    "orderId": "",
    "invoiceId": "",
    "resources": {
        "customerId": "",
        "paymentId": "s-pay-131937",
        "basketId": "",
        "metadataId": "",
        "payPageId": "12345",
        "traceId": "70ddf3152a798c554d9751a6d77812ae",
        "typeId": "s-eps-grpucjmy5zrk"
    },
    "transactions": [
        {
            "date": "2021-05-10 00:51:03",
            "type": "charge",
            "status": "success",
            "url": "https://api.unzer.com/v1/payments/s-pay-131937/charges/s-chg-1",
            "amount": "20.0000"
        }
    ]
}
icon
You should handle the status according to the payment method used by the customer.

Step 5: Display payment result
client side

After the transaction, you should display its result to the customer in the frontend using the information from the previous step.

icon
Keep in mind that depending on the payment method used, information relevant for the customer as a part of the success/error message can differ. For example, for Unzer Invoice and Unzer Prepayment you should display payment details to the customer on the success page.

Notifications

We recommend subscribing to the payment event to receive notifications about any changes to the payment resource. As soon as the event is triggered you should fetch the payment and update the order status in your shop according to its status.

  {
    "event":"payment.pending",
    "publicKey":"s-pub-xxxxxxxxxx",
    "retrieveUrl":"https://api.unzer.com/v1/payments/s-pay-774",
    "paymentId":"s-pay-774"
  }

For more details on implementing webhooks to receive notifications, see Notifications page.

Localization

To localize your page, pass the locale value in the locale attribute of the <unzer-payment> component. If the locale is not set, the browser language will be used. We will fall back to our default locale, which is “en-GB” in case of any trouble detecting a valid/supported locale.

Please refer to the following list of supported locales/languages:

  • en, en-GB (default)
  • de, de-DE
  • nl, nl-NL
  • da, da-DK
<unzer-payment publicKey="p-pub-123" locale="de-DE">
  <unzer-pay-page payPageId="123456789"></unzer-pay-page>
</unzer-payment>

Customization

The following customization options are available for the Payment Pages:

ParameterTypeDescriptionDefault value
style.fontstringThe font to be used through out the Payment Page.
TBD
style.brandColorstringThe color to be used as base color, such as the button color. Other colors will be derived from this color. For example, interactive state colors such as hover, focus and pressed, selected, loader and component colors.
TBD
style.shadowsbooleanThe style for the shadows.
TBD
style.textColorstringThe color of text, icons and borders on the page.#0C1332
style.linkColorstringThis will affect the link color and the inverse link color.#1B6AD7
style.backgroundColorstringThe background color of the payment page.#F1F1F3
style.cornerRadiusstringThe corner radius of elements in pixels.6
style.hideUnzerLogobooleanWill show “Secure checkout” instead of “Secure checkout by Unzer” in the bottom right corner of the payment page.false
style.logoImagestringWill show the given logo image in the top left of the payment page. The following formats are supported: jpg, svg and png.Will show the shopName if not set.
style.backgroundImagestringWill render the given image in the background of the payment page. The following formats are supported: jpg and png.Will use the backgroundColor if not set.
style.footerColorstringChanges the footer color to the given value.
TBD
style.headerColorstringChanges the header color to the given value.white
style.hideBasketbooleanHides the basket information within the “ORDER SUMMARY” section. It will appear as if no basket has been set on init payment page, however payment methods requiring the basket will still be availablewhite
style.faviconstringURL to your favicon file. Supported formats: ico, gif, png.
Link Pay and Hosted Page only
none
shopNamestringShop name will be shown next to the shop logo, as alias to the logo image and in the title (not EPP).none
POST https://paypage.unzer.com/v2/merchant/paypage

{docker build ./mocks --tag "connectivity/mocks:latest"
  ...
  "shopName": "My Shop Name",
  "style": {
      "font": "arial",
      "headerColor": "#123456",
      "footerColor": "#123456",
      "brandColor": "#123456",
      "textColor": "#123456",
      "linkColor": "#123456",
      "backgroundColor": "#123456",
      "cornerRadius": "6",
      "logoImage": "https://logo-image-url",
      "backgroundImage": "https://background-image-url",
      "shadows": true,
      "hideUnzerLogo": true,
      "hideBasket": true,
      "favicon": "https://favicon-url"
  },
  ...
}
// ...
$paypage->setLogoImage('https://logo-image-url');
// ...
...
paypage.setLogoImage('https://logo-image-url');
...

Customize the basket item images

You can set individual basket images that show on the Payment Page. Check the Basket resource documentation page for details: Manage basket (direct API calls), Manage basket (PHP SDK), Manage basket (Java SDK).

{
  "totalValueGross": "84.9000",
  "currencyCode": "EUR",
  "orderId": "",
  "basketItems": [ {
      "basketItemReferenceId": "item-1",
      "quantity": "2",
      "vat": "0E-7",
      "amountDiscountPerUnitGross": "0.0000",
      "amountPerUnitGross": "20.0000",
      "title": "Hoodie",
      "unit": "Pc.",
      "subTitle": "Clothes",
      "type": "goods",
      "imageUrl": "https://stg-static.unzer.com/assets/images/baskets/ZippHoodie_Unzer.jpg"
    },
    {
      "basketItemReferenceId": "item-2",
      "quantity": "6",
      "vat": "0E-7",
      "amountDiscountPerUnitGross": "0.0000",
      "amountPerUnitGross": "5.0000",
      "title": "Writing Pad",
      "unit": "Pc.",
      "subTitle": "Office Supplies",
      "type": "goods",
      "imageUrl": "https://stg-static.unzer.com/assets/images/baskets/WritingPad.jpg"
    },
    {
      "basketItemReferenceId": "item-6",
      "quantity": "10",
      "vat": "0E-7",
      "amountDiscountPerUnitGross": "0.0000",
      "amountPerUnitGross": "1.9900",
      "title": "Screws",
      "unit": "Pc.",
      "subTitle": "hardened aluminium",
      "type": "goods",
      "imageUrl": "https://stg-static.unzer.com/assets/images/baskets/WritingPad.jpg"
    },
    {
      "title": "10 EUR voucher newsletter registration",
      "basketItemReferenceId": "item-3",
      "quantity": 1,
      "amountPerUnitGross": 0.00,
      "amountDiscountPerUnitGross": 10.00,
      "vat": 1,
      "type": "voucher"
    },
    {
      "title": "Shipment costs",
      "basketItemReferenceId": "item-4",
      "quantity": 1,
      "amountPerUnitGross": 5.00,
      "vat": 1,
      "subTitle": "Insured standard shipment",
      "type": "shipment"
    }]
}

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 cancel a reservation on the customers account or reduce its amount 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("s-priv-xxxxxxxxxx");
Cancel cancel = unzer.cancelCharge("s-pay-1", "s-chg-1");

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": "",
    "payPageId": "",
    "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.

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