SEPA
- Get Financial Institution Data
- Initiate Authorization
- Collect Payment Option Details via SDK
- SEPA Mandate Acceptance Page
- Complete Authorization
1. Get Financial Institution Data
Before initializing the authorization process, call the API method 1.84 Get Financial Institution Data.
Get Financial Institution Data Request
Path:
GET {baseURL}/settings/getFinancialInstitutionData?localDate=2017-08-21&localTime=170911&partnerReference=TEST-4H363TJC68
Header:
Content-Type: application/json
Accept-Language: en-US
This will provide you with information about the financial institution, which will act as a Creditor in the SEPA Direct Debit process. This information is necessary for the SEPA Mandate Acceptance Page.
Get Financial Institution Data Response
Status Code:
200 (OK)
Header:
Content-Type: application/json
Accept-Language: en-US
{
"name": "J.P. Morgan Mobility Payments Solutions S.A. (SANDBOX)",
"addr1": "19-21, Route d'Arlon",
"city": "Luxembourg",
"state": "Strassen",
"countryName": "Germany",
"countryCode": "DE",
"countryCode3": "DEU",
"postCode": "L-8009",
"creditorIdentifier": "DE98ZZZ09999999999",
"contactPhone": "+49 892 488 5811",
"contactEmail": "user@example.com",
"partnerReference": "DEV-SVR001-DE_CUSTID-T8933PXJPK_CARTID-DJ7JKK662D_FK8K3MPJBQ",
"localDate": "2018-10-24",
"localTime": "093028",
"sysDate": "2018-10-24",
"sysTime": "073028",
"responseCode": "0000",
"responseDescription": "Successful execution",
"additionalInformation": {
"requestId": "aff2728481a181dc36daedc14055b516"
}
}
2. Initiate Authorization
SEPA
The authorization of a payment is initialized by calling the API method 1.38 Init Authorize.
In the example below, we authorize 3.99 EUR for a SEPA direct debit as part of the purchase of two premium widgets from Widgets GmbH. The shopper's full name is provided alongside their address.
Initiate Authorization Request
Path:
PUT {baseURL}/payment/initAuthorize
Header:
Content-Type: application/json
Accept-Language: en-US
X-Auth-Token: eyJhbGciOiJSUzI1NiI{abbreviated}RW5kVG9rZW4=
{
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_VGT284FYXV",
"programAccno": "1679541175",
"accno": "MERCHANT-DE4321",
"accnoType": "00",
"paymentOptionCode": "BNKACCT",
"mandateReference": "446ED8B3F6FD4CC195FB4D6E860E675A",
"mandateSignedDate": "2018-10-15",
"mandateSignedTime": "155107",
"presentationAmount": 3.99,
"presentationCurrCode": "EUR",
"presentationUsage": "Purchase:2xPremiumWidgets. Merchant:WidgetsGmbH. CUSTREF:52650FD95.",
"criteria": [
{
"name": "callbackURL",
"value": "https://example.com/Payment/CompleteAuthorize?SessionID=GP123EX456WC789"
}
],
"useDifferentBillingAddress": true,
"customerFullName": "Jacob Smith",
"addr1": "Anystreet",
"houseNumber": "321",
"city": "Anycity",
"countryCode": "DE",
"postCode": "12345",
"localDate": "2018-10-15",
"localTime": "155107",
"custom1": "WVWZZZ3BZWE689725"
}
It is strongly advised that real customer information be accurately provided - i.e., "useDifferentBillingAddress"
being set to true
, making the below mandatory:
customerFullName
addr1
houseNumber
(if not included in "addr1")city
postCode
countryCode
It is advised that "emailAddress"
also be provided, with accurate customer data.
Please discuss with you business contacts when providing accurate data may not be possible in production, as it may result in transactions being rejected.
If the value of "countryCode" is "US"
(United States of America) or "CA"
(Canada) the "state" parameter is required. The value of "state" must be a valid State Code. (ex. "countryCode": "US", "state": "NY"
)
The mandate reference is a unique identification number for each SEPA direct debit signed by one of your customers. You are free in assigning the mandate reference as long as it is unique and does not exceed 35 characters.
The Mandate Time and Mandate Date provide a time stamp, which is crucial for potential refund deadlines.
The maximum character length of the presentation usage (see variable presentationUsage
in the example above) varies between payment options. It may be that with certain payment options the specified presentation usage may be less than 127 and consequently be truncated. It would thus be strongly recommended that the most pertinent information be placed at the beginning of the presentation usage. To be compatible with most payment options we suggest that the presentation usage already be truncated at the 22nd character.
The value of "callbackURL" (provided in "criteria") specifies the endpoint where you will receive a POST request once the payment details are committed. The Request Body must be passed as "paymentProviderResponse" in the subsequent "Complete Authorize" API Call.
Only URLs starting with "https://"
are permitted as the value of "callbackURL"
As shown in the above example it is possible to add a "SessionID" parameter in the "callbackURL" so both the Redirect URL and POST Request can be easily identified for the relevant user payment instance.
Initiate Authorization Response
Status Code:
201 (Created)
Header:
Content-Type: application/json
Accept-Language: en-US
{
"programAccno": "1679541175",
"accno": "MERCHANT-DE4321",
"uniqueReference": "BNkk4BRkQEufPSvgf9lDwA",
"loadAccountReference": "NvPoE85cZE6FguOfrC7Fmw",
"authorizationToken": "yX15XwyXWe{partial omission for brevity}y5XwyXW9",
"paymentOptionCode": "BNKACCT",
"presentationAmount": 3.99,
"presentationCurrCode": "EUR",
"presentationUsage": "Purchase:2xPremiumWidgets. Merchant:WidgetsGmbH. CUSTREF:52650FD95.",
"custom1": "WVWZZZ3BZWE689725",
"statusCode": "RECEIVED",
"paymentProviderResponse": "yX15XwyXWe{partial omission for brevity}y5XwyXW9",
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_VGT284FYXV",
"localDate": "2018-10-15",
"localTime": "155550",
"sysDate": "2018-10-15",
"sysTime": "135551",
"responseCode": "0000",
"responseDescription": "Successful execution",
"additionalInformation": {
"requestId": "aff2728481a181dc36daedc14055b516"
}
}
The response includes the desired authorization token under the return parameter "authorizationToken" which is used to collect payment option details via the SDK and alongside the "uniqueReference" is required to complete the authorization of the initiated transaction. The transaction reference under the return parameter "uniqueReference" is furthermore required for the following API calls. Beyond this use, it should be persisted if possible, as it enables the identification of the transaction should the need arise at a later stage.# 3. Collect Payment Option Details via SDK
SEPA (Pay.ON)
The authorization of a payment is initialized by calling the API method 1.38 Init Authorize.
In the example below, we authorize 3.99 EUR for a PayU "Pay-by-Link" payment as part of the purchase of two premium widgets from Widgets GmbH. The shopper's full name is provided alongside their address.
Initiate Authorization Request
Path:
PUT {baseURL}/payment/initAuthorize
Header:
Content-Type: application/json
Accept-Language: en-US
X-Auth-Token: eyJhbGciOiJSUzI1NiI{abbreviated}RW5kVG9rZW4=
{
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_VGT284FYXV",
"programAccno": "1679541175",
"accno": "MERCHANT-DE4321",
"accnoType": "00",
"paymentOptionCode": "BNKACCT",
"mandateReference": "446ED8B3F6FD4CC195FB4D6E860E675A",
"mandateSignedDate": "2018-10-15",
"mandateSignedTime": "155107",
"presentationAmount": 3.99,
"presentationCurrCode": "EUR",
"presentationUsage": "Purchase:2xPremiumWidgets. Merchant:WidgetsGmbH. CUSTREF:52650FD95.",
"useDifferentBillingAddress": true,
"customerFullName": "Jacob Smith",
"addr1": "Anystreet",
"houseNumber": "321",
"city": "Anycity",
"countryCode": "DE",
"postCode": "12345",
"localDate": "2018-10-15",
"localTime": "155107",
"custom1": "WVWZZZ3BZWE689725"
}
It is strongly advised that real customer information be accurately provided - i.e., "useDifferentBillingAddress"
being set to true
, making the below mandatory:
customerFullName
addr1
houseNumber
(if not included in "addr1")city
postCode
countryCode
It is advised that "emailAddress"
also be provided, with accurate customer data.
Please discuss with you business contacts when providing accurate data may not be possible in production, as it may result in transactions being rejected.
The mandate reference is a unique identification number for each SEPA direct debit signed by one of your customers. You are free in assigning the mandate reference as long as it is unique and does not exceed 35 characters.
The Mandate Time and Mandate Date provide a time stamp, which is crucial for potential refund deadlines.
The maximum character length of the presentation usage (see variable presentationUsage
in the example above) varies between payment options. It may be that with certain payment options the specified presentation usage may be less than 127 and consequently be truncated. It would thus be strongly recommended that the most pertinent information be placed at the beginning of the presentation usage. To be compatible with most payment options we suggest that the presentation usage already be truncated at the 22nd character.
Initiate Authorization Response
Status Code:
201 (Created)
Header:
Content-Type: application/json
Accept-Language: en-US
{
"programAccno": "1679541175",
"accno": "MERCHANT-DE4321",
"uniqueReference": "BNkk4BRkQEufPSvgf9lDwA",
"loadAccountReference": "NvPoE85cZE6FguOfrC7Fmw",
"authorizationToken": "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01",
"paymentOptionCode": "BNKACCT",
"presentationAmount": 3.99,
"presentationCurrCode": "EUR",
"presentationUsage": "Purchase:2xPremiumWidgets. Merchant:WidgetsGmbH. CUSTREF:52650FD95.",
"custom1": "WVWZZZ3BZWE689725",
"statusCode": "RECEIVED",
"paymentProviderResponse": {
"result": {
"code": "000.200.100",
"description": "successfully created checkout"
},
"buildNumber": "b5487567b639c21ffd60a5f42c484f3276ff93b3@2018-10-11 13:50:52 +0000",
"timestamp": "2018-10-15 13:55:51+0000",
"ndc": "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01",
"id": "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01"
},
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_VGT284FYXV",
"localDate": "2018-10-15",
"localTime": "155550",
"sysDate": "2018-10-15",
"sysTime": "135551",
"responseCode": "0000",
"responseDescription": "Successful execution",
"additionalInformation": {
"requestId": "aff2728481a181dc36daedc14055b516"
}
}
The response includes the desired authorization token under the return parameter "authorizationToken" which is used to collect payment option details via the SDK and alongside the "uniqueReference" is required to complete the authorization of the initiated transaction. The transaction reference under the return parameter "uniqueReference" is furthermore required for the following API calls. Beyond this use, it should be persisted if possible, as it enables the identification of the transaction should the need arise at a later stage.
3. Collect Payment Option Details via SDK
SEPA
The SDK renders a customizable payment form and sends the entered payment details directly from the customer's browser to the Creditor. We offer SDKs for the integration into websites as well as mobile applications (Android and iOS).
The example below shows only the relevant part of the KC Web SDK implementation for Guest Payments with the SEPA payment. A complete and detailed description of the KC Web SDK can be found here.
The authorization token returned by the API method 1.38 Init Authorize which initiated the transaction is used to associate the payment option details collected via the KC Web SDK with the transaction.
Collect Payment Option Details via KC Web SDK
cw.initialize (
{
apiURL: {baseURL}, // KontoCloud API Base URL.
bankAccountPaymentProvider: "sepa" // Required for SEPA payment provider.
}
);
cw.PaymentForm(container,
{
authorizationToken: "yX15XwyXWe{partial omission for brevity}y5XwyXW9",
paymentOptionCodes: ["BNKACCT"],
submitButtonTitle: "Continue",
//Only as example. Use own SEPA Mandate Handler, with necessary data.
onBeforeSubmit: function(data, submit, cancel) { // Show SEPA Mandate
var mandate = confirm("Example SEPA Mandate Acceptance Page"+
"Name = " + data.accountHolder +"\n"+ "IBAN = " + data.iban);
if(mandate) { submit(); } // User Accepts SEPA Mandate
else { cancel(); } // Mandate Rejected, Can Edit Form
},
onError: function(message) {
console.log(message);
}
}
);
Please contact your Product Solution Specialist to align on the {baseURL}
that will be used as apiEndpoint.
Before the shopper can submit the payment, they must accept the SEPA Mandate. This can be ensured with the "onBeforeSubmit"-function (see example above). First, extract the IBAN from the payment form rendered by the KC Web SDK, and show it on the SEPA Mandate Acceptance Page.
SEPA (Pay.ON)
The SDK renders a customizable payment form and sends the entered payment details directly from the customer's browser to the Creditor. We offer SDKs for the integration into websites as well as mobile applications (Android and iOS).
The example below shows only the relevant part of the KC Web SDK implementation for Guest Payments with the SEPA payment. A complete and detailed description of the KC Web SDK can be found here.
The authorization token returned by the API method 1.38 Init Authorize which initiated the transaction is used to associate the payment option details collected via the KC Web SDK with the transaction.
Collect Payment Option Details via KC Web SDK
cw.PaymentForm(container,
{
authorizationToken: "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01",
callbackUrl: "https://www.example.com/Checkout/CompleteOrder",
confirmationUrl: "https://www.example.com/ConfirmOrder",
paymentOptionCodes: ["BNKACCT"],
locale: "en-US",
paymentProviderMode: "test",
submitButtonTitle: "Continue",
onBeforeSubmit: function (data, callback) {
var iban = document.getElementsByClassName("wpwl-control-accountIban")[0].value; // extract iban
$('#modal').show(); // show mandate acceptance page
$('#accept').select();
document.getElementById("iban").innerHTML = iban; // display iban in mandate acceptance page
$('#accept').click(function () { callback() }); // mandate must be accepted before submit
},
onError: function(message) {
console.log(message);
}
}
);
The "confirmationURL" can be replaced with the desired URL which will display the payment confirmation page. Note, that in most cases the display of a payment confirmation page is not mandatory (see 5. Payment Confirmation Page for further information). Do not specify a "confirmationURL" to skip this step.
The "callbackURL" should be replaced with the URL identifying the server side method which will call the next API method to complete the authorization (see 6. Complete Authorization).
Note, that authorization token is attached to the "callbackUrl" (as query string parameter "id") and the "confirmationUrl" (as query parameter "authorizationToken"). This approach avoids having to persist this variable on the server side and is thus recommended practice.
Before the shopper can submit the payment, they must accept the SEPA Mandate. This can be ensured with the "onBeforeSubmit"-function (see example above). First, extract the IBAN from the payment form rendered by the KC Web SDK, and show it on the SEPA Mandate Acceptance Page. The callback-function is not invoked until the user clicks the accept-button, thus submitting the payment form.
Payment Confirmation Page
The Payment Confirmation Page enables the collection of payment details prior to the payment i.e., allowing the shopper to review their purchase details prior to finally committing to the payment.
Depending on your location, the display of a payment confirmation page may be mandatory. Please seek assistance by contacting legal counsel should you be unsure of the legal requirements in your country. Do not specify a "confirmationURL" to skip the confirmation page.
You can integrate the payment confirmation button in a few lines of client-side code.
Payment Confirmation Page Example
<form id="confirmation">
<button type="submit">Pay now</button> <!-- confirmation button -->
<form>
<script src="cwPaymentForm-5.3.1.js"></script> <!-- add cwPaymentForm script -->
<script type="text/javascript">
var form = document.getElementById("confirmation"); // Find a confirmation form
try {
// Configure the confirmation form
cw.PaymentConfirmation(form, {
paymentProviderMode: "test" // use "live" for a release version
});
} catch (e) {
document.write(e);
console.log(e);
}
</script>
The embedded form in the body of your HTML site will create a confirmation button. The forwarded authorization token in the "confirmationUrl" (as query parameter "authorizationToken") associates the payment confirmation page with the payment option details previously collected via the KC Web SDK.
With the payment option details collected, the shopper is redirected to the previously specified "callbackURL".
4. SEPA Mandate Acceptance Page
Each mandate must include certain mandatory legal wording and mandatory information. The page contains not only the details of customer (name, address, etc.) and creditor information (see 1. Get Financial Institution Data), but also the mandate parameters (mandate reference number, date, time). You must display the following standard authorization text (replacing {FI name} with the name of the creditor) clearly visible and close to the accept button.
With the SEPA direct debit authorization, you authorize {FI name} to send instructions to your bank account. You also authorize your bank to debit your account in accordance with the instructions from {FI name}. A refund must be claimed within 8 weeks, starting from the date on which your account was debited.
We suggest to display the mandate in a modal window as depicted in the mockup below.
We highly recommend to use a GUID (Globally Unique Identifier) with the canonical 8-4-4-4-12 format as the mandate reference number.
With accepting the SEPA Mandate, the customer authorizes you to collect a payment for the specified amount from their bank account using SEPA Direct Debit and is redirected to the specified "callbackURL".
5. Complete Authorization
SEPA
When the POST request arrives at the specified "callbackURL" you can proceed to call the 1.39 Complete Authorize API, providing the content of the POST request's body as an URL-Encoded string in the "paymentProviderResponse" parameter under the "criteria" array.
Complete Authorization Request
Path:
POST {baseURL}/payment/{uniqueReference}/completeAuthorize
POST {baseURL}/payment/BNkk4BRkQEufPSvgf9lDwA/completeAuthorize
Header:
Content-Type: application/json
Accept-Language: en-US
X-Auth-Token: eyJhbGciOiJSUzI1NiI{abbreviated}RW5kVG9rZW4=
{
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_JYFGRFTQXM",
"authorizationToken": "yX15XwyXWe{partial omission for brevity}y5XwyXW9",
"criteria": [
{
"name": "paymentProviderResponse",
"value": "data=a0%ln7fr4h{partial omission for brevity}fr4hK9Bl%0"
}
],
"localDate": "2018-10-15",
"localTime": "155550"
}
Complete Authorization Response
Status Code:
200 (OK)
Header:
Content-Type: application/json
Accept-Language: en-US
{
"initiatorAccno": "1679541175",
"accno": "1679797975",
"uniqueReference": "BNkk4BRkQEufPSvgf9lDwA",
"initiationCountryCode": "DE",
"initiationCountryCode3": "DEU",
"processedAmount": 3.99,
"processedCurrCode": "EUR",
"statusCode": "AUTHORIZED",
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_JYFGRFTQXM";
"localDate": "2018-10-15",
"localTime": "160910",
"sysDate": "2018-10-15",
"sysTime": "140910",
"responseCode": "0000",
"responseDescription": "Successful execution",
"additionalInformation": {
"requestId": "aff2728481a181dc36daedc14055b516"
}
}
Note, that the 1.39 Complete Authorize response includes the internal representation of the Account Number indicated by the parameter Account Number Type.
The response includes the Transaction Status under the return parameter "statusCode", which at this point should be set to "AUTHORIZED" and indicates that the payment was authorized.
Please note if "responseCode": "0035"
is returned this indicates the transaction is already "Authorized"
and it should be treated as a Successful Response. This can occur if 1.39 Complete Authorize is called twice. In such a case it is safe to continue with 1.29 Capture.
SEPA (Pay.ON)
Since the SDK sends the payment details directly to the creditor, where the payment is subsequently processed, you have no knowledge about the current status of the payment and if it got authorized. Therefore, call the API method 1.39 Complete Authorize from your server-side method behind the "callbackURL", which you specified in the SDK.
Complete Authorization Request
Path:
POST {baseURL}/payment/{uniqueReference}/completeAuthorize
POST {baseURL}/payment/BNkk4BRkQEufPSvgf9lDwA/completeAuthorize
Header:
Content-Type: application/json
Accept-Language: en-US
X-Auth-Token: eyJhbGciOiJSUzI1NiI{abbreviated}RW5kVG9rZW4=
{
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_JYFGRFTQXM",
"authorizationToken": "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01",
"localDate": "2018-10-15",
"localTime": "155550"
}
The transaction authorization is identified by the "uniqueReference" and "authorizationToken" returned initially by the API method 1.38 Init Authorize. Instead of saving these variables on your server-side, pass them via the query string parameters in the "callbackURL".
In some cases e.g., where the user's device loses internet connectivity, the redirect to the specified "callbackURL" does not take place. To prevent the transaction expiring despite it being successful, the API method 1.39 Complete Authorize should automatically be called from your backend 28 minutes after 1.38 Init Authorize has been called, and the payment process completed.
Complete Authorization Response
Status Code: 200 (OK)
Header: Content-Type: application/json Accept-Language: en-US
{
"initiatorAccno": "1679541175",
"accno": "1679797975",
"uniqueReference": "BNkk4BRkQEufPSvgf9lDwA",
"initiationCountryCode": "DE",
"initiationCountryCode3": "DEU",
"processedAmount": 3.99,
"processedCurrCode": "EUR",
"statusCode": "AUTHORIZED",
"statusReason": "Request successfully processed in 'Merchant in Integrator Test Mode'",
"paymentProviderResponse": {
"id": "8ac7a4a26668b22f0166780ef9b571d1",
"paymentType": "PA",
"paymentBrand": "DIRECTDEBIT_SEPA",
"amount": "3.99",
"currency": "EUR",
"descriptor": "FS2- 2931.2232.0945 -VW- Purchase:2xPremiumWidgets. Merchant:WidgetsGmbH.
CUSTREF:52650FD95."
"merchantTransactionId": "BNkk4BRkQEufPSvgf9lDwA",
"result": {
"code": "000.100.110",
"description": "Request successfully processed in 'Merchant in Integrator Test Mode'"
},
"resultDetails": {
"ExtendedDescription": "The request was successful.",
"AcquirerResponse": "SUCCESS"
},
"bankAccount": {
"holder": "Jacob Smith",
"number": "DE89370400440532013000",
"iban": "DE89370400440532013000",
"country": "DE"
},
"customer": {
"ip": "123.123.123.123"
},
"customParameters": {
"kcMandateSignedDate": "2018-10-22T16:57:51",
"kcMandateReference": "446ED8B3F6FD4CC195FB4D6E860E675A"
},
"risk": {
"score": "0"
},
"buildNumber": "5cfb0b509a516adbf6f324943ea4522a2cd4ae9f@2018-10-22 08:37:51 +0000",
"timestamp": "2018-10-22 15:05:58+0000",
"ndc": "82C7C9F6C203F779BDE0F3F975C5C7B6.uat01-vm-tx01"
},
"partnerReference": "DEV-SVR001-DE_CUSTID-KD97TH2FP6_CARTID-PYQRTGMCMQ_JYFGRFTQXM",
"localDate": "2018-10-15",
"localTime": "160910",
"sysDate": "2018-10-15",
"sysTime": "140910",
"responseCode": "0000",
"responseDescription": "Successful execution",
"additionalInformation": {
"requestId": "aff2728481a181dc36daedc14055b516"
}
}
Note, that the 1.39 Complete Authorize response includes the internal representation of the Account Number indicated by the parameter Account Number Type. Additionally, the response includes the transaction status under the status code parameter, which, at this stage, should be set to AUTHORIZED
, indicating that the payment has been successfully authorized.
Please also see transaction status handling for non-successful response codes.