Java Client Library
The Jumio Java client library supports integrating the Jumio Platform into Java Spring applications. You configure an instance of the JumioClient class and use it to manage interactions with the Jumio Platform.
JumioClient exposes fluent interfaces using the builder design pattern that make it simple to configure and execute most common interactions with the platform including:
-
Obtaining and caching authorization tokens.Configure the JumioClient to use with your Jumio data center and OAuth2 credentials and the client will manage the JWT tokens for all calls to the Jumio Platform.
-
Initiating and executing transactions.
-
Retrieving transaction status and details. Jumio Client also provides access to lower-level objects that support more detailed configurations.
The Javadoc API reference is available at: index.html
1. Dependencies
Add these dependencies to your Spring Boot project.
1.1. Maven Dependencies
<repositories>
<repository>
<id>jumio-api</id>
<name>Jumio Api Repository</name>
<url>https://repo.api.jumio.ai</url>
</repository>
</repositories>
.....
<dependency>
<groupId>com.jumio</groupId>
<artifactId>jumio-client</artifactId>
<version>1.0.10</version>
</dependency>
2. Initializing the JumioClient
JumioClient implements the Builder pattern to make it easy to configure and initialize. It is usually created as a Spring Bean so it can be injected and used as needed in your application.
To configure JumioClient you need to provide:
- A DataCenter object representing the Jumio datacenter your application will be using. These objects are defined as public static instances in the DataCenters class, and can be accessed by
DataCenters.US,DataCenters.EU, orDataCenters.SGP. - A UsernamePassword object constructed from your OAuth2 credentials, obtained from the Jumio Portal. See API Credentials.
- A String with the value you want to use for the User-Agent header in calls to Jumio.
- (Optional) A ClientHttpRequestFactory instance, if you want to use a Spring RestTemplate other than the default.
2.1.Example: JumioClient Bean
Details
import com.jumio.sdk.kyx.DataCenters;
import com.jumio.sdk.kyx.JumioClient;
import com.jumio.sdk.kyx.UsernamePassword;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JumioClientProvider {
@Bean
public JumioClient jumioClient() {
return JumioClient.builder()
.dataCenter(DataCenters.EU)
.oauthCredentials(new UsernamePassword("xyz123...", "123xyz..."))
.userAgent("MyCompany Test/1.1")
.defaultRestTemplate()
.build();
}
}
2.2.Builder Steps
| Builder Method | Parameters | Description | Return Type |
|---|---|---|---|
builder() | Returns the first builder step. | BuilderStep1 | |
dataCenter() | DataCenter accessed as static object from DataCenters. | DataCenters provides static references to pre-defined objects for the Jumio datacenters. | BuilderStep2 |
oauthCredentials | UsernamePassword | Object containing your OAuth2 user name and password that you can obtain from the Jumio Portal. See API Credentials. | BuilderStep3 |
userAgent() | String | The value you want to use as the user-agent header in the underlying REST request. | BuilderStep4 |
defaultRestTemplate()or customRestTemplate() | No parameters or ClientHttpRequestFactory | Use the default Spring RestTemplate or specify an alternative RestTemplate. | FinalBuilderStep |
build() | Returns the configured JumioClient. | JumioClient |
3.Initiating a Transaction with the Java Library
JumioClient has two methods that provide fluent builder interfaces for initiating a transaction:
initiateNewAccount()for initiating a transaction for a new account.addNewWorkflowToExistingAccount()for initiating a transaction for an existing account.
The builder steps provide a simple way to configure an account request.
For additional information on the low-level calls that are executed by the client see Create or Update Accounts.
3.1. Example: Initiate a Transaction for a New Account
The following snippet shows the fluent builder interface you can use to initiate a transaction for a new account:
WebResponse webResponse = jumioClient.initiateNewAccount(FluentBuilderWorkflows.STANDALONE_ID_VERIFICATION_10015)
.customerInternalReference("my_company")
.callbackUrl("https://myserver.mycompany.com/callback")
.withDefaultCredentials()
.performWeb(new WebSettings()
.successUrl("https://jumio.com/success")
.errorUrl("https://jumio.com/failure"));
3.2. Example: Initiate a Transaction for an Existing Account
The following snippet shows the fluent builder interface you can use to initiate a transaction for an existing account:
jumioClient.addNewWorkflowToExistingAccount(FluentBuilderWorkflows.fluentWorkflow(Workflows.workflow(10025)), accountId)
.customerInternalReference(reference.toString())
.callbackUrl(JUMIO_CALLBACK_PUBLIC_URL)
.withDefaultCredentials()
.performWeb(new WebSettings()
.successUrl("https://jumio.com/success")
.errorUrl("https://jumio.com/failure"));
3.3. Builder Steps
| Builder Method | Parameters | Description | Return Type |
|---|---|---|---|
initiateNewAccount()or addNewWorkflowToExistingAccount() | FluentBuilderWorkflow accessed as static object from FluentBuilderWorkflows.addNewWorkflowToExistingAccount also requires the accountID as a String parameter. | FluentBuilderWorkflows provides static references to pre-defined objects for standard Jumio workflows. | CustomerReferenceBuilderStep |
customerInternalReference() | String | String that identifies your organization. | CallbackUrlBuilderStep |
callbackUrl() | String | String representation of the URL to use for the Callback. If you do not need a callback enter null. | CredentialRequestBuilderStep |
withDefaultCredentials()or withSpecificCredentials() | No parameters or List CredentialRequest credentials | withDefaultCredentials() is used for workflows that do not require additional credential configuration.or withSpecificCredentials() is used with services such as DocProof that require explicit credential specifications. A CredentialRequest allows you to configure the credential(s) required by the workflow. See Configuring Specific Credentials. | PerformWeb or PerformWebOrIdWithPreparedData |
performWeb()or performUploadIds() | WebSettings or See Uploading Credentials with the Java Library below. | Use a new WebSettings with no additional configuration to use the defaults configured in the Jumio Portal Settings. Optionally, you can override the successUrl and errorUrl by setting the appropriate values, as shown in the examples below. or See Uploading Credentials with the Java Library. | WebResponse or IdUploadResponse |
JumioClient also has a getAccountAPI() method that returns an AccountAPI object you can use if you require more detailed configuration.
3.4. WebResponse
The WebResponse object provides access to both the configured AccountRequest and the AccountResponse containing the values returned by Jumio. For example, you can extract the web URL and use it to launch the Web Client. See Returning the Jumio Web Client and Account Response.
3.5. Configuring Specific Credentials
Services such as Document Verification require you to specify the document you will be verifying.
See also:
Example: Initiate a Transaction for a New Account
WebResponse webResponse = jumioClient.initiateNewAccount(FluentBuilderWorkflows.STANDALONE_ID_VERIFICATION_10015)
.customerInternalReference("my_company")
.callbackUrl("https://myserver.mycompany.com/callback")
.withSpecificCredentials(
Collections.singletonList(
new CredentialRequest()
.category("ID")
.type(
new CredentialType()
.values(Arrays.asList("DRIVING_LICENSE", "ID_CARD", "PASSPORT"))
)
.country(new CredentialCountry()
.values(
Arrays.asList(
CountryCodeISO3166alpha3.USA,
CountryCodeISO3166alpha3.CAN,
CountryCodeISO3166alpha3.AUT,
CountryCodeISO3166alpha3.GBR
)
)
)
)
)
.performWeb(new WebSettings()
.successUrl("https://jumio.com/success")
.errorUrl("https://jumio.com/failure"));
3.6. Returning the Jumio Web Client
You can launch the Jumio Web Client by extracting the web URL from the AccountResponse.
Example
@GetMapping
ResponseEntity<Void> initiateWebOnlyVerification() {
final UUID reference = UUID.randomUUID();
final WebResponse webResponse = jumioClient.initiateNewAccount(FluentBuilderWorkflows.STANDALONE\_ID\_VERIFICATION\_10015)
.customerInternalReference(reference.toString())
.callbackUrl(CALLBACK\_URL)
.withDefaultCredentials()
.performWeb(new WebSettings()
.successUrl("https://jumio.com/success")
.errorUrl("https://jumio.com/failure"));
final HttpHeaders headers = new HttpHeaders();
final URI location = Optional.ofNullable(webResponse.getAccountResponse())
.map(AccountResponse::getWeb)
.map(AccountResponseWeb::getHref)
.orElseThrow(() -> new IllegalStateException("No URL configured for your account"));
headers.setLocation(location);
return new ResponseEntity<>(headers, HttpStatus.MOVED\_PERMANENTLY);
}
3.7. Uploading Credentials with the Java Library
Depending on the workflow that will be executed you can:
- Use the
performUploadIds()step method to upload credential files from your server. - Use the
performUploadPreparedData()step method to upload raw data values.
Uploading files requires that you obtain user consent. See End-User Consent to Collect Personal Data for additional information.
3.7.1. Example Using performUploadIds()
@GetMapping(path = "/upload", produces = MediaType.TEXT\_HTML\_VALUE)
public String htmlUploadForm() {
return """
<form action="./upload" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Upload ID</legend>
<input type="file" name="file">
<input type="checkbox" name="consent" value="yes" />
<input type="submit"value="Upload and verify">
</fieldset>
</form>
""";
}
@PostMapping("/upload")
public String createAPINewWorkflow(
@RequestParam("file") MultipartFile file,
@RequestParam("consent") String consent) throws IOException {
if (!"yes".equalsIgnoreCase(consent)) {
throw new IllegalStateException("User did not consent!");
}
final UUID reference = UUID.randomUUID();
final OffsetDateTime dateTimeNow = OffsetDateTime.now();
UserConsent userConsent = new UserConsent()
.userIp("46.139.143.174")
.userLocation(new UserLocation()
.country(CountryCodeISO3166alpha3.USA.toString())
.state("IL")
)
.consent(new Consent()
.obtained("yes")
.obtainedAt(dateTimeNow)
);
final IdUploadResponse finish = jumioClient.initiateNewAccount(FluentBuilderWorkflows.STANDALONE\_ID\_VERIFICATION\_10015)
.customerInternalReference(reference.toString())
.callbackUrl(CALLBACK\_URL)
.withDefaultCredentials()
.performUploadIds()
.userConsent(userConsent)
.uploadFront(file.getInputStream())
.skipBackUpload()
.finish();
return "Done with wfid: " + finish.getAccountResponse().getWorkflowExecution().getId();
}
3.7.2. Example Using performUploadPreparedData()
This example assumes you have a simple data transfer class called EndUserForm, with fields corresponding to the required prepared data values.
@PostMapping(value = "/verifyDL", consumes = {MediaType.APPLICATION_JSON_VALUE})
public String verifyDL(@RequestBody EndUserForm endUserForm) {
JumioClient jumioClient = applicationContext.getBean(JumioClient.class);
final PreparedDataResponse response = jumioClient
.initiateNewAccount(FluentBuilderWorkflows.Standalone_DL_Verification_USA_10008)
.customerInternalReference("mycompany")
.callbackUrl(null)
.withDefaultCredentials()
.performUploadPreparedData()
.userConsent(new UserConsent()
.userLocation(new UserLocation()
.country(CountryCodeISO3166alpha3.USA.toString())
.state("CA"))
.userIp("46.139.143.174")
.consent(new Consent()
.obtained("yes")
.obtainedAt(OffsetDateTime.now())))
.addPreparedData(new PreparedData()
.address(new Address()
.city(endUserForm.getAddress().getCity())
.country(endUserForm.getAddress().getCountry())
.line1(endUserForm.getAddress().getLine1())
.line2(endUserForm.getAddress().getLine2())
.subdivision(endUserForm.getAddress().getSubdivision())
.postalCode(endUserForm.getAddress().getPostalCode()))
.firstName(endUserForm.getFirstName())
.lastName(endUserForm.getLastName())
.dateOfBirth(LocalDate.parse(endUserForm.getDob()))
.socialSecurityNumber(endUserForm.getSsn())
.id(new IdDetails()
.idNumber(endUserForm.getIdNumber())
.type("DRIVING_LICENSE")
.issuingDate(LocalDate.of(2019, 12, 26))
.expiryDate(LocalDate.of(2025, 1, 18))))
.finish();
return response.toString();
}
4. Retrieving Transaction Data with the Java Library
JumioClient has two retrieveData() methods for retrieving transaction data.
public WorkflowExecutionResponse retrieveData(CallbackRequestBody callbackRequestBody)Use this method when you are Implementing a Callback Service.public WorkflowExecutionResponse retrieveData(UUID accountId, UUID workflowExecutionId)Use this method to retrieve data using the account ID and workflow execution ID.
Both methods return a WorkflowExecutionResponse object containing the data corresponding to the values returned by calling the Retrieval REST APIs (See Calling Retrieval APIs).
For example, the following snippet accesses the capabilities executed by the transaction and uses a convenience method called extractNonPassedCapabilities to print out the decision details label for any capabilities that have a decision:type value other than "PASSED":
@GetMapping(path = "/{acctId}/{transId}")
String returnReason(@PathVariable String acctId, @PathVariable String transId) {
JumioClient jumioClient = applicationContext.getBean(JumioClient.class);
WorkflowExecutionResponse details = jumioClient.retrieveData(UUID.fromString(acctId), UUID.fromString(transId));
WorkflowExecutionResponseCapabilities capabilities = details.getCapabilities();
return jumioClient.extractNonPassedCapabilities(capabilities);
}
Calling this endpoint with the account ID and workflow execution ID of a transaction for which the imageChecks capability returned a decision:type value of "WARNING" would return a string such as this:
\[imageChecks: WARNING,REPEATED_FACE\]
WorkflowExecutionResponse provides a variety of methods for accessing the transaction decision, credentials, capabilities, rules, and other values for the transaction.
4.1. Implementing a Callback Service
If your integration uses a Callback service you can implement it as shown in the example below.
Example: /jumio-callback Endpoint
package com.acme.demowithsdk;
import com.jumio.sdk.callback.model.CallbackRequestBody;
import com.jumio.sdk.kyx.JumioClient;
import com.jumio.sdk.retrieval_v3.model.WorkflowExecutionResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@RequestMapping("/jumio-callback")
public class JumioCallbackRestController {
private final JumioClient jumioClient;
private static final Logger logger = LoggerFactory.getLogger(JumioCallbackRestController.class);
public JumioCallbackRestController(JumioClient jumioClient) {
this.jumioClient = jumioClient;
}
@PostMapping
public void handleCallback(@RequestBody CallbackRequestBody callbackRequestBody) {
final UUID workflowExecutionId = callbackRequestBody.getWorkflowExecution().getId();
final String workflowExecutionStatus = callbackRequestBody.getWorkflowExecution().getStatus();
if (!"PROCESSED".equalsIgnoreCase(workflowExecutionStatus)) {
logger.warn("Workflow {} has not been processed. Status is {}", workflowExecutionId, workflowExecutionStatus);
return;
}
final WorkflowExecutionResponse workflowExecutionResponse = jumioClient.retrieveData(callbackRequestBody);
if (!"PASSED".equalsIgnoreCase(workflowExecutionResponse.getDecision().getType())) {
logger.warn("ID Scan has been rejected for {}", workflowExecutionId);
return;
}
logger.info("Verification {} successfully processed.", workflowExecutionId);
}
}