Introduction
Intended Audience
This documentation is for merchants and developers who want to implement the lynck payment system. Help us improve this guide by contacting us and pointing out errors, misspellings or unclear sections at service@lynck.de.
Getting started
Lynck offers an interface for web-shops to integrate with a variety of payment options by performing just a single integration with the lynck system. Integration with lynck spans into the various shop processes and systems from web-shop to warehouse to accounting.
The lynck interface is suitable for both immediate fulfilment – for example, for transactions involving electronic services or goods that are delivered immediately after the checkout took place – or delayed fulfilment – transactions involving goods ́ delivery (order delivery) to users after a time, possible days from checkout.
So lynck allows the shop to focus on the best shopping experience for its users without having to deal with the hassle of providing a variety of payment options and multiple integrations. The implementation of the multitude of payment options can be realized with just one integration. During checkout, lynck’s payment system is optimized to select the most convenient payment options for the shop’s customer and at the same time satisfy the shop’s needs for secure payments.
Integration options
The lynck platform offers great flexibility for the integration into the web shop's checkout process. In general, there are two types of integration for two versions each. This allows E-commerce merchants with any sales volume to choose the ideal integration type for their requirements.
Identifier | Type | Description | Benefit |
---|---|---|---|
API | API | The lynck System is integrated as pure backend API solution without using a Hosted Page or any frontend elements. To transfer credit card data the merchant has to be PCI compliant. | Full design control, seamless page tracking |
SecureFields | API with using secure fields | The lynck system is integrated as an API solution using the lynck Secure Fields to transfer credit card data in the shop frontend. | Full design control, seamless page tracking, drastically reduced PCI requirements |
HostedPageBefore | PRE-integrated Hosted Page | The Hosted Page, which shows all payment methods/instruments is integrated before the confirmation page of the merchant's shop is shown. The hosted page allows the user the select a payment method and enter payment instruments like credit card and bank account. | Less effort required for frontend integration, drastically reduced PCI requirements |
HostedPageAfter | POST-integrated Hosted Page | The Hosted Page, which shows all payment methods/instruments is integrated after the confirmation page of the merchant's shop is shown. The hosted page allows the user the select a payment method and enter payment instruments like credit card and bank account. | Less effort required for frontend integration, drastically reduced PCI requirements |
HostedPageAfter | Pay By Link via API | The lynck System creates a payment link which redirects the customer to a hosted payment page to complete the payment. | No integration into the shop front-end required, drastically reduced PCI requirements |
API integration
When using complete/self-sufficient API integration, the E-commerce merchant has maximum flexibility when designing and integrating the payment page, but in return he has to fulfil the high security requirements imposed by e.g. PCI-compliance guidelines issued by credit card companies. This integration type is therefore more suited to large companies which want to retain full design and process control.
API integration with secure fields
The API integration with secure fields corresponds to the aforementioned version, however, with the difference that the secure fields library is made available to the E-commerce merchant via the lynck platform. This solution is used to handover credit card and bank details in a secured environment outside of the shop sovereignty and avoids that the E-commerce merchant has to independently fulfil the PCI-compliance guidelines issued by the credit card companies. This integration type therefore tends to be more suited for large companies which want to retain full design and process control yet avoid more strict PCI-requirements.
Integration as Hosted Page (Before / After)
Lynck delivers a complete payment page with the easy and above all fast "Hosted Pages" integration type. It is a complete payment page for all payment types for the E-commerce merchant's shop and ensures that no safety relevant data is stored on the retailer's website. Therefore, the E-commerce merchant automatically fulfils the applicable high safety standards e.g. PCI-compliance imposed by credit card companies.
The standard Hosted Page design is responsive, i.e. depending on the end customer’s terminal (e.g. PC, smartphone or tablet) the payment page is optimised for the terminal's display. A special feature is the easy customization of the Hosted Page: It can be configured independently by the E-commerce merchant which allows them to retain in parts control over the page design. Changes can be checked with the preview function and set "live" with one click. In addition to the visual design of the payment page, the E-commerce merchant can also make content changes. This allows shops to provide individual, multi-lingual texts for every payment method (e.g. as explanatory note or to promote individual payment methods) and to save individual fees or discounts per payment type. This also enables the retailers to have significantly more control with regard to directing the end customer to certain payment methods.
The E-commerce merchant can also specify the point at which the payment page should be shown during the entire checkout process. There is a choice of "before" or "after" purchase confirmation, referred to as the pre-integration (3) or post integration version (4). Therefore, the Hosted Page can be ideally integrated into the checkout process according to the needs and preference of the E-commerce merchant.
Pay By Link integration
Pay By Link via API allows the creation of payment links directly from the merchant's system. These links can be used/delivered in any way to allow customers to pay in an fast and easy fashion. Optionally the lynck system can be instructed to automatically send these payment links in an email to the customer, which further reduces the implementation effort. The payment link redirects the customer to a payment page which is based on the 'Hosted Page After'. Pay By Link transactions require a minimal amount of parameters to be initiated compared to other integration options. Should solvency checks be performed for payment methods such as bill payment and direct debit, the necessary data for the check will be collected on the payment page directly from the customer. This integration type is not meant to be used in a shop checkout, but as an alternative way to collect payments independent of any shop. Possible use cases include, but are not limited to, mail and telephone orders, or offering alternative payment methods on the bill for a customer.
Process description
To understand the lynck system some terms and correlations need to be explained. The following graphic illustrates the relation between transactions and captures
Transactions
If a user initiates the payment process within the checkout process, the merchant’s shop system performs a createTransaction call in the lynck system and transfers all relevant data. A transaction can be referred later on by the shop system (or an ERP system) with the unique identifier orderID
. This could be the reference number of the order or an invoice number or anything else, but is has to be unique for the shop.
After receiving all necessary data, the lynck system creates a transaction with the status New
. The transaction will then pass through different states which are represented by the transaction status.
Status | Description |
---|---|
New | Internal status. Means that a transaction has been created within the lynck system after receiving the user and basket data from the shop system during checkout. |
AcknowledgePending | Internal status. The user has confirmed the purchase during checkout by pressing button "Buy" and in case of redirect payment methods lynck is waiting for the response from the shop which contains the success-URL. |
FraudPending | This status indicates, that the transaction is suspect due to fraud suspicions and needs to be reviewed manually. |
CIAPending | The transaction was created successfully and lynck is waiting for funds to arrive or become available. Relevant for payment methods: AMAZON_PAY, PAYPAL, PREPAID, ZINIA_BNPL, ZINIA_INSTALLMENT |
MerchantPending | The transaction was successful. Lynck is waiting for the merchant to capture the transaction when delivering the order or immediately after the checkout process. |
InProgress | The transaction was captured successfully. The transaction will remain in this status until all captures are in status paid. |
Expired | The transaction was not completed by the user within the duration of the basket-validity. |
Cancelled | The transaction was cancelled by the merchant. |
FraudCancelled | The transaction was cancelled due to fraud. This can occur if they were in status FraudPending and then declined by the merchant or lynck, or if the merchant reported the user as fraudulent in the MSA or using the reportFraudUser API. |
Done | The transaction has been completed. A transaction will change into this status if all of its captures have the status paid. |
The transaction status can be affected by the user, the system, the fraud team, the shop or the capture status.
The transaction status remains as New
until a reservation is made. This usually happens when the customer clicks the "Buy" button on the web-shop. After confirmation of the purchase the transaction status changes to AcknowledgePending
.
The resultCode of a reservation is 0 in case of a successful reservation, but it can also equal 1 regarding of the payment method. This signals that the user needs to be redirected to a payment page of a third party payment supplier (e.g. PayPal). The URL to which they should be redirected is provided by lynck in the response to the reserve call.
After the reservation has been confirmed, the status of the transaction is set to MerchantPending
in case the funds are ready to be captured or CIAPending
in case the funds are still pending. After the funds have become available the transaction status changes to MerchantPending
.
If the shop/ERP system cancels the transaction via cancel call, the status of the transaction is set to Cancelled
.
If any funds were received before a capture was performed, the lynck system will automatically initiate a refund.
Captures
All transactions with status MerchantPending
wait to be captured by the shop/ERP system. A capture can be referred later on by the shop/ERP system by passing the unique identifier captureID via capture call. So whereas the creation of a transaction is triggered by the user during checkout process, the creation of an capture
is initiated by the shop/ERP system.
Status | Description |
---|---|
PayPending | The capture or partial capture is waiting to be paid. |
Paid | The capture or partial capture was paid successfully. Alternatively the open amount could have been reduced to 0 using a refund on bill and direct debit transactions. |
PaymentFailed | This status indicates that the payment failed. |
Cleared | The capture or partial capture was booked successfully and cleared. |
Chargeback | A chargeback was reported on the capture. |
InDunning | This status can only occur if the dunning and collection service has been enabled at lynck. Customer is in the dunning process. |
InCollection | This status can only occur if the dunning and collection service has been enabled at lynck. Customer is in the collection process. |
The point of time when a capture should be done, depends on the business model:
- shops that want to charge the user with delivery perform the capture as soon as they have delivered or trigger the delivery(more user convenient)
- shops that want to charge the user immediately after ordering - either if they deliver their goods afterwards or because they sell digital goods - will perform the capture directly after a successful transaction creation
Lynck also supports the ability to perform more than one capture e.g for the case of partial delivery.
After a successful capture the status of a transaction is set to
Done
as soon as lynck received funds from the user for the capture so that the capture has the statusPaid
. In case of several captures the transaction status will be set toDone
as soon as all captures are in statusPaid
InProgress
when lynck waits for incoming funds (e.g. invoice or direct debit) so that the capture has the statusPayPending
The transaction status is therefore dependent on the action of the shop/ERP system up to a certain point in time. As soon as the shop/ERP system creates one or more captures for a transaction, the transaction status will be directly affected by the status of those captures.
Example: If a capture was created for a transaction and the capture was marked as Paid
, the transaction status is Done
as the capture status is Paid
. If a chargeback is reported by the bank or credit card company, the capture status changes from Paid
to Chargeback
and therefore the transaction status changes back from Done
to InProgress
. It is possible for the transaction status to move in either direction.
If the merchant does not want to capture the full amount, e.g. because some goods can not be delivered, the finish call should be used to close the transaction. This will refund the overpaid/uncaptured amount to the user in case the transaction was paid in advance, but keep all captured funds.
User
Users will automatically be created at lynck when createTransaction is called with a new userID. Alternatively registerUser can be used to create users without starting a transaction each time. The userID is the unique identifier of a user for a specific store. If a returning user for a store is identified by lynck using the userID, any payment instruments stored for this customer will be displayed when using the hosted pages integration type. This allows returning customers to re-use cards/bank accounts without the need to re-enter all data. Due to the sensitive nature of this data the merchant has to make sure that no userID can be shared between users.
Hosted Pages description
Types of Hosted Payment integration
There are two ways to integrate Hosted Pages. The payment page can be shown before or after the shops order confirmation page. Which option fits better depends on the used web-shop or module.
Hosted Pages Before
- With the API call createTransaction the shop passes all relevant data to lynck
- The lynck system returns a URL, which refers to the hosted payment selection page. The shop displays the hosted payment selection page to the user and lynck performs the first risk check before displaying the selectable payment methods
- The user selects a payment method on the payment selection page, and enters the payment instrument data if necessary
- In case of an error the lynck system shows the error message on the payment selection page
- The lynck system redirects the customer to the confirmation URL configured for this shop and informs the shop about the selected payment method. See: callback
- The shop calculates the final order amount and displays the purchase confirmation page to the user. After the user confirmed the purchase, the merchant reserves the final order amount with the reserve call
- In case of an error the lynck system returns a new URL in its response with the proper error message and the shop redirects the user back to the updated payment method selection page
- In case of a positive outcome for the risk check the processing of the payment can start
Hosted Pages After
- With the API call createTransaction the shop passes all relevant data to lynck
- In case of an error the lynck system shows the error message on the payment selection page
- The lynck system returns a URL, which refers to the hosted payment selection page. The shop displays the hosted payment selection page to the user and lynck performs the first risk check before displaying the selectable payment methods
- The user selects a payment method on the payment selection page. Lynck now validates the data and performs the second risk check
- In case of an error the lynck system shows the error message on the payment selection page
- In case of a decline due to a failed second risk check the lynck system shows an error message on the payment selection page
- In case of a positive outcome for the risk check lynck automatically reserves the full transaction amount. The merchant does not need to perform the reserve call themself
Supported Payment Methods
Name | General notes |
---|---|
Amazon Pay | Amazon Pay is an express checkout option by which the customer may directly pay for a specific product or basket by clicking on an Amazon Pay express button, and does not require the prior creation of a lynck transaction. The user is then redirected to Amazon Pay where they can select their preferred payment method and delivery address, which is communicated to the shop afterwards. The user is then redirected back to the shop where they can confirm their purchase. This payment method is not to be used as a regular checkout payment method, but for express checkouts only. For more details see the Amazon Pay section of the documentation. |
Bill | After checkout, the shop has to generate a invoice including the account information and payment reference provided by lynck. The account information and the payment reference are provided in the response to the reserve. Alternatively they can be retrieved by the shop from lynck using the getTransactionStatus call. |
Cash in Advance | After checkout, the shop can only deliver the order after payment has been received from the user. Incoming payments are reported to the shop by the Merchant Notification Service. |
Cash on Delivery | After checkout, the user makes payment only once he has received the product. This payment is not made via lynck checkout. So lynck cannot process any payment here. As a result, the merchant will have to process ‘Cash on Delivery’ payments separately. |
Credit Card | After checkout, the reservation or authorization is processed immediately. The shop receives the outcome of the payment as result of the reserve call |
Credit Card with 3D-Secure | If a credit card holder is registered with the 3D Secure process via one of the registration methods, then once the purchase is confirmed, the customer is forwarded to an entry page of their bank where they can enter their password. Payment is carried out only after the correct password is entered. The password is only known to the customer and their bank. For MasterCard this solution is called “MasterCard Secure Code”, for Visa “Verified by Visa”. |
Direct Debit | Direct Debit has to be processed by the bank system once it has been transferred to the bank gateway. This can take several days. The order status is PayPending during this period. As a result of the reconciliation process the bank system provides feedback which will be considered automatically within the lynck system: in case of a positive feedback, the status of the order will be set to Paid ; in case of a negative return it gets status PaymentFailed . Sometimes lynck does not receive any feedback from the bank. For this rare case the lynck system waits until a so called grace period has been passed. If the lynck system has not received a negative feedback within this grace period the status of the order will be set to Paid . The lynck system sets a grace period, since the bank system only provides feedback if the direct debit is rejected. The order status changes to Paid once the lynck system has not received negative feedback from the bank system after this grace period. |
iDEAL | After confirmation, the user is forwarded during checkout to a page on which they may select their bank. This takes them to the entry page of their bank where they have to authenticate themselves with their access data. They then triggers an online bank transfer from this environment. iDEAL will inform lynck about the outcome, after which lynck performs a callback and redirects the user back to the shop. |
PayPal | During checkout, the user will be required to login into their PayPal account to authenticate the payment. Depending on the version of the PayPal gateway this authentication happens in a pop-up window within the shop, or by redirecting the customer to PayPal after order confirmation. On purchase confirmation lynck redirects the user to PayPal to login using his credentials. After a successful authentication or cancellation using the redirect method, PayPal informs lynck about the outcome, lynck performs a callback and redirects the user back to the shop. In addition it is possible to offer PayPal as an express checkout option. For more details see the PayPal Express section of the documentation. |
Sofort (Online Remittance) | After confirmation, the user is forwarded during checkout to the SOFORTBank website where they can select their bank. This takes them to the entry page of their bank where they have to authenticate themselves with their access data. They then triggers an online bank transfer from this environment. Similar to iDEAL, SofortÜberweisung will inform lynck about the outcome, after which lynck performs a callback and redirects the user back to the shop. |
Other Payment methods | From time to time lynck may add payment methods. Consult your lynck representative. |
Risk Management
The integrated risk management platform uses a combination of machine learning, sector specific data and fully adjustable criteria in order to decide in real time whether transactions are accepted or rejected, if the end customer only gets offered secure payment methods or if the transaction has to be checked manually. Buyers shopping with online retailers can pay for their goods, services and digital contents using a range of payment methods such as credit cards, PayPal, direct debit, prepayment etc. The payment methods vary in cost and risk (with regards to non-payment risk) for the online retailer on the one hand and with regard to popularity with the customers on the other. If a preferred payment method is missing, then it may lead to an increased rate of purchase cancellations and reduce the so-called retailer conversion rate.
The risk management integrated in the lynck platform controls the payment types for E-commerce retailers actively and dynamically during checkout based on different check algorithms and criteria based on select parameters.
Dynamic control is carried out based on a two-step risk assessment. In advance, it is coordinated with the merchant which payment methods should be available in general and which of those are offered for certain risk assessments.
As seen in the graphic above, the process starts with the merchant initiating a createTransaction request when the customer enters the payment section of the checkout. Using this request the merchant can already decide how to treat the customer based on his own experience. This allows the merchant to:
- Offer all payment methods to VIP customers or business partners without any risk checks taking place. (Trusted customer - low risk)
- Offer only secure payment method to customers known to cause issues or who are suspicious. (Suspicious customer - high risk
- Let lynck decide whether the customer should be treated as high risk customer based on configured risk settings and provided data. (Unknown customer - medium risk)
Furthermore, the merchant is able to provide risk classes for basket items as well. Similar to the first level risk assessment done by lynck, these will only apply if the transaction risk class is medium. See the following table on how the combination of customer and basket items risk class affect the transaction risk class:
Extended Risk Classes
Instead of only providing the main three risk classes low(0), medium(1) and high(2), it is also possible to provide user risk classes with a decimal point from 0-2. This way merchants gain access to a more finely grained risk management of customers in the checkout process based on their past experiences with them.
By default all risk and solvency checks are performed in the risk class range from 0.1 - 1.9. Specifically for limit, velocity, open debt rules and all solvency checks it is possible to define risk class thresholds, which define at which risk class a rule or check becomes active. This means that multiple rules or checks with different thresholds can be configured, whereas the rule/check with the highest threshold that is reached will be applied.
The extended risk classes allow: * Application of different limit, velocity and open debt rules depending on the customer risk class * More control over the offered payment methods for each risk class * Usage of different solvency check products depending on the risk class * Different solvency check result interpretation depending on the risk class
Dunning and collection
Every German and Austrian shop has the option to use the professional dunning and collection service of our partner Accredis.
All orders will automatically be passed to Accredis for processing
- if the due date is reached in case of unpaid bill transactions
- if a direct debit payment bounced.
All orders, which have been passed to Accredis, go into status inDunning
.
Also the user/debtor gets this status.
If a user is in status inDunning
, they are (per default configuration) unable to pay with insecure payment methods like direct debit or bill until they have paid the outstanding amount.
If the dunning process was successful or the Accredis file gets closed, the lynck system is notified about it.
In this case the status of the order will be set to paid
even if the debt claim was not fully paid.
A file can be closed if the user was not able to pay or just paid a partial amount of the debt claim.
If the dunning process finished without the file being closed as mentioned above the collection process starts. Accredis notifies lynck about the start of the collection process, which triggers the order and the user status to change to inCollection
. Similar to inDunning
customers with status inCollection
will not be able to use insecure payment methods.
The order will only switch to paid
if the file is closed manually, or an incoming payment is registered.
All orders with status paid
will be passed to the clearing, so that the shop gets all payments which have been collected during dunning/collection.
To effectively use this service Accredis at least requires the invoice number of the order created by the merchant. The invoice number can either be passed to lynck and therefore Accredis by providing it in the field captureID when performing a capture, or alternatively it can be passed after capturing by using the updateInvoice.
Implementation Details
General Rules
Data Types
Following data types are used in this documentation:
Type | Description | Comments | Sample |
---|---|---|---|
AN (length) | Alpha-Numeric | Sequence of characters (UTF-8 encoded) with maximum length | Test |
N (length) | Numeric | Sequence of numbers with maximum length | 12356 |
V | Fixed Value | The possible values can be found in the comments | CC |
J (type) | JSON-Object | JSON object of a special type | { 'id': 'xyz' } |
JA (type) | JSON-Array | Array of JSON objects of a special type | ['abc', 'xyz'] |
B | Boolean value | true or false | true |
D (format) | DATE | Date with a specified Format like YYYY-MM-DD | 2020-02-22 |
Security and signing of requests
In order to ensure the security of the calls made to the lynck interface, there are certain rules that have to be followed.
- All calls have to be made via HTTPS.
- All parameters shall be passed via POST requests
- The requests should be sent with Content-Type "application/x-www-form-urlencoded" if not described otherwise in the API
- The responses will have Content-Type: "application/json"
In order to prevent any tampering with the parameters of the request, all calls have to be signed with what is known as a Message Authentication Code (MAC).
The MAC has to be calculated by the caller and passed along as a further parameter in the request. The algorithm used for this is HMAC (RFC 2104). The HMAC algorithm needs to be a shared secret between parties in order to validate the authenticity of the message. All responses from lynck contain a MAC in the response header which can be used for validation.
Status codes
Successful responses have HTTP status 200 (OK). If there is a problem with the content of the request the http status is 400 (Bad Request). In case of validation errors there is a http status 401 (Unauthorized) returned. Possible causes are:
- wrong or missing merchantID
- wrong or missing storeID
- wrong or missing MAC
- request to a non existing endpoint
Merchant credentials
- The merchant ID you will receive when getting access to our sandbox or production environment acts as a container for shops/stores, meaning a merchant ID may be related to multiple store IDs. Your private key is only valid for this merchant ID and all stores below it.
- Each store ID is bound to exactly one currency. Usually the ID contains the ISO 4217 currency code that it is bound to. For example: teststoreEUR. This means if a single store front-end supports multiple currencies it will require multiple store IDs. For each currency the calls will have to be made with their respective store ID.
- Each store ID is bound to exactly one confirmation, success and failure URL respectively. These URLS are the targets for callbacks which are performed synchronous to the payment process. For more information see: Callback documentation
- Each store ID can be assigned multiple notification-URLs. This URL is the target for transaction status updates. For more information see: Notification documentation
- Risk settings such as velocity rules, blacklists and solvency checks can be configured for each store ID.
MAC calculation
The Message Authentication Code (MAC) is used to ensure data integrity and therefore includes the request parameters with further calculations performed.
The MAC is included in both the request and response.
Request
In requests the MAC is sent as POST parameter
Response
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
X-Payco-HMAC: 289740cfda1c7f1df1c2ce9562930350e6bcb0a6
Transfer-Encoding: chunked
In the response the mac is part of the HTTP header as X-Payco-HMAC
There are cases where the lynck system can not generate a MAC. For example if the merchantID is missing in the request and the merchant can not be identified. In this case there will be no MAC in the header. This will only happen for error-messages (resultcode 101). Responses for successful calls will always include a MAC
Calculation
The MAC should be computed as follows:
Generate an HMAC-SHA1 key using the merchant's private key. The key can be computed once and stored if the private key is unchanged.
Request
Create the datastring. Build a string containing the calls parameter values alphabetically ordered (a - z). To order the parameters the key is used and not the value. The parameter "mac" is the only one that is not included in the calculation.
- The included strings' parameter values should be identical to the ones sent in the request or received in the response
- If a parameter value is sent as empty, or the parameter is not set at all, then related parameter value for MAC calculation can be an empty string ('') or simply not included at all.
- The datastring should not include any spaces or non-printable control characters ( \n, \r, \t, \f, \v space ), which can easily be found with the regular expression meta character '\s'. Remove all the non-printable characters from the datastring.
Compute the MAC using the HMAC-SHA1 calculation together with the private key on the datastring.
Response
In the response the whole body is the datastring as it contains all the payload, but the process is exactly the same as outlined in the previous paragraph. Keep in mind to remove the parameter 'mac' from the response before calculating and verifying its MAC.
To validate notifications sent from lynck to the merchant, the process is basically the same as described above.
Example
<?php
function getMac($request) {
global $privateKey;
// Sort parameters alphabetically by key for MAC calculation
ksort($request);
// Create a string from the parameter values for MAC calculation
$macstring = implode("", $request);
// Calculate MAC
return (hash_hmac('sha1', str_replace(array(" ","\t","\s","\r","\n",' '), "", $macstring), $privateKey));
}
?>
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class MACCalculator {
public String calculateMAC(String input, String secret) {
// generate MAC Secret Key (Step a)
Mac mac = null;
try {
SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), "HmacSHA1");
mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
} catch (Exception e) { /* handle exception*/}
return hmac(input, mac);
}
// method that applies mac key to the parameters string
private String hmac(String input, Mac mac) {
input = input.replaceAll("\\s", "");
final byte[] hmac = mac.doFinal(input.getBytes());
final StringBuilder hex = new StringBuilder(2 * hmac.length);
for (final byte b : hmac) {
// b & 0xff converts e.g. 0xffffff81 to 0x81
String hexString = Integer.toHexString(b & 0xff);
if (hexString.length() < 2) {
hex.append("0");
}
hex.append(hexString);
}
return hex.toString();
}
public String calculateAndGetMAC(MultiValueMap<String, String> map, final String merchantPassword) {
StringBuilder macInput = new StringBuilder();
SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) {
String value = map.toSingleValueMap().get(key);
macInput.append(value);
}
return calculateMAC(macInput.toString(), merchantPassword);
}
/*
* Main method only includes a simulation to a MAC Calculator client
*/
public static void main(String[] args) {
String merchantPassword = "8A!v#6qPc3?+G1on";
// The input variable below should include the call parameters in alphabetic order
String input = "123testOrdertestStore";
MACCalculator macCalculator = new MACCalculator();
System.out.println((macCalculator.calculateMAC(input, merchantPassword)));
}
}
To verify if the MAC calculation is implemented properly, please find following sample strings and the respective correctly calculated MAC value:
Assume merchant private key value here is:
8A!v#6qPc3?+G1on
The request is a cancel call with following parameters:
key | value |
---|---|
merchantID | 123 |
storeID | test Store |
orderID | testTransaction |
Ordered alphabetically:
key | value |
---|---|
merchantID | 123 |
orderID | testTransaction |
storeID | test Store |
Remove special delimiters:
key | value |
---|---|
merchantID | 123 |
orderID | testTransaction |
storeID | testStore |
The concatenated parameter string is:
123testTransactiontestStore
The resulting calculated MAC should be:
7aea4cc6313b2814053488079563375bf1544663
API Throttling
To prevent abuse of the API and ensure stability there are restrictions in place which limit the rate of requests per timeframe that can be performed to the lynck system.
Any given API endpoint has an assigned request pool which represents the amount of requests which can be made before the API rejects any further requests. This request pool refills with a set rate and therefore allows for a short burst of multiple requests at once, but limits the overall requests that can be made over longer periods of time.
The size of the request pool and the refill rate may depend on the specific API endpoint and the system which is called. Request pools and the refill rate are independent for each individual API endpoint. For example, even if the limit for the getTransactionStatus API is reached, the createTransaction API would remain unaffected.
Callback
Callbacks are redirects of the customer back to the shop performed by the lynck system to the URLs configured for the merchants shop. For each shop one confirmation, success and failure URL can be defined.
The following GET parameters can be added to the URLs:
Field | Type | Mandatory | Comments |
---|---|---|---|
-MERCHANTID- | N 16 | yes | This is the merchant ID assigned by lynck. |
-STOREID- | AN 60 | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
-ORDERID- | AN 30 | yes | This is a unique identifier for a transaction which is created by the shop. |
-MERCHANTREF- | AN | no | Reference, that additionally can be set by the shop. This parameter is sent back with every call from lynck to the shop |
-PAYMENTMETHOD- | V | yes | The identifier of the payment method. See PaymentMethods |
-LOCALE- | V | yes | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
-PI- | AN 20 | no | The unique ID of the payment instrument. This ID is created by lynck. |
-MAC- | AN 20 | no | Message Authentication Code. See: MAC calculation |
Confirmation
After a customer selected his payment method on the hosted page he will be redirected to the confirmation URL. This allows the merchant to display the selected payment method on his order confirmation page and change the final order amount accordingly if required.
Example of a confirmation URL:
https://www.example.com/testshop/confirm?merchantID=-MERCHANTID-&storeID=-STOREID-&orderID=-ORDERID-&paymentMethod=-PAYMENTMETHOD-&paymentInstrumentID=-PI-&mac=-MAC-
Successfull payment
For all payment methods which redirect the user to a different web-page the lynck system redirects the customer to the success URL of the shop, in case of a successful payment. For integration type HostedPageAfter this redirection will take place for all payment methods. The available GET parameters for the success URL are identical to those of the confirmation URL.
Example of a success URL:
https://www.example.com/testshop/success?merchantID=-MERCHANTID-&storeID=-STOREID-&orderID=-ORDERID-&paymentReference=-PAYMENTREFERENCE-&merchantReference=-MERCHANTREF-&mac=-MAC-
Failed payment
If a customer fails to complete the payment process after they were already redirected to an external payment provider, they will be redirected to the failure URL configured for the shop. This also happens if a negative response or any other error code is returned by the external payment provider. Additionally to the GET parameters available to the success and confirmation URLs, the failure URL receives a link to the hosted payment page as possible parameter, and the resultCode. This allows the shop to redirect the customer back to the hosted payment page after they cancelled the payment process or failed to authorize the payment.
Field | Type | Mandatory | Comments |
---|---|---|---|
-PIURL- | V | yes | URL of the hosted payment page |
-RESULTCODE- | N | yes | Used to identify the failure reason. See errorcodes |
-EXTERNALCODE- | AN | no | Will return the rejection/error code of the credit card acquirer, if provided. Only relevant for CC and CC3D |
-EXTERNALMESSAGE- | AN | no | Will return the rejection/error message of the credit card acquirer, if provided. Only relevant for CC and CC3D |
-RECOVERABLE- | V | no | Provides information on whether the reservation may be re-attempted. Options:
|
Example of a failure URL:
https://www.example.com/testshop/failure?merchantID=-MERCHANTID-&storeID=-STOREID-&orderID=-ORDERID-&merchantReference=-MERCHANTREF-&piUrl=-PIRUL-&resultCode=-RESULTCODE-&mac=-MAC-
Notification Call
The Merchant Notification System (MNS) is a push notification service for merchants who have integrated one of the payment systems. The MNS allows the merchant to receive a multitude of notifications asynchronously in order to decouple the merchant system from lynck’s payment systems. Integrating the merchant notification system allows the merchant to react to any kind of change in the status of transactions that were processed.
The MNS can provide two types of notifications: status notifications and payment notifications. Details for each type of request are listed below.
The status notification calls will be directed at the Status Notification Target URL that is configured for the shop, while payment notification calls will target the Payment Notification Target URL. Multiple notification-URLs may be configured for a single shop. This allows merchants to inform more than one system, for example shop system and ERP system. It is possible to configure different Status Notification Target URL/s for individual shops, in case the merchant uses multiple shops in the lynck system. By contrast, the Payment Notification Target URL/s must always be identical in all shops. If this URL is modified in one shop, the configuration is automatically applied for all other shops of the merchant. This is done because bank accounts are configured on a merchant-level and multiple shops of a merchant may use the same bank account.
If required it is also possible to configure Status Notification Target URL/s so that they only receive notifications for transactions with a certain context. This enables merchants to allow one system to receive notifications about their online checkouts, while another system could process notifications about their subscriptions.
Status Notification Request
Status notifications are sent by the lynck system whenever the status of a transaction, capture or subscription in the lynck system changes, and they include general related information, such as the transaction/capture/subscription status, transaction balance, the amount ready to be captured, or payment and merchant references. Additionally status notifications are triggered, when an incoming payment is registered, which might not necessarily trigger a transaction or capture status change. For example when an incoming payment does not fully cover the open amount of a capture, then a new capture status notification is triggered which contains the amount of the incoming payment, even though the status of the capture itself did not change. Or if an overpayment is registered for a transaction that is already considered to be paid, a new transaction status notification is triggered, as the incoming payment cannot be associated to a capture. In these cases only the fields amount and transactionBalance will be updated. Due to these incoming partial payments or overpayments, it may be possible to receive multiple notifications with the captureStatus=PAYPENDING or transactionStatus=DONE in a row.
The merchant has four options on which notifications to receive:
- All status changes (exluding INPROGRESS)(Default)
- All status changes (including INPROGRESS)
- Status changes from status PAID or to status PAID
- Changes to status PAID
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N 16 | yes | This is the merchant ID assigned by lynck. |
storeID | AN 60 | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN 50 | yes | This is a unique identifier for a transaction which is created by the shop. |
subscriptionID | AN 50 | no | This is a unique identifier for a subscription which is created by the shop. This value is only set for subscription status updates, or if a transaction/capture status update relate to a subscription. Named "subscriptionId" for notifications with version < 2.5. |
captureID | AN 50 | no | The confirmation ID of the capture. This parameter is only sent for notifications that belong to captures. |
merchantReference | AN 30 | no | Optional/additional reference for the transaction or subscription. This parameter is returned with every call from lynck to the shop. |
paymentReference | AN | no | The reference text to which the user needs to refer within his remittance so that lynck can link the incoming payments with the outstanding amounts of a transaction. |
userID | AN 50 | yes | The unique user id of the user. |
amount | N 16 | yes | The amount field is set to a positive value when an incoming payment or a chargeback was matched to a transaction and/or capture, otherwise it is set to 0. What this value represents depends on the context of the notification:
|
currency | AN 3 | no | 3 characters, Currency code according to ISO4217. This value matches the currency of the original transaction and is provided when the field "amount" is greater than 0. |
transactionStatus | V | no | Current status of the transaction. Possible values:
|
captureStatus | V | no | Current status of the capture. Named "orderStatus" for notifications with version < 2.4. Possible values:
|
subscriptionStatus | V | no | Current status of the subscription. Only available with version >= 2.5. Possible values:
|
transactionBalance | N | No | The sum of all received payments minus the sum of all captured amounts plus all reductions. This value is negative when still waiting for payments, positive in case a transaction was overpaid, and zero when the debt is paid exactly or no capture was performed yet. |
additionalData | J | no | Possible keys: accredisStatusCode |
timestamp | N | yes | The time when the status change happened in milliseconds since 1970-01-01 (Unix timestamp in milliseconds) |
version | AN | yes | Notification version |
mac | AN 40 | yes | Message Authentication Code see MAC calculation |
Payment Notification Request
Payment notifications are specific to bank based payment methods and serve to inform the merchant if payments or refunds, which were registered in their bank account, were processed. The different types of payment notifications are specified below. These notifications contain detailed information about the bank statement related to a payment. They can be used if the merchant wants to keep track of all incoming/outgoing payments and whether they were successfully matched to lynck transactions.
The use of payment notifications is completely optional and has no impact on the checkout or payment process.
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N 16 | yes | This is the merchant ID assigned by lynck. |
storeID | AN 60 | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN 50 | no | This is a unique identifier for a transaction which is created by the shop. This value is only set if the payment was associated to a lynck transaction. |
subscriptionID | AN 50 | no | This is a unique identifier for a subscription which is created by the shop. This value is only set, if the payment was associated to a lynck subscription. |
merchantReference | AN 30 | no | Optional/additional reference for the transaction, as provided by the merchant. |
paymentReference | AN | no | The reference text to which the user needs to refer within his remittance so that lynck can link the incoming payments with the outstanding amounts of a transaction. This value is only set if the payment was associated to a lynck transaction. |
notificationType | AN | yes | Describes in which context this notification was triggered. For a description of each option, see the table below. Possible values:
|
gvc | N 3 | yes | Transaction code from the bank statement (Geschäftsvorfall-Code) which describes the type of payment. |
gvcText | AN | no | Transaction description from the bank statement which describes the type of payment. |
accountNo | AN | yes | IBAN from/to which the payment is sent. |
sortCode | AN | yes | Bank identifier/SWIFT code |
owner | AN | yes | Name of the account holder. |
usage | AN | no | Customer reference as provided by the customer in case of incoming payments. Set by lynck in case of refunds. |
merchantIBAN | AN | yes | The bank account for which the payment notification was sent. |
statementNumber | AN | yes | Sequential number of the associated bank statement. |
debitCreditMarker | AN | yes | Indicates whether it is a debit or credit payment. Possible values: C (credit) and D (debit) |
valueDate | AN | yes | Value date of the payment in milliseconds since 1970-01-01 (Unix timestamp in milliseconds) |
bookingDate | N | yes | Booking date in milliseconds since 1970-01-01 (Unix timestamp in milliseconds) |
currency | AN 3 | yes | 3 characters, Currency code according to ISO4217. Currency of the payment. |
amount | N 16 | yes | Balance of the payment. |
timestamp | N | yes | The time when the payment notification was triggered in milliseconds since 1970-01-01 (Unix timestamp in milliseconds) |
version | AN | yes | Notification version |
mac | AN 40 | yes | Message Authentication Code see MAC calculation |
Notification types
Type | Description |
---|---|
FAILED | The automatic payment matching failed and the payment could therefore not be associated to a lynck transaction. |
IGNORED | The payment was automatically or manually ignored and is therefore not associated to a lynck transaction. |
MATCHED | The payment was matched to a lynck transaction. |
REFUNDED | The payment was manually refunded before it was associated to a lynck transaction. |
SENTTOACCREDIS | The payment was associated to a lynck transaction for which a dunning or collection process is active. The dunning provider was informed about the payment. |
MATCHEDBYACCREDIS | The dunning provider processed a payment for which they were previously notified and matched the payment to a lynck transaction. |
ACCREDISFEE | Notification about dunning or collection fees raised by the dunning provider. |
Response
Every notification request should be answered by the merchant's system with an HTTP response of status 200. The content is not relevant and will be ignored. If there's no such response from the merchant, the merchant notification system uses a retry mechanism in order to ensure the delivery of notifications to the merchant. The merchant notification system will try to deliver the notifications:
- every 5 minutes for 3 consecutive times and
- every hour for 5 consecutive times
In cases where the notification fails to be delivered successfully after the above tries, the Notification Service will stop any further notifications. The merchant can reactivate the MNS-Service in the 'Merchant Service Area': https://service.lynck.de in the section Settings -> Notification System -> System Notifications, selecting the locked target and then clicking the 'Reactivate' button. Also the last error message or reason why the notifications stopped is listed there.
Payment Methods
Payment Method Overview
Column | Description |
---|---|
Identifier | Payment method identifier as used in API calls |
Name | Name of the payment method in the checkout process |
Redirect | Specifies whether the customer is required to be redirected to a third party page on transaction reservation |
Country | Specifies in which countries a merchants shop must operate to offer the payment method |
Currency | Specifies which currencies are supported by the payment method |
Secure | Specifies whether the payment methods is inherently considered to be secure by lynck. This may be adapted using risk configuration |
Recurring | Specifies whether the payment method can be offered in lynck subscriptions or recurring payments |
Integration Type | Specifies which integration types support the payment method |
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
AMAZON_PAY | Amazon Pay | yes | US, GB, AT, BE, CY, DK, FR, DE, HU, IE, IT, JP, LU, NL, PT, ES, SE, CH | Amazon Pay supported currencies | yes | yes | all, Express - See Amazon Pay |
APPLE_PAY | Apple Pay | variable | Apple Pay supported countries | variable | yes | yes | API, SecureFields |
BILL | Bill payment | no | all | all | no | no | all |
BILL_SECURE | Bill secure / Billie | no | DE | EUR | yes | no | SecureFields, HostedPageAfter, HostedPageBefore |
CC | Credit card | no | variable | variable | no | yes | all |
CC3D | Credit card 3D-Secure | variable | variable | variable | yes | yes | all |
COD | Cash on delivery | no | all | all | yes | no | all |
DD | Direct debit | no | all | all | no | yes | all |
DUMMY | Dummy | no | all | all | yes | no | all |
EPS | eps | yes | all | EUR | yes | no | all |
GIROPAY | giropay | yes | all | EUR | yes | no | all |
GOOGLE_PAY | Google Pay™ | variable | variable | variable | yes | yes | all |
IDEAL | iDEAL | yes | all | EUR | yes | yes | all |
PAYPAL | PayPal | variable | PayPal supported countries | PayPal supported currencies | yes | yes | SecureFields, HostedPageAfter, HostedPageBefore, Express - See PayPal Express |
PREPAID | Cash in advance | no | all | all | yes | no | all |
SU | Sofort | yes | all | EUR | yes | no | all |
ZINIA_BNPL | Zinia Buy Now Pay Later | yes | DE | EUR | yes | no | all |
ZINIA_INSTALLMENT | Zinia Splitpay | yes | DE | EUR | yes | no | all |
Amazon Pay
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
AMAZON_PAY | Amazon Pay | yes | US, GB, AT, BE, CY, DK, FR, DE, HU, IE, IT, JP, LU, NL, PT, ES, SE, CH | Amazon Pay supported currencies | yes | yes | all, Express - See Amazon Pay |
Description
Amazon Pay should mainly be offered to customers as a pure express payment method. This means that the customer may skip the regular payment process by clicking on an Amazon Pay button to almost immediately complete a purchase. Using this process the customer data, including the delivery address, is delivered by Amazon Pay to lynck and the merchant, so that the customer does not have to register manually in the store.
As an alternative, it is also possible to provide the customer data and delivery address upfront, and to use Amazon Pay like a conventional payment method, where the user is redirected to the Amazon Pay payment page at the end of the checkout. This checkout flow should be used for recurring payments and Pay By Link, where the express checkout is not an option. Amazon Pay specifies that the express checkout should be the main integration to complete orders using Amazon Pay.
Requirements
To offer Amazon Pay as a payment method, an Amazon Pay business account is required. Within the business account, lynck needs to be registered as a developer, so that they are able to create and manage payments in the name of the merchant. Additionally, lynck requires the seller ID, client ID and the MWS auth token of the Amazon Pay business account for configuration.
Integration specifics
Amazon Pay will behave as a redirect payment method when used in one-time or recurring transactions that were initiated using createTransaction, including Pay By Link. The express checkout, in which a transaction is initiated through use of an Amazon Pay button, should be the main integration for one-time payments in any shop. See Amazon Pay
Apple Pay
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
APPLE_PAY | Apple Pay | variable | Apple Pay supported countries | variable | yes | yes | API, SecureFields |
Description
Apple Pay allows customers to pay with the press of a button, using payment methods saved to their Apple account.
The lynck system supports two different integration types, which offer different advantages:
Option | Supported channels | Benefits | Limitations |
---|---|---|---|
Option 1 | Web only |
|
|
Option 2 | Web, App |
|
|
Requirements
The requirements depend on which integration option is chosen.
Option 1
To offer Apple Pay as a payment method you will need to register the domains on which the Apple Pay button should be displayed in the merchant service area. To do so, please navigate to Settings -> Apple Pay -> Web, Hosted Pages & Subscriptions. Here you will find the option to add one or more domains and register them.
Option 2
To offer Apple Pay as a payment method, an Apple Pay Developer account is required. Depending on your integration you need to adhere to Apple Pay brand guidelines, and follow the Apple Pay integration checklist. It is required to create an Apple Pay Payment Processing Certificate and upload it in the Merchant Service Area to use Apple Pay in the production environment. To do so, please navigate to Settings -> Apple Pay -> Web & App Integration.
- Apple Pay design resources and guidelines
- Apple Pay App developer documentation
- Apple Pay Web developer documentation
Integration specifics
If you do not use a lynck plugin that supports Apple Pay, you will need to integrate the Apple Pay button into your checkout process.
Note that the Apple Pay button may only be rendered in supported browsers or devices. Before offering the payment method it should be verified that the customers' browser/device is supported. This may be done using the canMakePayments function of the official Apple Pay JS API.
Optimally the Apple Pay button should be displayed on the order confirmation page of the shop, so that the payment authorization with Apple Pay is the last step in the checkout process. This is important as the transaction amount provided when rendering the Apple Pay button should be the final amount for which the customer should be charged.
In a best case scenario the Apple Pay button would replace the "Buy" button of the store, when it was selected as a payment method.
How the Apple Pay button is integrated into the checkout depends on which integration option is chosen.
Option 1
//Apple Pay library
//For use on the production environment
<script src="https://api.crefopay.de/libs/3.0/apple-client.js"></script>
//For use on the sandbox environment
<script src="https://sandbox.crefopay.de/libs/3.0/apple-client.js"></script>
To render the Apple Pay button for a transaction, the lynck apple client JavaScript library needs to be included in the header of the page.
<script type="text/javascript" charset="utf-8">
appleClient = new AppleClient(
shopPublicKey,
orderNo,
sessionRequest,
configuration,
initializationCompleteCallback,
cancelCallback,
approveCallback
);
appleClient.createButton();
</script>
To render the button, an instance of the AppleClient needs to be created first. This is done by providing the public key of your shop, the orderID of the transaction, a session request containing transaction details, a configuration object and three callback functions. Afterwards the createButton function of the AppleClient instance can be used, to insert the button on the page.
<div data-crefopay-placeholder="appleButton"></div>
This function will search for a placeholder field on the entire page, and render the button inside it. The placeholder should be a simple DIV-element with the attribute data-crefopay-placeholder=”appleButton”.
Argument | Description |
---|---|
shopPublicKey | Your public shop key. This key is shared during onboarding or can be found in the merchant service area at Settings - Shop Details - API Credentials |
orderNo | The orderID of the transaction for which the Apple Pay button should be rendered |
sessionRequest | An Apple Pay session request which contains some transaction data to be displayed during the Apple Pay payment authorization. Details follow below |
configuration | This argument should be used to provide additional transaction information required for processing. Details follow below |
initializationCompleteCallback | This function will be called right after the client initialization and receives the API response of lynck as argument |
cancelCallback | This function will be called if the customer cancels the payment authorization process at Apple Pay |
approveCallback | This function will be called when the payment authorization at Apple Pay was successful. The transaction may be reserved afterwards |
session object
Value | Information |
---|---|
countryCode | ISO 3166 country code of the billing address country |
currencyCode | Three-letter ISO 4217 currency code of the transaction currency |
total | Object containing a label and an amount to be displayed during the Apple Pay payment authorization |
total object
Value | Information |
---|---|
label | Short description of the basket as per Apple Pay documentation |
amount | The total transaction amount as per Apple Pay documentation |
configuration object
Value | Information |
---|---|
stagingSystemUrl | Base URL of the system for which the transaction should be created. Set to Sandbox if not provided. Possible values:
|
nonce | The nonce will be passed on in the script tags for all libraries that are automatically fetched by the apple-client.js, so that the content security policy of shops can allow them to load |
buttonstyle | Sets the color/style of the Apple Pay button. Possible values:
|
locale | Sets the language used to display the Apple Pay button. Most relevant options:
|
type | Sets the Apple Pay button type which influences the text shown on the button. Most relevant options:
|
Initialization callback
The provided callback function initializationCompleteCallback will be called once the createButton function was executed, and the result will be provided to it. When resultCode=0 is returned then the button was successfully rendered. For any other resultCode the rendering failed, and an error message is provided.
Relevant fields for result processing:
Field | Description |
---|---|
resultCode |
|
message | If an error occurs, this field contains details about that error. Not set if resultCode = 0 |
Cancel callback
This function will be called if the customer cancels the payment authorization process at Apple Pay, or if the authorization failed due to any other reason. In this scenario the checkout process should not progress, and the transaction should not be reserved. The customer may re-attempt the authorization at Apple Pay.
Approve callback
This function will be called when the payment authorization at Apple Pay was successful. The payment token returned by Apple Pay is automatically stored for the transaction, so the transaction may be reserved without providing any additional parameters.
If the Apple Pay button replaced the "Buy" button of the shop, as is recommended, you may mark the order as accepted in your shop system, and immediately call the reserve API to complete the transaction.
Option 2
To process payments using Apple Pay on the lynck platform, you will need to present the Apple Pay button to your customer to collect a payment token. This payment token then needs to be passed in your reserve call in the field paymentToken when the customer confirmed their order.
For this option please follow the instructions provided by Apple Pay on how to include the Apple Pay button on the web or in app.
Recurring payments with Apple Pay
Whenever an Apple Pay transaction is successfully reserved, the card data collected from the payment token is stored as a payment instrument for the customer. The associated paymentInstrumentId can be returned as GET parameter in the callback, or it can be fetched from the field lastUsedPaymentInstrumentID using the getUser API.
If you wish to process your own recurring payments using Apple Pay, then only the initial transaction with recurringTransactionType=FIRST should be completed with payment method APPLE_PAY. For all recurring payments with recurringTransactionType=RECURRING, for which the customer is not present, the returned paymentInstrumentID should be used in combination with the payment method CC in the reserve call. Essentially the recurring payments are handled as regular recurring credit card payments based on the payment instrument that was created using Apple Pay.
Bill payments
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
BILL | Bill payment | no | DE, AT, CH | EUR, CHF | no | no | all |
Description
Bill payments are the most basic solution to allow your customers to buy something now and pay later.
Per default settings this payment method is considered insecure and will therefore only be offered to customers if no risk rules are hit, or if a configured solvency check returns a positive result.
For this payment method a dunning and collection service can be enabled, which will automatically be informed if no payment is registered upon reaching the due date of the invoice.
Requirements
To allow lynck to automatically track and match incoming payments to lynck transactions, it is required to provide account permissions to the lynck finance department. It is also recommended to create/use a bank account that is dedicated for lynck transactions. To make use of dunning and collection services, a contract with a service provider is required.
Integration specifics
In contrast to most other payment methods no payment has been made yet when the merchant creates the invoice and ships the goods when using bill as payment method. Usually a capture collects the funds that were previously reserved in the checkout process, but for bill payments the capture serves to mark when a merchant triggered the shipment of the goods and therefore the point in time from which the debt is considered to be open. It is especially important to properly capture bill transactions when the dunning and collection service is enabled, as they heavily depend on them.
Bill secure
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
BILL_SECURE | Bill payment | no | DE | EUR | yes | no | SecureFields, HostedPageAfter, HostedPageBefore |
Description
Bill payments are the most basic solution to allow your customers to buy something now and pay later. Bill secure is an alternative to regular bill payments in which the debt is bought by a third party (Billie) that pays out the merchant immediately. Therefore, it presents a more secure option for merchants that ensures liquidity.
Requirements
A business contract with Billie is required to offer bill secure as a payment method.
The payment method has the following restrictions which must be fulfilled to be offered in the checkout:
- A billing address with country=DE is set
- The transaction amount must include taxes (field netAmount)
- The userType of the customer is BUSINESS
Integration specifics
Billie requires customer identification via widget. For more details, see Billie.
Cash on delivery
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
COD | Cash on delivery | no | all | all | yes | no | all |
Description
For this payment method no actual payment gateway or provider is contacted, and the customer is not prompted to perform any payment on order completion. Generally this payment method should be used for cash or alternative payments outside the lynck platform.
Requirements
None
Integration specifics
Whenever a COD transaction is captured by the merchant, it will automatically consider itself to be paid, and immediately transition into status DONE.
Credit card
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
CC | Credit card | no | variable | variable | no | yes | all |
Description
This payment method enables customers to pay using their credit card without using 3D-Secure to verify their identity.
Due to PSD2 regulations it is no longer permitted within the EU to offer credit card payments without SCA(strong customer authentication). For shops outside the EU it is possible to still use this payment method, though it is recommended to use CC3D, or at least define conditions under which 3D-Secure should be applied.
Requirements
A contract with a partner acquirer of lynck is required to process credit card payments.
Integration specifics
Before a transaction can be reserved using CC as payment method, the credit card of the customer needs to be registered as a payment instrument in the lynck system. Merchants that are PCI certified may collect the card data themselves and provide it using the registerUserPaymentInstrument API. For all other merchants the credit card data may be collected using the SecureFields solution, which allows collection of the card data without it ever coming into direct contact with the merchant environment. When using a hosted pages solution, lynck will handle the registration of payment instruments.
Credit card 3D-Secure
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
CC3D | Credit card 3D-Secure | variable | variable | variable | yes | yes | all |
Description
This payment method enables customers to pay using their credit card while verifying their identity using 3D-Secure.
Requirements
A contract with a partner acquirer of lynck is required to process credit card payments.
Integration specifics
Before a transaction can be reserved using CC3D as payment method, the credit card of the customer needs to be registered as a payment instrument in the lynck system. Merchants that are PCI certified may collect the card data themselves and provide it using the registerUserPaymentInstrument API. For all other merchants the credit card data may be collected using the SecureFields solution, which allows collection of the card data without it ever coming into direct contact with the merchant environment. When using a hosted pages solution, lynck will handle the registration of payment instruments.
When processing credit card payments with CC3D, then the 3D-Secure v2 process is applied, and in most cases the customer is asked to verify their identity. For this purpose the customer is redirected to an external page. Depending on the issuer/bank of the customer, the payment process may also be frictionless, in which case the customer is not required to be redirected at all. Hence, it is variable whether the customer must be redirected or not. The supported countries/currencies mostly depend on the acquirer that is used to process the payments.
Direct debit
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
DD | Direct debit | no | DE, AT, CH | EUR, CHF | no | yes | all |
Description
Direct debit payments are a convenient solution to allow your customers to buy something now and pay later.
Per default settings this payment method is considered insecure and will therefore only be offered to customers if no risk rules are hit, or if a configured solvency check returns a positive result.
For this payment method a dunning and collection service can be enabled, which will automatically be informed if no payment is registered upon reaching the due date of the invoice.
Requirements
To allow lynck to automatically track and match incoming payments to lynck transactions, it is required to provide account permissions to the lynck finance department. It is also recommended to create/use a bank account that is dedicated for lynck transactions. To make use of dunning and collection services, a contract with a service provider is required.
Integration specifics
Before a transaction can be reserved using DD as payment method, the bank account of the customer needs to be registered as a payment instrument in the lynck system. Merchants may do so using the registerUserPaymentInstrument API, or alternatively using the SecureFields solution, which allows collection of the bank account data without it ever coming into direct contact with the merchant environment. When using a hosted pages solution, lynck will handle the registration of payment instruments.
In contrast to most other payment methods no payment has been made yet when the merchant creates the invoice and ships the goods when using direct debit as payment method. For direct debit, the capture will trigger the payment process, in which a SEPA file is generated and provided to the customers bank. Therefore, it is highly important that merchants properly capture their transactions, because both the actual payments and the potential dunning/collection processes depend on it. Captures may transition into status CHARGEBACK after they were already paid, if the customer triggers a payment reversal with their bank.
eps
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
EPS | eps | yes | all | EUR | yes | no | all |
Description
Eps is a bank account based payment method that is popular in Austria.
Requirements
A contract with PPRO is required to process eps payments. Lynck requires the PPRO contract ID for configuration purposes, and also the account holder name/creditor ID of the merchant to process refunds.
Integration specifics
For any eps transaction, the actual payment/transfer of funds is immediately performed after the customer authorized the payment at their bank. Therefore, captures on an eps transaction do not actually trigger any collection of funds, and only serve to mark the transaction as being fulfilled when the goods are shipped.
Giropay
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
GIROPAY | Giropay | yes | all | EUR | yes | no | all |
Description
Giropay is a bank account based payment method that is popular in Austria.
Requirements
A contract with PPRO is required to process Giropay payments. Lynck requires the PPRO contract ID for configuration purposes, and also the account holder name/creditor ID of the merchant to process refunds.
Integration specifics
For any Giropay transaction, the actual payment/transfer of funds is immediately performed after the customer authorized the payment at their bank. Therefore, captures on a Giropay transaction do not actually trigger any collection of funds, and only serve to mark the transaction as being fulfilled when the goods are shipped.
Google Pay™
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
GOOGLE_PAY | Google Pay™ | variable | variable | variable | yes | yes | all |
Description
Google Pay allows customers to pay with the press of a button, using payment methods saved to their Google account. It supports both Android™ application integrations and web integrations.
Requirements
To display the Google Pay button on your domain, a Google Pay business account is required. Depending on your integration you need to adhere to Google Pay brand guidelines, and follow the Google Pay integration checklist. In a final step you will need to request production access to use Google Pay in the production environment.
For solutions in which the payment method selection is done on either the crefopay.de or lynck.de domain, such as transactions and subscriptions using the integration type Hosted Page After and Pay By Link, no business account is required.
Google Pay Android integration:
- Google Pay Android developer documentation
- Google Pay Android integration checklist
- Google Pay Android brand guidelines
Google Pay Web integration:
- Google Pay Web developer documentation
- Google Pay Web integration checklist
- Google Pay Web brand guidelines
In case you want to use a plugin solution which renders the Google Pay button in your name, then your Google Pay merchant ID is required for configuration. You may register with the Google Pay and Wallet Console to receive your merchant ID. Further you must adhere to the Google Pay APIs Acceptable Use Policy and accept the terms that the Google Pay API Terms of Service defines.
Integration specifics
If you do not use a plugin that supports Google Pay or an integration that uses Hosted Page After, you will need to integrate the button into your checkout process. To do so please refer to the documentation listed in the 'Requirements' section. This brief video guide also provides on overview on how the button is to be integrated: Google Pay API Implementation Demo (Web)
The following description is only needed in case you integrate the button yourself:
To process payments using Google Pay on this platform, you will need to present the Google Pay button to your customer to collect a payment token. This payment token then needs to be passed in your reserve call in the field paymentToken when the customer confirmed their order.
When initializing the Google Pay button in your checkout process, you will need to set parameters to identify us as your payment provider:
Field | Value |
---|---|
gateway | lynck |
gatewayMerchantId | The merchant ID you received in the onboarding process |
Further notes:
- Only define card networks which are supported by your acquirer. This should be VISA and MASTERCARD.
- For allowedCardAuthMethods set PAN_ONLY. 3D-Secure checks for Google Pay are automatically enforced.
- Ensure the totalPriceStatus paymentDataRequest is set to FINAL if your business operates in the European Economoic Area.
- It is not required to receive and process any billing/shipping address through Google Pay, as they would already have been collected before createTransaction/createSubscription was called, or are not necessary for transactions with context PAY_BY_LINK.
Recurring payments with Google Pay
Whenever a Google Pay transaction is successfully reserved, the card data collected from the payment token is stored as a payment instrument for the customer. The associated paymentInstrumentId can be returned as GET parameter in the callback, or it can be fetched from the field lastUsedPaymentInstrumentID using the getUser API.
If you wish to process your own recurring payments using Google Pay, then only the initial transaction with recurringTransactionType=FIRST should be completed with payment method GOOGLE_PAY. For all recurring payments with recurringTransactionType=RECURRING, for which the customer is not present, the returned paymentInstrumentID should be used in combination with the payment method CC in the reserve call. Essentially the recurring payments are handled as regular recurring credit card payments based on the payment instrument that was created using Google Pay.
iDEAL
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
IDEAL | iDEAL | yes | all | EUR | yes | yes | all |
Description
iDEAL is a bank account based payment method that is popular in the Netherlands.
Requirements
A contract with PPRO is required to process iDEAL payments. Lynck requires the PPRO contract ID for configuration purposes, and also the account holder name/creditor ID of the merchant to process refunds.
Integration specifics
For any iDEAL transaction, the actual payment/transfer of funds is immediately performed after the customer authorized the payment at their bank. Therefore, captures on an iDEAL transaction do not actually trigger any collection of funds, and only serve to mark the transaction as being fulfilled when the goods are shipped.
Recurring payments with iDEAL
Natively iDEAL does not support recurring payments, but the lynck system was adapted to support recurring payments based on the customer bank account that is returned when completing a purchase with iDEAL. For lynck subscriptions, lynck will automatically process all recurring payments using the payment method direct debit(DD).
Whenever an IDEAL transaction is successfully reserved, the bank account returned by iDEAL is stored as a payment instrument for the customer. The associated paymentInstrumentId can be returned as GET parameter in the callback, or it can be fetched from the field lastUsedPaymentInstrumentID using the getUser API. If you wish to process your own recurring payments using iDEAl, then only the initial transaction with recurringTransactionType=FIRST should be completed with payment method IDEAL. For all recurring payments the returned paymentInstrumentID should be used in combination with the payment method DD. If a customer completed an iDEAL transaction with recurringTransactionType=FIRST, then a recurring SEPA mandate is automatically generated and provided to the customer via email.
PayPal
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
PAYPAL | PayPal | variable | PayPal supported countries | PayPal supported currencies | yes | yes | SecureFields, HostedPageAfter, HostedPageBefore, Express - See PayPal Express |
Description
Using this payment method allows the processing of payments through the PayPal platform. Additionally, lynck supports a multitude of PayPal services such as PayPal Express, PayPal subscriptions and PayPal disputes.
Requirements
To offer PayPal as a payment method, a PayPal business account is required. The merchant will need to grant lynck permissions to perform certain actions in their name, so that lynck can create and manage payments for them. Additionally, lynck requires the email associated to the PayPal business account for configuration purposes.
Integration specifics
Pending payments
In some cases PayPal will accept payment attempts from customers, but mark them as pending. This may be the case if PayPal performs some additional risk or fraud checks after the payment process, or if a bank based payment method was chosen by the customer. These transactions will transition into status CIAPENDING directly after being reserved, and will only go into status MERCHANTPENDING, after PayPal notified that the reservation was successful.
Merchants may ask the lynck support to disable pending payment methods in their configuration to avoid this scenario.
Redirection
Whether PayPal can be treated as a redirect payment method or not depends on the version of the PayPal gateway that is enabled for you. Generally, the latest version is not treated as a redirect payment method, but if you use lynck plugins, you may have to use an older version which still requires customer redirection.
Generally, it is recommended to dynamically react to the response code in the reserve response on whether to redirect the customer or not.
PayPal button and overlay
The latest integration type for PayPal requires that a PayPal button is rendered and displayed to the customer on the payment selection page. This PayPal button opens a window in which the customer is then able to authorize the payment, before actually completing the purchase within the shop. This type of integration is favorable as the customer will never be completely redirected outside the shop.
When using the SecureFields integration type, the merchant may decide the location and style of the PayPal button when by using a placeholder element with the attribute data-crefopay-placeholder=payPalButtons. Upon initializing the SecureFields library, the PayPal button will be rendered inside the placeholder, using the configuration values provided.
If no placeholder element for the PayPal button can be found upon initialization, then the SecureFields library will instead open an overlay if the customer triggers registerPayment() while PAYPAL was selected as payment method. Within this overlay the PayPal button will be rendered, so that the customer can log in and authorize the payment.
Overage limit and re-authorization
If a customer authorizes a certain transaction amount during the checkout process using the PayPal button, and the pop-up window which is triggered by the button, then it may be possible that the transaction amount is modified after the authorization. This may be due to last-minute changes in the shop basket, or due to delivery costs and other fees being added.
While PayPal allowed a certain amount of overcharge in the past, new regulations require that the customer re-authorizes the payment whenever the final amount is higher than the amount the payer was made aware of initially.
To allow for this, an optional flow may be enabled for your account. In this flow, when a reserve-attempt is performed, and PayPal rejects the transaction due to an overcharge, then our system will automatically initiate a process to re-authorize the new final transaction amount, and return a URL in the reserve-response, to which the customer should be redirected. When successful, the customer will be redirected to your configured success-URL, and otherwise to the configured failure-URL.
This flow is optional, and it may not be relevant to your integration, if it’s not possible to modify the transaction amount between selecting the payment method and completing the transaction.
Alternative payment methods
Additional buttons for alternative payment methods can be rendered next to the PayPal button. This will happen automatically if the relevant option was enabled by the lynck support.
Because a payment for the full transaction amount is immediately triggered upon authorization even before the reserve call was performed, it is no longer possible to modify the transaction amount in the reserve call. This makes it impossible to add or adjust delivery costs or modify the basket after the payment method was selected in the checkout process. Additionally, it is not possible to perform partial captures after a transaction was reserved using PayPal with additional payment methods enabled.
Which of the 4 enabled alternative payment methods are shown is controlled by PayPal, and it depends on the customer. PayPal attempts to identify whether the customer is from a certain country, and will offer payment methods depending on the result.
The following APMs are supported:
Name | Country |
---|---|
iDEAL | NL |
eps | AT |
bancontact | BE |
Przelewy24 | PL |
Prepaid
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
PREPAID | Cash in advance | no | DE, AT, CH | EUR, CHF | yes | no | all |
Description
Prepaid allows customers to pay their order upfront, so that the order is shipped only after the funds were received on the bank account.
Requirements
To allow lynck to automatically track and match incoming payments to lynck transactions, it is required to provide account permissions to the lynck finance department. It is also recommended to create/use a bank account that is dedicated for lynck transactions.
Integration specifics
All transactions reserved with PREPAID will transition into status CIAPENDING. They will remain in this status until a payment was added or matched to the transaction, and then transition into status MERCHANTPENDING._
Sofort
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
SU | Sofort | yes | all | EUR | yes | no | all |
Description
Sofort is a bank account based payment method that is popular in Germany.
Requirements
A Sofort business account is required to process Sofort payments. Lynck requires the Sofort user ID, project ID and API key for configuration purposes, so that they are able to trigger payments in the name of the merchant.
Integration specifics
For any Sofort transaction, the actual payment/transfer of funds is immediately performed after the customer authorized the payment at Sofort. Therefore, captures on a Sofort transaction do not actually trigger any collection of funds, and only serve to mark the transaction as being fulfilled when the goods are shipped.
Zinia Buy Now Pay Later
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
ZINIA_BNPL | Zinia Buy Now Pay Later | yes | DE | EUR | yes | no | all |
Description
Zinia Buy Now Pay Later (BNPL) allows customers to pay their debt within 30 days after they received their invoice and the delivery was triggered. To do so, they are redirected to a payment page on which they may be asked to confirm their user data and Zinia performs risk checks and either confirms or denies the customer. The merchant is paid out by Zinia when a capture is performed.
Requirements
A business contract with Zinia and their online platform provider Payever is required to offer Zinia BNPL. Lynck requires the client ID, client secret and business uuid as provided from Payever for configuration.
The payment method has the following restrictions which must be fulfilled to be offered in the checkout:
- A billing address with country=DE is set
- If a shipping address is set, it is equal to the billing address
- If a shippingRecipient is set, it is equal to the billingRecipient
- The transaction currency is EUR
- The userType is PRIVATE
- The transaction amount is between the minimum and maximum amount as dictated by Zinia
- Zinia sets these amounts per merchant contract, and they are negotiable
- The default minimum is 50€ and the default maximum is 750€
- The transaction context is not SUBSCRIPTION
- The transaction recurringTransactionType is not FIRST or RECURRING
Integration specifics
On reserve with ZINIA_BNPL as payment method, the responseCode will be 1 (redirect) and the response will contain a parameter redirectUrl, to which the customer must be redirected. On the page the customer is redirected to Zinia will ask for additional data and the user is able to confirm their payment method and review payment details.
Depending on the outcome, the customer will return to the redirect URL (API 2.0) or failure/success URL (API 2.1).
For ZINIA_BNPL, any capture will immediately trigger a payout from Zinia to the merchant. A capture can be a partial or full capture, and it will immediately transition into status PAID. If a merchant only intends to deliver a part of the order, because the customer partially cancelled it, then it is possible to inform Zinia about the cancellation by performing a finish call to cancel the remaining uncaptured amount at Zinia.
Example 1: Full capture
- A transaction of 40€ is successfully reserved using ZINIA_BNPL
- A partial capture C1 with 40€ is created
- The capture C1 automatically transitions into status PAID
- The transaction transitions into status DONE
- Zinia triggers a payout of 40€ to the merchant
Example 2: Partial captures
- A transaction of 40€ is successfully reserved using ZINIA_BNPL
- A partial capture C1 with 30€ is created
- The capture C1 automatically transitions into status PAID
- The transaction transitions into status DONE
- Zinia triggers a payout of 30€ to the merchant
- A partial capture C2 with 10€ is created
- The capture C2 automatically transitions into status PAID
- Zinia triggers a payout of 10€ to the merchant
Example 3: Partial capture and finish
- A transaction of 40€ is successfully reserved using ZINIA_BNPL
- A partial capture C1 with 30€ is created
- The capture C1 automatically transitions into status PAID
- The transaction transitions into status DONE
- Payever triggers a payout of 30€ to the merchant
- A finish call is performed for the transaction
- Zinia is notified that the remaining open 10€ of the order are cancelled
Zinia Splitpay
Payment method details
Identifier | Name | Redirect | Country | Currency | Secure | Recurring | Integration Type |
---|---|---|---|---|---|---|---|
ZINIA_INSTALLMENT | Zinia Splitpay | yes | DE | EUR | yes | no | all |
Description
Zinia Splitpay allows customers to select a payment plan in which they pay off their debt within 3-36 months. To do so, they are redirected to a payment page on which they may be asked to confirm their user data and then select a payment plan. Zinia then performs risk checks and either confirms or denies the customer. The merchant is paid out by Zinia upon fully capturing the order.
Requirements
A business contract with Zinia and their online platform provider Payever is required to offer Zinia Splitpay. Lynck requires the client ID, client secret and business uuid as provided from Payever for configuration.
The payment method has the following restrictions which must be fulfilled to be offered in the checkout:
- A billing address with country=DE is set
- If a shipping address is set, it is equal to the billing address
- If a shippingRecipient is set, it is equal to the billingRecipient
- The transaction currency is EUR
- The userType is PRIVATE
- The transaction amount is between the minimum and maximum amount as dictated by Zinia
- Zinia sets these amounts per merchant contract, and they are negotiable
- The default minimum is 50€ and the default maximum is 750€
- The transaction context is not SUBSCRIPTION
- The transaction recurringTransactionType is not FIRST or RECURRING
Integration specifics
On reserve with ZINIA_INSTALLMENT as payment method, the responseCode will be 1 (redirect) and the response will contain a parameter redirectUrl, to which the customer must be redirected. On the page the customer is redirected to Zinia will ask for additional data and the user is able to confirm their payment method and review payment details.
Depending on the outcome, the customer will return to the redirect URL (API 2.0) or failure/success URL (API 2.1).
It is possible to perform partial captures and reductions by calling the capture and refund API, but each individual call will not trigger the payout by Zinia. They are treated as virtual captures and reductions, until the full transaction amount is accounted for. Only then will Zinia be informed about the final amount that needs to be paid out to the merchant.
Example 1: Multiple partial captures
- A transaction of 40€ is successfully reserved using ZINIA_INSTALLMENT
- A partial capture C1 with 20€ is created
- The capture C1 remains in status PAYPENDING
- A partial capture C2 with 20€ is created
- The full transaction amount of 40€ is accounted for
- Both captures C1 and C2 automatically transition into status PAID
- The transaction transitions into status DONE
- Zinia triggers a payout of 40€ to the merchant
Example 2: Partial capture and reduction
- A transaction of 40€ is successfully reserved using ZINIA_INSTALLMENT
- A partial capture C1 with 20€ is created
- The capture C1 remains in status PAYPENDING
- A refund of 10€ is created with no captureID provided
- The total transaction amount is reduced to 30€
- A partial capture C2 with 10€ is created
- The full transaction amount of 30€ is accounted for
- Both captures C1 and C2 automatically transition into status PAID
- The transaction transitions into status DONE
- Zinia triggers a payout of 30€ to the merchant
API
addChargeback
The addChargeback call may be used to simulate an incoming chargeback for transactions that were reserved using the payment methods CC, CC3D or DD. This functionality may only be used on transaction captures that have registered an incoming payment, which may be simulated using the addPayment API.
For CC and CC3D the chargeback amount should be set to the paid amount of the capture for which the chargeback should be simulated.
For DD the chargeback amount may be higher than the paid amount of the capture. The difference between the chargeback amount and the paid amount of the capture will then be added as a chargeback fee, which is usually added by banks. Example: If a DD transaction with a fully paid capture c1 of 10€ exists, and a chargeback of 12€ is simulated for this capture, then the capture will be fully reopened, and an additional 2€ fee amount is added to the capture. This sets the transaction balance to -12€.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/addChargeback
<?php
function addChargeback($orderID, $captureID, $amount) {
global $requestUrl, $merchantID, $storeID;
$amount = json_encode(array('amount' => $amount));
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'captureID' => $captureID,
'amount' => $amount
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "A chargeback was simulated for order {$orderID}. Amount: {$amount}\n\r";
return true;
} else {
echo "Chargeback simulation failed: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult addChargeback() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "1200")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-123");
map.add("captureID", "capture-123");
map.add("amount", getAmount());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "44b8b355a6c42a3a"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | yes | This is the unique reference of a capture or a partial capture (e.g. the invoice number). |
amount | J (Amount) | yes | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
addressCheck
This API can be used to validate or correct a customers address. Both the mandatory fields in the request and the response to this call may vary depending on the product that is configured to perform the address check.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/addressCheck
Live: https://api.crefopay.de/2.0/addressCheck
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
address | J (Address) | yes | The address to be checked. While th address object in the request itself is mandatory, the exact fields which it should contain differ depending on the service that will be used. Independent of which service is used the field "country" is always mandatory. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
checkReferenceId | N | Unique reference to the performed check |
responseData | J | Contains the raw response data of the address check provider in JSON format |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
addPayment
The addPayment call allows the merchant to add funds to a transaction, thereby informing lynck about incoming payments. This should generally be done in case a payment was received on an account or by other means to which lynck has no access and therefore cannot match the payment to a transaction.
If it should be possible to perform a refund on this payment later on, then it is mandatory that the bank data of the account from which the payment originated from is provided.
Payments can only be added to transaction in the following states: CIAPending, MerchantPending, InProgress, Done, Cancelled or FraudCancelled. Additionally for direct debit transactions, the transaction has to have at least one capture in the status Chargeback, InDunning or InCollection.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/addPayment
Live: https://api.crefopay.de/2.0/addPayment
public lynckResult addPayment() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "500")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-130");
map.add("captureID", "capture-129");
map.add("amount", getAmount());
map.add("valutaDate", "2019-01-15");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d5813e5feb22b47d"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | see description | This is the unique reference of a capture or a partial capture (e.g. the invoice number). Only mandatory for direct debit transactions. |
amount | J (Amount) | yes | The amount of the received payment. |
valutaDate | D (YYYY-MM-DD) | yes | Date on which the payment was received. |
iban | AN (34) | no | IBAN of the bank account from which the payment was received. Required if a refund is to be performed on this payment. |
accountHolder | AN (70) | no | The account holder of the bank account from which the payment was received. Required if a refund is to be performed on this payment later on. |
message | AN (255) | no | Payment description |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
batch
Request Header
Field | Mandatory | Comments |
---|---|---|
X-API-Key | yes | Your public API key |
Content-Type | yes | application/json |
Sample batch/createAndReserveRecurringTransaction request body:
{
"url": "https://notification.merchant.de/errors",
"createAndReserveTransactionRequest": [
{
"orderID": "recurringOrder-500",
"referenceOrderID": "initialOrder-10",
"userID": "user-123",
"merchantReference": "Additional reference text 1",
"amount": 1000,
"locale": "DE"
},
{
"orderID": "recurringOrder-501",
"referenceOrderID": "initialOrder-11",
"userID": "user-321",
"merchantReference": "Additional reference text 2",
"amount": 500,
"locale": "EN"
}
]
}
batch createAndReserveRecurringTransaction
This endpoint starts, automatically reserves and captures one or more transactions in the lynck system. The purpose of this is to create batches of up to 1000 recurring transactions within one request, instead of performing individual requests for each charge. This increases the speed at which the recurring charges can be processed.
This API cannot be used to create transactions that require any sort of customer interaction. The transactions created here are only intended to charge existing customers based on an already existing payment agreement.
Every transaction created using this endpoint will be created with integrationType=API, recurringTransactionType=RECURRING and autoCapture=true and has to refer to the initial transaction in which the customer authorized the recurring charges.
While the formatting is validated upfront, the contents are only evaluated when each transaction is processed. Should an error occur while a transaction is processed, or should the payment be declined by a service provider, then a POST notification is sent to a URL provided in the initial request. Each notification should be answered with HTTP code 200 to confirm that it was received. Should the notification delivery fail for any reason, then it is possible to fetch all errors that occurred during processing using the batch errors endpoint.
Method | URL |
---|---|
POST |
|
POST createAndReserveRecurringTransaction Request Body
Field | Type | Mandatory | Comments |
---|---|---|---|
url | string | yes | This URL receives POST notifications about failed transactions, should any error occur. See MerchantNotificationMessage |
createAndReserveTransactionRequest | J (CreateAndReserveTransactionRequest) | yes | Container object for one to 1000 create transaction and reserve requests |
POST createAndReserveRecurringTransaction HTTP Response Code
Code | Comments |
---|---|
202 | Request accepted, the system will attempt to process all provided transactions. Response body contains resultCode |
400 | Bad request |
401 | Unauthorized |
POST createAndReserveRecurringTransaction Response Body
Field | Type | Comments |
---|---|---|
resultCode | N |
|
batch errors
This endpoint may be used to receive (Method=GET) a list of all errors that have occurred during batch transaction creation, in case the delivery of error notifications failed. Alternatively it can be used to clear (Method=DELETE) the list. No request body parameters are required.
Method | URL |
---|---|
|
|
GET errors HTTP Response Code
Code | Comments |
---|---|
200 | OK. Response body may return one or multiple errors that may have occurred during batch transaction creation. See MerchantNotificationMessage |
400 | Bad request |
401 | Unauthorized |
DELETE errors HTTP Response Code
Code | Comments |
---|---|
200 | OK. Error list was cleared |
400 | Bad request |
401 | Unauthorized |
cancel
The cancel call allows the merchant to cancel an transaction where no capture has been processed yet.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/cancel
Live: https://api.crefopay.de/2.0/cancel
<?php
function cancel($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully cancelled the order {$orderID}.\n\r";
return true;
} else {
echo "We failed to cancel the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult cancel() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-130");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d5813e5feb22b47d"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
capture
The capture call allows the merchant to create orders or part-orders for already started transactions
URL:
Sandbox: https://sandbox.crefopay.de/2.0/capture
Live: https://api.crefopay.de/2.0/capture
<?php
function capture($orderID, $captureID, $transactionAmount) {
global $requestUrl, $merchantID, $storeID;
$amount = json_encode(array('amount' => $transactionAmount));
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'captureID' => $captureID,
'amount' => $amount
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully captured the order {$orderID}. Amount: {$transactionAmount}\n\r";
return true;
} else {
echo "We failed to capture the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult capture() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("captureID", "capture-129");
map.add("amount", getAmount());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"39e01bcfcc9eabb1",
"status":"PAYPENDING"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | yes | This is the unique reference of a capture or a partial capture (e.g. the invoice number). |
amount | J (Amount) | yes | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
status | AN | The status of the order. PAID, PAYPENDING or PAYMENTFAILED |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
createSubscription
The createSubscription call creates a subscription in the lynck system and evaluates which paymentMethods are available for the given user and basket data under consideration of various risk management aspects. A subscription will charge a customer in defined intervals. If a trial period is set the customer will be charged afterwards. A subscription always has a reference to an existing plan, which sets the default rate, trial period and payment interval. Though the trial period and amount can be overwritten for an individual subscription. Plans are created in the merchant service area.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/createSubscription
Live: https://api.crefopay.de/2.0/createSubscription
<?php
function createSubscription($subscriptionID, $userID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters for creating a transaction here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'subscriptionID' => $subscriptionID,
'userID' => $userID,
'planReference => 'daily basic subscription',
'integrationType' => 'API',
'autoCapture' => 'false',
'context' => 'ONLINE',
'userType' => 'PRIVATE',
'userRiskClass' => '0',
'amount' => json_encode(
array(
'amount' => '100',
)
),
'basketItems' => json_encode(
array(
array(
'basketItemText' => 'User Registration Item',
'basketItemCount' => '1',
'basketItemAmount' => array(
'amount' => '100',
),
),
)
),
'locale' => 'DE'
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully created the subscription {$subscriptionID}. Amount: {$transactionAmount}\n\r";
return true;
} else {
echo "We failed to created the subscription: {$subscriptionID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult createSubscription() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getUserData() {
return Json.createObjectBuilder()
.add("name", "Max")
.add("surname", "Mustermann")
.add("dateOfBirth", "1978-08-15")
.add("email", "max@mustermann.de")
.build()
.toString();
}
private String getBillingAddress() {
return Json.createObjectBuilder()
.add("street", "Hauptstraße")
.add("no", "1")
.add("zip", "10827")
.add("city", "Berlin")
.add("country", "DE")
.build()
.toString();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private String getBasketItems() {
JsonArrayBuilder builder = Json.createArrayBuilder();
builder.add(Json.createObjectBuilder().add("basketItemText", "Item1").add("basketItemCount", "1").add("basketItemAmount", Json.createObjectBuilder()
.add("amount", "12399")).build());
builder.add(Json.createObjectBuilder().add("basketItemText", "Item2").add("basketItemCount", "3").add("basketItemAmount", Json.createObjectBuilder()
.add("amount", "12399")).build());
return builder.build().toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("subscriptionID", "subscription-132");
map.add("userID", "user-127");
map.add("planReference", "daily basic subscription");
map.add("context", "ONLINE");
map.add("userType", "PRIVATE");
map.add("userRiskClass", "0");
map.add("userData", getUserData());
map.add("billingAddress", getBillingAddress());
map.add("amount", getAmount());
map.add("basketItems", getBasketItems());
map.add("locale", "DE");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d9d59524d630930d",
"userData":{
"name":"Max",
"surname":"Mustermann",
"dateOfBirth":"1978-08-15",
"email":"max@mustermann.de"
},
"billingAddress":{
"street":"Hauptstraße",
"no":"1",
"zip":"10827",
"city":"Berlin",
"country":"DE"
},
"allowedPaymentMethods":[
"DD"
],
"allowedPaymentInstruments":[
],
"additionalInformation":[
{
"paymentMethodType":"DD",
"issuer":[
],
"logos":[
],
"customTranslations":{
},
"sepaPaymentType":"RCUR",
"mandateReference":"535357",
"creditorId":"DE39ZZZ00001385300",
"merchantName":"DEMO",
"date":"13.08.2018"
}
]
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
subscriptionID | AN (50) | yes | This is a unique identifier for a subscription which is created by the shop. |
planReference | AN (15) | yes | ID of the plan that the subscription will be based upon. |
startDate | D(YYYY-MM-DD) | no | Defines a future date on which the subscription will become active and trigger the first payment. If a trial period is defined, then the trial period will begin on the start date. If no start date is provided the subscription will start immediately upon user confirmation. |
trialPeriod | N (3) | no | Trial period in days. Range from 1 to 366. The trial period begins when the subscription becomes active, and the first payment will be triggered when the trial period ends. |
userID | AN (50) | yes | The unique user id of the user. |
integrationType | V | no | The type of integration in the web shop. Possible Values:
|
merchantReference | AN (30) | no | Optional/additional reference for the transaction. This parameter is returned with every call from lynck to the shop. |
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation. Possible Values:
|
userRiskClass | N (1) / D (1.1) | no | Possible values are:
|
userIpAddress | AN (15) | no | The IP address of the customer |
companyData | J (Company) | see comment | Contact data of the user's company. This field is mandatory if the userType is BUSINESS and the userID was not registered before |
userData | J (Person) | see comment | Contact data of the user. This field is mandatory if the userType is PRIVATE and the userID was not registered before |
billingRecipient | AN (80) | no | Recipient for the Bill. |
billingAddress | J (Address) | see comment | The user's billing address. This field is mandatory if if user was not registered before with this userID |
shippingRecipient | AN (80) | no | Recipient for shipping |
shippingAddress | J (Address) | no | The customers shipping address |
amount | J (Amount) | no | If provided, this amount will overwrite the amount set in the subscription plan. This is not permitted for subscription plans for which the option "Enable PayPal Subscriptions" was checked. If not provided, the amount of the subscription plan is used. |
basketItems | JA (Basket Item) | yes | A detailed list of all basket items |
basketValidity | AN (4) | no | m -> minutes, h -> hours, d -> days; Example: one hour: 1h, ten minutes: 10m, two days: 2d - only one unit of time can be provided |
locale | V | yes | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
userData | J (Person) | Data of the user |
billingAddress | J (Address) | Address of the user |
companyData | J (Company) | Data of the company |
allowedPaymentMethods | JA (PaymentMethods) | List of payment methods that are allowed for this user |
allowedPaymentInstruments | JA (PaymentInstrument) | List of valid payment instruments that are registered for this user |
redirectUrl | AN (1024) | The URL of the page that should be shown to the user. This is only set if the resultCode is 1 |
additionalInformation | JA (PaymentMethodInformation) | List of additional information for presenting the payment instruments to the customer. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
createTransaction
This call starts a transaction in the lynck system. The workflow depends on the integrationType. For more information refer to Integration options. Further, this call can act both as registerUser and updateUser call if an unknown/known userID is provided, often making the implementation of these calls unnecessary
URL:
Sandbox: https://sandbox.crefopay.de/2.0/createTransaction
Live: https://api.crefopay.de/2.0/createTransaction
<?php
function createTransaction($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters for creating a transaction here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'userID' => $userID,
'integrationType' => 'API',
'autoCapture' => 'false',
'context' => 'ONLINE',
'userType' => 'PRIVATE',
'userRiskClass' => '0',
'amount' => json_encode(
array(
'amount' => '100',
)
),
'basketItems' => json_encode(
array(
array(
'basketItemText' => 'User Registration Item',
'basketItemCount' => '1',
'basketItemAmount' => array(
'amount' => '100',
),
),
)
),
'locale' => 'DE'
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully created the order {$orderID}. Amount: {$transactionAmount}\n\r";
return true;
} else {
echo "We failed to created the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult createTransaction() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getUserData() {
return Json.createObjectBuilder()
.add("name", "Max")
.add("surname", "Mustermann")
.add("dateOfBirth", "1978-08-15")
.add("email", "max@mustermann.de")
.build()
.toString();
}
private String getBillingAddress() {
return Json.createObjectBuilder()
.add("street", "Hauptstraße")
.add("no", "1")
.add("zip", "10827")
.add("city", "Berlin")
.add("country", "DE")
.build()
.toString();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private String getBasketItems() {
JsonArrayBuilder builder = Json.createArrayBuilder();
builder.add(Json.createObjectBuilder().add("basketItemText", "Item1").add("basketItemCount", "1").add("basketItemAmount", Json.createObjectBuilder()
.add("amount", "12399")).build());
builder.add(Json.createObjectBuilder().add("basketItemText", "Item2").add("basketItemCount", "3").add("basketItemAmount", Json.createObjectBuilder()
.add("amount", "12399")).build());
return builder.build().toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-124");
map.add("userID", "user-127");
map.add("context", "ONLINE");
map.add("userType", "PRIVATE");
map.add("userRiskClass", "0");
map.add("userData", getUserData());
map.add("billingAddress", getBillingAddress());
map.add("amount", getAmount());
map.add("basketItems", getBasketItems());
map.add("locale", "DE");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d9f7268bb493e51b",
"userData":{
"name":"Max",
"surname":"Mustermann",
"dateOfBirth":"1978-08-15",
"email":"max@mustermann.de"
},
"billingAddress":{
"street":"Hauptstraße",
"no":"1",
"zip":"10827",
"city":"Berlin",
"country":"DE"
},
"allowedPaymentMethods":[
"CC",
"PAYPAL",
"BILL"
],
"allowedPaymentInstruments":[
{
"paymentInstrumentID":"Aqc9O5SSJuQTDHC9KXFE0Q",
"paymentInstrumentType":"CREDITCARD",
"accountHolder":"Max Mustarmann",
"number":"************1111",
"validity":"2025-01",
"issuer":"VISA",
"mandatoryReserveFields":[
"cvv"
]
}
],
"additionalInformation":[
{
"paymentMethodType":"CC",
"issuer":[
"VISA",
"MC"
],
"logos":[
"VISA",
"MC"
],
"customTranslations":{
}
},
{
"paymentMethodType":"PAYPAL",
"issuer":[
],
"logos":[
],
"customTranslations":{
}
},
{
"paymentMethodType":"BILL",
"issuer":[
],
"logos":[
],
"customTranslations":{
}
}
]
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
userID | AN (50) | yes | The unique user id of the user. |
integrationType | V | no | The type of integration in the web shop. Possible Values:
|
autoCapture | B | no | Enable automatic capture directly after the successful reservation, if the parameter is not set, the default is "false" |
merchantReference | AN (30) | no | Optional/additional reference for the transaction. This parameter is returned with every call from lynck to the shop. |
context | V | no | Determines if the transaction was initiated during online-checkout process or offline where no direct user interaction happens. Will be set to ONLINE by default if not provided. Possible Values:
|
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation. Possible Values:
|
userRiskClass | N (1) / D (1.1) | no | Possible values are:
|
userIpAddress | AN (39) | no | The IP address of the customer. Supported formats are IPv4 and IPv6 |
restrictedPaymentMethods | V | no | The payment methods provided in this field will not be marked as available for this transaction, and will not be offered to the customer on the hosted payment pages. Should contain a comma separated string of payment method identifiers |
companyData | J (Company) | see comment | Contact data of the user's company. This field is mandatory if the userType is BUSINESS and the userID was not registered before |
userData | J (Person) | see comment | Contact data of the user. This field is mandatory if the userType is PRIVATE and the userID was not registered before |
creditLimit | J (Amount) | no | If this field is provided then the value is saved as specific credit limit for this customer only. Any previously saved credit limit will be overwritten. |
billingRecipient | AN (80) | no | Recipient for the Bill. |
billingAddress | J (Address) | see comment | The user's billing address. This field is mandatory if if user was not registered before with this userID |
shippingRecipient | AN (80) | no | Recipient for shipping |
shippingAddress | J (Address) | no | The customers shipping address |
amount | J (Amount) | yes | The amount of the basket |
basketItems | JA (Basket Item) | yes | A detailed list of all basket items |
basketValidity | AN (4) | no | m -> minutes, h -> hours, d -> days; Example: one hour: 1h, ten minutes: 10m, two days: 2d - only one unit of time can be provided |
hostedPagesTexts | JA (HostedPages text) | no | A list of texts for the hosted page in for different languages for different payment methods |
locale | V | yes | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
additionalPaymentOptions | J (Payment options) | no | additional options |
solvencyCheckInformation | J (Solvency check information) | no | result of a solvency check done by the merchant. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
userData | J (Person) | Data of the user |
billingAddress | J (Address) | Address of the user |
companyData | J (Company) | Data of the company |
allowedPaymentMethods | JA (PaymentMethods) | List of payment methods that are allowed for this user |
allowedPaymentInstruments | JA (PaymentInstrument) | List of valid payment instruments that are registered for this user |
redirectUrl | AN (1024) | The URL of the page that should be shown to the user. This is only set if the resultCode is 1 |
additionalInformation | JA (PaymentMethodInformation) | List of additional informations for presenting the payment instruments to the customer. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
Handling of Packstation addresses
- These type of address is only valid for shipping address
- The “Postnummer” is expected in the field shippingRecipient
- The word “Packstation” is expected in field street of the shippingAddress
- The number of “Packstation” is expected in field number of shippingAddress
deleteUserPaymentInstrument
The deleteUserPaymentInstrument call adds the functionality to delete a payment instrument from a user.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/deleteUserPaymentInstrument
Live: https://api.crefopay.de/2.0/deleteUserPaymentInstrument
<?php
function deleteUserPaymentInstrument($paymentInstrumentID) {
global $requestUrl, $merchantID;
$param = array(
'merchantID' => $merchantID,
'paymentInstrumentID' => $paymentInstrumentID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully deleted the paymentinstrument {$paymentInstrumentID}\n\r";
return true;
} else {
echo "We failed to delete the paymentinstrument: {$paymentInstrumentID}\n\r Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult deleteUserPaymentInstrument() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("paymentInstrumentID", "b2z4aogwDQJbvH144Kwt8g");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"951733fa7ecc7a7e"
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
paymentInstrumentID | AN (20) | yes | The unique identifier of the payment instrument |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response:
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
finish
The finish call allows the merchant to finish an transaction where at least one capture has been created. This signals lynck that all expected funds were captured and no further payment are expected.
The finish call will trigger the following actions:
- If there are any uncaptured funds matched to the transaction, they will be refunded to the customer
- The open amount of all existing captures is set to 0, meaning they will transition into status PAID
- The transaction will transition into status DONE, if it is not in this status already
- For CC/CC3D/PAYPAL: the reservation for the remaining uncaptured amount is revoked at the respective payment provider, which means no further captures are permitted
URL:
Sandbox: https://sandbox.crefopay.de/2.0/finish
Live: https://api.crefopay.de/2.0/finish
<?php
function finish($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully finished the order {$orderID}.\n\r";
return true;
} else {
echo "We failed to finish the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult finish() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"39b83acd3064a20b"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getCaptureStatus
This call returns the status of a captured order.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getCaptureStatus
Live: https://api.crefopay.de/2.0/getCaptureStatus
<?php
function getCaptureStatus($orderID, $captureID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'captureID' => $captureID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the status for the capture: {$captureID}.\n\r";
return responseBody;
} else {
echo "We failed to get the status for capture: {$captureID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getCaptureStatus() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("captureID", "capture-129");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"761493d8ca3ef46c",
"captureStatus":"PAID",
"additionalData":{
"transactionAmount":12399,
"capturedAmount":12399,
"paidAmount":12276,
"creditAmount":123,
"reducedAmount":0,
"guaranteedAmount":0,
"returnedGuaranteeAmount":0,
"feeAmount":0,
"openAmount":0,
"transactionCurrency":"EUR"
}
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | yes | This is the unique reference of a capture or a partial capture (e.g. the invoice number). |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
captureStatus | V | The status of a capture. Possible values: see capture process |
additionalData | J (CaptureStatusDetail) | Additional information to the capture |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getSubscriptionPlans
The getSubscriptionPlans call provides details of all subscription plans created in the lynck system. The result can be filtered using parameters. This call can be used to dynamically display subscription plans in a shop front-end or to receive a specific plan ID for use in the createSubscription call.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getSubscriptionPlans
Live: https://api.crefopay.de/2.0/getSubscriptionPlans
<?php
function getSubscriptionPlans() {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the plans for store: {$storeID}.\n\r";
return responseBody;
} else {
echo "We failed to get the plans for store: {$storeID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getSubscriptionPlans() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d53159b2fc5118e1",
"pageNumber":2,
"pageSize":100,
"totalEntries":11,
"subscriptionPlans":[
{
"planReference":"bas",
"name":"basic",
"description":"daily basic subscription",
"interval":"DAILY",
"hasSubscribers":true,
"amount":{
"amount":499
}
},
{
"planReference":"pre",
"name":"premium",
"description":"daily premium subscription",
"interval":"DAILY",
"hasSubscribers":true,
"amount":{
"amount":999
}
}
]
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
interval | V | no | Possible values are:
|
trialPeriodRange | J | no | Range object of numeric type with values between 1 and 366 ( {minimum: number, maximum: number} ) |
pageNumber | N | no | Number of the page that should be returned. |
pageSize | N (3) | no | Amount of results returned per page. (1-100) |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
pageNumber | N | Number of the page that was returned. |
pageSize | N (3) | Amount of results returned per page. (1-100) |
totalEntries | N | The total amount of results. |
subscriptionPlans | JA (SubscriptionPlan) | Contains information of all plans that fit the provided parameters. |
salt | AN | A random number to guarantee the uniqueness of the message. |
getSubscriptionStatus
This call returns the status of a subscription.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getSubscriptionStatus
Live: https://api.crefopay.de/2.0/getSubscriptionStatus
<?php
function getSubscriptionStatus($subscriptionID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'subscriptionID' => $subscriptionID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the status for subscription: {$subscriptionID}.\n\r";
return responseBody;
} else {
echo "We failed to get the status for subscription: {$subscriptionID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getSubscriptionStatus() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("subscriptionID", "S-100002");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "520e21131977c584",
"userType": "PRIVATE",
"planReference": "subscrPlan1",
"nextPayment": {
"transactionAmount": {
"amount": 500
},
"paymentDate": "2021-03-04"
},
"subscriptionStatus": "ACTIVE",
"subscriptionID": "S-100002",
"userID": "subscriptionUser1",
"subscriptionCreationDate": "2021-02-04",
"subscriptionAmount": {
"amount": 500
}
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
subscriptionID | AN (50) | yes | This is a unique identifier for a subscription which is created by the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
salt | AN | A random number to guarantee the uniqueness of the message. |
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
subscriptionStatus | V | The status of the subscription referred by the subscription ID. Possible values:
|
merchantReference | AN (30) | Optional/additional reference for the subscription. |
userID | AN (50) | The unique user id of the user. |
userType | V | This parameter defines business or private customers. This value cannot be changed after user creation. Type of the subscribed customer. Possible Values:
|
subscriptionAmount | J (Amount) | Current amount to be charged regularly. |
subscriptionCreationDate | D (YYYY-MM-DD) | The date when the in subscription was created |
subscriptionStartDate | D (YYYY-MM-DD) | The date when the subscription is scheduled to start. Only returned if the subscription is scheduled to start in the future. Will not be returned in status NEW or USER_PENDING. |
firstPaymentDate | D (YYYY-MM-DD) | The date when the first subscription payment was performed, or will be performed. Will not be returned in status NEW or USER_PENDING. |
trialPeriod | N (3) | Trial period set for the subscription in days. |
planReference | AN (15) | Reference of the subscription plan used to create the subscription. |
nextPayment | J (nextPayment) | Returns the amount and the payment date of the next scheduled payment for the subscription. This field will not be set, if no next payment is scheduled, which is the case when the subscription was not confirmed yet (subscriptionStatus=USER_PENDING) is paused (subscriptionStatus=PAUSED) or the subscription was cancelled (subscriptionStatus=CANCELLED). |
Subscription status | Description |
---|---|
NEW | The subscription was created. |
USER_PENDING | The subscription was created and the customer received an email with a link to complete the subscription. |
START_PENDING | The subscription was confirmed by the user, and it is set to trigger the first payment at a future start date. |
ACTIVE | The subscription was confirmed by the customer and it is now actively triggering payments in the scheduled interval. |
PAUSED | The subscription was paused by the merchant. The regular payment cycle will continue once it was reactivated. |
CANCELLED | The subscription was cancelled by the merchant. No further payments will be triggered. |
DONE | All scheduled payments for the subscription were performed. Subscriptions with an endless payment cycle will never reach this status. |
getSubscriptionTransactions
This call returns a list of all transactions related to a subscription and their status.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getSubscriptionTransactions
Live: https://api.crefopay.de/2.0/getSubscriptionTransactions
<?php
function getSubscriptionTransactions($subscriptionID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'subscriptionID' => $subscriptionID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the transactions for subscription: {$subscriptionID}.\n\r";
return responseBody;
} else {
echo "We failed to get the transactions for subscription: {$subscriptionID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getSubscriptionTransactions() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("subscriptionID", "1606830285083");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "b5f617e981c4571b",
"transactions": [
{
"orderID": "S-103819",
"transactionStatus": "DONE",
"creationDate": "2021-01-26",
"lastStatusChange": "2021-01-26",
"transactionAmount": {
"amount": 500
}
},
{
"orderID": "S-103786",
"transactionStatus": "DONE",
"creationDate": "2020-12-29",
"lastStatusChange": "2020-12-29",
"transactionAmount": {
"amount": 500
}
},
{
"orderID": "1606830285083",
"transactionStatus": "DONE",
"creationDate": "2020-12-01",
"lastStatusChange": "2020-12-01",
"transactionAmount": {
"amount": 500
}
}
]
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
subscriptionID | AN (50) | yes | This is a unique identifier for a subscription which is created by the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
transactions | J (Subscription transactions) | Contains basic information for one or multiple transactions associated to the subscription |
salt | AN | A random number to guarantee the uniqueness of the message. |
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) |
getTransactionPaymentInstruments
This call gets a refreshed list of payment instruments. This is useful if the reserve call fails because of problems with a specific payment instrument or because of fraud rules. This call will only work in TransactionStatus 'NEW' The list of payment instruments returned by this call is the same or less like the list returned by create transaction.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getTransactionPaymentInstruments
Live: https://api.crefopay.de/2.0/getTransactionPaymentInstruments
<?php
function getTransactionPaymentInstruments($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the paymentinstrument for order: {$orderID}.\n\r";
return responseBody;
} else {
echo "We failed to get the paymentinstrument for order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getTransactionPaymentInstruments() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-131");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"8d83157f738bca24",
"userData":{
"name":"Max",
"surname":"Mustermann",
"dateOfBirth":"1978-08-15",
"email":"max@mustermann.de"
},
"billingAddress":{
"street":"Hauptstraße",
"no":"1",
"zip":"10827",
"city":"Berlin",
"country":"DE"
},
"allowedPaymentMethods":[
"CC",
"PAYPAL"
],
"allowedPaymentInstruments":[
],
"additionalInformation":[
{
"paymentMethodType":"CC",
"issuer":[
"VISA",
"MC"
],
"logos":[
"VISA",
"MC"
],
"customTranslations":{
}
},
{
"paymentMethodType":"PAYPAL",
"issuer":[
],
"logos":[
],
"customTranslations":{
}
},
],
"billingRecipient":"Max Mustermann"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
userData | J (Person) | Data of the user |
billingAddress | J (Address) | Billing address of the user |
shippingAddress | J (Address) | Shipping address of the user |
companyData | J (Company) | Data of the company |
allowedPaymentMethods | JA (PaymentMethods) | List of payment methods that are allowed for this user |
allowedPaymentInstruments | JA (PaymentInstrument) | List of valid payment instruments that are registered for this user |
redirectUrl | AN (1024) | The URL of the page that should be shown to the user. This is only set if the resultCode is 1 |
additionalInformation | JA (PaymentMethodInformation) | List of additional informations for presenting the payment instruments to the customer. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getTransactionStatus
This call returns the status of a transaction.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getTransactionStatus
Live: https://api.crefopay.de/2.0/getTransactionStatus
<?php
function getTransactionStatus($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the status for order: {$orderID}.\n\r";
return responseBody;
} else {
echo "We failed to get the status for order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getTransactionStatus() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"9bbc1ca20347517d",
"transactionStatus":"DONE",
"additionalData":{
"paymentMethod":"BILL",
"paymentReference":"PCB-0000668890",
"accountHolder":"Max Mustermann",
"iban":"DE06000000000023456789",
"bankname":"Postbank",
"bic":"SFRTDE20000",
"customerEmail":"max@mustermann.de",
"transactionAmount":12399,
"transactionCurrency":"EUR",
"transactionBalance":0
},
"billingAddress": {
"street": "Teststraße",
"no": "123",
"zip": "10961",
"city": "Berlin",
"country": "DE",
"name": "Max Mustermann"
},
"shippingAddress": {
"street": "Teststraße",
"no": "123",
"zip": "10961",
"city": "Berlin",
"country": "DE",
"name": "Max Mustermann"
}
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
returnRiskData | B | no | Set to 'true' if solvency-check information should be returned in the response |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
transactionStatus | V | The status of the transaction referred by the order ID. Possible values: see Transaction process |
riskData | J (RiskData) | This array contains data of all solvency-checks that are connected to the transaction |
additionalData | J (TransactionStatusDetail) | Additional information to the transaction. Only set after the transaction was reserved. |
billingAddress | J (Address) | The customer's billing address |
shippingAddress | J (Address) | The customer's shipping address |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getUser
This call returns relevant user data. Optionally it may return solvency check information or the balance of the user.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getUser
Live: https://api.crefopay.de/2.0/getUser
<?php
function getUser($userID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'userID' => $userID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the user: {$userID}.\n\r";
return responseBody;
} else {
echo "We failed to get the user: {$userID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getUser() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"c1d5c2585402b44a",
"userData":{
"name":"Max",
"surname":"Mustermann",
"dateOfBirth":"1978-08-15",
"email":"max@mustermann.de"
},
"billingRecipient":"Max Mustermann",
"billingAddress":{
"street":"Hauptstraße",
"no":"1",
"zip":"10827",
"city":"Berlin",
"country":"DE"
},
"shippingRecipient":"Max Mustermann",
"shippingAddress":{
"street":"Hauptstraße",
"no":"1",
"zip":"10827",
"city":"Berlin",
"country":"DE"
},
"locale":"DE"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
returnUserBalance | B | no | Set to 'true' if the balance of the user should be returned in the response |
returnRiskData | B | no | Set to 'true' if solvency-check information should be returned in the response |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
companyData | J (Company) | Contact data of the user's company |
userBalance | J (userBalance) | Contains the current balance and total transaction amount of the user |
userData | J (Person) | Contact data of the user |
billingRecipient | AN | Recipient for the billing address |
billingAddress | J (Address) | The person's billing address |
shippingRecipient | AN | Recipient for shipping address |
shippingAddress | J (Address) | The person's shipping address |
lastUsedPaymentInstrumentID | AN | The ID of the payment instrument that was last used by the user |
userStatus | V | Possible values:
|
riskData | J (RiskData) | This array contains data of all solvency-checks that were requested for this user |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getUserPaymentInstrument
The getUserPaymentInstrument call adds the functionality to get a user‘s PaymentInstruments.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getUserPaymentInstrument
Live: https://api.crefopay.de/2.0/getUserPaymentInstrument
<?php
function getUserPaymentInstrument($userID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'userID' => $userID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the paymentinstruments for user: {$userID}.\n\r";
return responseBody;
} else {
echo "We failed to get the paymentinstruments for user: {$userID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getUserPaymentInstrument() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"140e15d63d36eba6",
"paymentInstruments":[
{
"paymentInstrumentID":"Aqc9O5SSJuQTDHC9KXFE0Q",
"paymentInstrumentType":"CREDITCARD",
"accountHolder":"Max Mustarmann",
"number":"************1111",
"validity":"2025-01",
"issuer":"VISA"
}
]
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
mac | AN 40 | yes | Message Authentication Code. See: MAC calculation |
Response:
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
paymentInstruments | JA (PaymentInstrument) | List of valid payment instruments that are registered for this user |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
getUserTransactions
This call returns basic information for all transactions of a user.
The result may contain a maximum of 100 transactions. If more than 100 transactions exist for the customer, pagination can be used to fetch more entries.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/getUserTransactions
Live: https://api.crefopay.de/2.0/getUserTransactions
<?php
function getUserTransactions($userID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'userID' => $userID
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully received the user transaction data";
return responseBody;
} else {
echo "We failed to get the user transaction data: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult getUserTransactions() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "5f79aa38348dd07b",
"pageNumber": 1,
"pageSize": 100,
"totalEntries": 2,
"transactions": [
{
"orderID": "1709635019797",
"transactionStatus": "DONE",
"transactionAmount": 500,
"transactionBalance": 0,
"creationDate": "2024-05-03",
"lastStatusChangeDate": "2024-05-03"
},
{
"orderID": "1709633438801",
"transactionStatus": "INPROGRESS",
"transactionAmount": 500,
"transactionBalance": -500,
"creationDate": "2024-05-03",
"lastStatusChangeDate": "2024-05-03"
}
]
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
pageNumber | N | no | Number of the page that should be returned |
pageSize | N (3) | no | Amount of results returned per page (1-100) |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
transactions | J (UserTransactions) | Contains basic information for one or multiple transactions associated to the user |
pageNumber | N | Number of the page that was returned |
pageSize | N (3) | Amount of results returned per page (1-100) |
totalEntries | N | The total amount of results |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
identificationCheck
This API can be used to identify and validate customer data. Both the mandatory fields in the request and the response to this call may vary depending on the product that is configured to perform the identification check.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/identificationCheck
Live: https://api.crefopay.de/2.0/identificationCheck
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation. This value cannot be changed after user creation. Possible Values:
|
userData | J (Person) | see comment | Data of a PRIVATE customer. This field is mandatory if the userType is PRIVATE. |
companyData | J (Company) | see comment | Data of a BUSINESS customer. This field is mandatory if the userType is BUSINESS. |
address | J (Address) | yes | The address to be checked. While th address object in the request itself is mandatory, the exact fields which it should contain differ depending on the service that will be used. Independent of which service is used the field "country" is always mandatory. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
checkReferenceId | N | Unique reference to the performed check |
responseData | J | Contains the raw response data of the address check provider in JSON format |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
payByLink
The PayByLink via API solution allows the creation of payment links based on the provided parameters and to optionally send these automatically to the customer.
Similar to other integration types the createTransaction call is used to initiate a transaction, with the main difference being that less parameters are required. After providing the data several risk checks are performed, which make decisions on which payment methods the customer will be able to select from. Depending on the amount of data provided some risk checks may not be performed.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/createTransaction
Live: https://api.crefopay.de/2.0/createTransaction
<?php
function createTransactionPayByLink($orderID) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters for creating a transaction here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'integrationType' => 'HostedPageAfter',
'context' => 'PAY_BY_LINK',
'amount' => json_encode(
array(
'amount' => '100',
)
)
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully created the payByLink order {$orderID}. Amount: {$transactionAmount}\n\r";
return true;
} else {
echo "We failed to created the payByLink order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult createTransactionPayByLink() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 1) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-133");
map.add("integrationType", "HostedPageAfter");
map.add("context", "PAY_BY_LINK");
map.add("amount", getAmount());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":1,
"salt":"1647a342d1917ae3",
"redirectUrl":"https://sandbox.crefopay.de/hosted-pages/5b719933bca0266009608be6"
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
sendPayByLinkEmail | B | no | Decides whether to automatically send the payment link via email to the customer. If set to 'true', it is mandatory to provide an email address of the customer. If set to 'false', no mail delivery will be triggered and no email address is required. If the value is not provided it is set to 'false' by default. |
userID | AN 50 | no | The unique user id of the user. |
integrationType | V | yes | Possible Values:
|
autoCapture | B | no | Enable automatic capture directly after the successful reservation, if the parameter is not set, the default is "false" |
merchantReference | AN (30) | no | Optional/additional reference for the transaction. This parameter is returned with every call from lynck to the shop. |
context | V | yes | Determines if the transaction was initiated during online-checkout process or offline where no direct user interaction happens. Possible Values:
|
userType | V | no | This parameter defines business or private customers. This value cannot be changed after user creation.. This value cannot be changed after user creation. Possible Values:
|
userRiskClass | N (1) / D (1.1) | no | Possible values are:
|
userIpAddress | AN (15) | no | The IP address of the customer |
companyData | J (Company) | no | Contact data of the user's company. If automatic payment emails should be triggered at least the parameter 'email' has to be provided in the J (Company) object. |
userData | J (Person) | no | Contact data of the user. If automatic payment emails should be triggered at least the parameter 'email' has to be provided in the J (Person) object. The field "date of birth" is not mandatory. It's needed for solvency checks and the payment method "bill secure". An absent "date of birth" could cause less payment methods to be offered to the user. |
billingRecipient | AN (80) | no | Recipient for the billing address |
billingAddress | J (Address) | no | The user's billing address. This field is mandatory if the user was not registered before with this userID |
shippingRecipient | AN (80) | no | Recipient for the shipping address |
shippingAddress | J (Address) | no | The user's shipping address |
amount | J (Amount) | yes | The amount of the basket |
basketItems | JA (Basket Item) | no | A detailed list of all basket items |
basketValidity | AN (4) | no | m -> minutes, h -> hours, d -> days; Example: one hour: 1h, ten minutes: 10m, two days: 2d - only one unit of time can be provided |
hostedPagesTexts | JA (HostedPages text) | no | A list of texts for the hosted page in for different languages for different payment methods |
locale | V | no | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
additionalPaymentOptions | J (Payment options) | no | additional options |
solvencyCheckInformation | J (Solvency check information) | no | result of a solvency check done by the merchant. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
redirectUrl | AN | The url of the hosted page that should be shown to the user. This is only set if the resultCode is 1 |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
Handling of Packstation addresses
- These type of address is only valid for shipping address
- The “Postnummer” is expected in the field shippingRecipient
- The word “Packstation” is expected in field street of the shippingAddress
- The number of “Packstation” is expected in field number of shippingAddress
refund
The refund call allows the merchant to return money to the user. At least one capture on a transaction is required to perform a refund; therefore the call cannot be used on transactions in status NEW, ACKNOWLEDGEPENDING or MERCHANTPENDING.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/refund
Live: https://api.crefopay.de/2.0/refund
<?php
function refund($orderID, $captureID, $transactionAmount, $refundDescription) {
global $requestUrl, $merchantID, $storeID;
$amount = json_encode(array('amount' => $transactionAmount));
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'captureID' => $captureID,
'refundDescription' => $refundDescription,
'amount' => $amount
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully refunded the order {$orderID}. Amount: {$transactionAmount}\n\r";
return true;
} else {
echo "We failed to refund the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult refund() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("captureID", "capture-129");
map.add("refundDescription", "refund");
map.add("amount", getAmount());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"b414f1f508e0d653"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | yes | This is the unique reference of a capture or a partial capture (e.g. the invoice number). |
refundDescription | AN (256) | yes | Description to be shown to the end user on the refund |
amount | J (Amount) | yes | The amount of the refund |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
registerUser
The registerUser call adds the functionality to register a new user.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/registerUser
Live: https://api.crefopay.de/2.0/registerUser
public lynckResult registerUser() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getUserData() {
return Json.createObjectBuilder()
.add("name", "Max")
.add("surname", "Mustermann")
.add("dateOfBirth", "1978-08-15")
.add("email", "max@mustermann.de")
.build()
.toString();
}
private String getBillingAddress() {
return Json.createObjectBuilder()
.add("street", "Hauptstraße")
.add("no", "1")
.add("zip", "10827")
.add("city", "Berlin")
.add("country", "DE")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-123");
map.add("userType", "PRIVATE");
map.add("userRiskClass", "0");
map.add("userData", getUserData());
map.add("billingAddress", getBillingAddress());
map.add("email", "max@mustermann.de");
map.add("locale", "DE");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"029ebe3a1ea785e0"
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation.. This value cannot be changed after user creation. Possible Values:
|
companyData | J (Company) | see comment | Information about the user's company. This field is mandatory if the userType is BUSINESS and the userID was not registered before |
userData | J (Person) | see comment | Information about the user. This field is mandatory if the userType is PRIVATE and the userID was not registered before |
creditLimit | J (Amount) | no | If this field is provided then the value is saved as specific credit limit for this customer only. |
billingRecipient | AN (80) | no | Recipient for the billing address. |
billingAddress | J (Address) | see comment | The user's billing address. This field is mandatory if the user was not registered before with this userID |
shippingRecipient | AN (80) | no | Recipient for the shipping address |
shippingAddress | J (Address) | no | The user's shipping address |
solvencyCheckInformation | J (Solvency check information) | no | Result of a solvency check done by the merchant. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
registerUserPaymentInstrument
The registerUserPaymentInstrument call adds the functionality to register a payment instrument to a user.
Anyone involved with the processing, transmission, or storage of credit card data must comply with the Payment Card Industry Data Security Standards PCI DSS. If your system is not compliant please a different ingetration type, see: Integration options.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/registerUserPaymentInstrument
Live: https://api.crefopay.de/2.0/registerUserPaymentInstrument
public lynckResult registerUserPaymentInstrument() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getPaymentInstrumentString() {
return Json.createObjectBuilder()
.add("paymentInstrumentType", "CREDITCARD")
.add("accountHolder", "John Doe")
.add("number", "4111111111111111")
.add("validity", "2025-01")
.add("issuer", "VISA")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("paymentInstrument", getPaymentInstrumentString());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"17cb8cb80c38a7c8",
"paymentInstrumentID":"Aqc9O5SSJuQTDHC9KXFE0Q"
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
paymentInstrument | J (PaymentInstrument) | yes | The payment instrument to register. The PaymentInstrumentID has to be empty |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response:
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
paymentInstrumentID | AN 20 | Unique ID for this payment instrument, to be used in the reserve API |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
reportFraudUser
The reportFraudUser call reports a customer as fraudulent. This will set their status to "FRAUD" and prevent them and all users that can be associated to them to complete any further purchases. Optionally you may chose to close all open transactions of this customer. If this is done, then all open or pending transactions of this customer will be closed, and all dunning and collection processes will be stopped. All transactions in status CIAPENDING, MERCHANTPENDING or INPROGRESS are considered open transactions.
For transactions which have an open dunning or collection file at Accredis, the closure of the transaction and the dunning/collection file will be pending and may take up to 2 business days.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/reportFraudUser
Live: https://api.crefopay.de/2.0/reportFraudUser
<?php
function reportFraudUser($userID, $closeTransactions) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'userID' => $userID,
'closeTransactions' => $closeTransactions
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully reported the user: {$userID}.\n\r";
return responseBody;
} else {
echo "We failed to report the user: {$userID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult reportFraudUser() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "exampleUser111");
map.add("closeTransactions", true);
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "0b466141b307ec76",
"closedTransactions": [
{
"orderId": "1612465866966",
"closureStatus": "SUCCESS",
"previousTransactionStatus": "INPROGRESS",
"newTransactionStatus": "FRAUDCANCELLED",
"creationDate": "2021-02-04",
"transactionAmount": {
"amount": 0
}
},
{
"orderId": "1612465852295",
"closureStatus": "SUCCESS",
"previousTransactionStatus": "CIAPENDING",
"newTransactionStatus": "FRAUDCANCELLED",
"creationDate": "2021-02-04",
"transactionAmount": {
"amount": 500
}
},
{
"orderId": "1612465761342",
"closureStatus": "SUCCESS",
"previousTransactionStatus": "MERCHANTPENDING",
"newTransactionStatus": "FRAUDCANCELLED",
"creationDate": "2021-02-04",
"transactionAmount": {
"amount": 500
}
}
]
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
closeTransactions | B | no | Set to 'true' if all open transactions of the user should be closed. Default value: false |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
closedTransactions | J (closedTransactions) | Contains basic information about all closed transactions related to the customer. Only provided if transactions were closed |
reserve
A reserve call on a transaction signals that the customer confirmed their purchase and selected a specific payment method and/or payment instrument.
If the call succeeds with resultCode 0, the transaction will transition into status MerchantPending or CIAPending, depending on the selected payment method, and whether the funds are immediately available for capture.
If the call succeeds with resultCode 1, the customer needs to be redirected to the provided redirectUrl, usually for further authentication. On success, they will be redirected to the success URL configured for the shop, and the transaction will transition into status MerchantPending or CIAPending. On failure they will be redirected to the failure URL configured for the shop. For more information about callbacks see: Callback
If a reserve call failed with resultCode not being 0 or 1, then it is required to call getTransactionPaymentInstruments if another purchase attempt is to be made using the same transaction. This returns an updated list of the available payment methods and payment instruments of the transaction.
If the option "autoCapture" was enabled within the createTransaction call of the transaction being reserved, a capture call does not have to be performed afterwards; instead the lynck system will automatically create a capture with the orderID as captureID.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/reserve
Live: https://api.crefopay.de/2.0/reserve
<?php
function reserve($orderID, $paymentMethod) {
global $requestUrl, $merchantID, $storeID;
// Enter all mandatory parameters here
$param = array(
'merchantID' => $merchantID,
'storeID' => $storeID,
'orderID' => $orderID,
'paymentMethod' => $paymentMethod
);
// Add calculated MAC to params
$param['mac'] = getMac($param);
// Create POST body
$postData = http_build_query($param);
// Build your own communication function
$responseBody = sendRequest($postData, $requestUrl); // Returns an object
if($responseBody === false) {
return false;
}
// Collect resultCode from response object
$resultCode = $responseBody->resultCode;
if ($resultCode === 0) {
echo "We successfully reserved the order: {$orderID}.\n\r";
return responseBody;
} else {
echo "We failed to reserve the order: {$orderID}\n\rlynck Errormessage: {$responseBody->message}\n\r";
return false;
}
}
?>
public lynckResult reserve() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-125");
map.add("paymentMethod", "BILL");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"cae2f36e6c251692",
"additionalData":{
"bankname":"Postbank",
"bic":"SFRTDE20000",
"iban":"DE06000000000023456789",
"bankAccountHolder":"Max Mustermann",
"paymentReference":"PCB-0000668888"
}
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop.. The subscriptionID of a subscription will be accepted as well. |
paymentMethod | V | yes | The payment method that should be used. See: supported PaymentMethods |
paymentInstrumentID | AN (20) | no | The unique ID of the payment instrument. This ID is created by lynck. Required for payment method CC, CC3D, DD. |
paymentToken | JSON | no | Payment token as provided by Google Pay. Mandatory when reserving transactions with payment method GOOGLE_PAY. |
additionalInformation | J (ReserveInformationRequest) | no | Additional information needed for some payment methods. |
returnExternalErrorDetails | B | no | If set to true, then the response may contain a field externalErrorDetails. This field contains error codes from the related service provider which may be used to identify why the reservation failed. Only supported for payment methods CC, CC3D and PAYPAL. |
amount | J (Amount) | no | The amount of the basket. If this field is set, it will overwrite the amount that was set in the createTransaction call |
basketItems | JA (Basket Item) | no | A detailed list of all basket items. If this field is set, it will overwrite the basketItems that were set in the createTransaction call |
cvv | AN (4) | no | CVV for credit card transactions. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response:
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
redirectUrl | AN | Will only be returned if the user has to be redirected to the website of a third party payment provider like CC3D, PAYPAL or SU (Sofort) |
additionalData | J (ReserveInformationResponse) | Additional information will be set only in case of PREPAID, BILL and BILL_SECURE Payments |
errorDetails | J (ErrorDetails) | |
externalErrorDetails | J (ExternalErrorDetails) | This field contains error codes from the related service provider which may be used to identify why the reservation failed |
salt | AN | A random number to guarantee the uniqueness of the message. |
solvencyCheck
The solvencyCheck call allows the merchant to perform solvency checks on business customers independent of the transaction workflow.
The response to the solvencyCheck call will contain a score that is returned based on the solvency check configuration in the lynck system. If exact check report data is required, the results can be fetched using the getUser call. Similar to createTransaction, this call will act as registerUser or updateUser call if an unknown/known userID is provided.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/solvencyCheck
Live: https://api.crefopay.de/2.0/solvencyCheck
public lynckResult solvencyCheck() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getUserData() {
return Json.createObjectBuilder()
.add("name", "Max")
.add("surname", "Mustermann")
.add("dateOfBirth", "1978-08-15")
.add("email", "max@mustermann.de")
.build()
.toString();
}
private String getBillingAddress() {
return Json.createObjectBuilder()
.add("street", "Hauptstraße")
.add("no", "1")
.add("zip", "10827")
.add("city", "Berlin")
.add("country", "DE")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("userType", "PRIVATE");
map.add("userData", getUserData());
map.add("billingAddress", getBillingAddress());
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"checkResult":0,
"salt":"e59bb022501b780c",
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation. This value cannot be changed after user creation. Possible Values:
|
companyData | J (Company) | see comment | Contact data of the user's company. This field is mandatory if the userType is BUSINESS and the userID was not registered before |
userData | J (Person) | see comment | Contact data of the user. This field is mandatory if the userType is PRIVATE and the userID was not registered before |
billingAddress | J (Address) | see comment | The user's billing address. This field is mandatory if if user was not registered before with this userID |
billingRecipient | AN (80) | no | Recipient for the Bill. |
returnRiskData | B | no | Set to 'true' if solvency-check information should be returned in the response |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
checkResult | N |
|
riskData | J (RiskData) | Contains data of the solvency-check that was performed for this solvencyCheck API request |
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
status
This call returns the status of the lynck system and can be used as health-check. If the status is UP, all core systems are running.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/status
Live: https://api.crefopay.de/2.0/status
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response:
Field | Type | Comments |
---|---|---|
status | AN |
|
degradation | JA | If this Json array is present, one or more minor systems have problems, but the main transaction processing does still work. Possible values are: |
updateInvoice
With updateInvoice, it is possible to send additional invoice information for an existing transaction, if e.g. the invoice data for a transaction is only generated by the ERP system after checkout. The provision of invoice date is necessary, if you also want to process dunning and debt collection via the lynck partner, since the call centre of the debt collection agency requires this data for information provision purposes. Furthermore, you can also transmit the due date for account purchases and overwrite the preset due date individually for every transaction.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/updateInvoice
Live: https://api.crefopay.de/2.0/updateInvoice
public lynckResult updateInvoice() {
final LinkedMultiValueMap<String, Object> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendMultipartPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getAmount() {
return Json.createObjectBuilder()
.add("amount", "12399")
.build()
.toString();
}
private FileSystemResource getInvoice() {
return new FileSystemResource("/tmp/file.pdf");
}
private LinkedMultiValueMap<String, Object> getRequestMap() {
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("captureID", "capture-129");
map.add("invoiceNumber", "invoice-1");
map.add("invoiceDate", "2018-01-01");
map.add("originalInvoiceAmount", getAmount());
map.add("dueDate", "2018-03-01");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
//the invoicePDF is not part of the mac
map.add("invoicePDF", getInvoice());
return map;
}
Response:
{
"resultCode":0,
"salt":"b3035fc8a72cb252"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
captureID | AN (50) | yes | This is the unique reference of a capture or a partial capture (e.g. the invoice number). |
invoiceNumber | AN (50) | yes | The invoice number |
invoiceDate | D (YYYY-MM-DD) | no | The date when the in voice was created. Is set to capture date if not provided |
originalInvoiceAmount | J (Amount) | no | The original amount of the invoice. Please refer also to the information box below |
dueDate | D (YYYY-MM-DD) | no | Payment date of the invoice. The due date cannot be smaller or equal to the invoice date |
paymentTarget | D (YYYY-MM-DD) | no | Only relevant, if payment method is Bill: payment target to pay the invoice. Please refer also to the information box below |
shippingDate | D (YYYY-MM-DD) | no | The shipping date of the order |
trackingID | AN (50) | no | The tracking ID of the sending |
remark | AN (500) | no | Free text field to pass additional information like article numbers etc. so that the collection agency can see, which item is associated with the dunning process |
invoicePDF | Multipart attachment | no | The original invoice as PDF. This parameter has to be ignored for the mac calculation |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
updateSubscription
The updateSubscription call is used to update the charge rate or interval, cancel an active subscription or request the customer to change their payment method.
For subscriptions that were completed using the PayPal Subscriptions solution, only the action CANCEL is available.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/updateSubscription
Live: https://api.crefopay.de/2.0/updateSubscription
public lynckResult updateSubscription() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("subscriptionID", "subscription-134");
map.add("action", "CHANGE_RATE");
map.add("rate", "200");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"01ebbd8ccb51b8d9"
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
subscriptionID | AN (50) | yes | This is a unique identifier for a subscription which is created by the shop. |
action | V | yes | Possible Values:
|
changeIntervalTime | V | no | Defines when the interval change should apply. Only required if the action is CHANGE_INTERVAL. Possible Values:
|
interval | V | no | Interval to which the subscription interval should be updated to. Only required if the action is CHANGE_INTERVAL. Possible values:
|
rate | N (9) | no | Amount to which the subscription rate should be updated to. Only required if the action is CHANGE_RATE |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
redirectUrl | AN | Only returned for action UPDATE_PAYMENT_LINK. |
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
Retrying failed payments
The action RETRY_PAYMENT will trigger new payments for all previous payment attempts which failed. Therefore this action can be used to collect all outstanding payments for a single subscription.
RETRY_PAYMENT is only allowed for subscription in status active, paused and done. Once the action was used, it cannot be used again until the resulting payments are resolved.
Changing the subscription interval
The action CHANGE_INTERVAL will apply depending on the selected changeIntervalTime.
After next payment
If changeIntervalTime was set to AFTER_NEXT_PAYMENT, then the selected interval will be applied only after the next scheduled payment was executed.
Immediate
If changeIntervalTime was set to IMMEDIATE, then selected interval will be applied immediately. If the new interval is smaller than the previously set interval, then it is possible that multiple payments can be triggered in a row. The next payment date will be set using the newly selected interval based on the last successful payment.
Changing the payment method
To change the payment method of an active subscription it is required that the customer selects and confirms their new payment method. To this end three different actions can be triggered, which allow the customer to do so in different ways. With all three methods a new 0-amount transaction is automatically created in the lynck system which serves to register and authorize the new payment method or payment instrument.
UPDATE_PAYMENT_EMAIL
This action will trigger an email to the customer associated with the subscription. In this email the customer will receive a link that can be used to change the payment method of the subscription. No further action is required by the merchant.
UPDATE_PAYMENT_LINK
This action will return a link to a payment page directly in the response to the updateSubscription call. This link is identical to the link provided in the email triggered by the action UPDATE_PAYMENT_EMAIL. It should be provided to the customer to select and confirm their new payment method. This could be done by either delivering the link through a messaging service or by loading the link within an iFrame inside the shop.
Example response for action UPDATE_PAYMENT_SECUREFIELDS:
{
"resultCode": 0,
"salt": "196cfb042e979ba9",
"orderID": "S-100002",
"userData": {
"salutation": "M",
"name": "Max",
"surname": "Mustermann",
"email": "mustermann@lynck.de"
},
"billingAddress": {
"street": "Schloßstr.",
"no": "20",
"zip": "12163",
"city": "Berlin",
"country": "DE"
},
"allowedPaymentMethods": [
"PAYPAL",
"CC3D",
"DD"
],
"allowedPaymentInstruments": [],
"additionalInformation": [
{
"paymentMethodType": "PAYPAL"
},
{
"paymentMethodType": "CC3D",
"issuer": [
"VISA",
"MC"
],
"logos": [
"VISA",
"MC"
]
},
{
"paymentMethodType": "DD",
"sepaPaymentType": "RCUR",
"mandateReference": "10",
"creditorId": "DE98ZZZ09999999999",
"merchantName": "TestMerchant",
"date": "May 17, 2021"
}
],
"billingRecipient": "Max Mustermann"
}
UPDATE_PAYMENT_SECUREFIELDS
This action will cause the updateSubscription response to return transaction details similar to the createTransaction API, including an orderID, allowed payment methods and allowed payment instruments. The returned orderID should be used to initialize the SecureFields library in a shop frontend. After the customer selected their preferred payment method or payment instrument using the SecureFields, the transaction needs to be reserved using the reserve API, similar to a regular lynck transaction.
updateTransactionData
With updateTransactionData the merchantReference of a transaction can be set or updated. The merchantReference can be used as an alternative for automated payment matching if the paymentReference provided by lynck can not be forwarded to customers. In this case it is advisable to update the merchantReference of the transaction to whatever value was given to the customer as payment reference for their bank transfer.
This call may be extended in the future to allow further modification of transaction data.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/updateTransactionData
Live: https://api.crefopay.de/2.0/updateTransactionData
public lynckResult updateTransactionData() {
final LinkedMultiValueMap<String, Object> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendMultipartPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private LinkedMultiValueMap<String, Object> getRequestMap() {
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("orderID", "order-129");
map.add("merchantReference", "bill-501234");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode": 0,
"salt": "250ffaf62f444faa",
"updatedData": {
"merchantReference": {
"oldValue": "oldMerchantReference",
"newValue": "bill-501234"
}
}
}
Request:
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
orderID | AN (50) | yes | This is a unique identifier for a transaction which is created by the shop. |
merchantReference | AN (30) | no | Optional/additional reference for the transaction. This parameter is returned with every call from lynck to the shop. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
updatedData | J (UpdatedData) | Contains the fields that were updated, their new values (newValue), and the old values if any were overwritten (oldValue). Only set if any fields were updated. |
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
updateUser
The updateUser call adds the functionality to update a user's details like billing and or delivery address.
URL:
Sandbox: https://sandbox.crefopay.de/2.0/updateUser
Live: https://api.crefopay.de/2.0/updateUser
public lynckResult updateUser() {
final MultiValueMap<String, String> map = getRequestMap();
ResponseEntity<lynckResult> response = restTemplateService.sendPostRequest(url, map);
if (response.getStatusCode() != HttpStatus.OK || response.getBody().getResultCode() > 0) {
throw new RuntimeException(response.getBody().getMessage());
}
return response.getBody();
}
private String getBillingAddress() {
return Json.createObjectBuilder()
.add("street", "Hauptstraße")
.add("no", "3")
.add("zip", "10827")
.add("city", "Berlin")
.add("country", "DE")
.build()
.toString();
}
private MultiValueMap<String, String> getRequestMap() {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("merchantID", merchantID);
map.add("storeID", storeID);
map.add("userID", "user-127");
map.add("userType", "PRIVATE");
map.add("userRiskClass", "0");
map.add("billingAddress", getBillingAddress());
map.add("email", "max@mustermann.de");
map.add("locale", "DE");
map.add("mac", macCalculator.calculateAndGetMAC(map, merchantPassword));
return map;
}
Response:
{
"resultCode":0,
"salt":"d8bff4bbec235087"
}
Request
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantID | N (16) | yes | This is the merchant ID assigned by lynck. |
storeID | AN (60) | yes | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
userID | AN (50) | yes | The unique user id of the user. |
userType | V | yes | This parameter defines business or private customers. This value cannot be changed after user creation.. This value cannot be changed after user creation. Possible Values:
|
userRiskClass | N (1) | no | Possible values are:
|
companyData | J (Company) | see comment | Contact data of the user's company. This field is mandatory if the userType is BUSINESS and the userID was not registered before |
userData | J (Person) | see comment | Contact data of the user. This field is mandatory if the userType is PRIVATE and the userID was not registered before |
creditLimit | J (Amount) | no | If this field is provided then the value is saved as specific credit limit for this customer only. Any previously saved credit limit will be overwritten. |
billingRecipient | AN (80) | no | Recipient for the billing address |
billingAddress | J (Address) | see comment | The user's billing address. This field is mandatory if if user was not registered before with this userID |
shippingRecipient | AN (80) | no | Recipient for the shipping address |
shippingAddress | J (Address) | no | The user's shipping address |
locale | V | yes | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
solvencyCheckInformation | J (Solvency check information) | no | Result of a solvency check done by the merchant. |
mac | AN (40) | yes | Message Authentication Code. See: MAC calculation |
Response
Field | Type | Comments |
---|---|---|
resultCode | N |
|
message | AN | This parameter contains details about an error, otherwise it will left as empty. |
errorDetails | JA (ErrorDetails) | |
salt | AN | A random number to guarantee the uniqueness of the message. |
SecureFields
Prerequisites
The JavaScript library must be included in the page using the following snippet:
//For use on the production environment
<script src="https://api.crefopay.de/libs/3.0/secure-fields.js"></script>
//For use on the sandbox environment
<script src="https://sandbox.crefopay.de/libs/3.0/secure-fields.js"></script>
//For use on the production environment (deprecated)
<script src="https://libs.crefopay.de/3.0/secure-fields.js"></script>
SecureFields process description
The SecureFields Solution can be used in with the Integration option "SecureFields". This includes the usual process of creating a transaction and reserving it with the PaymentInstrument. After creating the transaction the SecureFields JavaScript library needs to be initialized. This is usually done when the customer enters the payment selection page. As soon as the initialization of the library and the creation of a session for submitting credit card and bank data with the HostedFields is completed, you will receive a response in the registered callback function.
After the customer selected the payment method the registerPayment function of the library should be called. It's not necessary to actively pass the selected payment method, because the library will recognize and transfer the selection based on the set data-attributes. After selecting and registering the payment the API response contained in the callback function needs to be handled. As mentioned, the response of the API might not always be a successful message. In case of an error it will contain information about missing data or any other errors that may occur during payment method/instrument registration. In case of a successful payment method selection the checkout process can be continued. Now the reserve call can be performed on the transaction, after the customer confirmed their purchase on the order confirmation page.
Registration of new payment instruments
The most important feature of the SecureFields solution is to securely collect bank account and credit card data from the customer, without storing them on the merchants shop environment. This severely reduces the security measures required for the shop and allows the merchant to accept credit card payments without full PCI certification.
The SecureFields library offers two methods to collect this data:
- Placeholder elements which are filled with hosted fields/iframes and marked input fields
- Allows for a seamless integration into the shop
- Requires implementation of field validation error handling
- An overlay input form
- Allows for an easier integration by handling validation and form frontend
- Requires an overlay form to be displayed
Placeholder elements and input fields
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="PREPAID">Cash in advance</label><br>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="BILL">Bill payment</label><br>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="DD">Direct debit</label><br>
<label>Account holder: <input type="text" data-crefopay="paymentInstrument.bankAccountHolder" placeholder="John Doe"></label><br>
<label>IBAN: <input type="text" data-crefopay="paymentInstrument.iban" placeholder="DE12 3456 7890 1112 1314"></label><br>
<label>BIC: <input type="text" data-crefopay="paymentInstrument.bic" placeholder="SFRTDE20000"></label><br>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="Aqc9O5SSJuQTDHC9KXFE0Q">Registered bank account (IBAN: DE12 3456 7890 1112 1314)</label>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="y6hijnZJt38FeNPUFM2E6g">Registered bank account (IBAN: DE65 4321 4131 2111 5432)</label>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="CC">Creditcard</label><br>
<span>Accountholder: </span>
<div data-crefopay-placeholder="paymentInstrument.accountHolder"></div>
<span>Number: </span>
<div data-crefopay-placeholder="paymentInstrument.number"></div>
<span>Validity: </span>
<div data-crefopay-placeholder="paymentInstrument.validity"></div>
<span>CVV: </span>
<div data-crefopay-placeholder="paymentInstrument.cvv"></div>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="lt-vfbxBlSffx0e6QQ_hpg">Registered creditcard (Number: 12***********3456)</label>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="t_QOm8SvkGWaChoYeI0rrg">Registered creditcard (Number: 65***********4321)</label>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="PAYPAL">PayPal</label><br>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="SU">Sofort</label><br>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="CC3D">Creditcard 3D-secure</label><br>
<span>Accountholder: </span>
<div data-crefopay-placeholder="paymentInstrument.accountHolder"></div>
<span>Number: </span>
<div data-crefopay-placeholder="paymentInstrument.number"></div>
<span>Validity: </span>
<div data-crefopay-placeholder="paymentInstrument.validity"></div>
<span>CVV: </span>
<div data-crefopay-placeholder="paymentInstrument.cvv"></div>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="COD">Cash on delivery</label><br>
</div>
For the SecureFields library to find the selected payment method as well as the placeholders for the secure fields, several HTML-data-attributes have to be set.
These should generally begin with data-crefopay
.
The following attributes can be set:
data-crefopay
Attribute value | Description |
---|---|
paymentMethod | Marks PaymentMethods, should be used in combination with a radio button input or similar, as only one payment method can be selected. |
paymentInstrument.id | Identifies an existing PaymentInstrument ( bank account / credit card ). Can be used to allow customers to re-use already registered payment instruments. |
paymentInstrument.bankAccountHolder | Marks the field for the bank account holder. |
paymentInstrument.iban | Marks the fields for the IBAN. |
paymentInstrument.bic | Marks the field for the BIC. |
data-crefopay-placeholder
Attribute value | Description |
---|---|
paymentInstrument.accountHolder | Placeholder for the card-holder name. |
paymentInstrument.number | Placeholder for the credit card number. |
paymentInstrument.validity | Placeholder for the credit card validity date. |
paymentInstrument.cvv | Placeholder for the CVV of the credit card. |
Overlay with input fields
As an alternative to the paymentInstrument placeholders and input fields, it is possible to collect both credit card and bank account data using an overlay widget, in which a pre-built input form is displayed to the customer. To use the overlay solution the fields ccOverlay or ddOverlay must be set to 'true' in the configuration object used to initialize the SecureFields library.
The overlay is displayed to the customer once their payment method selection was confirmed using secureFieldsClientInstance.registerPayment().
The overlay will handle field validation and also allow customers to select previously registered payment instruments. Once a valid new payment instrument was registered, or an existing payment instrument was selected, the paymentRegisteredCallback function is called with resultCode=0. If the user closed the overlay window without selecting a payment instrument, the paymentRegisteredCallback function is called with resultCode=6005 and message="cancelled by user".
Initialization
To initialize the library, an instance of the SecureFieldsClient needs to be created. An example and a list of arguments for the initialization follow:
var secureFieldsClientInstance =
new SecureFieldsClient(shopPublicKey,
orderID,
paymentRegisteredCallback,
initializationCompleteCallback,
configuration);
Argument | Description |
---|---|
shopPublicKey | Will be provided by lynck |
orderID | Reference to the transaction, set by the merchant in createTransaction. Alternatively the subscriptionID of a subscription, set in createSubscription, can be provided as well. |
paymentRegisteredCallback | This function will be be called after registration of a payment method and receives the API response of lynck as argument. |
initializationCompleteCallback | This function will be called right after the secure fields initialization and receives the API response of lynck as argument. |
configuration | This argument may be used to provide placeholders for the secure fields or select a different endpoint for the requests. Details follow below (see Secure Fields Configuration) |
Registering the payment method
After initialization of an instance of the SecureFieldsClient and successful session creation a payment method can be registered as follows:
secureFieldsClientInstance.registerPayment();
Upon calling the registerPayment function the SecureFields library will scan the page for any elements with the data-crefopay attribute set to "paymentMethod". If more than one element can be found, it will only recognize the "checked" element. Therefore it should be ensured that only one element with the attribute data-crefopay="paymentMethod" can be selected at any time. If only one element can be found, it does not need to be "checked"/selected.
After executing this function the paymentRegisteredCallback function will be called automatically to process the lynck API response. It's recommended to check the resultCode of the response first, to differentiate between failure and success:
function paymentRegisteredCallback(response) {
if (response.resultCode === 0) {
// Successful registration, continue to next page using JavaScript
} else {
// Error during registration, check the response for more details and dynamically show a message for the customer or perform other actions
}
}
Display and selection of already registered credit cards and bank accounts
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="DD">Direct debit</label><br>
<label>Account holder: <input type="text" data-crefopay="paymentInstrument.bankAccountHolder" placeholder="John Doe"></label><br>
<label>IBAN: <input type="text" data-crefopay="paymentInstrument.iban" placeholder="DE12 3456 7890 1112 1314"></label><br>
<label>BIC: <input type="text" data-crefopay="paymentInstrument.bic" placeholder="SFRTDE20000"></label><br>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="Aqc9O5SSJuQTDHC9KXFE0Q">Registered bank account (IBAN: DE12 3456 7890 1112 1314)</label>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="y6hijnZJt38FeNPUFM2E6g">Registered bank account (IBAN: DE65 4321 4131 2111 5432)</label>
</div>
<div>
<label><input type="radio" data-crefopay="paymentMethod" name="paymentMethodSelect" value="CC">Creditcard</label><br>
<span>Accountholder: </span>
<div data-crefopay-placeholder="paymentInstrument.accountHolder"></div>
<span>Number: </span>
<div data-crefopay-placeholder="paymentInstrument.number"></div>
<span>Validity: </span>
<div data-crefopay-placeholder="paymentInstrument.validity"></div>
<span>CVV: </span>
<div data-crefopay-placeholder="paymentInstrument.cvv"></div>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="lt-vfbxBlSffx0e6QQ_hpg">Registered creditcard (Number: 12***********3456)</label>
<label><input type="radio" data-crefopay="paymentInstrument.id" name="savedPaymentInstrumentSelect" value="t_QOm8SvkGWaChoYeI0rrg">Registered creditcard (Number: 65***********4321)</label>
</div>
This section is only relevant if you use your own placeholder elements and input fields, as the overlay solution will automatically handle this step.
For a better checkout experience it is recommended to display already registered payment instruments such as credit cards and bank accounts, so that customers do not have to repeatedly enter their data. To submit existing payment instruments the attribute data-crefopay="paymentInstrumentId" should be set, with the value being the paymentInstrumentId of the registered card or bank account.
Upon calling the registerPayment function the SecureFields library will scan the page for any elements with the data-crefopay attribute set to "paymentMethod" and "paymentInstrument.id". Specifically for "paymentMethod" and "paymentInstrument.id" it will only recognize those elements that are "checked", therefore it is recommended to keep all payment methods and payment instruments in separate radio-button groups. This will ensure that only one payment method and one payment instrument can be selected at any given time. The separation can be achieved by giving the form elements different name attributes.
Inclusion of multiple CVV fields
For any transaction for which the payment method credit card "CC" is offered, either by registering a new payment instrument or using an existing payment instrument, it is required to also provide a CVV. The CVV field is a hosted field which is designated by the attribute data-crefopay-placeholder="paymentInstrument.cvv". Compared to the other fields which use the attribute data-crefopay-placeholder, the CVV field can be included multiple times on one page, but only one of them should be visible at any give time. This allows the shop to display the field right next to either the input fields for a new credit card, or alternatively to already registered cards.
It is sufficient if a parent element of the element containing the CVV field is hidden, to make it unrecognizable for the SecureFields library.
Secure Fields Configuration
The following values should be set in the configuration object for the SecureFields:
Value | Information |
---|---|
ccOverlay | If the customer selects CC or CC3D as payment method, and registerPayment() is triggered, the credit card overlay will be displayed to collect card data if this field is set to 'true'. Set to 'false' if not provided |
ddOverlay | If the customer selects DD as payment method, and registerPayment() is triggered, the direct debit overlay will be displayed to collect bank account information if this field is set to 'true'. Set to 'false' if not provided |
nonce | The nonce will be passed on in the script tags for all libraries that are automatically fetched by the secure-fields.js, so that the content security policy of shops can allow them to load |
placeholders | Placeholders object. Contains values with which the placeholder fields will be pre-filled with. See below for object structure |
paypal | Allows to customize the PayPal button, if it is rendered |
url | API endpoint (If this value is not set, it will default to the lynck production system) |
URL
Sandbox: https://sandbox.crefopay.de/secureFields/
Live: https://api.crefopay.de/secureFields/
Placeholders
The placeholders
object may contain the following values:
Value | Information |
---|---|
accountHolder | Pre-filled values for the cardholder name field |
number | Pre-filled values for the credit card number field |
cvv | Pre-filled values for the CVV field |
var configuration = {
url: "https://sandbox.crefopay.de/secureFields/",
ddOverlay: true,
ccOverlay: false,
placeholders: {
accountHolder: "Your Name",
number: "0123456789101112",
cvv: "000"
},
paypal: {
layout: "horizontal",
color: "silver"
}
}
Paypal customization
The paypal
object may contain the following values:
Value | Information |
---|---|
layout | Possible values: horizontal, vertical |
color | Possible values: gold, blue, silver, white, black |
shape | Possible values: rect, pill |
height | Numerical height in pixel |
label | Possible values: paypal, checkout, buynow, pay, installment |
tagline | Possible values: true, false |
See the PayPal documentation for examples of the options.
Error handling
Errors or exceptions should be properly handled by the callback functions.
The field resultCode
is the main indicator used to recognize whether something went wrong. In general, if a resultCode higher than 0 is returned, it can be assumed that something went wrong. At errorcodes you may find general errors that may occur during payment method registration.
In case of any error an error message will be provided to give more detailed information. Most errors will occur due to either validation or missing data-attributes. In those cases the user should be asked to check his inputs.
If a reserve call failed due to the resultCode not being 0 or 1, then it is required to call getTransactionPaymentInstruments if another purchase attempt is to be made using the same transaction. This returns an updated list of the available payment methods and payment instruments of the transaction.
Billie
To be able to reserve a SecureFields transaction using Billie as payment method, the customer needs to go through an identification process using the Billie widget. Generally this payment method is treated as a secure payment method by lynck, as Billie perform their own risk checks for each transaction/customer. As such lynck risk checks will not influence whether Billie can be offered as a payment method or not.
The Billie widget will be automatically initialized in the customer browser, when registerPayment() of the SecureFields library is called and Billie was selected as payment method. This requires that the latest version of the SecureFields library is used within the shop. Billie specifically uses the payment method BILL_SECURE, which can be offered using radio buttons, just like any other payment method.
<input type="radio" data-crefopay="paymentMethod" value="BILL_SECURE">Billie</label>
Billie success case handling
If the registerPayment() function returned resultCode=0 then the identification process was successful and the checkout can continue.
{
"resultCode": 0,
"salt": "8ad7ea63c2fecd63",
"orderNo": "1603709147671",
"paymentMethod": "BILL_SECURE"
}
During the identification process in the Billie-widget, the customer may provide a company/billing address that can differ from the billing address that was originally provided in the shop environment. To make sure that the address in the shop is correct, the billing address with which Billie successfully identified the merchant should be used within the shop.
It is recommended to call the getTransactionStatus API after every registerPayment() execution using BILL_SECURE that returned resultCode=0, and to compare the returned billing address to the address stored in the shop. If these differ, then the shop should update the billing address of the order before redirecting the customer to the order confirmation page.
After successful identification with the Billie widget, the transaction can be reserved like any other regular SecureFields transaction.
Billie failure case handling
If the response to registerPayment() is anything else but resultCode=0, then the checkout process should not continue, and the user should remain on the payment selection page.
Specifically for Billie, the following resultCodes can be returned:
{
"resultCode": 3005,
"message": "Financing limit of debtor currently exceeded."
}
resultCode | Message | Hard decline |
---|---|---|
3001 | Debtor address or name mismatch. | no |
3002 | Debtor could not be identified with the information given. | no |
3003 | Risk decline. | yes |
3004 | Not enough data available to make a decision. | no |
3005 | Financing limit of debtor currently exceeded. | yes |
3006 | User rejected suggested company. | no |
3099 | Unknown decline: (variable reason) | no |
The resultCodes 3003 and 3005 represent so called "hard declines". If either of those resultCodes is returned, then Bille should not be offered as an available payment method, as the customer was identified and not accepted by Billie. Optimally this would result in the payment method BILL_SECURE being hidden for this specific order.
Express Checkout
Amazon Pay Express
Payment Process
Amazon Pay should be integrated into shops as an express payment method. This means compared to conventional payment methods, it is not offered on the payment method selection page, but on different pages before that. Compared to other payment methods offered by lynck, using Amazon Pay does not require the merchant to create a transaction upfront.
Given that the payment method can be offered on the product pages or the basket page in the shop, the customer may not yet have provided any customer data with which a lynck transaction can be created. To create and process a lynck transaction with Amazon Pay, the customer needs to log into the Amazon system and then select a delivery address and a payment method using the Amazon Pay button.
After successful authentication with Amazon Pay, the customer would then be redirected back to the shop, where the shop has the chance to request all relevant customer data from lynck and display the order confirmation page of the shop. On order confirmation by the customer, the transaction should be reserved using the lynck reserve API, which finalizes the payment.
Prerequisites
//lynck library
//For use on the production environment
<script src="https://api.crefopay.de/libs/3.0/amazon-client.js"></script>
//For use on the sandbox environment
<script src="https://sandbox.crefopay.de/libs/3.0/amazon-client.js"></script>
//Amazon Pay library
//For use on any environment (EU)
<script src="https://static-eu.payments-amazon.com/checkout.js"></script>
To render the Amazon Pay button for a lynck transaction, the lynck amazon client JavaScript library and the Amazon checkout JavaScript library need to be included in the header of any given page.
Rendering the Amazon Pay button
<script type="text/javascript" charset="utf-8">
amazonClient = new AmazonClient(
shopPublicKey,
configuration,
initializationCompleteCallback,
onButtonClickCallback
);
amazonClient.createButton();
</script>
To render the button, an instance of the AmazonClient needs to be created first. This is done by providing the public key of your shop, provided by lynck, a configuration object and two callback functions. Afterwards the createButton function of the AmazonClient instance can be used, to insert the button on the page.
<div data-crefopay="amazonPayButton"></div>
This function will search for a placeholder field on the entire page, and render the button inside it. The placeholder should be a simple DIV-element with the attribute data-crefopay=”amazonPayButton”.
Argument | Description |
---|---|
shopPublicKey | Will be provided by lynck |
configuration | This argument should be used to provide transaction information required for processing. Details follow below (see Configuration options) |
initializationCompleteCallback | This function will be called right after the client initialization and receives the API response of lynck as argument. |
onButtonClickCallback | This function will be called right after the customer clicked the Amazon Pay button and receives the name of the placeholder element as argument. |
Rendering multiple buttons on one page
In certain cases it may be required to render multiple Amazon Pay buttons on a single page in a shop. This can be relevant in case the button should be displayed next to multiple products which are displayed on the same page.
<script type="text/javascript" charset="utf-8">
//Rendering 3 buttons simultaneous
amazonClient.createButton("button1","button2","button3");
</script>
//Placeholder elements for the 3 buttons
<div data-crefopay="button1"></div>
<div data-crefopay="button2"></div>
<div data-crefopay="button3"></div>
To render multiple buttons at once, the createButton function can be while providing the names of the placeholder elements. By doing so the amazon-client will scan the page for elements for which the data-crefopay attribute are set to the provided names, and render the buttons inside them.
<script type="text/javascript" charset="utf-8">
function onButtonClickCallback(button) {
switch(button){
case "button1":
//action for button 1
break;
case "button2":
//action for button 2
break;
case "button3":
//action for button 3
break;
}
}
</script>
When one of the buttons was clicked, the name of the placeholder in which the button was rendered will be provided to the onButtonClickCallback function as an argument. With this it is possible to perform different actions, depending on which of the buttons was clicked.
Amazon JS Configuration options
The configuration object maybe contain the following fields:
Value | Information |
---|---|
url | Base URL of the lynck system for which the transaction should be created. Set to Sandbox if not provided. Possible values:
|
buttonColor | Sets the color of the Amazon Pay button. Set to "Gold" per if not provided. Possible values:
|
placement | Informs Amazon Pay about the location in which the button is displayed. Set to "Cart" if not provided. Possible values:
|
checkoutLangage | Sets the preferred language displayed on the Amazon Pay page. Set to English if not provided. Possible values:
|
sandbox | Decides if test transactions or real transactions are created in the Amazon Pay system. For transactions performed on any lynck test/staging system, this should be set to "true". Only set this to "false" when you use the lynck production system to perform real payments. Set to "false" if not provided. Possible values:
|
autoCapture | Indicates whether the lynck system should automatically capture all funds immediately after successful authorization with Amazon Pay. |
deliverySpecifications | Specifies which addresses the customer is allowed to select at Amazon Pay. Details follow below (see Delivery address restrictions) |
orderId | Unique reference to the lynck transaction that will be created if the user clicks on the button and authorizes with Amazon Pay. Lynck will generate a random orderID if none was provided. A maximum of 30 characters are allowed. Not mandatory. |
userId | Unique reference to the customer in the lynck system. Providing this field is useful to improve risk detection by the lynck risk engine. Lynck will generate a random userID if none was provided. A maximum of 50 characters are allowed. Not mandatory. |
Initialization callback
The provided callback function initializationCompleteCallback will be called once the createButton function was executed, and the result will be provided to it. When resultCode=0 is returned then one or multiple buttons were successfully rendered. For any other resultCode the rendering failed, and a message and further error details are provided.
Relevant fields for result processing:
Field | Description |
---|---|
resultCode |
|
salt | A random number to guarantee the uniqueness of the message. |
message | If an error occurs, this field contains details about that error. Not set if resultCode = 0. |
errorDetails | Structured information about any invalid request values. |
Button click callback
The provided callback function onButtonClickCallback will be called immediately after the customer clicked on a rendered Amazon Pay button. This function can be used to prepare the basket of the customer in the shop by adding new basket items, or to store other relevant data in the customer session. After execution of the function the customer will be redirected to Amazon Pay to authenticate.
Delivery address specifications
//Example: restrict packstation addresses
{
\"specialRestrictions\": [\"RestrictPackstations\"]
}
//Example: only allow delivery to Austria and Germany
{
\"addressRestrictions\": {
\"type\": \"Allowed\",
\"restrictions\": {
\"AT\":{},
\"DE\":{}
}
}
}
//Example: specifically disallow delivery to France
{
\"addressRestrictions\": {
\"type\": \"NotAllowed\",
\"restrictions\": {
\"FR\":{}
}
}
}
//Example: only allow delivery to a certain zip code in Germany and restrict packstation addresses
{
\"specialRestrictions\": [\"RestrictPackstations\"],
\"addressRestrictions\": {
\"type\": \"Allowed\",
\"restrictions\": {
\"DE\":{
\"zipCodes\": [\"10317\"]
}
}
}
}
As the customer selects their delivery address on the Amazon Pay page, it needs to be ensured that they are not able to select addresses in locations/countries which are not supported by the shop. For this the deliverySpecifications field in the configuration should be set accordingly. The field can be used to restrict delivery addresses to specific, zones, countries, zip codes and even disallow PO boxes and packstation addresses.
The see official Amazon Pay documentation on how the deliverySpecifications can be set.
Fetching customer data & order confirmation page
After the customer successfully logged in with Amazon Pay and authenticated the order, they are redirected to the “checkout review URL”. Using the GET-parameters provided in this redirection, the shop should now fetch the relevant user data, such as customer name and address, so that the order in the shop can be updated accordingly.
The following GET-parameters can be provided:
Parameter | Information |
---|---|
-MERCHANTID- | This is the merchant ID assigned by lynck. |
-STOREID- | This is the store ID of a merchant assigned by lynck as a merchant can have more than one store. |
-ORDERID- | This is a unique identifier for a lynck transaction. Will be set to the value provided in the configuration when initializing the Amazon Pay button. Otherwise it is automatically generated. |
-PAYMENTMETHOD- | The payment method selected by the customer. This will always be AMAZON_PAY in case of a redirection from Amazon Pay to the shop. |
-PAYMENTREFERENCE- | Amazon Pay session ID. This ID can be used to render buttons which allow the customer to change their address on the order confirmation page. |
Example of a checkout review URL: https://www.example.com/testshop/review?merchantID=-MERCHANTID-&storeID=-STOREID-&orderID=-ORDERID-&paymentMethod=-PAYMENTMETHOD-&sessionID=-PAYMENTREFERENCE-
Afterwards the user should be redirected to the order confirmation page of the shop, if they were not redirected there immediately. The order confirmation page should contain a summary of the order, with all relevant user and transaction data being displayed, the same as for any other payment method in the shop.
Changing the address
Customers should have the option to change the address on the order confirmation page. As the customer initially selected these addresses on the Amazon Pay page, they must be redirected back to the page to change it again. This can be done by binding click events to HTML elements on the order confirmation page using the Amazon Pay library.
<script src="https://static-eu.payments-amazon.com/checkout.js"></script>
Then the action can be bound to elements on the page:
<script type="text/javascript" charset="utf-8">
amazon.Pay.bindChangeAction('#changeButton1', {
amazonCheckoutSessionId: 'xxxx',
changeAction: 'changeAddress'
});
</script>
First, same as for displaying the Amazon Pay button, the Amazon Pay JavaScript library needs to be included in the header of the order confirmation page.
Upon triggering the event, the customer will then be redirected back to the Amazon Pay page, where they will be able to modify their address.
After the customer selected their new address they will be redirected back to the “checkout review URL”, same as they were initially. Upon re-entry, the customer data should be fetched again from lynck to update the order in the shop.
Finalizing the transaction
When the customer confirms their purchase on the order confirmation page of the shop, the lynck reserve API should be called, same as for any other payment method. On success, the response will contain resultCode=1, which signifies that the customer should be redirected to a specific url, which is provided in the field redirectUrl. This redirection is required by Amazon to perform last risk checks to authorize the payment. Depending on the outcome, the user will then be redirected back to the configured success URL of the shop, or on failure to the configured failure URL of the shop. This is identical behavior to all other payment methods that require a redirection on the lynck platform.
Transaction management
After successful reservation of the Amazon Pay transaction, the transaction may be in one of two states. If Amazon Pay notified that the authorization for the payment is still pending, then the transaction will be in status CIAPending. At this stage, the transaction cannot be captured yet, but it may be cancelled. When Amazon Pay confirmed that the authorization is successful, the lynck transaction will be in status MerchantPending. This signifies that the funds are ready to be captured.
Generally an Amazon Pay transaction in the lynck system can be managed identically to any other payment method, in that captures and refunds can be created, and that they can be cancelled.
PayPal Express
Payment Process
The inclusion of a PayPal Express button in the shop will allow customers to skip parts of the checkout process to have an easier and faster checkout experience. Compared to conventional payment methods, PayPal Express should not be offered on the payment method selection page, but on different pages before that. The button could be included directly on product pages or the basket overview for example. Using PayPal Express does not require the merchant to create a lynck transaction upfront, as would be the case for regular lynck integrations.
Given that the payment method can be offered on the product pages or the basket page in the shop, the customer may not yet have provided any customer data with which a lynck transaction can be created. To create and process a lynck transaction with PayPal Express, the customer needs to log into the PayPal system and then select a delivery address and a payment method using the PayPal Express button.
After successful authentication with PayPal, the customer would then be redirected back to the shop, where the merchant is able to request all relevant customer data from lynck and display the order confirmation page of the shop. On order confirmation by the customer, the transaction should be reserved using the lynck reserve API, which finalizes the payment.
Prerequisites
//lynck library
//For use on the production environment
<script src="https://api.crefopay.de/libs/3.0/paypal-client.js"></script>
//For use on the sandbox environment
<script src="https://sandbox.crefopay.de/libs/3.0/paypal-client.js"></script>
To render the PayPal Express button for a lynck transaction, the PayPal client JavaScript library needs to be included in the header of any given page.
Rendering the PayPal Pay button
<script type="text/javascript" charset="utf-8">
paypalClient = new PaypalClient(
shopPublicKey,
configuration,
initializationCompleteCallback,
cancelCallback,
approveCallback);
paypalClient.createButton();
</script>
To render the button, an instance of the PayPal client needs to be created first. This is done by providing the public key of your shop, provided by lynck, a configuration object and three callback functions. Afterwards the createButton function of the PayPal client instance can be used, to insert the button on the page.
<div data-crefopay-placeholder="payPalExpressButton"></div>
This function will search for a placeholder field on the entire page, and render the button inside it. The placeholder should be a simple DIV-element with the attribute data-crefopay=”payPalExpressButton”.
Argument | Description |
---|---|
shopPublicKey | Will be provided by lynck |
configuration | This argument should be used to provide transaction information required for processing. Details follow below (see Configuration options) |
initializationCompleteCallback | This function will be called right after the client initialization and receives the API response of lynck as argument. |
cancelCallback | This function will be called if the customer either cancels the PayPal login or closes the PayPal window. |
approveCallback | This function will be called if the customer successfully logged in with PayPal and authorized the payment. |
PayPal JS configuration options
The configuration object maybe contain the following fields:
Value | Type | Mandatory | Information |
---|---|---|---|
stagingSystemUrl | V | yes | Base URL of the lynck system for which the transaction should be created. Set to production if not provided. Possible values:
|
color | V | no | Sets the color of the PayPal Express button. Set to "gold" if not provided. Possible values:
|
shape | V | no | Sets the shape of the PayPal Express button. Set to "rect" if not provided. Possible values:
|
tagline | B | no | Decides whether a tagline is displayed below the button or not. Set to "true" if not provided. |
shippingAddress | J (Address) | no | Shipping address of the customer, can be provided if known. |
basketItems | JA (Basket Item) | yes | List of current basket items of the customer. Required to create the PayPal order. If a shipping address was provided, it is mandatory that the basketItems JSON contains an item with basketItemType = SHIPPINGCOSTS. |
orderID | AN (50) | yes | If provided, the value will be used as orderID in the lynck transaction if the user successfully authorized with PayPal. The orderID must be unique. |
userID | AN (50) | yes | If provided, the value will be used as userID in the lynck transaction if the user successfully authorized with PayPal. |
autoCapture | B | no | If true, the resulting lynck transaction will be captured automatically after it was reserved. Set to "false" if not provided. |
nonce | AN | no | The nonce will be passed on in the script tags for all libraries that are automatically fetched by the paypal-client.js, so that the content security policy of shops can allow them to load |
Initialization callback
The provided callback function initializationCompleteCallback will be called once the createButton function was executed, and the result will be provided to it. When resultCode=0 is returned then the button was successfully rendered. For any other resultCode the rendering failed, and a message and further error details are provided.
Relevant fields for result processing:
Field | Description |
---|---|
resultCode |
|
salt | A random number to guarantee the uniqueness of the message. |
message | If an error occurs, this field contains details about that error. Not set if resultCode = 0. |
errorDetails | Structured information about any invalid request values. |
Cancel callback
The provided callback function cancelCallback will be called if the customer cancels the process by closing the PayPal Express popup window. In this case the user did not grant authorization to perform any payments and the user should not progress in the checkout.
Approve callback
The provided callback function approveCallback will be called if the customer successfully authorized the payment inside the PayPal Express popup window. The function will receive the following data which will be needed for further processing:
Field | Description |
---|---|
orderID | OrderID of the lynck transaction associated to this purchase. The orderID will be required in the reserve API call, which should be performed to finalize the transaction one the customer confirmed the purchase on the order confirmation page. |
userID | UserID of the customer associated to this purchase. |
customerEmail | The customers email address that was returned by PayPal. |
shippingAddress | The shipping address associated to this purchase, including the name of the recipient. If no shipping address was provided when the PayPal Express button was initialized, the shipping address which the customer selected at PayPal will be returned. |
Order confirmation page
After the customer successfully logged in with PayPal and authorized the order, they should be redirected to the order confirmation page of the shop on which they can review the order details and provide final confirmation. The order confirmation page should contain a summary of the order, with all relevant user and transaction data being displayed, the same as for any other payment method in the shop.
Finalizing the transaction
When the customer confirms their purchase on the order confirmation page of the shop, the lynck reserve API should be called, same as for any other payment method. No further redirection of the customer is required, meaning the reserve API will respond with resultCode=0 in case the transaction amount was reserved successfully at PayPal
Transaction management
After successful reservation of the PayPal Express transaction, the transaction may be in one of two states. If PayPal notified that the authorization for the payment is still pending, then the transaction will be in status CIAPending. At this stage, the transaction cannot be captured yet, but it may be cancelled. When PayPal confirmed that the authorization is successful, the lynck transaction will be in status MerchantPending. This signifies that the funds are ready to be captured. If the parameter autoCapture=true was provided in the configuration, then the transaction would be captured automatically as well, which would transition it into status Done.
Generally a PayPal Express transaction in the lynck system can be managed identically to any other payment method in the system, in that captures and refunds can be created, and that they can be cancelled.
Data Structures
Address
The address object only contains the street address. It can be used in combination with a person or company to send a complete address.
Field | Type | Mandatory | Comments |
---|---|---|---|
street | AN (80) | yes | street |
no | AN (32) | no | house number |
additional | AN (80) | no | additional information |
zip | AN (16) | yes | zip |
city | AN (80) | yes | city |
state | AN (80) | no | state, e.g. NRW |
country | AN (2) | yes | 2 letter country code according ISO 3166 |
name | AN (153) | no | Full name (PRIVATE user) or company name (BUSINESS user) of the customer. Can be set using the fields billingRecipient and shippingRecipient in createTransaction or createSubscription. Only returned in getTransactionStatus. |
Amount
Field | Type | Mandatory | Comments |
---|---|---|---|
amount | N (9) | yes | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). (including taxes) |
netAmount | N (9) | no | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). (excluding taxes) |
Amount (deprecated, do not use)
Field | Type | Mandatory | Comments |
---|---|---|---|
amount | N (9) | yes | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). |
vatAmount | N (9) | no | Amount in smallest possible denomination (e.g. 12399 for 123.99 Eur). |
vatRate | N (2.2) | no | floating point number with two decimals, e.g (19.00 or 32.75) |
Basket Item
Field | Type | Mandatory | Comments |
---|---|---|---|
basketItemText | AN (500) | yes | Description of the basket item |
basketItemID | AN (20) | no | Unique ID for a single article of the basket |
basketItemCount | N (5) | yes | Number of basket items of this kind |
basketItemAmount | J (Amount) | yes | The subtotal of the basket item. This is the product of the price per item times the item count: basketItemAmount = basketItemCount x pricePerItem. This amount must always be a positive amount, even for the type COUPON |
basketItemRiskClass | V | no | Risk class of this basket item. Possible values are:
|
basketItemType | V | no | Possible values are:
|
Boniversum
Field | Type | Mandatory | Comments |
---|---|---|---|
requestDate | D (YYYY-MM-DD) | yes | Date of the original request |
identification | V | yes | One of the following constants:
|
addressValidationStatus | V | yes | One of the following constants:
|
trafficLightColor | V | yes | One of the following constants:
|
score | N | yes | Score value |
CaptureStatusDetail
Field | Type | Comments |
---|---|---|
transactionAmount | N | The amount which has been confirmed by the user during the checkout process |
capturedAmount | N | The capturedAmount delivers the captured value for this specific (partial) order. If no reference number has been passed capturedAmount contains the sum of all captured amounts for all orders of the transaction |
paidAmount | N | The paidAmount delivers the paid value for this specific (partial) order. If no reference number has been passed paidAmount contains the sum of all paid amounts for all orders of the transaction. |
creditAmount | N | The creditAmount delivers the refunded value for this specific (partial) order. If no reference number has been passed creditAmount contains the sum of all refunds for all orders of the transaction |
reducedAmount | N | Describes how much of the openAmount was reduced via the refund call. |
guaranteedAmount | N | Describes how much was paid out to the merchant from payment guarantee. |
returnedGuaranteedAmount | N | Describes the amount of paid out payment guarantee that was refunded. |
feeAmount | N | Set in case of chargeback. Describes the fees issued by banks or service providers. |
openAmount | N | Describes the incoming amount which the lynck system expects for this order. |
transactionCurrency | AN | Currency code according to ISO4217 |
ClosedTransactions
Field | Type | Mandatory | Comments |
---|---|---|---|
orderID | AN | yes | Unique identifier of the transaction |
closureStatus | V | yes | Shows if the closure of the transaction was successful, failed or is still pending. Possible values:
|
previousTransactionStatus | V | yes | The status of the transaction before closure was triggered. Possible values: see Transaction process |
newTransactionStatus | V | yes | The status of the transaction after the closure was triggered. Possible values: see Transaction process |
transactionAmount | J (Amount) | yes | The total amount of the transaction |
creationDate | D (YYYY-MM-DD) | yes | Date on which the transaction was created |
Company
Field | Type | Mandatory | Comments |
---|---|---|---|
companyName | AN (100) | yes | The name of the company |
AN (254) | yes | Company e-mail address | |
companyRegisterType | V | no | The register type of the company. A list of valid values can be found in the section Company register type |
companyRegistrationID | AN (30) | no | The registration number |
companyVatID | AN (30) | no | The VAT id of the company |
companyTaxID | AN (30) | no | The tax id of the company |
CreateAndReserveTransactionRequest
Field | Type | Mandatory | Comments |
---|---|---|---|
orderID | AN (50) | yes | Unique identifier for the transaction to be created |
referenceOrderId | AN (50) | yes | Order ID of the initial transaction (recurringTransactionType=FIRST) with which the payment agreement was created |
userID | AN (50) | yes | The unique user ID of the customer for which the recurring transaction is created |
merchantReference | AN (30) | no | Optional/additional reference for the transaction |
amount | N (99999999) | yes | The numerical transaction amount in the smallest denomination |
locale | V | yes | Should the transaction result in any communication to the customer, such as a SEPA prenotification email, then the locale will determine the language in which they are contacted. See Languages |
Crediconnect
Field | Type | Mandatory | Comments |
---|---|---|---|
requestDate | D (YYYY-MM-DD) | yes | Date of the original request |
trafficLightColor | V | yes | One of the following constants:
|
Creditreform
Field | Type | Mandatory | Comments |
---|---|---|---|
requestDate | D (YYYY-MM-DD) | yes | Date of the original request |
crefoProductName | V | yes | One of the following constants:
|
blackWhiteResult | B | no | Result of the black/white check:
|
trafficLightResult | V | no | Result of the traffic light check:
|
compactScore | N | no | Result of a compact report: score between 1 - 600. |
dateOfFoundation | V | no | Result of a compact report: company foundation date |
legalForm | V | no | Result of a compact report: company legal form |
lineOfBusiness | V | no | Result of a compact report: company line of business |
companyEmail | V | no | Result of a compact report: company email address |
ErrorDetails
Field | Type | Mandatory | Comments |
---|---|---|---|
message | V | yes | Key for failure reason (e.g. "field.invalid", "fieldName.invalid") |
field | AN | yes | Name of the invalid field. This is exactly the name of the field in the interface. (e.g. userData.dateOfBirth). This value can be used to mark the invalid field in the user interface. |
number | N | yes | Error number |
description | AN | yes | Human readable message in English |
ExternalErrorDetails
Field | Type | Mandatory | Comments |
---|---|---|---|
externalCode | AN | yes | Error code as provided by the service provider |
externalMessage | AN | no | Error message as provided by the service provider |
recoverable | V | no | Provides information on whether the reservation may be re-attempted. Options:
|
HostedPages text
Field | Type | Mandatory | Comments |
---|---|---|---|
paymentMethodType | V | yes | The identifier of the payment method. See PaymentMethods |
fee | N (16) | no | The fee of a payment method in smallest possible denomination e.g. 199 for 1.99 Eur. The fee will be displayed next to the payment method on the Hosted Page, where the user selects his payment method. |
description | AN (255) | yes | Additional text/explanation of a payment method. This text will be displayed next to the payment method on the Hosted Page, where the user selects his payment method |
locale | V | yes | The locale determines the user’s communication language e.g. for e-mails which will be send to the user or for payment pages. See Languages |
MerchantNotificationMessage
Field | Type | Comments |
---|---|---|
merchantID | N (16) | Merchant ID to which the transaction belongs |
storeID | AN (60) | Shop ID to which the transaction belongs |
orderID | AN (50) | Order ID for which the error occurred |
resultCode | N | Related error code. See errorcodes |
message | AN | Contains details about the error |
nextPayment
Field | Type | Mandatory | Comments |
---|---|---|---|
transactionAmount | J (Amount) | yes | Total amount of the next payment that will be tiggered for the subscription. |
paymentDate | D (YYYY-MM-DD) | yes | Date on which the next payment for the subscription will be triggered. |
OldNewValuePair
Field | Type | Mandatory | Comments |
---|---|---|---|
newValue | Same type as updated field | Yes | Contains the updated field value. |
oldValue | Same type as updated field | No | Contains the overwritten field value. Not set if no value was overwritten. |
Payment options
Field | Type | Mandatory | Comments |
---|---|---|---|
recurringTransactionType | V | no | Possible values:
|
PaymentInstrumentRequest
Field | Type | Comments | Mandatory for credit card | Mandatory for bank account |
---|---|---|---|---|
paymentInstrumentType | V | Possible values:
|
yes | yes |
accountHolder | AN (70) | The account holder of the payment instrument | yes | yes |
number | AN (16) | Credit card number | yes | no |
validity | D (YYYY-MM) | Validity date of the credit card | yes | no |
issuer | V | Possible values:
|
yes | no |
iban | AN (34) | Bank account number | no | yes |
bic | AN (11) | Bank identifier - mandatory for non-German bank accounts | no | no |
PaymentInstrumentResponse
Field | Type | Comments | Provided for credit card | Provided for bank account |
---|---|---|---|---|
paymentInstrumentID | AN (20) | The unique ID of the payment instrument. This ID is created by lynck. | yes | yes |
paymentInstrumentType | V | Possible values:
|
yes | yes |
accountHolder | AN (70) | The account holder of the payment instrument | yes | yes |
number | AN (16) | Masked credit card number | yes | no |
validity | D (YYYY-MM) | Validity date of the credit card | yes | no |
issuer | V | Credit card issuer. Possible values:
|
yes | no |
iban | AN (34) | Masked bank account number | no | yes |
unmaskedIban | AN (34) | Unmasked bank account number. Only provided in response to createTransaction. | no | yes |
bic | AN (11) | Bank identifier | no | yes |
mandatoryReserveFields | J(AN) | Array of parameters that are required for the reserve call, such as CVV. Only provided in response to createTransaction. | if required | if required |
Person
Field | Type | Mandatory | Comments |
---|---|---|---|
salutation | V | no | Possible values:
|
name | AN (50) | yes | Person's name |
surname | AN (50) | yes | Person's surname |
dateOfBirth | D (YYYY-MM-DD) | no | Date of birth. The field 'dateOfBirth' is not mandatory, but it is required to perform most solvency checks for the payment methods direct debit and bill payment. If no date of birth is provided the available payment methods may be restricted. |
AN (254) | yes | Person's e-mail address | |
phoneNumber | AN (30) | no | Person's phone number |
faxNumber | N (30) | no | Person's fax number with leading zero |
PaymentMethodInformation
Field | Type | Mandatory | Payment methods | Comments |
---|---|---|---|---|
paymentMethodType | AN | yes | all | Name payment method |
sepaPaymentType | V | no | DD | Describes whether the SEPA mandate is recurring or one-off. Possible values:
|
issuer | V | no | CC, CC3D | List of supported issuers. Possible values:
|
logos | V | no | CC, CC3D, BILL_SECURE | List of possible logos for presenting the payment method or payment instrument. |
mandatoryReserveFields | Array of AN | no | Array of fields the reserve call is expecting for this payment method | |
mandateReference | AN | no | DD | Information for displaying SEPA mandate reference |
creditorId | AN | no | DD | The creditor ID of the merchant |
merchantName | AN | no | DD | The merchant's name |
date | AN | no | DD | Date when the SEPA mandate was created |
RawReportData
Field | Type | Mandatory | Comments |
---|---|---|---|
identificationReportData | J | no | Identification report data coming from solvency check provider Creditreform |
checkReportData | J | no | Solvency check report data coming from solvency check Creditreform |
ReserveInformationRequest
Field | Type | Mandatory | Comments |
---|---|---|---|
dateOfBirth | D (YYYY-MM-DD) | no | Date of birth. The field 'dateOfBirth' is not mandatory, but it is required to perform most solvency checks for the payment methods direct debit and BILL payment. If no date of birth is provided the available payment methods may be restricted. |
referenceOrderId | AN (50) | no | Only mandatory for recurring/subscription transactions (recurringTransactionType=RECURRING). Order ID of the initial transaction (recurringTransactionType=FIRST) with which the payment agreement was created. |
salutation | V | no | Possible values:
|
ReserveInformationResponse
Field | Type | Comments |
---|---|---|
bankname | AN | Bankname of the bankaccount the customer has to transfer the money to |
bic | AN | BIC of the bank account to which the user should remit the money. For bill payments with payment guarantee it is the BIC of their bank account. |
iban | AN | IBAN of the bank account to which the user should remit the money. For bill payments with payment guarantee it is the IBAN of their bank account. |
bankAccountHolder | AN | Name of the bank account holder to whom the user should remit the money. |
paymentReference | AN | The reference text to which the user needs to refer within his remittance so that lynck can link the incoming payments with the outstanding amounts of a transaction. |
RiskData
Field | Type | Comments |
---|---|---|
solvencyData | JA(SolvencyData) | Information about different solvency checks |
SolvencyCheckInformation
Field | Type | Mandatory | Comments |
---|---|---|---|
boniversumResult | J (Boniversum) | no | Data coming from solvency check provider Boniversum |
crediConnectResult | J (Crediconnect) | no | Data coming from solvency check credi connect |
crefoResult | J (Creditreform) | no | Data coming from solvency check provider Creditreform |
SolvencyData
Field | Type | Mandatory | Comments |
---|---|---|---|
solvencyInterface | V | yes | Possible values are:
|
lastRequestDate | D (yyyy-MM-dd'T'HH:mm:ss'Z') | yes | Date of last request to the third party provider |
pdfReportDownloadLink | URL | no | Link to download a ZIP file containing a PDF version of the solvency check report. Only available for Creditreform Webservices products. |
rawReportData | J (Raw report data) | no | Contains the raw response from the solvency check provider. Only available for Creditreform Webservices products. |
checkDate | D (yyyy-MM-dd'T'HH:mm:ss'Z') | yes | Date of the last solvency check request. As the third party provider is not called every time the solvency check is called, this date can differ from the lastRequestDate |
checkType | V | yes | Possible values are:
|
paymentMethod | V | no | The identifier of the payment method. See PaymentMethods. Only set for checkType SECOND_LEVEL_CHECK |
actions | JA(V) | yes | All actions that were triggered by the lynck system because of this check. Possible values are:
|
thirdPartyRequested | B | yes | Indicates if the SolvencyCheck information has been refreshed at the third party provider or if it is historical data. |
orderID | AN | no | Only in the response to getUser. The order which was the trigger for the solvency check |
score | N | no | The score of this solvency check. Different number formats will be returned for different providers |
trafficLight | V | no | Optional for solvencyInterface except BUERGEL, not set for BUERGEL. Possible values are:
|
identification | V | no | Only optional for solvencyInterface BONIMA and VERITA, not set for all other types. Possible values are:
|
addressValidation | V | no | Only optional for solvencyInterface BONIMA and VERITA, not set for all other types. Possible values are:
|
correctedAddress | AN | no | Only optional for solvencyInterface BONIMA, CUBE, and VERITA, not set for all other types. Structure: <street> <houseNo>, <zip> <city>, <countryCode> |
addressOrigin | AN | no | Only set optional solvencyInterface BUERGEL, not set for all other types |
addressOriginCode | N | no | Only optional for solvencyInterface BUERGEL, not set for all other types |
decisionMessage | AN | no | Only optional for solvencyInterface BUERGEL, not set for all other types |
statusCode | AN | no | Only optional for solvencyInterface CREDICONNECT, not set for all other types |
productName | V | no | Only optional for solvencyInterface CREDITREFORM, not set for all other types. Possible values are:
|
checkResult | V | no | Only optional for solvencyInterface CREDITREFORM, not set for all other types. Possible values are:
|
identificationNumber | AN | no | Only optional for solvencyInterface CREDITREFORM, not set for all other types |
negativeIndicator | B | no | Only optional for solvencyInterface CUBE, not set for all other types |
status | V | no | Only optional for solvencyInterface CUBE, not set for all other types Possible values are:
|
specialAddress | V | no | Only optional for solvencyInterface VERITA , not set for all other types. Possible values are:
|
SubscriptionPlan
Field | Type | Mandatory | Comments |
---|---|---|---|
planReference | AN (15) | yes | Plan reference/identification. Used in createSubscription. |
name | AN (25) | yes | Subscription plan name |
description | AN (100) | yes | Subscription plan description provided on plan creation |
amount | J (Amount) | yes | Default subscription rate of the plan |
interval | V | yes | Possible values are:
|
trialPeriod | N (3) | no | Trial period set on plan creation. Possible values: 1 to 366 |
basicPaymentsCount | N (3) | no | Total amount of subscription payments to be done. Possible values: 1 to 999. Unlimited payments if not set. |
contactDetails | AN (100) | no | Contact details set on plan creation |
hasSubscribers | B | yes | Shows whether the plan has subscriptions associated with it |
SubscriptionTransactions
Field | Type | Comments |
---|---|---|
orderID | AN(30) | OrderID of the transaction as set by the merchant |
transactionStatus | V(NEW, ACKNOWLEDGEPENDING, FRAUDPENDING, MERCHANTPENDING, CIAPENDING, EXPIRED, CANCELLED, FRAUDCANCELLED, DONE) | Current status of the transaction |
transactionAmount | J (Amount) | Total amount of the transaction |
creationDate | D (YYYY-MM-DD) | Date on which the transaction was created |
lastStatusChangeDate | D (YYYY-MM-DD) | Date on which the last status change occurred |
UserTransactions
Field | Type | Comments |
---|---|---|
orderID | AN(30) | OrderID of the transaction as set by the merchant |
transactionStatus | V(NEW, ACKNOWLEDGEPENDING, FRAUDPENDING, MERCHANTPENDING, CIAPENDING, EXPIRED, CANCELLED, FRAUDCANCELLED, DONE) | Current status of the transaction |
transactionAmount | N | Total amount of the transaction |
transactionBalance | N | Current balance of the transaction |
creationDate | D (YYYY-MM-DD) | Date on which the transaction was created |
lastStatusChangeDate | D (YYYY-MM-DD) | Date on which the last status change occurred |
TransactionStatusDetail
Field | Type | Only cash in advance or bill | Only direct debit | Comments |
---|---|---|---|---|
transactionAmount | N | No | No | The amount which has been confirmed by the user during the checkout process |
transactionBalance | N | No | No | The sum of all received payments minus the sum of all captured amounts plus all reductions. This value is negative when still waiting for payments, positive in case a transaction was overpaid, and zero when the debt is paid exactly or no capture was performed yet. |
transactionCurrency | AN | No | No | Currency code according to ISO4217 |
customerEmail | AN | No | No | E-mail address of the customer related to the transaction. |
paymentDescriptor | AN | No | No | Description of the payment method selected by a customer at Amazon Pay |
paymentMethod | AN | No | No | The identifier of the payment method. See PaymentMethods |
bankname | AN | Yes | No | Name of the bank where the user should remit the money. |
bic | AN | Yes | No | BIC of the bank to which the user should remit the money. |
iban | AN | Yes | No | IBAN of the bank to which the user should remit the money. |
accountHolder | AN | Yes | No | Name of the bank account holder to whom the user should remit the money. |
paymentReference | AN | Yes | No | The reference text to which the user needs to refer within his remittance so that lynck can link the incoming payments with the outstanding amounts of a transaction. |
sepaMandate | AN | No | Yes | Reference Number of the SEPA Mandate, only available if Payment method was DD |
debitAccountHolder | AN | Yes | Yes | |
debitIban | AN | No | Yes | IBAN of the bankaccount that will be debited |
debitBic | AN | No | Yes | BIC of the bankaccount that will be debited |
UpdatedData
Field | Type | Mandatory | Comments |
---|---|---|---|
merchantReference | J (OldNewValuePair) | No | Contains the updated merchantReference and the previous merchantReference if any value was overwritten. Only set if the merchantReference was updated. |
UserBalance
Field | Type | Comments |
---|---|---|
balance | N | The sum of the last 100 transaction balances of the user |
transactionAmount | N | The sum of transaction amounts of the last 100 transactions of the user |
Additional services
SmartSignup
The Smart Sign-Up JavaScript library is designed to help your business customers complete the checkout process far quicker, and make sure you always have accurate data about your business customers, which greatly enhances the chances of a successful B2B solvency check. The data returned by Smart Sign-Up comes from Creditreform databases for business information reports. The Creditreform data is collected decentralised by 130 German branch offices.
User flow
After your business customer types the first three letters of his business name, we call the 'Firmenwissen' Smart Sign-Up API to query the Creditreform database.The user will see a drop-down with possible selection options displayed based on his input. A new query is performed after the user changes his input and pauses for 300 milliseconds.
After the user selects his company from the drop-down list, the address fields (street, number, ZIP, county and country) are automatically populated. We can also return the CrefoNummer, which you can store in your ERP or database for later use.
To understand the user flow better, have a look at the 'Firmenwissen' Smart Sign-Up website https://www.firmenwissen.de/index.html.
SmartSignup Prerequisites
Before you can use Smart Sign-Up you need to add this option to your contract with lynck. If you did not register for this option yet just contact the support team at service@lynck.de. You will need a public key to initialize the library.
The JavaScript Library should be included in the page using the following snippet:
<script src="https://libs.crefopay.de/3.0/smart-sign-up.js"></script>
URL:
Sandbox: https://sandbox.crefopay.de/autocomplete/
Live: https://api.crefopay.de/autocomplete/
SmartSignup Configuration
let configuration = {
"url": "https://sandbox.crefopay.de/autocomplete/",
"itemCount": 10,
"suggestion": {"zip": true, "city": true, "county": true, "country": true}
};
The following values can be set in the configuration object for the SmartSignup client:
Field | Type | Mandatory | Comments |
---|---|---|---|
url | AN | no | API endpoint (If this value is not set, it will default to the lynck production system.) |
itemCount | N | yes | Number of suggestions that are shown in the drop-down |
suggestion | J | no | configuration of the content that is shown in the suggestion drop-down. As a default only the company name is shown in the droptown. To add additional information following parameter can be added to this Json object:
|
SmartSignup Initialization
To initialize the library, an instance of the SecureFieldsClient needs to be created.
function SmartSignUpClient(shopPublicToken, onInit, configuration)
new SmartSignUpClient("6bebbcabf03b937c05d1db9f0af98b29363880ba903fab10c4f5d4d96d58193f", function (data) {
$("#result-content").html('');
if (data.resultCode === 0) {
$("#result-content").append('<p>Successfully initialized</p>');
}
$("#result-content").append(JSON.stringify(data, null, 4));
}, configuration);
Field | Type | Mandatory | Comments |
---|---|---|---|
shopPublicToken | AN | yes | The key you get from the support team after successfully registering with SmartSignup |
onInit | JS function | yes | This function will be called right after the SmartSignup initialization and receives the API response of lynck as argument. |
configuration | JS object | yes | The configuration object for the SmartSignup client |
Display the result of the search
<div>
<label for="companyName">Company Name</label>
<input data-crefopay-placeholder="address.name" type="text" name="companyName"/>
</div>
<div>
<label for="street">streetWithNumber</label>
<input data-crefopay-placeholder="address.street" type="text" name="street"/>
</div>
<div>
<label for="zip">Zip</label>
<input data-crefopay-placeholder="address.zip" type="text" name="zip"/>
</div>
<div>
<label for="city">City</label>
<input data-crefopay-placeholder="address.city" type="text" name="city"/>
</div>
<div>
<label for="country">Country</label>
<input data-crefopay-placeholder="address.country" type="text" name="country"/>
</div>
<div>
<label for="crefoNo">Crefo No</label>
<input data-crefopay-placeholder="crefoNo" type="text" name="crefoNo"/>
</div>
The attribute data-crefopay-placeholder
is used in all input input that should be used be autocompleted by SmartSignup. Following values can be used:
Value | Description |
---|---|
address.name | Company name. The input field with this tag is parsed by the SmartSignup client library to present suggestions. After at least 3 letters have been typed, the client library starts to show suggestions |
address.street | Street name |
address.streetNo | Street number |
address.streetWithNumber | Street name with number |
address.zip | ZIP code |
address.city | City name |
address.state | State of county |
address.country | 2 letter country code according ISO 3166 |
crefoNo | The crefo number of the company |
SmartSignup Example
This example shows a minimal HTML page that uses SmartSignup to autocomplete all address-fields and show the result of the initialization of the initialization of the client library.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://sandbox.crefopay.de/smart-sign-up.css">
<script src="https://libs.crefopay.de/3.0/smart-sign-up.js"></script>
</head>
<body onload="configureSmartSignup()" >
<h1>Smart SignUp</h1>
<div>
<label for="companyName">Company Name</label>
<input data-crefopay-placeholder="address.name" type="text" name="companyName"/>
</div>
<div>
<label for="street">Street</label>
<input data-crefopay-placeholder="address.street" type="text" name="street"/>
</div>
<div>
<label for="streetNo">Street No</label>
<input data-crefopay-placeholder="address.streetNo" type="text" name="streetNo"/>
</div>
<div>
<label for="zip">Zip</label>
<input data-crefopay-placeholder="address.zip" type="text" name="zip"/>
</div>
<div>
<label for="city">City</label>
<input data-crefopay-placeholder="address.city" type="text" name="city"/>
</div>
<div>
<label for="state">State</label>
<input data-crefopay-placeholder="address.state" type="text" name="state"/>
</div>
<div>
<label for="country">Country</label>
<input data-crefopay-placeholder="address.country" type="text" name="country"/>
</div>
<div>
<label for="crefoNo">Crefo No</label>
<input data-crefopay-placeholder="crefoNo" type="hidden" name="crefoNo"/>
</div>
<div id="result-container">
<h1>Result</h1>
<div id="result-content" class="result form"></div>
</div>
<script>
function configureSmartSignup() {
let configuration = {
"url": "https://sandbox.crefopay.de/autocomplete/",
"itemCount": 20,
"suggestion": {"city": true, "country": true, "zip": true, "county": true}
};
new SmartSignUpClient("abcdefghijkjmnopqrstuvwxyz", function (data) {
$("#result-content").html('');
if (data.resultCode === 0) {
$("#result-content").append('<p>Successfully initialized</p>');
}
$("#result-content").append(JSON.stringify(data, null, 4));
}, configuration);
}
</script>
</body>
</html>
Additional resources
Company register type
Value | Description |
---|---|
UNKNOWN | Not specified |
HRA | German trade register department A |
HRB | German trade register department B |
PARTR | German partnership register |
GENR | German cooperative society register |
VERR | German register of associations |
FN | Austrian commercial register |
LUA | Luxembourg trade registry A |
LUB | Luxembourg trade registry B |
LUC | Luxembourg trade registry C |
LUD | Luxembourg trade registry D |
LUE | Luxembourg trade registry E |
LUF | Luxembourg trade registry F |
LUG | Luxembourg trade registry G |
Currency codes
Supported ISO 4217 currency codes
Code | Name |
---|---|
EUR | Euros |
USD | United States Dollar |
GBP | United Kingdom Pound |
CHF | Switzerland Franc |
SEK | Sweden Krona |
NOK | Norway Krone |
CZK | Czech Republic Koruna |
DKK | Denmark Krone |
HRK | Croatian kuna |
HUF | Hungarian forint |
ISK | Icelandic króna |
PLN | Polish złoty |
RUB | Russian ruble |
AUD | Australian dollar |
BRL | Brazilian real |
CAD | Canadian dollar |
MXN | Mexican peso |
ARS | Argentine peso |
ILS | Israeli new shekel |
INR | Indian rupee |
JPY | Japanese yen |
KRW | South Korean won |
SGD | Singapore dollar |
ZAR | South African rand |
HKD | Hong Kong dollar |
RON | Romanian leu |
ALL | Albanian lek |
MKD | Macedonian denar |
MDL | Moldovan leu |
Errors
Successful call
Code | Description |
---|---|
0...999 | See documentation of request methods for more information. These codes are reserved for different uses |
Technical or interface errors
Code | Description |
---|---|
1000 | An unknown error occurred, please contact the lynck Support to find out details. |
1001 | The calculated MAC is invalid. |
1002 | The request is invalid. Please refer to the message for further explanation of the cause. |
Status codes for rejected requests
Code | Description |
---|---|
2000 | The payment method is not available. Please use another payment method. |
2001 | The payment has been rejected. Please use another payment method. |
2002 | Method call is not allowed in this state of transaction. |
2003 | The transaction is expired. |
2004 | The requested order number does not exists. |
2005 | Method call already in process for this transaction. |
2006 | No shop found with this shopID. |
2007 | Shop is not activated. |
2008 | Order ID already exist: |
2010 | The credit card is expired. |
2011 | The credit card number does not match the issuer. |
2012 | The credit card is already stored for this user. |
2013 | The bank account is already stored for this user. |
2014 | The user already exist. |
2015 | The user does not exist. |
2016 | Refund amount must not be greater than capture amount. |
2017 | Payment declined by fraud check. Please use another payment method. |
2018 | Refund failed. |
2019 | The provided captureID is unknown. |
2020 | Reduce/Refund failed partially. |
2021 | The MSA user already exists. |
2022 | The Shop already exists. |
2023 | Transaction is already finished. |
2024 | Invalid token, |
2025 | Merchant doesn't have the right to do this call. |
2026 | The provided paymentInstrumentID is unknown. |
2027 | No payment method available due to configuration. |
2028 | This order was already captured. |
2029 | This order was already captured with different Amount. |
2030 | Capture is not allowed in this state of transaction. |
2031 | "Payment Instrument is not a Bank Account." or "Payment Instrument is not a Credit Card." |
2032 | Merchant notification failed. |
2033 | The payment instrument is invalid. |
2034 | The payment instrument does not support SEPA direct debit. |
2035 | Bank account or routing number do not match. |
2036 | Non PCI compliant merchant is not allowed to send CVV. |
2037 | Capture rejected. |
2038 | Multiple captures not allowed. |
2039 | Issuer is not supported by the shop. Please try another one. |
2040 | The issuer of the credit card could not be detected. Please use another card. |
2041 | The credit card number is empty. Please enter a credit card number. |
2042 | The validity month of the credit card is empty. Please enter a validity month. |
2043 | The validity year of the credit card is empty. Please enter a validity year. |
2044 | The name of the credit card holder is empty. Please enter an account holder. |
2045 | Error in sending email. |
2046 | Invalid card number. |
2047 | No active dunning configuration for transaction. |
2048 | No plan found with this planReference. |
2049 | Transaction type not allowed. |
2050 | Subscription ID already exists. |
2051 | The provided subscription id is unknown. |
2052 | Method call is not allowed in this state of subscription. |
2053 | No changes were performed. Please provide at least one optional parameter. |
2054 | Refund not allowed. |
2055 | The payment has been rejected. Please use another payment method. |
2056 | The provided paymentInstrumentID incorrect. |
2057 | The credit card is expiring soon. |
2058 | Solvency checks are not configured. |
2059 | Add Payment Failed. |
2060 | An external payment provider is not available. |
2062 | Check is not configured. |
2063 | Non PCI compliant merchant is not allowed to register credit cards. |
Additional status codes for notification callbacks
Code | Description |
---|---|
6001 | parameter or format error |
6002 | unknown |
6003 | transaction or payment method not allowed |
6004 | system error, no response, time-out |
6005 | cancelled by user |
6006 | authentication failed |
6007 | expired, blocked, stolen, declined with no specific reason |
6008 | no JavaScript in user's browser |
6009 | overload, merchant busy, processing temporarily not possible |
6010 | invalid amount |
6011 | fraud |
6012 | communication error |
6013 | reservation outdated |
6014 | configuration error |
6015 | partial capture not allowed |
6016 | third party gateway returned an error or declined transaction, details will be in the error description |
6017 | no funds |
6018 | partial refund failed |
6025 | Invalid Amazon Pay payment method |
Testdata
Amazon Pay:
Customer E-Mail | amazonmerchant+sandbox@crefopay.de |
Password | test123 |
Apple Pay:
To test Apple Pay on the sandbox environment, a "Sandbox Tester Account" is required. Please review the following resource regarding Apple Pay Sandbox Testing: https://developer.apple.com/apple-pay/sandbox-testing/
Credit Card:
Owner | Any name |
Card Number | 4321123443211234 |
CVV | Any three digit number |
Expiration Date | Any valid date in the future |
Request | Amount | Result code | Description |
---|---|---|---|
Reserve (CC) | 1.11 € | 2060 | Authorization error |
Reserve (CC3D) | 1.12 € | 2060 | Authorization error before redirection to 3D-secure check |
Reserve (CC3D) | 1.19 € | 6012 | Authorization error after redirection to 3D-secure check |
Capture | 1.13 € | 2037 | Capture rejected |
Capture | 1.22 € | Capture transitions to status PENDING before changing to status PAID | |
Capture | 1.23 € | Capture transitions to status PENDING before changing to status FAILED | |
Capture | 1.24 € | Capture transitions to status PENDING and remains in this status | |
Refund | 1.14 € | 2018 | Refund failed |
Refund | 1.20 € | Refund transitions to status PENDING before changing to status DONE | |
Refund | 1.21 € | Refund transitions to status PENDING before changing to status FAILED |
Direct Debit:
Account owner | Any name |
IBAN | DE06000000000023456789 |
BIC | SFRTDE20000 |
eps / giropay / iDEAL:
Bank name or BIC | Testbank |
Account Number | Any |
PIN | Any |
TAN | 1234 |
Google Pay:
Customer E-Mail | googlepay-test@lynck.de |
Password | GoogleTest123! |
To test Google Pay you may add test cards to your own Google account. Please review this resource regarding Google Pay testing: https://developers.google.com/pay/api/web/guides/resources/test-card-suite
Paypal:
Username | testing@crefopay.de |
Password | #vaS7Rjt |
Sofort:
Bankname | 88888888 |
Bank Routing Number | 88888888 |
PIN | 8888 |
Zinia:
Please keep the payment method restrictions for Zinia Buy Now Pay Later and Zinia Splitpay in mind when testing.
To receive approval for your transaction in the Zinia sandbox environment, please use the following user data:
First name | Jan |
Last name | ZINIA_AP |
When you are prompted for a phone number by Zinia, provide any valid German phone number and confirm it with the one time password 9999.
Languages
Lynck support the following languages within the checkout process
Code | Name |
---|---|
EN | English |
DE | German |
ES | Spanish |
FR | French |
IT | Italian |
NL | Dutch |
Cookies
The Cookies that are set by different lynck products can be found in the table below:
Merchant Service Area
Name | Domain | Path | Expires | Description |
---|---|---|---|---|
JSESSIONID | service.crefopay.de | / | Session | ID to identify the user during the session |
language | service.crefopay.de | /msa3 | Session | Stores the language of the user |
locale | service.crefopay.de | /msa3 | Session | Stores the locale of the user |
HostedPages
No Cookies are set
SecureFields
No Cookies are set