Nav
bash php javascript java C#

General use

Twikey has put in place several services enabling software partners, companies with own ERP or CRM systems, banks and other 3rd parties to exchange information. This page describes the different calls that are available to you. The calls allow integration in a number of ways.

Since there are numerous ways a company can allow its customers to pay, we also provided a couple of high level use-cases to get you up and running in no time.

All exchanges require a valid AuthorizationToken passed on as a header named "Authorization". The AuthorizationToken can be retrieved via the login call and is valid for 24h. We suggest that the call to the login is done when the actual call you wish to make is returning a 401. This way you don't need to handle the lifecycle of your token yourself.

Exchanges can be in both JSON & XML responses. By default they will be in JSON, but by giving the "Accept" header a value of 'application/xml', you can get an xml payload.

Errors can be divided into 2 categories. The first category are errors based on user input for which we return a 400 error with the code of the error mentioned in the response header "ApiError'. The translated error can be found in the body of the required exchange. The language is provided by the "Accept-Language" header or defaults to English. The second category of errors is one that you normally shouldn't run into a lot. In this case we return a 500 error which means that something went wrong on our end. We'll probably already know about it when you see the error.

Sample use cases

The fitness scenario

Imagine you're going to the fitness where you exercise every once in a while. Since this doesn't come free you pay a monthly subscription fee. This subscription fee is a recurring payment (we'll come back to that later). But since all those exercises get you thirsty, you want to drink there too. But of course, there are hotter and colder days. So how much you drink can vary.

Regardless of what you consume, the fitness wants to get paid. But you'd like to avoid getting out your wallet when you're all sweaty. So your fitness made the great decision to use direct debits to allow you to pay. At the end of the month they add the recurring amount to the one-off's (the drinks). They send the payment request to the bank. Everyone's happy and relax.

What did the fitness do to achieve this relaxed way of working:

First of all, everything starts with a mandate. When a customer enrolls at the fitness he fills in the details for the internal bookkeeping of the fitness. The same information is sent to the prepare call. This returns a URL (representing an unsigned mandate) that opens up after entering all details in the enrollment screen. Since the fitness has an internal subscription number they want to use to track payments and have multiple subscriptions (eg. with and without personal trainer) they add both parameters in the prepare call. Making it visible in the mandate overview.

Once the customer filled in the account info and signed the mandate he's sent back to the fitness website with a "thank you" message. When a customer ask for a drink at the bar, the cash register calls the transaction endpoint with the details and amount. These are one-off transactions. Recurring transactions can either be handled the same way or if a subscription parameter was added in the prepare call, a recurring transaction is automatically added every month to get this subscription paid. At the end of each month, the file is created and sent to the bank manually via the collect call or automatically every night. Your bill is paid and the bank sends you the money. When the bank sends us back the account information, it is marked in your transaction overview that the transaction was paid. This information can be retrieved by the payment call. This call returns all new payment information since the last call. If a payment didn't succeed, you can configure what will happen next in the interface in the dunning section.

The parking app scenario

Because my customers don't like running in the rain looking for a parking meter while there's an app for that. How can I use Twikey to get my parking fees paid? First of all, you need a mandate . There are three possible options to have this mandate signed:

Use an in-app browser with the link retrieved via the prepare call Use the sign call to invite the user to sign via an sms confirmation Use the sign call adding the manual signature as a png-image in the payload Once the mandate is signed, in-app purchases can be sent from the backend of the app, collected the same way as mentioned in the fitness scenario.

The (off-line) webshop scenario

I have a shop where people come in physically but I also have a webshop. I want people who signed a mandate (either online via the above flow or physically) to be able to purchase something from the online shop without requiring them to use their credit card and if possible give them the sameconvenience in the physical shop. This way I can send them an invoice every month by only registering their purchases and collecting the payment via direct debit.

In the past, I had to send out all invoices and patiently waited for them to be paid. Since I'm not the most patient person on earth and even a bit chaotic at times, I'd rather collect the money directly from my customers. This way they can't forget to pay and I don't need to remind them to do so. How convenient this is for both my customers and I.

Authentication

Login

When using the API the login call will provide you with an AuthorizationToken, which is to be send upon every subsequent call (via the authorization header) in order to use the api. If the creditor opted for enhanced security, the private key allows the generation of a Time-based One-time password. See Appendix C of the Creditor API documentation for a more detailed explanation or sample code on how to calculate this OTP (samples in various languages are available).

Normally this call is made on request of another call that returned a 401 (UNAUTHORIZED) indicating that there was no session token or that it expired.

Requires an API Token which can be found in the Twikey Creditor Dashboard

curl -X POST https://api.twikey.com/creditor /
-d apiToken=**API Token**
$host = "https://api.twikey.com";
$apitoken = "**API_TOKEN**";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"apiToken=$apitoken");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
$authorization = $result->{'Authorization'} ;
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    apitoken = "**API_TOKEN**",
    authorization = null,
    options = {
        host: host,
        port: '443',
        path: '/creditor',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body:{
            'apiToken' : apitoken
        }
    };

var req = https.request(options, function (res) {
    authorization = res.headers.authorization;
    console.log("authorization : ",authorization);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        apiToken = "**API_TOKEN**";
    public void logIn(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
            .add("apiToken", apiToken)
            .build();

        Request request = new Request.Builder()
            .url(host + "/creditor")
            .post(body)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        apiToken ="**API_TOKEN**";

    public void logIn(){    
        RestClient client = new RestClient(host + "/creditor");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "apiToken=" + apiToken,
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

This AuthorizationToken acts as a session token and has a validity of 24h.

HTTP Request

POST https://api.twikey.com/creditor

Query Parameters

Name Description Required Type
apiToken API Token Yes string
otp Value calculated based on salt and private key (if enhanced security) No long

HTTP Response

Code Description
200 For security reasons, the http status is always 200, however for returning error codes specific to the call 2 additional response headers were added "ApiError" and "ApiErrorCode" which are added on every response that contains errors. Notible exceptions are authentication errors and authorisation errors that don't have these 2 headers.

Logout

Invalidates the AuthorizationToken by making a GET request to /creditor

curl https://api.twikey.com/creditor \
  -H 'authorization: authorization'
$host = "https://api.twikey.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setOpt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: $authorization"
);
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    options = {
            host: host,
            port: '443',
            path: '/creditor',
            method: 'GET',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Authorization': authorization
            }
        };

var req = https.request(options, function (res) {
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com";

    public void logOut(){
    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
      .url(host + "creditor")
      .get()
      .addHeader("cache-control", "no-cache")
      .addHeader("Authorization", authorization)
      .build();

    Response response = client.newCall(request).execute();
    };
}
public class TwikeyApi {
    private String host = "https://api.twikey.com";
    public void logOut(){
        RestClient client = new RestClient(host + "/creditor");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

GET https://api.twikey.com/creditor

HTTP Response

Code Description
204 Logged out succesfully

Mandate

Invite a customer

Necessary to start with an eMandate or to create a contract. The end-result is a signed or protected shortlink that will allow the end-customer to sign a mandate or contract. The (short)link can be embedded in your website or in an email or in a paper letter. We advise to use the shortlink as the data is not exposed in the URL's. The parameters are as described in detail on the page "Create contracts".

After signing the end-customer is either presented with a thank-you page or is redirected to an exit url defined on the template. This url can contain variables that are filled in depending on the outcome. See exit urls

Requires a ct_id which can be found in the Twikey Creditor Template overview

curl -X POST https://api.twikey.com/creditor/invite \
  -H 'authorization: **authorization**' \
  -d 'ct=**ct_id**' \
  -d 'l=nl' \
  -d 'email=support@twikey.com' \
  -d 'lastname=Support' \
  -d 'firstname=Twikey' \
  -d 'mobile=32479123123' \
  -d 'address=Derbystraat 43' \
  -d 'zip="9051"' \
  -d 'city=Sint Denijs Westrem' \
  -d 'country=BE'
$host = "https://api.twikey.com";
$ct = **ct_id**;
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/invite");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
    "ct=$ct"
    ."&l=nl"
    ."&email=support%40twikey.com"
    ."&lastname=Support"
    ."&firstname=Twikey"
    ."&address=Derbystraat%2043"
    ."&zip=9051"
    ."&city=Sint%20Denijs%20Westrem"
    ."&country=BE"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
$result = json_decode($server_output);
$url = $result->{'url'} ;
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    ct = "**ct_id**",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/invite',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        data: {
            "ct": ct,
            "l": "nl",
            "email": "support@twikey.com",
            "lastname": "Support",
            "firstname": "Twikey",
            "address": "Derbystraat 43",
            "zip": "9051",
            "city": "Sint Denijs Westrem",
            "country": "BE"
        }
    };

var req = https.request(options, function (res) {
    res.on('data', function (chunk) {
        console.log("Redirect to : " + chunk)
    });
});
public class TwikeyApi{
    private string host = "https://api.twikey.com";
    private String ct = "**ct_id**";
    private String authorisation = null; //collected through logIn

    public void invite(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
                .add("ct", ct)
                .add("l", "nl")
                .add("email", "support@twikey.com")
                .add("firstname", "Twikey")
                .add("lastname", "Support")
                .add("address", "Derbystraat 43")
                .add("zip", "9051")
                .add("city", "Sint-Denijs-Westrem")
                .add("country", "BE")
                .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/invite")
          .post(formBody)
          .addHeader("Content-Type", "application/x-www-form-urlencoded")
          .addHeader("Authorization", authorisation)
          .addHeader("Cache-Control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct ="**ct_id**",
        authorisation = null; // collected through logIn

    public void invite(){    
        RestClient client = new RestClient(host + "/creditor/invite");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "ct=" + ct +
            "&l=nl" + 
            "&email=support%40twikey.com" +
            "&lastname=Support" +
            "&firstname=Twikey" +
            "&address=Derbystraat%2043" +
            "&zip=9051" + 
            "&city=Sint%20Denijs%20Westrem" +
            "&country=BE"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
  "mndtId": "COREREC01",
  "url": "http://twikey.to/myComp/ToYG",
  "key": "ToYG"
}

HTTP Request

POST https://api.twikey.com/creditor/invite

Query Parameters

Name Description Required Type
ct Contract template to use Yes integer
l Language (en/fr/nl/de/pt/es/it) No string
iban No string
bic No string
mandateNumber Mandate Identification number (if not generated) No string
email No string
lastname No string
firstname No string
mobile mobile number required for sms (International format +32499123445) No string
address Address (street + number) No string
city City of debtor No string
zip Zipcode of debtor No string
country ISO format (2 letters) No string
companyName the company name (if debtor is company) No string
vatno the enterprise number (if debtor is company) No string
form the legal form of the company (if debtor is company) No string
contractNumber the contract number which can override the one defined in the template. No string
campaign Campaign to include this url in No string
prefix Optional prefix to use in the url (default companyname) No string
check If an existing collectable mandate exists, don't prepare a new (based on email + template(=ct)) No boolean
reminderDays Send a reminder if contract was not signed after number of days No number
sendInvite Send out invite email directly No boolean
document Add a contract in base64 format No string
                    }

HTTP Response

Code Description
200 If the check option is provided and an existing collectable mandate is available it will be returned. Otherwise an url and key will be returned.
400 User error if parameter is given but not valid or collectable (available in apierror header and response)

Error codes

Code Description
err_no_such_ct No template found (or not active)
err_invalid_domain Invalid domain
err_mandatenumber_required No mandatenumber was given, while setting does not allow generation
err_double_mandatenumber Signed mandate with the same mandatenumber already exists
err_missing_params Attributes are missing while configured as mandatory

Sign a mandate

Create a contract with an invitation/signature directly via API. Note that this call can require different parameters depending on the method of signature. All parameters are described in Create contracts When enabled for your contract it is possible to negiotiate mandates with their signature directly via API. Depending on the method the set of required parameters and/or handling may differ. Methods currently supported :

curl -X POST https://api.twikey.com/creditor/mandate/sign \
  -H 'authorization: **authorization**' 
  -d 'method=sms' \
  -d '&place=Gent' \
  -d '&ct=**ct_id**' \
  -d '&iban=BE68068897250734' \
  -d '&bic=GKCCBEBB' \
  -d '&email=sms%40twikey.com' \
  -d '&lastname=Twikey' \
  -d '&firstname=SMS' \
  -d '&mobile=%2B32479123123' \
  -d '&address=Derbystraat%2043' \
  -d '&city=Gent' \
  -d '&zip=9051' \
  -d '&country=BE'
$host = "https://api.twikey.com";
$ct = **ct_id**;
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/sign");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
    "method=sms"
    ."&place=Gent"
    ."&ct=1323"
    ."&iban=BE68068897250734"
    ."&bic=GKCCBEBB"
    ."&email=sms%40twikey.com"
    ."&lastname=Twikey"
    ."&firstname=SMS"
    ."&mobile=%2B32479123123"
    ."&address=Derbystraat%2043"
    ."&city=Gent"
    .'&zip=9051'
    ."&country=BE"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");

$server_output = curl_exec ($ch);
$result = json_decode($server_output);
$mandateId = $result->{'MndtId'} ;
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    ct = "**ct_id**",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/sign',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        data: {
            "method": "sms",
            "place": "Gent",
            "ct": ct,
            "l": "nl",
            "email": "support@twikey.com",
            "lastname": "Support",
            "firstname": "Twikey",
            "mobile": "+32479123123",
            "address": "Derbystraat 43",
            "zip": "9051",
            "city": "Sint Denijs Westrem",
            "country": "BE"
        }
    };

var req = https.request(options, function (res) {
    res.on('data', function (chunk) {
        console.log("manatenumber: " + chunk)
    });
});
public class TwikeyApi{
    private string host = "https://api.twikey.com";
    private String ct = "**ct_id**";
    private String authorisation = null; //collected through logIn

    public void inviteAndSign(){
        OkHttpClient client = new OkHttpClient();

        RequestBody body = new FormBody.Builder() 
            .add("ct",ct) 
            .add("method", "sms")
            .add("place"="Gent")
            .add("mobile","+32479123123")
            .add("l","nl")
            .add("email","support%40twikey.com")
            .add("lastname","Support")
            .add("firstname","Twikey")
            .add("address","Derbystraat%2043")
            .add("zip","9051")
            .add("city","Sint Denijs Westrem")
            .add("country","BE")
            .build();
        Request request = new Request.Builder()
          .url(host + "/creditor/sign")
          .post(body)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct ="**ct_id**",
        authorisation = null; // collected through logIn

    public void inviteAndSign(){    
        RestClient client = new RestClient(host + "/creditor/sign");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "method=sms" +
            "&place=Gent"
            "&ct="+ ct +
            "&iban=BE68068897250734" +
            "&bic=GKCCBEBB" +
            "&email=sms%40twikey.com" +
            "&lastname=Twikey" +
            "&firstname=SMS" +
            "&mobile=%2B32479123123" +
            "&address=Derbystraat%2043" +
            "&city=Gent" +
            "&zip=9051" +
            "&country=BE" +
            , ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);
    }
}
{
  "mndtId": "MyMandateId",
  "Msg": "OK"
}

HTTP Request

POST https://api.twikey.com/creditor/mandate/sign

Query Parameters

Name Description Required Type
ct Contract template to use Yes number
l Language (en/fr/nl/de/pt/es/it) No string
method Method to sign (sms/digisign/...) Yes string
mandateNumber Mandate Identification number (if not generated) No string
iban Yes string
bic Yes string
email No string
lastname No string
firstname No string
mobile mobile number required for sms (International format +32499123445) No string
address Address (street + number) No string
city No string
zip No string
country ISO format (2 letters) No string
companyName the company name (if debtor is company) No string
vatno the enterprise number (if debtor is company) No string
form the legal form of the company (if debtor is company) No string
contractNumber the contract number which can override the one defined in the template. No string
signDate Date of signature (xsd:dateTime), sms uses date of reply No string
place Place of signature No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error code

Code Description
err_no_such_ct No template found (or not active)
err_invalid_domain Invalid domain
err_mandatenumber_required No mandatenumber was given, while setting does not allow generation
err_double_mandatenumber Signed mandate with the same mandatenumber already exists
err_missing_params Attributes are missing while configured as mandatory
err_invalid_signature No valid method was provided

Update Feed

Returns a List of all updated mandates (new, changed or cancelled) since the last call. From the moment there are changes (eg. a new contract/mandate or an update of an existing contract) this call provides all related information to the creditor. The service is initiated by the creditor and provides all MRI information (and extra metadata) to the creditor. This call can either be triggered by a callback once a change was made or periodically when no callback can be made. This information can serve multiple purposes:

If your system is out of sync or the full mandate database needs to be refreshed an optional "X-RESET" header can be passed. The format can be a timestamp like "2015-08-20T13:02:03Z". After that you will receive (all) mandate updates since that time again.

In order too avoid polling, a #19-callbacks can be setup to notify the client when new information is available. This hook can be configured in the Settings > API.

There are 3 possible updates.

curl https://api.twikey.com/creditor/mandate \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$ct = **ct_id**;$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");

$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/mandate',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void updateFeed(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .url(host + "/creditor/mandate")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("x-reset", "2017-08-29T00:00:00.000Z")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void updateFeed(){    
        RestClient client = new RestClient(host + "/creditor/mandate");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("x-reset", "2017-08-29T00:00:00.000Z");
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
    }
}
{
    "GrpHdr": {
        "CreDtTm": "2015-08-20T13:02:03Z"
    },
    "Messages": [
        {
            "EvtTime": "2015-06-23T11:31:51Z",
            "Mndt": {
                "Cdtr": {
                    "CtctDtls": {
                        "EmailAdr": "info@creditor.com"
                    },
                    "CtryOfRes": "BE",
                    "Id": "BE0533800797",
                    "Nm": "Twikey N.V.",
                    "PstlAdr": {
                        "AdrLine": "Veldstraat 11",
                        "Ctry": "BE",
                        "PstCd": "9000",
                        "TwnNm": "Gent"
                    }
                },
                "CdtrSchmeId": "BE54ZZZ0533800797",
                "Dbtr": {
                    "CtctDtls": {
                        "EmailAdr": "admin@debtorcpy.be"
                    },
                    "CtryOfRes": "BE",
                    "Id": "BE123456789",
                    "Nm": "debtorCompany Inc.",
                    "PstlAdr": {
                        "AdrLine": "Street 52",
                        "Ctry": "BE",
                        "PstCd": "1000",
                        "TwnNm": "Brussels"
                    }
                },
                "DbtrAcct": "BE493104522",
                "DbtrAgt": {
                    "FinInstnId": {
                        "BICFI": "BBRUBEBB",
                        "Nm": "ING BELGIUM NV/SA"
                    }
                },
                "LclInstrm": "CORE",
                "MaxAmt": "0",
                "MndtId": "1600650622",
                "Ocrncs": {
                    "Drtn": {
                        "FrDt": "2015-06-13"
                    },
                    "Frqcy": "ADHO",
                    "SeqTp": "RCUR"
                },
                "RfrdDoc": "1000",
                "SplmtryData": [
                    {
                        "Key": "SignerPlace#0",
                        "Value": "Brussels"
                    },
                    {
                        "Key": "SignerDate#0",
                        "Value": "2015-06-22T21:00:00Z"
                    }
                ]
            }
        },
        {
              "CxlRsn": {
                "Orgtr": {
                  "Nm": "Test Naam",
                  "PstlAdr": {
                    "AdrLine": "Derbystraat 43",
                    "PstCd": "9051",
                    "TwnNm": "Sint Denijs Westrem",
                    "Ctry": "BE"
                  },
                  "CtryOfRes": "BE",
                  "CtctDtls": {
                    "EmailAdr": "test@twikey.com",
                    "MobNb": "+32123456789"
                  }
                },
                "Rsn": "testing"
              },
              "OrgnlMndtId": "1700650622",
              "CdtrSchmeId": "BE54ZZZ0533800797",
              "EvtTime": "2017-10-31T14:14:51Z"
            },
            {
                "AmdmntRsn": {
                "Orgtr": {
                  "Nm": "Test Naam",
                  "PstlAdr": {
                    "AdrLine": "Andere straat 34",
                    "PstCd": "9000",
                    "TwnNm": "Gent",
                    "Ctry": "Gent"
                  },
                  "CtryOfRes": "NL",
                  "CtctDtls": {
                    "EmailAdr": "jonathan@twikey.nl",
                    "MobNb": "+32474519130"
                  }
                },
                "Rsn": "_T51"
              },
              "Mndt": {
                "MndtId": "1500650622",
                "LclInstrm": "CORE",
                "Ocrncs": {
                  "SeqTp": "RCUR",
                  "Frqcy": "ADHO",
                  "Drtn": {
                    "FrDt": "2017-10-31"
                  }
                },
                "CdtrSchmeId": "BE54ZZZ0533800797",
                "Cdtr": {
                  "Nm": "test Creditor",
                  "PstlAdr": {
                    "AdrLine": "test",
                    "PstCd": "test",
                    "TwnNm": "test",
                    "Ctry": "BE"
                  },
                  "Id": "BE0369258147",
                  "CtryOfRes": "BE",
                  "CtctDtls": {
                    "EmailAdr": "info@debtor.com"
                  }
                },
                "Dbtr": {
                  "Nm": "Test Test",
                  "PstlAdr": {
                    "AdrLine": "Derbystraat 43",
                    "PstCd": "9000",
                    "TwnNm": "Gent",
                    "Ctry": "BE"
                  },
                  "CtryOfRes": "NL",
                  "CtctDtls": {
                    "EmailAdr": "inf@debtor.com",
                    "MobNb": "+32474519130"
                  }
                },
                "DbtrAcct": "BE000000000000000",
                "DbtrAgt": {
                  "FinInstnId": {
                    "BICFI": "BICCODE1",
                    "Nm": "Testbank"
                  }
                },
                "RfrdDoc": "General terms and conditions"
              },
              "OrgnlMndtId": "1500650622",
              "CdtrSchmeId": "BE54ZZZ0533800797",
              "EvtTime": "2017-10-31T14:19:09Z"
            }
    ]
}

HTTP Request

GET https://api.twikey.com/creditor/mandate

Query Parameters

Name Description Required Type
chunkSize Amount of mandates to return per call (max 100) No long

Response

Code Description
200 The request has succeeded

Import mandates

Import existing mandates (or updates)

curl -X POST https://api.twikey.com/creditor/mandate \
  -H 'authorization: **authorization**' \
  -d @import.json
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$post = array(
    "file_box"=>"@/path/to/import.json",
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate");
curl_setOpt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: $authorization",
    "Content-Type: application/json',
    "Content-Length: ' . strlen($post))
);
curl_setOpt($ch, CURLOPT_POST, true);
curl_setOpt($ch, CURLOPT_POSTFIELDS, $post);

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null; //collected through login

var requestUrl = 'path/to/import.json';
var request = new XMLHttpRequest();
request.open('GET', requestUrl);
request.responseType = 'json';

request.send();
request.onload = function (){
    var options = {
        host: host,
        port: '443',
        path: '/creditor/mandate',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        data: request.response
    };
    var req = https.request(options, function (res) {
        console.log(res);
    });
};


var req = https.request(options, function (res) {
    console.log(res);
});
import java.io.FileReader;
import java.io.BufferedReader;
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn


    public void importMandates(){
        String json;
         try{
            FileReader fr = new FileReader("/path/to/import.json"); 
            BufferedReader br = new BufferedReader(fr); 
            String s; 
            while((s = br.readLine()) != null) { 
                json+=s;
            } 
            fr.close(); 

            OkHttpClient client = new OkHttpClient();
            RequestBody body = RequestBody.create(mediaType, "import.json");
            Request request = new Request.Builder()
              .url(host + "/creditor/mandate")
              .post(json)
              .addHeader("content-type", "application/x-www-form-urlencoded")
              .addHeader("authorization", authorisation)
              .build();

            Response response = client.newCall(request).execute();
        }catch(FileNotFoundException e){
            System.out.printLn(e);             
        }
    }
}
using System.IO;
public class TwikeyAPI {

    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    String json = file.ReadAllText("\path\to\import.json");

    public void importMandates(){    
        RestClient client = new RestClient(host + "/creditor/mandate);
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
        request.AddParameter("application/x-www-form-urlencoded",
            json,
            ParameterType.RequestBody
        );
    }
}

HTTP Request

POST https://api.twikey.com/creditor/mandate

Query Parameters

Name Description Required Type
Mandates All mandate updates like in fetch (json) Yes

HTTP Response

Code Description
204 Batch import of mandates was fully done or not at all

Cancel a mandate

A contract can be cancelled by either debtor or creditor, this can be done via the website or the api. However, there may be circumstances in which the creditor receives the cancel not through Twikey. In order to avoid extra costs & stale information, Twikey requires the update of its systems. The creditor, the creditor bank or the debtor bank, can initiate this request. Afterwards the update is distributed to all parties.

curl -X DELETE https://api.twikey.com/creditor/mandate?mndtId123&rsn=test \
  -H 'authorization: **authorization**' 
$host = "https://api.twikey.com";
$ct = **ct_id**;$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate".
    "?mndtId=mndtId123&rsn=some%20reason"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/mandate?mndtId=**mdntId**&rsn=some%20reason',
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void cancelMandate(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .url(host + "/creditor/mandate?mndtId=**mndtId&rsn=some%20reason")
          .delete(null)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void cancelMandate(){    
        RestClient client = new RestClient(host + "/creditor/mandate" +
            "?mndtId=mndtId123" +"
            &rsn=some%20reason"
        );
        RestRequest request = new RestRequest(Method.DELETE);
        request.AddHeader("x-reset", "2017-08-29T00:00:00.000Z");
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

DELETE https://api.twikey.com/creditor/mandate

Query Parameters

Name Description Required Type
mndtId Mandate Reference Yes string
rsn Reason of cancellation (Can be R-Message) Yes string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract No contract was selected or invalid mndtId supplied
err_mandate_invalid_state Contract had wrong status (eg. already cancelled) or not authorised
err_no_contract No mandate was found
err_provide_reason Please provide reason

Fetch mandate details

Retrieve details of a specific mandate. Since the structure of the mandate is the same as in the update feed but doesn't include details about state, 2 extra headers are added.

Header name Description
X-STATE State of the mandate (PREPARED, SIGNED, CANCELLED, ...)
X-COLLECTABLE Whether this mandate can be used for collections (true/false)
curl https://api.twikey.com/creditor/mandate/detail?mndtId=mndtId123 \
  -H 'authorization: **authorization**' 
$host = "https://api.twikey.com";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate/detail" + "
    ?mndtId=mndtId123"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/mandate/detail?mndtId=mndtId123',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void getMandateDetail(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .get()
          .url(host +
            "/creditor/mandate/detail" +
            "?mndtId=mndtId123"
          )
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void getMandateDetail(){    
        RestClient client = new RestClient(host +
            "/creditor/mandate/detail" +
            "?mndtId=mndtId123"
        );
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

GET https://api.twikey.com/creditor/mandate/detail

Query Parameters

Name Description Required Type
mndtId Mandate Reference Yes string
force Also include non-signed states No boolean

Response

Code Description
200 Details of the mandate (see /creditor/mandate)
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract No contract was selected or invalid mndtId supplied
err_no_contract No contract was found
err_mandate_invalid_state Contract was not signed (ignored when force=true)

Customer access

You may want to give your customer access to the mandate details without actually requiring him to get a Twikey account. You can do this by using this call. This call returns a url that you can redirect the user to for a particular mandate.

curl -X POST https://api.twikey.com/creditor/customeraccess \
  -H 'authorization: **authorization**' \
  -d 'mndtId=mndtId123' 
$host = "https://api.twikey.com";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/customeraccess");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setOpt($ch, CURLOPT_POSTFIELDS, array(
    "mndtId" =>  "mdntId123"
);
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
?>
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/customeraccess',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body:{
            'mndtId': 'mndtId123'
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void updateMandate(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                        .add("mndtId", "mndtId123")
                        .build();
        Request request = new Request.Builder()
          .post(body)
          .url(host + "/creditor/customeraccess")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void updateMandate(){    
        RestClient client = new RestClient(host + "/creditor/customeraccess);
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("authorization", authorisation);
        request.AddParameter("application/x-www-form-urlencoded", 
            "mndtId=mndtId123" , 
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
    "token": "A4DE98FD091....",
    "url": "https://merchant.twikey.com/p/customeraccess?token=A4DE98FD0915F"
}

HTTP Request

POST https://api.twikey.com/creditor/customeraccess

Query Parameters

Name Description Required Type
mndtId Mandate Reference Yes string

Update planned transactions

Sometimes a plan on an existing mandate needs to be updated. This endpoint allows to update a plan, just by passing the new plan data.

curl -X POST https://api.twikey.com/creditor/mandate/plan \
  -H 'authorization: **authorization**' \
  -d 'mndtId=mdntId123'\
  -d 'plan=planName'\
  -d '_pls=2017-11-09'\
  -d '_pli=1m'\
  -d '_plo=15'\
  -d '_plt=5'\
  -d '_pla=50.00'\
  -d '_pld=description for the plan'
$host = "https://api.twikey.com";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate/plan");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setOpt($ch, CURLOPT_POSTFIELDS, array(
    "mndtId" => "mdntId123",
    "plan" => "planName",
    "_pls" => "2017-11-09",
    "_pli" => "1m",
    "_plo" => "15",
    "_plt" => "5",
    "_pla" => "50.00",
    "_pld" => "description for the plan")
);
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
?>
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/mandate/plan',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body:{
            'mndtId': 'mndtId123',
            'plan': 'planName',
            '_pls': '2017-11-09',
            '_pli': '1m',
            '_plo': '15',
            '_plt': '5',
            '_pla': '50.00',
            '_pld': 'description for the plan'
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void updateMandate(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                        .add("mndtId", "mndtId123")
                        .add("plan", "planName")
                        .add("_pls", "2017-11-09")
                        .add("_pli", "1m")
                        .add("_plo", "15")
                        .add("_plt", "5")
                        .add("_pla", "50.00")
                        .add("_pld", "description for the plan")
                        .build();
        Request request = new Request.Builder()
          .post(body)
          .url(host + "/creditor/mandate/plan")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void updateMandate(){    
        RestClient client = new RestClient(host + "/creditor/mandate/update);
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("authorization", authorisation);
        request.AddParameter("application/x-www-form-urlencoded", 
            "mndtId=mndtId123" +
            "&plan=planName" +
            "&_pls=2017-11-09" +
            "&_pli=1m" + 
            "&_plo=15" +
            "&_plt=5" +
            "&_pla=50.00" +
            "&_pld=description for the plan", 
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

POST https://api.twikey.com/creditor/mandate/plan

Query Parameters

Name Description Required Type
mndtId Mandate Reference Yes string
plan Name of the plan (can be empty in order to remove the plan) Yes string
_pls Startdate for the plan No string
_pli Periodicity of the plan, possible values are 1w, 2w, 1m, 2m, 3m, 4m, 6m, 12m No string
_plo The day of the periodicity on wich the plan needs to be executed No string
_plt Number of times the plan should be executed No string
-pla Amount associated with the plan No string
_pld Message you want to send to the debtor when a plan is executed No string

HTTP Response

Code Description
204 The server has fulfilled the request but does not need to return an entity-body, and might want to return updated meta-information
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_plan_name The plan parameter was not provided or an invalid planparameter supplied
err_mandate_invalid_state Mandates are editable only when in Prepared/Print state or CORE or not authorised
err_no_contract No contract was found

Retrieve pdf

Retrieve pdf of a mandate

curl https://api.twikey.com/creditor/mandate/pdf?mndtId123 \
  -H 'authorization: **authorization**' 

# Example for downloading the content straight to a file  
curl -v -X GET https://api.twikey.com/creditor/mandate/pdf?mndtId=mndtId123 -H 'authorization: **authorization**' --output test.pdf
$host = "https://api.twikey.com";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate/pdf?mndtId=mndtId123");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/mandate/pdf?mndtId=mdntId123',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void retrievePdf(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .get()
          .url(host + "/creditor/mandate/pdf?mndtId=mndtId123")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void retrievePdf(){    
        RestClient client = new RestClient(
            host +
            "/creditor/mandate/pdf" +
            "?mndtId=mndtId123"
        );
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        request.AddParameter("application/x-www-form-urlencoded", 
            "mandate.pdf", 
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

GET https://api.twikey.com/creditor/mandate/pdf

Query Parameters

Name Description Required Type
mndtId Mandate Reference Yes string

HTTP Response

Code Description
200 PDF is available in the body of the response
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract No contract was found

Upload pdf

Import existing mandate pdf (eg. scan of a printed document)

curl -X POST https://api.twikey.com/creditor/mandate/pdf \
  -H 'authorization: **authorization**' \
  -d 'mndtId=mndtId123' \
  -d @mndtId123.pdf
$host = "https://api.twikey.com";

$post = array(
    "file_box"=>"@/path/to/mndtId123.pdf",
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/mandate/pdf?mndtId=mndtId123");
curl_setOpt($ch, CURLOPT_HTTPHEADER, array(
    "authorization: $authorization",
    "Content-Type: application/pdf',
    "Content-Length: ' . strlen($post))
);
curl_setOpt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setOpt($ch, CURLOPT_POSTFIELDS, $post);
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null; //collected through login

var requestUrl = 'path/to/import.json';
var request = new XMLHttpRequest();
request.open('GET', requestUrl);
request.responseType = 'json';

request.send();
request.onload = function (){
    var options = {
        host: host,
        port: '443',
        path: '/creditor/mandate/pdf?mndtId=mndtId123',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        data: request.response
    };
    var req = https.request(options, function (res) {
        console.log(res);
    });
};
import java.io.FileReader;
import java.io.BufferedReader;
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void uploadPdf(){
        String pdf;
        try{
           FileReader fr = new FileReader("/path/to/mndtId123.pdf"); 
           BufferedReader br = new BufferedReader(fr); 
           String s; 
           while((s = br.readLine()) != null) { 
               pdf+=s;
           } 
           fr.close();
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .post(pdf)
          .url(host + "/creditor/mandate/pdf?mndtId=mndtId123")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
        } catch (FileNotFoundException e){
            System.out.printLn(e);
        }
    }
}
using System.IO;
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    String pdf = file.ReadAllText("\path\to\mndtid123.pdf");

    public void uploadPdf(){    
        RestClient client = new RestClient(
            host +
            "/creditor/mandate/pdf" +
            "?mndtId=mndtId123"
        );
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("authorization", authorisation);
        request.AddParameter("application/x-www-form-urlencoded", 
            pdf, 
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Parameters

Name Description Required Type
mndtId Mandate Reference Yes string

Responses

Code Description
200 Import of the pdf was done
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract Contract not found

Retrieve legal terms

curl https://api.twikey.com/creditor/legal?locale=nl_BE \
  -H 'authorization: authorization'
$host = "https://api.twikey.com";
$authorisation = null; // collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/legal?locale=nl_BE");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    host = "api.twikey.com",
    authorization = null, // collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/legal?locale=nl_BE',
        headers: {
            'Content-Type': 'application/json'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; // collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/json");

        Request request = new Request.Builder()
          .url(host + "/creditor/legal?locale=nl_BE")
          .addHeader("content-type", "application/json")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/legal?locale=nl_BE");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/json");
        IRestResponse response = client.Execute(request);
    }
}
{
    "tcUrl": "https://www.beta.twikey.com/nl/tc.html",
    "bySigning": "Door ondertekening van dit mandaatformulier ...",
    "rightsCore": "U kunt een Europese domiciliƫring laten terugbetalen. Vraag ...",
    "rightsB2b": "Dit mandaat is uitsluitend bedoeld voor betalingen tussen bedrijven. U hebt ...",
    "infoCorrect": ""
}

Parameters

Name Description Required Type
locale the locale (fr, fr_FR, fr_BE, de, nl, nl_BE, nl_NL, es, pt, it) no (defaults to en) string

Responses

Code Description
200 The request has succeeded

Transactions

New transaction

Add transaction to an existing mandate. This transaction will be sent to the bank when the collection is sent to the bank either automatically or manually.

HTTP Request

POST /creditor/transaction

curl -X POST https://api.twikey.com/creditor/transaction \
  -H 'authorization: **authorization**'\
  -d 'mndtId=mndtId123' \
  -d 'message=Monthly payment' \
  -d 'amount=10'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"mndtId=mndtId123"
    ."&message=Monthly payment"
    ."&amount=10");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body :{
            'mndtId' : 'mndtId123',
            'message': 'Monthly payment',
            'amount': '10'
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void addTransaction(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
            .add("mndtId", "mndtId123")
            .add("message", "Monthly payment")
            .add("amount", "10")
            .build();

        Request request = new Request.Builder()
            .url(host + "/creditor/transaction")
            .post(body)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; //collected through logIn

    public void addTransaction(){    
        RestClient client = new RestClient(host + "/creditor/transaction");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);
        request.AddParameter("application/x-www-form-urlencoded",
            "mndtId=mndtId123" +
            "message=Monthly payment" +
            'amount=10"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
  "Entries": [
    {
      "id": 381563,
      "contractId": 325638,
      "mndtId": "MNDT123",
      "contract": "Algemene voorwaarden",
      "amount": 10.0,
      "msg": "Monthly payment",
      "place": null,
      "ref": null,
      "date": "2017-09-16T14:32:05Z"
    }
  ]
} 

Request Parameters

Name Description Required Type
mndtId Mandate Reference Yes string
date Date of the billable event or now when empty No string
reqcolldt Requested date of the billable event No string
message Message to the customer (if only 1 entry) Yes string
ref Your reference No string
amount Amount to be billed Yes string
place Optional place No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract No mandate found
err_mandate_invalid_state The mandate is not active
err_invalid_date Invalid Date
err_invalid_sepachars Invalid characters in message to debtor
err_invalid_amount Invalid Amount given
err_billing_overdrawn Maximum amount reached according to risk rules

Transaction feed

Retrieve list of transactions that had changes since the last call.

curl https://api.twikey.com/creditor/transaction \
  -H 'authorization: **authorization**' \
  -H 'x-reset: 2017-08-29T00:00:00.000Z'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction");
curl_setopt($ch, CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void getTransactions(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transaction")
            .get()
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // gathered through logIn

    public void getTransactions(){    
        RestClient client = new RestClient(host + "/creditor/transaction");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

GET /creditor/transaction

{
    "Entries": [
        {
            "amount": 99.99,
            "bkdate": "2017-03-21T08:13:21Z",
            "contract": "contractNumber",
            "contractId": 10001,
            "final": true,
            "id": 123456789,
            "mndtId": "mandateReference",
            "msg": "transaction message",
            "place": "web",
            "ref": null,
            "reqcolldt": "2017-03-23T08:13:21Z",
            "state": "PAID"
        },
        {
            "amount": 100,
            "bkdate": "2016-09-21T08:13:21Z",
            "bkerror": "MS03",
            "bkmsg": "No reason specified",
            "contract": "contractNumber",
            "contractId": 2002,
            "final": false,
            "id": 987654321,
            "mndtId": "mandateReference",
            "msg": "transaction message",
            "place": "web",
            "ref": "INVOICE001",
            "reqcolldt": null,
            "state": "ERROR"
        },
        {
            "amount": 49.99,
            "bkdate": "2016-08-29T13:14:40Z",
            "bkerror": "AC04",
            "bkmsg": "Account closed",
            "contract": "contractNumber",
            "contractId": 3003,
            "final": true,
            "id": 56789123,
            "mndtId": "mandateReference",
            "msg": "buy item X",
            "place": "web",
            "ref": null,
            "reqcolldt": null,
            "state": "ERROR"
        },
        "..."
    ]
}

HTTP Response

Code Description
200 The request has succeeded

Transaction status

Retrieve the status of transactions

Note that the status of a transaction is a snapshot in time and may change

curl https://api.twikey.com/creditor/transaction/detail?id=1234 \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction/detail?id=1234");
curl_setopt($ch, CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction/detail?id=1234',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void getTransactionDetail(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transaction/detail?id=1234")
            .get()
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // gathered through logIn

    public void getTransactionDetail(){    
        RestClient client = new RestClient(host + "/creditor/transaction/detail?id=1234");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}
{
    "Entries": [
        {
            "amount": 10.0,
            "contract": "Algemene voorwaarden",
            "contractId": 325638,
            "date": "2017-09-16T14:32:05Z",
            "id": 381563,
            "mndtId": "MNDT123",
            "msg": "Monthly payment",
            "place": null,
            "ref": null,
            "state": "OPEN"
        }
    ]
}

HTTP Request

GET /creditor/transaction/detail

Request Parameters

Name Description Required Type
id 1 or more ids of a transaction No string
ref 1 or more refs of a transaction No string
mndtId 1 or more mandate references No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_invalid_params Either id or ref or mndtId is invalid or is empty

Action a transaction

Execute an action on a transaction, this will allow you to change the status or start a specific flow for the given transaction.

HTTP Request

POST /creditor/transaction/action

curl -iX POST https://api.twikey.com/creditor/transaction/action \
  -H 'authorization: **authorization**'\
  -d 'id=345' \
  -d 'action=REOFFER'
$host = "https://api.twikey.com";
$authorization = null; // collected through login

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction/action");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"id=345"
    ."&action=REOFFER");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction/action',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body :{
            'id' : '345',
            'action': 'REOFFER'
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; // collected through login
    public void addTransaction() {
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
            .add("id", "345")
            .add("action", "REOFFER")
            .build();

        Request request = new Request.Builder()
            .url(host + "/creditor/transaction/action")
            .post(body)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host = "https://api.twikey.com",
        authorization = null; // collected through login

    public void addTransaction() {    
        RestClient client = new RestClient(host + "/creditor/transaction/action");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);
        request.AddParameter("application/x-www-form-urlencoded",
            "id=345" +
            'action=REOFFER"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Request Parameters

Name Description Required Type Options
id Transaction id Yes string
action Action to execute for the given transaction Yes string PAID, REOFFER, TRANSFER

HTTP Response

Code Description
200 The request has succeeded
201 Deletion of the transaction has succeeded
400 User error if parameter is given but not valid (available in api error header and response)

Error codes

Code Description
err_no_transaction No transaction found
err_no_contract No mandate found (or not active)
err_invalid_params one of the parameters provided contains invalid data

Update a transaction

Update parameters for an existing transaction.

HTTP Request

PUT /creditor/transaction

curl -iX PUT https://api.twikey.com/creditor/transaction \
  -H 'authorization: **authorization**'\
  -d 'id=345' \
  -d 'message=Monthly payment' \
  -d 'amount=10'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS,"id=345"
    ."&message=Monthly payment"
    ."&amount=10");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction',
        method: 'PUT',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body :{
            'id' : '345',
            'message': 'Monthly payment',
            'amount': '10'
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void updateTransaction(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
            .add("id", "345")
            .add("message", "Monthly payment")
            .add("amount", "10")
            .build();

        Request request = new Request.Builder()
            .url(host + "/creditor/transaction")
            .put(body)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host = "https://api.twikey.com",
        authorization = null; // collected through login

    public void updateTransaction(){    
        RestClient client = new RestClient(host + "/creditor/transaction");
        RestRequest request = new RestRequest(Method.PUT);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);
        request.AddParameter("application/x-www-form-urlencoded",
            "id=345" +
            "message=Monthly payment" +
            'amount=10"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Request Parameters

Name Description Required Type
id Transaction id Yes string
reqcolldt Requested date of the billable event No string
message Message to the customer No string
ref Your reference No string
amount Amount to be billed No string
place Optional place No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in api error header and response)

Error codes

Code Description
err_no_transaction No transaction found
err_no_contract No mandate found (or not active)
err_invalid_params one of the parameters provided contains invalid data
err_invalid_date Invalid Date
err_invalid_amount Invalid Amount given

Remove a transaction

Remove a transaction that wasn't collected yet

curl -X DELETE https://api.twikey.com/creditor/transaction \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transaction");
curl_setopt($ch, CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transaction',
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void removeTransaction(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transaction")
            .delete(null)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // gathered through logIn

    public void removeTransaction(){    
        RestClient client = new RestClient(host + "/creditor/transaction");
        RestRequest request = new RestRequest(Method.DELETE);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

DELETE /creditor/transaction

Request Parameters

Name Description Required Type
id a transactionId as returned in the post No string
mndtId all open transactions linked to the mandateReference No string
ref transactionReference as provided in the post to be removed No string

HTTP Response

Code Description
204 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract Contract not found

Transaction reporting

Get transaction reporting, this API call will be activated on request.

Returns all reporting *since the last call. *

When you want to go back in history and retrieve past records you can pass an optional "X-RESET" header. The format can be a timestamp like "2018-10-16T13:02:03Z".

HTTP Request

GET /creditor/reporting

curl -iX GET https://api.twikey.com/creditor/reporting \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorization = null; // collected through login

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/reporting");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, // collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/reporting',
        method: 'GET',
        headers: {
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; // collected through login
    public void updateTransaction(){
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
            .url(host + "/creditor/transaction")
            .get()
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host = "https://api.twikey.com",
        authorization = null; // collected through login

    public void updateTransaction(){    
        RestClient client = new RestClient(host + "/creditor/reporting");
        RestRequest request = new RestRequest(Method.PUT);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("Authorization", authorization);
        IRestResponse response = client.Execute(request);
    }
}

HTTP Response

Code Description
200 The request has succeeded

Error codes

Code Description

Collections

Prenotify a customer

Send a prenotification notice to the customer

HTTP Request

POST /creditor/prenotification

curl -X POST https://api.twikey.com/creditor/prenotification \
  -d mndtId=MNDT123 \
  -d message="Monthly payment" \
  -d collectionDate=2017-09-15 \
  -d amount="10" \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/prenotification");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "mndtId=MNDT123" 
    ."message=Monthly payment"
    ."collectionDate="2017-09-15"
    ."amount=10"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    ct = "**ct_id**",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/prenotification',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "message":"Monthly payment",
            "collectionDate":"2017-09-15",
            'amount': 10
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void prenotify(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
                .add("message","Monthly payment")
                .add("collectionDate","2017-09-15")
                .add("amount","10")
                .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/prenotify")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void prenotify(){    
        RestClient client = new RestClient(host + "/creditor/prenotify");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "message=Monthly payment" +
            "collectionDate="2017-09-15" +
            "amount=10"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
mndtId Mandate Reference Yes string
message Message to debtor Yes string
collectionDate Date of collection Yes string
amount Amount (Format 12.33) Yes double
invoiceUrl Url to the actual invoice No string

HTTP Response

Code Description
200 success
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_contract Contract not found
err_invalid_amount Invalid amount was given
err_invalid_date Invalid date was given

Execute Collection

Prepare a collection file and sent to collecting agent if available with the account data specified in the contract template.

HTTP Request

POST /creditor/collect

curl -X POST https://api.twikey.com/creditor/collect \
  -d ct=123 \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$ct = "**ct_id**";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/collect");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 
    "ct=$ct"
    ."clltndt=2017-09-15"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    ct = "**ct_id**",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/collect',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "ct":"$ct",
            "clltndt":"2017-09-15"
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn
    private String ct = "**ct_id**";

    public void executeCollect(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
            .add("ct", ct)
            .add("clltndt","2017-09-15")
            .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/collect")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void executeCollect(){    
        RestClient client = new RestClient(host + "/creditor/collect");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "ct=" + ct +
            "clltndt="2017-09-15"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
ct Contract template for which to do the collection Yes number
colltndt Collection date (default=earliest possible) No string
mndtId Optional array of mandateId's (default = all with billable entries) No array
prenotify Optional parameter, it's existence will trigger the prenotification towards the debtor (true/false) No boolean

HTTP Response

Code Description
200 Returns the id referencing both first and recurring sdd send to bank
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_such_ct No template specified
err_invalid_ct Invalid template specified
err_provide_account No account specified in template
err_no_access_subscription No connection to the bank in your subscription
err_invalid_date Invalid date

Download collection file(s)

Prepare the collection file(s) and download the zipped sdd file(s)

HTTP Request

POST /creditor/collect/sdd

curl -X POST https://api.twikey.com/creditor/collect/sdd \
  -d 'ct=**ct_id**' \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$ct = **ct_id**;
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/collect/sdd");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CURLOPT_POST, true);
curl_setOpt($ch, CURLOPT_POSTFIELDS, "ct=**ct_id**");
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    ct = "**ct_id**",
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/collect/sdd',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body :{
            'ct': ct
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String ct = "**ct_id**";
    private String authorisation = null; //collected through logIn

    public void downloadCollection(){
        OkHttpClient client = new OkHttpClient();
        Requestbody body = Formbody.Builder()
            .add("ct", ct)
            .build();
        Request request = new Request.Builder()
          .url(host + "/creditor/collect/sdd")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .post(body)
          .addHeader("x-reset", "2017-08-29T00:00:00.000Z")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct="**ct_id",
        authorisation = null; // collected through logIn

    public void downloadCollection(){    
        RestClient client = new RestClient(host + "/creditor/collect/sdd");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("x-reset", "2017-08-29T00:00:00.000Z");
        request.AddHeader("authorization", authorisation);
         request.AddParameter("application/x-www-form-urlencoded", 
            "ct=" + ct 
            , ParameterType.RequestBody
         );
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
ct Contract template for which to do the collection Yes number
colltndt Collection date No string
mndtId Optional array of mandateId's (default = all with billable entries) No array
prenotify Optional parameter, it's existence will trigger the prenotification towards the debtor (true/false) No boolean

HTTP Response

Code Description
200 Returns the zip containing all files to be uploaded to the bank
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_such_ct No template specified
err_invalid_ct Invalid template specified
err_provide_account No account specified in template
err_invalid_date Invalid date

Status collection

Retrieve all payments obtained so far from collecting agent per collection batch

HTTP Request

GET /creditor/payment

curl https://api.twikey.com/creditor/payment \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/payment");
curl_setOpt($ch, CURLOPT_HTTPHEADER, "authorization: $authorization");
curl_setOpt($ch, CUSTOMREQUEST, 'GET');
$server_output = curl_exec ($ch);
$result = json_decode($server_output);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/payment',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log(res);
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void statusCollection(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
          .url(host + "/creditor/collect/sdd")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("x-reset", "2017-08-29T00:00:00.000Z")
          .addHeader("authorization", authorisation)
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        authorisation = null; // collected through logIn

    public void statusCollection(){    
        RestClient client = new RestClient(host + "/creditor/payment");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("x-reset", "2017-08-29T00:00:00.000Z");
        request.AddHeader("authorization", authorisation);
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
id Specific SDD reference No number
detail Include details (true = default/false) No boolean

HTTP Response

Code Description
200 The request has succeeded

Payments

The payment information can be retrieved in 2 ways. This can either be done by polling the transaction feed or by the status of the collection. Both can be polled periodically or triggered by a callback.

Per transaction

{
    "Entries": [
            {
                "id": 123456789,
                "contractId": 10001,
                "mndtId": "mandateReference",
                "contract": "contractNumber",
                "amount": 99.99,
                "msg": "transaction message",
                "place": "web",
                "ref": null,
                "final": true,
                "state": "PAID",
                "bkdate": "2017-03-21T08:13:21Z",
                "reqcolldt": "2017-03-23T08:13:21Z"
        },
        {
                "id": 987654321,
                "contractId": 2002,
                "mndtId": "mandateReference",
                "contract": "contractNumber",
                "amount": 100,
                "msg": "transaction message",
                "place": "web",
                "ref": "INVOICE001",
                "final": false,
                "state": "ERROR",
                "bkerror": "MS03",
                "bkmsg": "Geen reden opgegeven",
                "bkdate": "2016-09-21T08:13:21Z",
                "reqcolldt": null
        },
        {
                "id": 56789123,
                "contractId": 3003,
                "mndtId": "mandateReference",
                "contract": "contractNumber",
                "amount": 49.99,
                "msg": "buy item X",
                "place": "web",
                "ref": null,
                "final": true,
                "state": "ERROR",
                "bkerror": "AC04",
                "bkmsg": "Rekening afgesloten",
                "bkdate": "2016-08-29T13:14:40Z",
                "reqcolldt": null
        }
    ]
}

This endpoint allows to retrieve a list of all the transactions for which new payment information has been received since the last call. This endpoint doesn't require any parameters. If we receive an error from the bank, we mark the transaction with status "error" or "paid". We also add a final flag which can either be true or false. True (being final) means that we can't do anything with it anymore. This could be the case for paid transactions as well as for errors like debtor deceased. An action will be required on your part. False means that we still have actions pending to debit the debtor's account.

Per Collection

{
    "Sdds":[
        {
            "id":1437939405111,
            "pmtinfid": "mypmtid",
            "tx":4,    // Number of transactions
            "amount":120.0,   // Total amount of the transactions
            "Entries": [
                {
                    "e2eid": "mye2e",
                    "amount": 30.0,
                    "contractId": 7488, // internal reference to the contract
                    "mandateRef": "TWIKEYCORE22",  // mandate reference
                    "msg": "testing",
                    "final": false,  // Does Twikey have any outstanding actions ?
                    "state": "open"  // No payment information received as of yet
                },
                {
                    "e2eid": "mye2e",
                    "amount": 30.0,
                    "contractId": 7488,
                    "mandateRef": "TWIKEYCORE22",
                    "msg": "testing",
                    "final": true,
                    "state": "paid",  // Transaction was paid
                    "bkamount": 30.0,  // Booked amount as stated in account information
                    "bkdate": "2015-07-27",  // Booking date as stated in account information
                    "bkerror": null   // No errors
                },
                {
                    "e2eid": "mye2e",
                    "amount": 30.0,
                    "contractId": 6358,
                    "mandateRef": "TWIKEYCORE21",
                    "msg": "test",
                    "final": false, // This is FYI, since we haven't exhausted yet all possibilities (will re-offer)
                    "state": "error", // Transaction was paid
                    "bkamount": 30.0,
                    "bkdate": "2015-07-27",
                    "bkerror": "MSO3"  // Actual error code
                },
                {
                    "e2eid": "mye2e",
                    "amount": 30.0,
                    "contractId": 6358,
                    "mandateRef": "TWIKEYCORE21",
                    "msg": "test",
                    "final": true,  // Could not collect, please contact your customer
                    "state": "error",
                    "bkamount": 30.0,
                    "bkdate": "2015-07-27",
                    "bkerror": "AG01"
                }
            ]
        }
    ]
}

This endpoint allows to retrieve a list of SDD's for which new payment information is given. If the parameter 'id' is passed, it will also return the details of the mandates contained in the referenced SDD. If the 'detail' parameter is passed (regardless of its value) then the call with the 'id' parameter is obsolete as the details are included in the general call. In case we receive an error from the bank, we mark the transaction with status "error" or "paid", but on top of it we add a final flag which will either be true or false. True (being final) means that we can't do anything with it anymore. This could be the case for paid transactions as well as for errors like debtor deceased. An action would be required from your part. False means that we still have actions pending to debit the debtor's account.

Sometimes the customer can't pay via direct debit from his regular account even though he wants to pay. To help that customer pay his debt, we allow you to create a payment link (with or without expiry).

HTTP Request

POST /creditor/payment/link

curl -X POST https://api.twikey.com/creditor/transaction \
  -H 'authorization: **authorization**'\
  -d 'email=no-repy@twikey.com'\
  -d 'message=Faulty payments last month'\
  -d 'amount=100'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/payment/link");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
      "email=no-repy@twikey.com"
    ."&message=Monthly payment"
    ."&amount=10");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/payment/link',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        },
        body :{
            'email': 'no-repy@twikey.com',
            'message': 'Monthly payment',
            'amount': '10'
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void addTransaction(){
        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
            .add("email=no-repy@twikey.com")
            .add("message", "Monthly payment")
            .add("amount", "10")
            .build();

        Request request = new Request.Builder()
            .url(host + "/creditor/payment/link")
            .post(body)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; //collected through logIn

    public void addTransaction(){    
        RestClient client = new RestClient(host + "/creditor/payment/link");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);
        request.AddParameter("application/x-www-form-urlencoded",
            "email=no-repy@twikey.com" +
            "message=Monthly payment" +
            'amount=10"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
  "id": 1,
  "amount": 55.66,
  "msg": "Test",
  "url": "https://mycompany.twikey.com/payment/tr_l2iKz0LT8HvRrmf0"
}

Request Parameters

Name Description Required Type
email Email of the debtor No (Required to send invite) string
lastname No string
firstname No string
message Message to the customer (if only 1 entry) Yes string
ref Your reference No string
amount Amount to be billed Yes string
redirectUrl Optional redirect after pay url No url
place Optional place No string
expiry Optional expiration date No date
sendInvite Send out invite email directly No boolean
address Address (street + number) No string
city City of debtor No string
zip Zipcode of debtor No string
country ISO format (2 letters) No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_invalid_amount Invalid Amount given
err_invalid_date Invalid Expiry Date

Refunds

New entry

Add entry to batch.

HTTP Request

POST /creditor/transfer

curl https://api.twikey.com/creditor/transfer \
  -H 'authorization: authorization' \
  -d 'iban=BE68068897250734' \
  -d 'message=test%20credit%20transfer' \
  -d 'amount='0.00'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 
    "iban=BE68068897250734" 
    ."message= test credit transfer"
    ."amount="50.00"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "iban":"BE68068897250734", 
            "message":"test credit transfer",
            "amount":"50.00"
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
            .add("iban", "BE68068897250734")
            .add("message","test credit transfer")
            .add("amount", "50.00")
            .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/transfer")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfer");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "iban=BE68068897250734" +
            "message=test credit transfer" +
            "amount=50.00"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
    "Entries": [
        {
            "id": "11DD32CA20180412220109485",
            "iban": "BE12356798",
            "bic": "BBRUBEBB",
            "amount": 12,
            "msg": "test",
            "place": null,
            "date": "2018-04-12"
        }
    ]
}

Query parameters

Name Description Required Type
iban Iban of the beneficiary (requires the registration in settings > credit transfer) Yes string
message Message to the creditor (maximum length of 4x35 characters) Yes string
amount Amount to be send Yes number
date Required execution date of the transaction (ReqdExctnDt) No string
place Optional place No string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_invalid_iban Invalid Iban
403 Account unregistered
err_mandate_invalid_state Mandate existed, but was not active
err_invalid_date Invalid date
err_invalid_sepachars Invalid message
err_invalid_amount Invalid amount

Details Entry

Get entry details by id

HTTP Request

GET /creditor/transfer

curl https://api.twikey.com/creditor/transfer?id=123 \
  -H 'authorization: authorization'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer?id=123");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer?id=123',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");

        Request request = new Request.Builder()
          .url(host + "/creditor/transfer?id=123")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfer?id=123");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        IRestResponse response = client.Execute(request);
    }
}
{
    "Entries": [
        {
            "id": "11DD32CA20180412220109485",
            "iban": "BE12356798",
            "bic": "BBRUBEBB",
            "amount": 12,
            "msg": "test",
            "place": null,
            "date": "2018-04-12",
            "state": "PAID", // when paid
            "bkdate": "2017-03-24" // when paid
        }
    ]
}

Query parameters

Name Description Required Type
id id of the created refund Yes string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_transaction No such transaction

Remove Entry

Remove entry details by id

HTTP Request

curl -X DELETE https://api.twikey.com/creditor/transfer?id=123 \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer?id=123");
curl_setopt($ch, CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer?id=123',
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void removeTransaction(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transfer?id=123")
            .delete(null)
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // gathered through logIn

    public void removeTransaction(){    
        RestClient client = new RestClient(host + "/creditor/transfer?id=123");
        RestRequest request = new RestRequest(Method.DELETE);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
id id of the created refund Yes string

HTTP Response

Code Description
200 The request has succeeded
400 User error if parameter is given but not valid (available in apierror header and response)

Error codes

Code Description
err_no_transaction No such transaction

Batch creation

Create bank file (and optionally send)

HTTP Request

POST /creditor/transfer/complete

curl https://api..twikey.com/creditor/transfer/complete \
  -H 'authorization: authorization' \
  -d 'ct=**ct_id**' \
$host = "https://api.twikey.com";
$ct = "**ct_id**";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer"/complete);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "ct=$ct");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    ct= "**ct_id**",
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer/complete',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "ct": ct
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String ct = "**ct_id**";
    private String authorisation = null; //collected through logIn

    public void completeCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
            .add("ct", ct)
            .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/transfer/complete")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void completeCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfer/complete");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter(
            "application/x-www-form-urlencoded", 
            "ct=" + ct,
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
ct Template containing the originating account Yes string
iban Originating account, if different from ct account No string

HTTP Response

Code Description
200 The request has succeeded
400 Invalid request

Batch details

Get details about batch information

HTTP Request

GET /creditor/transfer/complete

curl https://api..twikey.com/creditor/transfer/complete \
  -H 'authorization: authorization' \
  -d 'id=**id**' \
$host = "https://api.twikey.com";
$id = "**id**";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer/complete?id=123");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    ct= "**ct_id**",
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer/complete?id=123',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void completeCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");        
        Request request = new Request.Builder()
          .url(host + "/creditor/transfer/complete?id=123")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void completeCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfer/complete?id=123");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
id Id of the batch previously submitted No string
pmtinfid PmtInfId of the batch previously submitted No string

HTTP Response

Code Description
200 The request has succeeded
400 Invalid request

Error codes

Code Description
err_invalid_params No such batch available

Get credit transfer feed

Retrieve list of credit transfers that have changes since the last call.

curl https://api.twikey.com/creditor/transfer \
  -H 'authorization: **authorization**' \
  -H 'x-reset: 2017-08-29T00:00:00.000Z'
$host = "https://api.twikey.com";
$authorization = null; // collected through login

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfer");
curl_setopt($ch, CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, // collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfer',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; // collected through login
    public void getTransactions(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transfer")
            .get()
            .addHeader("content-type", "application/x-www-form-urlencoded")
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // collected through login

    public void getTransactions(){    
        RestClient client = new RestClient(host + "/creditor/transfer");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}

HTTP Request

GET /creditor/transfer

{
    "Entries": [
        {
            "id": "IBWICD6E44Y1N3YRMCVB2U7BA",
            "iban": "BE70361272935897",
            "bic": "GDOENFY",
            "amount": 1000,
            "msg": "credit transfer message",
            "place": null,
            "date": "2017-01-20"
        },
        {
            "id": "X52D04L9DNNPWKCRGBV7YPV2R",
            "iban": "BE93261223700539",
            "bic": "BRODBZL",
            "amount": 12345,
            "msg": "credit transfer message",
            "place": "Brugge",
            "date": "2018-01-23"
        },
        {
            "id": "ZE31QPMT6GRMHEY7IPOOD219R",
            "iban": "BE4447226747140",
            "bic": "ORNSRAM",
            "amount": 250099,
            "msg": "",
            "place": "Ghent",
            "date": "2017-03-23",
            "state": "PAID", // when paid
            "bkdate": "2017-03-24"
        },
        "..."
    ]
}

HTTP Response

Code Description
200 The request has succeeded

Get beneficiaries

Get all credit transfer beneficiaries

HTTP Request

GET /creditor/transfers/beneficiaries

curl https://api.twikey.com/creditor/transfers/beneficiaries?withAddress=true \
  -H 'authorization: authorization'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfers/beneficiaries?withAddress=true");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfers/beneficiaries?withAddress=true',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");

        Request request = new Request.Builder()
          .url(host + "/creditor/transfers/beneficiaries?withAddress=true")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfers/beneficiaries?withAddress=true");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        IRestResponse response = client.Execute(request);
    }
}
{
    "beneficiaries": [
        {
            "name": "sdfsf",
            "iban": "BE92221216720939",
            "bic": "GEBABEBB",
            "available": true,
            "address": null
        },
        {
            "name": "beneficiary2",
            "iban": "BE16645348971174",
            "bic": "JVBABE22",
            "available": true,
            "address": {
                "street": "Veldstraat 11",
                "city": "Gent",
                "zip": "9000",
                "country": "BE"
            }
        }
    ]
}

Query parameters

Name Description Required Type
withAddress include addresses in reponse Yes boolean

HTTP Response

Code Description
200 The request has succeeded
500 System error

Error codes

Code Description
error_system An error occured on the system

Create/update a beneficiary

Create/update a beneficiary Data for the entity will be updated when the IBAN exists in the system.

HTTP Request

POST /creditor/transfers/beneficiaries

curl -X POST https://api.twikey.com/creditor/transfers/beneficiaries \
  -H 'authorization: authorization' \
  -d 'name=Beneficiary Name' \
  -d 'iban=BE68068897250734' \
  -d 'bic=JVBABE22' 
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfers/beneficiaries");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 
    "name=Beneficiary Name" 
    ."iban=BE68068897250734"
    ."bic=JVBABE22"
);
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfers/beneficiaries',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "name": "Beneficiary Name", 
            "iban": "BE68068897250734",
            "bic": "JVBABE22"
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
            .add("name", "Beneficiary Name")
            .add("iban","BE68068897250734")
            .add("bic", "JVBABE22")
            .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/transfers/beneficiaries")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/transfers/beneficiaries");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter("application/x-www-form-urlencoded", 
            "name=Beneficiary Name" +
            "iban=BE68068897250734" +
            "bic=JVBABE22"
            , ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}
{
    "name": "Beneficiary Name",
    "iban": "BE68068897250734",
    "bic": "JVBABE22",
    "available": true,
    "address": {
        "street": "Veldstraat 11",
        "city": "Gent",
        "zip": "9000",
        "country": "BE"
    }
}

Query parameters

Name Description Required Type
name The name of the beneficiary Yes string
iban IBAN of the beneficiary Yes string
bic BIC of the beneficiary Yes string
street The street name and number/box No string
zip The zip code No string
city The city No string
country the country ISO code No string

HTTP Response

Code Description
200 The request has succeeded
400 Validation error due to user wrong user input
500 System error

Error codes

Code Description
err_name_required Invalid or missing name
err_invalid_iban Invalid IBAN number
err_invalid_bic Invalid BIC number
error_system An error occured on the system

Remove a beneficiary

Remove a beneficiary on it's IBAN number, the beneficiary will not actually be deleted and just made not available.

Updating the beneficiary entity will re-enable it.

HTTP Request

DELETE /creditor/transfers/beneficiaries/{IBAN}

curl -X DELETE https://api.twikey.com/creditor/transfers/beneficiaries/BE16645348971174 \
  -H 'authorization: **authorization**'
$host = "https://api.twikey.com";
$authorization = null; /collected through logIn

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$host/creditor/transfers/beneficiaries/BE16645348971174");
curl_setopt($ch, CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, 'Authorization : $authorization");
$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through logIn
    options = {
        host: host,
        port: '443',
        path: '/creditor/transfers/beneficiaries/BE16645348971174',
        method: 'DELETE',
        headers: {
            'Authorization': authorization
        }
    };

var req = https.request(options, function (res) {
    console.log("result : ",result);
});
public class TwikeyAPI {
    private String host = "https://api.twikey.com", 
        authorization = null; //collected through logIn
    public void removeTransaction(){
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
            .url(host + "/creditor/transfers/beneficiaries/BE16645348971174")
            .delete(null)
            .addHeader("authorization", authorization)
            .build();

        Response response = client.newCall(request).execute();
    };
}
public class TwikeyAPI {
    private String host ="https://api.twikey.com",
        authorization =null; // gathered through logIn

    public void removeTransaction(){    
        RestClient client = new RestClient(host + "/creditor/transfers/beneficiaries/BE16645348971174");
        RestRequest request = new RestRequest(Method.DELETE);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("Authorization", authorization);

        IRestResponse response = client.Execute(request);
    }
}

HTTP Response

Code Description
200 the request has succeeded, no content
400 bad request, the IBAN provided is not valid
404 the entity was not found
500 system error

Error codes

Code Description
err_not_found No such beneficary
err_invalid_iban No beneficary found for that IBAN
error_system An error occured on the system

Create/update beneficiaries in bulk

Create/update credit transfer beneficiaries in bulk. Data for entities will be overwritten when the IBAN exists in the system.

HTTP Request

POST /creditor/transfers/beneficiaries/bulk


# XML
curl -v -X POST https://api.twikey.com/creditor/transfers/beneficiaries/bulk \
  -H 'authorization: **authorization**' \
  -H "Accept: text/xml" \
  -d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<beneficiaries>
    <beneficiary>
        <name>Beneficiary Name</name>
        <iban>BE16645348971174</iban>
        <bic>JVBABE22</bic>
        <address>
            <street>Veldstraat 11</street>
            <zip>9000</zip>
            <city>Gent</city>
            <country>BE</country>
        </address>
    </beneficiary>
    <beneficiary>
        <name>Beneficiary Name</name>
        <iban>BE16645348971174</iban>
        <bic>JVBABE22</bic>
        <address>
            <street>Avenue Albert 10 B1</street>
            <zip>1000</zip>
            <city>Brussels</city>
            <country>BE</country>
        </address>
    </beneficiary>
</beneficiaries>' 

# JSON
curl -v -X POST https://api.twikey.com/creditor/transfers/beneficiaries/bulk \
  -H 'authorization: **authorization**' \
  -H "Content-Type: application/json" \
  -d '[
    {
        "name": "Beneficiary Name",
        "iban": "BE16645348971174",
        "bic": "JVBABE22",
        "address": {
            "street": "Veldstraat 11",
            "city": "Gent",
            "zip": "9000",
            "country": "BE"
        }
    },{
        "name": "Beneficiary Name 2",
        "iban": "BE16645348971174",
        "bic": "JVBABE22",
        "address": {
            "street": "Avenue Albert 10 B1",
            "city": "Brussels",
            "zip": "1000",
            "country": "BE"
        }
    }
]' 

HTTP Response

Code Description
200 The request has succeeded
500 System error

Error codes

Code Description
err_name_required Invalid or missing name
err_invalid_iban Invalid IBAN number
err_invalid_bic Invalid BIC number
error_system An error occured on the system

Identification

Fetch allowed banks

Return the banks that are currently connected to Idin

HTTP Request

GET /creditor/ident

curl https://api.twikey.com/creditor/ident \
  -H 'authorization: authorization' \
  -d 'ct=1234' \
  -d 'method=idin'
$host = "https://api.twikey.com";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/ident?ct=1234&method=idin");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/ident?ct=1234&method=idin',
        method: 'GET',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String authorisation = null; //collected through logIn

    public void createCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        Request request = new Request.Builder()
          .url(host + "/creditor/ident?ct=1234&method=idin")
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void createCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/ident?ct=1234&method=idin");
        RestRequest request = new RestRequest(Method.GET);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
ct Template number Yes number
method Method of identification False string

HTTP Response

Code Description
200 The request has succeeded

Retrieve authentication url

Retrieve direct link from the bank

HTTP Request

POST /creditor/ident

curl https://api..twikey.com/creditor/ident \
  -H 'authorization: authorization' \
  -d 'ct=**ct_id**' \
$host = "https://api.twikey.com";
$ct = "**ct_id**";
$authorisation = null; //collected through login

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "$host/creditor/ident");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "ct=$ct&bic=ABNANL2A");
curl_setOpt($ch, CURLOPT_HTTPHEADER,"authorization: $authorization");

$server_output = curl_exec ($ch);
curl_close ($ch);
var https = require('https'),
    ct= "**ct_id**",
    querystring = require('querystring'),
    host = "api.twikey.com",
    authorization = null, //collected through login
    options = {
        host: host,
        port: '443',
        path: '/creditor/ident',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        data: {
            "ct": ct,
            "bic": 'ABNANL2A'
        }
    };

var req = https.request(options, function (res) {
        console.log("response: " + res)
});
public class TwikeyApi{
    private String host = "https://api.twikey.com";
    private String ct = "**ct_id**";
    private String authorisation = null; //collected through logIn

    public void completeCreditTransfer(){
        OkHttpClient client = new OkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody formBody = new FormBody.Builder()
            .add("ct", ct)
            .add("bic","ABNANL2A")
            .build();

        Request request = new Request.Builder()
          .url(host + "/creditor/ident")
          .post(formBody)
          .addHeader("content-type", "application/x-www-form-urlencoded")
          .addHeader("authorization", authorisation)
          .addHeader("cache-control", "no-cache")
          .build();

        Response response = client.newCall(request).execute();
    }
}
public class TwikeyAPI {
    private  String host ="https://api.twikey.com",
        ct = "**ct_id**",
        authorisation = null; // collected through logIn

    public void completeCreditTransfer(){    
        RestClient client = new RestClient(host + "/creditor/ident");
        RestRequest request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", authorisation);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddParameter(
            "application/x-www-form-urlencoded", 
            "ct=" + ct,
            "bic=ABNANL2A",
            ParameterType.RequestBody
        );
        IRestResponse response = client.Execute(request);
    }
}

Query parameters

Name Description Required Type
ct Template containing the originating account Yes string
bic BICCode of the bank to retrieve a url for Yes string

HTTP Response

Code Description
200 The request has succeeded

Webhooks

In order to reduce the number of polling requests, one can opt to implement a webhook endpoint and use this as a way to trigger polling requests. The endpoint is set in the API section of the settings screen and will convey information about various events in Twikey. The call is done via a simple GET with basic (non-sensitive) parameters eg. http://my.company.com/callback?type=contract&mandateNumber=MNDT123&state=signed...

In order to verify that the request is indeed coming from Twikey you can verify the headers 'apiToken' and optionally 'otp' which should hold the same values as you'd use for the login.

Note that the url to be given in the interface is without parameters since these are filled up depending on the type.

type=contract

Triggered when something happens to the mandate. Activation events (when a mandate becomes suspended or gets resumed) will be included in the event=Update with the reason being either 'resumed" or 'suspended'

curl -H "apiToken=MyToken" https://example.com/callback \
    -d type=contract \
    -d reason=resumed \
    -d mandateNumber=CORE01 \
    -d name=MyMandate \
    -d contractNumber=454 \
    -d state=SIGNED \
    -d event=Update

type=transaction

Triggered when a new transaction is being added.

Extra parameters:

type=plan

Triggered when a plan was executed

Extra parameters:

type=payment

Triggered when a batch of payments were received. Note that this is triggered for the batch and not per transaction as it could cause a flood of requests.

No parameters to avoid hammering your site when new transaction feedback is received

This is also triggered when a paymentlink was updated to either paid, rejected or expired. In that case you will receive the initial id, ref and status back.

type=dunning

Triggered when a dunning action was executed for a failed transaction

Extra parameters:

Exit Url

An alternative to a webhook can be the exit url or the page where the end-user is being redirected to after signing. This is a thank-you page or a redirect to an exit url defined on the template. This url can contain variables that are filled in depending on the outcome. The variables can either be positional of named.

Some of the exceptional statusses can be (but not limited to):

In order to be sure that the return call is coming from Twikey, it's strongly recommended to verify the signature to the exit url. Calculation of the signature is done as described in Appendix E.

eg. an exit url with the following value

http:///website.com/{0}/{1}/{3}

or

http:///website.com/{{mandateNumber}}/{{status}}/{{s}}

would be expanded to if the end-customer returned without error

http:///website.com/MND123/ok/C9FB0D93...