API Bridge Continued ~ Bringing the Bridge to Life...
Welcome to the second blog in our mini-series, featuring Judopay’s API Bridge.
Recapping from the first blog, we examined the circumstances behind Judopay’s decision to create an API Bridge. This was our solution to make the migration process for merchants from their current API, to Judopay’s Transaction API, as straightforward and seamless as possible.
Philip will now take you on the journey Judopay’s Engineering Team took, to bring this solution to life.
The core task of the API Bridge - translation - turned out to be fairly simple. There were however, several obstacles along the way. I will briefly describe the core task of the API Bridge, before diving into the additional complexities we had to overcome.
The core task of the API Bridge.
The payments industry is fairly standardised. There are a lot of services that overlap between PSPs, and the sort of information one PSP requires for a payment request, will tend to be the sort of information another PSP requires for the same type of request.
For the API Bridge, this meant the request / response translation was mainly a question of field-to-field mapping:
The API Bridge could read in the raw XML request and start the translation task with an empty {} JSON object, building up the converted request by reading through the XML and adding any translated fields to the JSON.
On the return journey, the API Bridge would begin with an empty <Reponse></Response> XML, adding in the response tags, reading in values from Judopay’s JSON response.
However, there were complications to all of this.
What if the sender:
Submitted < amount currency="GBP">twenty five</amount>?
Our API expects amount to be expressed using digits; it won’t accept "amount": "twenty five".
Also, what if the sender:
Is attempting to refund a transaction, but mistypes the transaction's ID?
When Judopay’s API responds with a "not found" error, we will also need to translate this to some XML that the sender will understand.
So making our translation logic robust added extra complexity to the core task. I will consider some of these complexities in the next section.
Complexities to overcome.
Firstly, I will examine the sorts of validations the API Bridge is required to perform against incoming XML.
Secondly, I will consider a case where the API Bridge needs to perform some orchestration, in order to support a particular type of request.
Thirdly, I will look at the issue of interlinked requests, where requests in the API are expected to be executed in a particular sequence.
And finally, I consider the error-handling and translation of the error messages.
Validation.
As I mentioned above, there is a danger that merchants may send a badly-formed request. It is key the API Bridge performs validations against incoming XML.
For example, maybe one of the fields has an invalid value, or maybe there's a mandatory field missing.
As a result, we needed to insert a validation step before the translation step, just after the XML request has been read-in.
If the request fails validation:
The API Bridge prepares an XML error response to send back to the merchant, outlining what went wrong. As much as possible, we tried to get the API Bridge to mimic the error XML that the current API would return in this case, right down to the error codes and error messages.
If the request passes validation:
The translation can continue. Because obvious request errors have been weeded out, the API Bridge's code can handle translation failures by dropping the involved field entirely. This sounds clumsy, but the preceding validation means these translation errors don't happen in practice.
Orchestration.
As stated above, most requests could be mapped to Judopay’s requests on a one-to-one basis. However, there were situations where this wasn’t the case.
For example, in case the above change is accepted, Judopay lets merchants take card payments by either providing:
- The consumer’s card details, or
- A card token (that represents a card whose encrypted details have been saved in our systems).
The current API we were mimicking, offered an additional method:
Judopay had nothing like this, so in order to honour these payment requests, meant introducing some basic business logic into the API Bridge. The problem was solvable, but it did require an orchestration capability to be added into the API Bridge.
Request flows.
Another complexity was with 3D Secure.
A 3D Secure-backed transaction is not only more likely to be approved, but also means the merchant is not liable for any chargebacks.
However, 3D Secure requires a number of steps.
The current API we were mimicking followed the same flow as ours, except they included an extra call at the beginning with an enquiry about enrolment:
Judopay however, bundles this as part of Step 1. We do not expose the enrolment check to the merchant as a separate call. When the merchant submits a payment request, we first check the card’s enrolment in 3D Secure. If the card is enrolled, then we begin a 3D Secure session.
As things stand, we were in luck. The current API flow I outlined was actually for version 2 of 3D Secure, and all their consumers had not yet moved from version 1.
This provided us with the freedom to redesign the current API’s 3D Secure (version 2) flow to match our own. While it may have been tempting to match the old flow, this would have meant (in our view), compromising the quality of the 3D Secure workflow.
Error-handling.
The last complexity we faced was:
I have already mentioned having to return errors if validations failed, or if the orchestration couldn’t find the previous transaction. But what about other errors?
These errors can only be detected once the request has been passed to Judopay’s API. Going further, what if our systems don’t respond in a timely manner?
“Coping” in this case means converting the Judopay error to an appropriate XML error.
The issue here is that Judopay has its own error codes and error messages, unfortunately bearing no relation to the current API’s error codes or error messages.
How is the translation to be done?
In the end, we decided to draw up a list of Judopay error codes that we thought users of the API Bridge could possibly trigger. For instance, if you tried to capture a sale via Judopay’s API, you would receive a response like:
The API Bridge would pick up code 43 and look up the associated error code and messages for the current API:
It's not an elegant solution, but it served as a useful backstop.