Return To Blogs
Open Banking

Making Multiple KYC checks with an OpenAPI generated Java Client

This blog looks at how you can make multiple Know Your Customer (KYC) checks with automatic client generation. Specifically it covers the creation of an OpenApi Java client to allow the consumption of Unified Software’s BankVal Enhanced (BVE) web services. OpenAPI (formerly known as Swagger) is a technology which documents RESTful APIs to allow easy integration into your existing systems.

The BankVal Enhanced OpenAPI documents are located at either:
https://www.unifiedservices.co.uk/services/enhanced/openapi.json or 
https://www.unifiedservices.co.uk/services/enhanced/openapi.yaml .

BVE OpenAPI YAML loaded in editor
BVE OpenAPI YAML loaded in editor

Creating the client code

There are numerous OpenAPI code generators here we are using the Swagger Editor available at https://editor.swagger.io/. See our python client blog post for an example of using the OpenAPITools openapi-generator-cli tool.

First download the BVE OpenAPI document and load it into the Swagger Editor as shown in the diagram above, or directly import it from the File > Import URL drop down menu. Whichever format you chose is not really important, yaml or json work the same. Once the file is parsed you will be able to select your desired language from the Generate Client dropdown. Here we are selecting Java.

This will give you a download of the generated client.

Building the Client Code

We are going to incorporate our client into a library project. To do this we create a netbeans gradle project (the generated client is already Gradle if you prefer to use another build agent such as Maven you can just copy the source code into a project of your choice).

Calling the Client Code to Make Multiple KYC Checks

Once we’ve built the project we can import it wherever we need ot use it and call the methods within. As the Unified Software SLA requires use of the failover we will create two methods to make use of the service, with the call to the server abstracted out to allow a call to the primary server and if required a call to the second. The second is a method that controls calling that as well as building the data to be posted to the service.

First we’ll look at the method that calls the service which is shown below:

private BVEResponse callServer(BVERequestPayload bverp, String url) throws ApiException{
    BVEResponse bveResponse = null;
    DefaultApi api = new DefaultApi();
    OkHttpClient client = new OkHttpClient();
    ApiClient apiClient = api.getApiClient();
    apiClient.setHttpClient(client);
    api.setApiClient(apiClient.setBasePath(url));
    bveResponse = api.bankval(bverp);
    return bveResponse;
}

This method takes the BVERequestPayload object we will create later, the url of the server to call and returns the BVEResponse object. N.b. both these classes (BVERequestPayload and BVEResponse) are part of the generated client. In the event of an issue calling the server we throw an ApiException which is also a client code class.

Next we’ll look at the method that builds the BVERequestPayload and handles the response. We’ve included this all in one method for brevity. We will look at KYC checks on the address and bank account so our method will take four parameters, a sortcode and account pair, and a postcode and address premise. so the signature looks like so:

private boolean doValidation(String sc, String acc, String postcode, String AddressPremise){ 

Boolean true is returned if a successful call has been made to either servers. The method handles the response within itself, for production you would probably call callbacks, or return data. It first builds the request data as shown below:

Credentials credentials = new Credentials();
credentials.setUname("UNAME_FROM_UNIFIED");
credentials.setPin("PIN_FROM_UNIFIED");
//create the uk account request
UKAccountRequest account = new UKAccountRequest();
account.setSortcode(sc);
account.setAccount(acc);
//create the Address request
AddressVal address = new AddressVal();
address.setPostcode(postcode);
address.setAddress1(AddressPremise);
//build the request payload
BVERequestPayload bverp = new BVERequestPayload();
bverp.setCredentials(credentials);
bverp.setAccount(account);
bverp.setAddress(address);

The above simply builds the Credentials, UKAccountRequest and AddressVal objects. These are then combined into a BVERequestPayload object ready to be send to the server.

Calling the servers

The portion of the method which calls the server is below:

String primaryurl = "https://www.unifiedsoftware.co.uk/services";
String secondaryurl = "https://www.unifiedservices.co.uk/services";
...
//call the first server
boolean success = false;
try{
    bveResponse = callServer(bverp, primaryurl);
    success = true;
}catch(ApiException ex){
    Logger.getAnonymousLogger().log(Level.SEVERE, null, ex);
}
if(!success){
    try {
        bveResponse = callServer(bverp, secondaryurl);
        success = true;
    } catch (ApiException ex) {
        Logger.getAnonymousLogger().log(Level.SEVERE, null, ex);
    }
}

Because we want to maintain availability this calls the primary server and in the unlikely event of an exception calls the secondary server. Following this our example handles using the returned data, shown below:

//process response
boolean addressValid = false;
boolean accountvalid = false;
BVEResponse.ErrorEnum error = bveResponse.getError();
if(error != null){
     // handle error
}else{
    BankValUKResponseObject bankValUK = bveResponse.getBankValUK();
    BankValUKResponseObject.ResultEnum accRes = bankValUK.getResult();
    accountvalid=accRes.equals(ResultEnum.VALID)||                                             accRes.equals(ResultEnum.VERIFIED);
    BacsstatusEnum bacsstatus = bankValUK.getBacsstatus();
    boolean bacs =     bacsstatus.equals(BacsstatusEnum.A)||bacsstatus.equals(BacsstatusEnum.M);
    String bacsdrdisallowed = bankValUK.getBacsdrdisallowed();
    boolean dddisallowed = bacsdrdisallowed.equals("DR");
    boolean accOkForDD = accountvalid && bacsparticipant && !dddisallowed;
    System.out.println("Account valid:"+(accountvalid?"true":"false"));
    System.out.println("Bacs Participant:"+(bacs?"true":"false"));
    System.out.println("Account accepts dd:"+(accOkForDD?"true":"false"));
    AddressValResponse addressVal = bveResponse.getAddressVal();
    List addresses = addressVal.getAddresses();
    int size = addresses.size();
    if(size == 1){
        Address add = addresses.get(0);
        Address.ResultEnum addResult = add.getResult();
        addressValid = addResult.equals("VALID");
        System.out.println(add.getAddresscsv());
    }
}
return success;

Consuming the services

Finally we process the returned account data to check for account validity, membership of bacs and whether it accepts direct debits. This is just printed to terminal in the example for demonstration purposes. The returned address data is checked for validity. In addition to this the service returns the whole canonical address as well as separated elements.

The output for this example would be something like the below:

Account valid:true
Bacs Participant:true
Account accepts dd:true
1 Front Street, Village, Durham, AB1 2CD

To request a demo account please click here to try it yourself.