Integration Guide
Step-by-step guide to integrate Berbix into your application.
Introduction
With this integration guide, we’ve made it as easy as possible to quickly get up and running with an end-to-end embedded Berbix integration. Please see our Hosted Flow if you're only looking to create unique links to share with your customers.
In this guide, you will:
- Create Test Transactions
- Initialize the Berbix Verify Flow
- Fetch Transaction Data
- Customize Berbix
- Move to Production
We recommend reading our Platform Overview for a look at key terms, concepts and a diagram of an end-to-end integration. Additionally, a sample open-source Ruby integration is available for review on our GitHub.
Create Test Transactions
To begin, you'll integrate the Berbix Verify API into your backend to start creating test transactions
.
The Berbix Verify API can be called from any basic HTTP client. Berbix provides several Server-Side SDKs to simplify interactions with the API:
Constructing the Berbix Client
Before creating a transaction, you'll first need to construct the Berbix API client.
If you're using one of our Client-Side SDKs, you can initialize the Berbix client by following the example code below for your selected SDK. You'll need to include your test API Secret
.
var berbix = require('berbix');
var client = new berbix.Client({
apiSecret: '<<user>>',
})
require_once('/path/to/berbix-php/init.php');
$client = new \Berbix\Client(
"<<user>>");
import berbix
client = berbix.Client(
api_secret='<<user>>')
require 'berbix'
client = Berbix::Client.new(
api_secret: '<<user>>',
)
BerbixClient berbixClient = Berbix.create(
new Berbix.BerbixOptions.Builder()
.apiSecret("<<user>>")
.build());
import "github.com/berbix/berbix-go"
client := NewClient("<<user>>", &ClientOptions{})
Where do I find my API Secret?
- Log in to the Berbix dashboard
- Make sure Test Mode is toggled ON*
- Select
Integrations
in the nav menu- Tap
Add Key
or copy the existing keyMore information about API Keys can be reviewed here.
*Please use the
Test
API secret when integrating Berbix in a non-production environment.
Creating a Transaction
To create a transaction, you just need to send a customerUid
and templateKey
along in the API request.
The customerUid
should map to the primary identifier for the user in your internal systems, and the templateKey
should map to the Berbix template you want to use to verify your user.
You will have a Default
template for web integrations configured for a front & back ID check in your account by default. Please create a new template for native mobile integrations.
var transactionTokens = client.createTransaction({
customerUid: "internal_customer_uid", // ID for the user in internal database
templateKey: "<<template_key>>", // Template key for this transaction
})
$transactionTokens = $client->createTransaction(array(
'customerUid' => "internal_customer_uid", // ID for the user in internal database
'templateKey' => "<<template_key>>", // Template key for this transaction
));
transaction_tokens = client.create_transaction(
customer_uid="internal_customer_uid", # ID for the user in internal database
template_key="<<template_key>>", # Template key for this transaction
)
transaction_tokens = client.create_transaction(
customer_uid: 'internal_customer_uid', # ID for the user in client database
template_key: '<<template_key>>', # Template key for this transaction
)
CreateTransactionRequest request = new CreateTransactionRequest();
request.customerUid = "internal_customer_uid"; // ID for the user in internal database
request.templateKey = "<<template_key>>"; // Template key for this transaction
CreateTransactionResponse response = berbixClient.createTransaction(request);
tokens, err := client.CreateTransaction(&CreateTransactionOptions{
CustomerUID: "internal_customer_uid", // ID for the user in client database
TemplateKey: "<<template_key>>", // Template key for this transaction,
})
An access_token
, client_token
, and refresh_token
will be returned in the response as shown in the example below.
Please refer to the Create transaction reference documentation for a full request and response format specification.
{
"transaction_id":5689410907470336
"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1dsfsWQiOjU2NzYwNDE5MDc0NzAzMzYsImNpZCI6NTYzNDQ3MjU2OTQ3MDk3Niw"
"refresh_token":"x9iBVHQUVqx9sHGjRyTAEBOdsD23Wxld"
"expires_in":3600
"token_type":"Bearer"
"client_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ8dsdfsaWQiOjU2NzYwNDE5MDc0NzAzMzYsImNpZCI6NTYzNDQ3MjU2OTQ3MDk3Niw"
}
Tokens
Interacting with the Berbix API involves 3 types of tokens:
client token
- Needs to be passed to your front end to initialize the verification flow for your end-user
- Expires after 1 hour
access token
- Will be used to fetch transaction metadata once your end-user completes the verification flow
- Expires after 1 hour
refresh token
- Can be used to fetch a new
client_token
to resume an incomplete transaction. - Can be used to regenerate an
access_token
in the future for fetching, updating or deleting transaction data - Does not expire until the transaction is deleted manually in the dashboard, programmatically via the API, or automatically via retention policy
Refresh Token Best Practice
Always store the
refresh_token
in your application database associated with the respectivecustomerUid
.
Reusing transactions
Keep in Mind!
Every time the
create_transaction
endpoint is called, a new transaction is created.This is the case even if the endpoint is called with the same
customer_uid
, since we allow for multiple transactions for a givencustomer_uid
.
We recommend including a server-side check when creating a transaction to see if an incomplete transaction exists for a given user before calling create_transaction
.
If an incomplete transaction already exists, you should use its refresh_token
to create a new client_token
in order to re-start the incomplete transaction.
This allows the end-user to pick up where they left off in the initial transaction rather than starting over. Additionally, this keeps your Berbix dashboard clear of excess incomplete transactions, making it easier to review results and investigate issues.
Remember!
Keep track of the
refresh_token
for each transaction you create.
If you're planning to allow users to retry verifying with Berbix after completing an initial transaction, keep track of the refresh_token
of both the initial and subsequent transactions to maintain a one-to-many relationship between users and Berbix transactions.
This maximizes the amount of data you'll have available for debugging your integration and potentially investigating fraud on your platform.
Exception!
In order to successfully reuse transactions, subsequent transactions must be on the same platform as the initial.
Ex: If the initial transaction used a
Web
template type, the transaction cannot be reused for a subsequent transaction with aNative Mobile
template type.
Creating hosted transactions
In order to create a hosted transaction, you'll need to include the hosted_options
parameter in your Create transaction request. This parameter can be an empty object (hosted_options={}
) if you don't require additional configuration.
When provided, Berbix will return a hosted verification link that is unique to each transaction in the hosted_url
response field.
Initialize the Berbix Verify Flow
There are several ways you can integrate the Berbix identity verification flow into your application.
In addition to Basic JavaScript, Berbix provides the following Client-Side SDKs across web and mobile:
Basic JavaScript
When your page loads, you should create a handler via BerbixVerify.configure()
. The verification flow can then be initialized by calling open()
on the handler in response to any user events. The simple example below initializes the Berbix flow when a user clicks the Verify Me
button.
Upon completion of the verification flow, Berbix will trigger the onComplete
callback that can be used to advance the user through your application. Berbix will invoke the onError
callback if the verification fails for any reason and the onExit
when someone closes the Berbix modal.
<button id="myButton">Verify Me</button>
<script src="https://sdk.berbix.com/latest/berbix-verify.js"></script>
<script>
var handler = BerbixVerify.configure({
onComplete: function() {
},
onExit: function() {
}
});
document.getElementById('myButton').addEventListener('click', function(e) {
handler.open({
clientToken: 'your_client_token',
modal: 'true'
});
});
</script>
Configuration
Required
clientToken
: A token returned after creating a transaction that connects your frontend with the associated transaction metadata. This allows a user to perform incremental verification in addition to any previously completed verifications. A client token can be regenerated using Create access token if necessary.modal
: This value should be set totrue
unless you intend to use Berbix in an embedded element on the page rather than a modal invoked after button click. To use Berbix in an embedded element on the page, use theroot
attribute to specify the ID of the rootdiv
in which Berbix should be embedded.
Modals are your friend!
We recommend using the
modal
option for most web integrations. The Berbix Verify Flow will generally perform best when it can use the entirety of the vertical space available on the screen, especially on mobile browsers and smaller screens.By using the
modal
option, you avoid having to worry about the way the design of your website might interfere with the rendering of the Berbix Verify Flow on various devices.
onComplete
: The callback invoked when Berbix Verify completes.onExit
: The callback invoked when a user exits or closes the Berbix Verify modal. Required when using the modal experience.
Optional
onDisplay
: The callback invoked when Berbix Verify is visible to the user. This is useful for removing loading states or hiding other elements.onError
: The callback invoked when verification fails. It is passed any reason for failure as a parameter.showCloseModalButton
(bool): Whether or not there should be a close button on the Berbix Verify modal.
Allowlist domains serving Berbix
You'll need to add the domains from which you expect to serve Berbix Verify when initializing the frontend flow. Please see our domains documentation for instructions.
Avoid re-instantiating the Berbix Verify Flow after a transaction has been completed
As a general rule, you should avoid re-instantiating the Berbix Verify Flow after a transaction has been completed. Instead, you should keep track of whether transactions are completed or not in your database, and only instantiate the Berbix Verify Flow if a transaction has not been completed yet.
If you rely on the
onComplete
callback in order to determine whether a transaction has been completed, you risk significant latency due to loading the Berbix Verify Flow and passing the requisite data from your client to your backend. Moreover, doing so puts unnecessary load on Berbix's infrastructure.See Fetch Transaction Data and Receive Actions via Webhooks below for more information on how to access a transaction's result post-completion.
Fetch Transaction Data
Once a verification completes, you'll need to consume the metadata about a transaction to determine next steps for your end-users.
Create Access Token from Refresh Token
To fetch metadata for a given transaction, you first need an access_token
for the associated transaction. A short-lived access_token
is returned in the transaction creation response but you'll often need to regenerate the access_token
for later requests.
If you're using one of our Server-Side SDKs, you can utilize the example code below for your selected SDK. You'll need to load the transaction's refresh_token
from your application database.
refreshToken = ''; // fetched from database
// Load refresh token from database into a Token object
const transactionTokens = berbix.Tokens.fromRefresh(refreshToken);
// Call Berbix API to exchange refreshToken for fresh tokens.
// This is typically not needed to be called explicitly as it will be called
// by the higher-level SDK methods, but can be used to get fresh client or
// access tokens.
const refreshedTokens = client.refreshTokens(transactionTokens);
$refreshToken = ''; // fetched from database
// Load refresh token from database into a Token object
$transactionTokens = new \Berbix\Tokens::fromRefresh($refreshToken);
// Call Berbix API to exchange refreshToken for fresh tokens.
// This is typically not needed to be called explicitly as it will be called
// by the higher-level SDK methods, but can be used to get fresh client or
// access tokens.
$refreshedTokens = $client->refreshTokens($transactionTokens)
refresh_token = '' # fetched from database
# Load refresh token from database into a Token object
transaction_tokens = Tokens.from_refresh(refresh_token)
# Call Berbix API to exchange refreshToken for fresh tokens.
# This is typically not needed to be called explicitly as it will be called
# by the higher-level SDK methods, but can be used to get fresh client or
# access tokens.
refreshed_tokens = client.refresh_tokens(transaction_tokens)
refresh_token = '' # fetched from database
# Load refresh token from database into a Token object
transaction_tokens = Berbix::Tokens.from_refresh(refresh_token)
# Call Berbix API to exchange refreshToken for fresh tokens.
# This is typically not needed to be called explicitly as it will be called
# by the higher-level SDK methods, but can be used to get fresh client or
# access tokens.
refreshed_tokens = client.refresh_tokens(transaction_tokens)
refreshToken := "" // fetched from database
// Load refresh token from database into a Token object
transactionTokens := TokensFromRefresh(refreshToken)
// Call Berbix API to exchange refreshToken for fresh tokens.
// This is typically not needed to be called explicitly as it will be called
// by the higher-level SDK methods, but can be used to get fresh client or
// access tokens.
refreshedTokens, err := client.RefreshTokens(transactionTokens)
If you're not using one of our Server-Side SDKs, you'll need to make a request including the refresh_token
to the /tokens
endpoint and the associated access_token
will be included in the response.
Complete documentation for the Berbix /token
endpoint is available in our API reference.
Fetch Transaction Data
After generating the access_token
, you'll then pass this to the /transactions
endpoint to get all associated transaction data.
If you're using one of our API Libraries, you can reference the code samples below. Otherwise, please refer to our Get transaction verifications API spec.
var transactionData = await client.fetchTransaction(transactionTokens)
$transactionData = $client->fetchTransaction($transactionTokens);
transaction_data = client.fetch_transaction(transaction_tokens)
transaction_data = client.fetch_transaction(transaction_tokens)
transactionData, err := client.FetchTransaction(transactionTokens)
All data for the given transaction will be returned in the response as shown in the example below. A complete list of properties returned is defined in our API Reference.
{
"action": "reject",
"addons": null,
"created_at": "2019-07-02T21:18:43Z",
"customer_uid": "123456789",
"dashboard_url": "https://dashboardberbix.com/transaction?orgId=123456789&transactionId=123456789123",
"duplicates": [...],
"flags": [...],
"fields": [...],
"images": {...}
}
Most importantly, you'll want to consume the action
value (accept
, reject
, review
, or a custom action) to determine next steps for your verified end-user.
Avoid strict enums that cause fatal errors
From time to time, Berbix might incorporate new values in its API responses, typically to enable access to new features. For example, we might introduce new options for
flags
, or additionalfields
.Unlike removals of existing values, we consider these changes to be non-breaking and typically do not version our API when we make them.
As a result, we strongly suggest that you build your integration in a way that is robust to such changes. In particular, you should avoid strict enums that would result in a fatal error being thrown in the presence of a novel value. Instead, you should make sure to handle the error in a way that ensure that you can "fail open" in the event that new values are introduced in Berbix's API response.
We recommend relying on the action
value for your business logic based on a customized Action Map. You may also retrieve and reference the raw flags (id_fake_likely
, id_under_18
, etc.) or the fields data (address
, date_of_birth
, cropped_front_url
, etc.) returned from the transaction.
Receive Actions via Webhooks
Alternatively, you may receive the transaction ID and the determined action via a webhook when verification is complete. Please see our webhook docs to implement.
Do not poll the Berbix API
You might be tempted to design your integration such that it would "poll" the Berbix API while waiting for a transaction's completion by querying the Berbix API at regular interval. Because of the drain it can put on Berbix's infrastructure, that style of integration is not supported by Berbix, and might cause our automated abuse prevention systems to interfere with your ability to access transactions.
Rather than polling, please either wait for the
onComplete
callback to be triggered client-side before querying our API, or use a server-side webhook.Naturally, you should feel free to design your system such that it retries any failed API requests (e.g. in the event that you encounter network connectivity issues, or in the rare event that Berbix is not reachable). If you decide to do so, we strongly recommend the use of exponential backoff in your implementation of your retry logic.
Updating transactions
If your desired workflow involves reviewing completed transactions internally, you may want to send the updated action
back to Berbix.
This can be accomplished using our API with the Update an existing transaction endpoint.
Deleting transactions
Our API provides an endpoint for programmatically deleting transactions. Our API libraries also include helpers for calling that endpoint.
The ability to programmatically delete transactions is provided primarily as a means to deal with certain testing and compliance edge cases (e.g. to comply with a request from one of your users to delete all of their data from all of your systems). We generally do not recommend deleting transactions in the normal course of usage of Berbix.
Deleting transactions shortly after their completion could additionally limit your ability to diagnose issues with your integrations, and Berbix's own ability to provide you with support. In general, if you're hoping to delete transactions in a regular fashion, we recommend that you rely on our automated retention policies, which can be set to be as short as 7 days.
Allowing users to re-verify with Berbix
If you're thinking of deleting transactions as a means to enable your users to retry verifying their ID after having failed, you might consider storing the reference to the most recent Berbix transaction in a one-to-one relationship with your representation of your users.
Rather than doing that, we suggest you instead consider enabling a one-to-many relationship between the representation of your users in your database and that of Berbix transactions. Indeed, by enabling a one-to-many relationship between users and Berbix transactions, you maximize the amount of data you'll have available for not only debugging your integration, but also potentially investigating fraud on your platform.
Customize Berbix
You've now built a fully functional end-to-end Berbix integration! Before moving to production, you'll want to customize the required verification steps, the look-and-feel, and the business logic behind your integration.
Custom Template
Templates control the experience for your end-users and enable you to specify differing levels of verification required for different user account types. Templates include the types of verification you'd like to conduct (photo ID, selfie, etc.) and settings for the verification flow (number of attempts, timeouts, etc.). At a minimum, you should decide what types of IDs are allowed as well as if you need to require a selfie image and liveness check.
Custom Theme
You optionally may want to create a custom theme associated with your template(s). Themes configure the look-and-feel of your verification flow. Theme customization is currently only supported for web templates.
Action Map
Action maps allow you to customize the business logic associated with Berbix transactions. By default, Berbix provides three actions: reject
, review
, and accept
. Review Queues are populated by review
actions. If appropriate for your use case, custom actions can be added.
The determined action after a verification will be returned in the transaction metadata and exposed in the Berbix Dashboard for a given transaction.
Move to Production
At this point, you'll be able to test a fully customized Berbix flow in your own application. Please refer to our Testing Guide for instructions on how to best test Berbix end-to-end. Assuming all goes well, you can move your integration to production by simply replacing your Test
API Secret with a corresponding Live
value.
You'll need to accept our terms and subscribe to Berbix before gaining access to live mode. Please don't hesitate to contact us if you have any questions!
© Berbix Inc. All rights reserved.
Updated 7 months ago