Get started for free Contact sales

An API to unlock the potential of SEPA Direct Debits

Negotiate eMandates in minutes and set up their payment at the same time

Setting up a subscription

Anyone can design a form to request the account number of a customer, but are you sure this will lead to a valid mandate? Are you sure you want to validate IBAN's or check that the customer's bank is SEPA enabled? We want you to be able to integrate within minutes. Just copy and paste the code below and be up and running in no time. Adn this, without adding extra complexity to your website/application.

<?php
$host = "https://api.twikey.com";
$apitoken = "**API_TOKEN**";
$ct = **ct**;

$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);
$auth = $result->{'Authorization'} ;
curl_close ($ch);

$payload = http_build_query([
    "ct" => $ct,
    "email" => "info@twikey.com",
    "firstname" => "Info",
    "lastname" => "Twikey",
    "l" => "en",
    "address" => "Abbey road",
    "city" => "Liverpool",
    "zip" => "1526",
    "country" => "BE",
    "mobile" => "",
    "iban" => "",
    "bic" => "",
    "mandateNumber" => "",
    "contractNumber" => ""
]);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"$host/creditor/prepare");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: $auth"));
curl_setopt($ch, CURLOPT_POSTFIELDS,$payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
var_dump(json_decode($server_output));
curl_close ($ch);
?>
var https = require('https'),
    querystring = require('querystring');

var host = "api.twikey.com",
    apitoken = "**API_TOKEN**",
    ct = **ct**,
    authorization = null,
    options = {
        host: host,
        port: '443',
        path: '/creditor',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

var req = https.request(options, function (res) {
    res.setEncoding('utf8');
    authorization = res.headers.authorization;
    console.log("authorization : ",authorization);
    options.path = '/creditor/prepare';
    var inviteReq = https.request(options, function (res) {
        res.on('data', function (chunk) {
            console.log("Redirect to : "+chunk)
        });
    });
    inviteReq.data = querystring.encode({
        ct: ct,
        email: "info@twikey.com",
        firstname: "Info",
        lastname: "Twikey",
        l: "en",
        address: "Abby road",
        city: "Liverpool",
        zip: "1526",
        country: "BE",
        mobile: "",
        iban: "",
        bic: "",
        mandateNumber: "",
        contractNumber: ""
    });
    inviteReq.end();
});
req.data = querystring.encode({apiToken: apitoken});
req.end();
import java.io.*;
import java.lang.String;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static javax.xml.bind.DatatypeConverter.parseHexBinary;

public class TwikeyAPI {

    public static final String UTF_8 = "UTF-8";

    //from_creditor_env
    private static final String TEMPLATE_ID = "**ct**";// id of contract template in https://www.twikey.com/r/admin#/c/template
    private static final String API_TOKEN = "**API_TOKEN**"; // found in https://www.twikey.com/r/admin#/c/settings/ei

    public static void main(String... args) throws GeneralSecurityException, ExecutionException, InterruptedException, IOException {

        String query = java.lang.String.format("apiToken=%s", API_TOKEN);

        URL myurl;
        HttpURLConnection con;
        DataOutputStream output;
        String sessionToken;

        // login
        {
            myurl = new URL("https://api.twikey.com/creditor");
            con = (HttpURLConnection)myurl.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setDoOutput(true);
            con.setDoInput(true);

            output = new DataOutputStream(con.getOutputStream());
            output.writeBytes(query);
            output.close();

            sessionToken = con.getHeaderField("Authorization");
            con.disconnect();
            System.out.println("Authorization:" + sessionToken);
        }

        // prepare new contract and redirect user
        if(sessionToken != null){
            Map<String,String> params = new HashMap<>();
            params.put("ct",TEMPLATE_ID);
            params.put("email","info@twikey.com");
            params.put("firstname","Info");
            params.put("lastname","Twikey");
            params.put("l","en");
            params.put("address","Abbey road");
            params.put("city","Liverpool");
            params.put("zip","1526");
            params.put("country","BE");
            params.put("mobile","");
            params.put("vatno","");
            params.put("iban","");
            params.put("bic","");
            params.put("mandateNumber","");
            params.put("contractNumber","");

            myurl = new URL("https://api.twikey.com/creditor/prepare");
            con = (HttpURLConnection)myurl.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setRequestProperty("Authorization", sessionToken);
            con.setDoOutput(true);
            con.setDoInput(true);

            output = new DataOutputStream(con.getOutputStream());
            output.writeBytes(getPostDataString(params));
            output.flush();
            output.close();

            int responseCode=con.getResponseCode();

            StringBuilder response = new StringBuilder();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                String line;
                BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream()));
                while ((line=br.readLine()) != null) {
                    response.append(line);
                }
            }

            con.disconnect();
            System.out.println("Url to redirect too:" + response);
        }
    }

    private static String getPostDataString(Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for(Map.Entry<String, String> entry : params.entrySet()){
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), UTF_8));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), UTF_8));
        }

        return result.toString();
    }
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace TestWebApp
{
    public static class TwikeyAPI
    {
        private const string baseAddress = "https://api.twikey.com";
        private const string API_TOKEN = "**API_TOKEN**"; // Twikey settings > ERP Info > ERP API Token

        static void Main(string[] args)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(baseAddress);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                var content = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("apiToken", API_TOKEN)
                });
                content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                var result = client.PostAsync("/creditor", content).Result;
                string resultContent = result.Content.ReadAsStringAsync().Result;
                Console.WriteLine("Response was : "+resultContent);
            }
        }
    }
}
require 'net/http'
require 'json'
require "uri"

ct = **ct**;
apiToken = "**API_TOKEN**";

uri = URI.parse("https://api.twikey.com")
http = Net::HTTP.new(uri.host, uri.port)

request = Net::HTTP::Post.new(uri + "/creditor")
request.set_form_data({
    "apiToken" => apiToken
})
response = http.request(request)
authHeader = response['Authorization']

request = Net::HTTP::Post.new(uri + "/creditor/prepare")
request['Authorization'] = authHeader
request.set_form_data({
    "ct" => ct,
    # "mandateNumber" => "Mandate001",
    "email" => "info@twikey.com",
    "firstname" => "Info",
    "lastname" => "Twikey",
    "l" => "nl",
    "address" => "Derbystraat 43",
    "city" => "Sint Denijs Westrem",
    "zip" => "9051",
    "country" => "BE",
    "mobile" => "",
    "iban" => "",
    "bic" => ""
})
response = http.request(request)
invite = JSON.parse(response.body)

puts "Redirecting to "+invite["url"]
import hmac
import time
import base64
import struct
import hashlib
import binascii
import httplib
import urllib
import urllib2
import json

ct = **ct**
url = "https://api.twikey.com"
params = urllib.urlencode({'apiToken': '**API_TOKEN**'})
req = urllib2.Request(url+"/creditor", params)
req.add_header("Accept","application/json")
req.add_header("Content-type", "application/x-www-form-urlencoded")
response = urllib2.urlopen(req)
authorization = response.headers["Authorization"]

params = urllib.urlencode({
    "ct": ct,
    "email": "info@twikey.com",
    "firstname": "Info",
    "lastname": "Twikey",
    "l": "en",
    "address": "Abby road",
    "city": "Liverpool",
    "zip": "1526",
    "country": "BE",
    "mobile": "",
    "iban": "",
    "bic": "",
    "mandateNumber": "",
    "contractNumber": ""
})

req = urllib2.Request(url+"/creditor/prepare",params)
req.add_header("Content-type", "application/x-www-form-urlencoded")
req.add_header("Authorization",authorization)
req.add_header("Accept","application/json")
response = urllib2.urlopen(req)

invite = json.loads(response.read())
print "Redirecting to "+invite["url"]

TWIKEY API

Negotiate eMandates in minutes and set up their payment at the same time.

FULL ROUND-TRIP

Negotiate eMandates, send transactions to the bank and check the payments. This can all by done via the API.

FULL FLEXIBILITY

To be used with bank or PSP.

NO LOCK-IN

The best-of-breed integration via REST. Support for Json, Xml, ...



From a website

Provide us with the necessary Metadata and we'll deliver you the link to your fully branded environment, with access to multiple eMandate signing methods and a signed mandate as end result.

In your app

Integrate our API in your app to have a seamless negotiation process to launch eMandates. No need for a separate app.

In mailings

You have a CRM and want to launch a mailing? Generate bulk invitations via our API and follow up who signed when.

In Sync

Receive all information on new, updated and cancelled eMandates and synchronize this with your own back office. We capture these changes from difference sources and make them available to you.

Download mandates

Signed PDF's remain the property of the merchant. Download them via API for internal storage purposes.

Automated transactions

Define and change payment plans via API

New collections

Transactions can be sent from different sources. Just pass on the mandate reference, the amount and the message and we take care of the rest.

Payment follow-up

Follow up paid and unpaid collections. Get all the details of every transaction.

Refunds

Need to do an exceptional refund on a SEPA Direct Debit? Our API allows the preparation of refunds or takes care of them for you.


Want to use this API as integrator?

Assistance

We assist our partners along the way and quickly interact to help you choose the best optimal integration.

Flexible

Use our API from different interfaces. Your ERP, CRM and other back office systems can simultaneously exchange the same data.

Need more information?