Cards service
Reference Documents
Some relevant documents
| Reference | Document Location |
|---|---|
| COP001 | Cards product description |
| COP002 | C4 MVP - Diagrams |
| COP003 | Use Cases - Flows |
| COP004 | Card - Money Movements |
| COP005 | Money Movements Service |
| COP006 | FenX Data Extraction (Phase 2) |
| COP007 | Service-to-Service Authentication |
| COP008 | Authenticating proxy |
| COP009 | Ebury 2.0 Gateways |
| COP010 | Using Benthos for Webhook Gateways |
| COP011 | [PDF Generator Service](https://blueprints.ebury.rocks/components/pdf-generator/pdf-generator-service |
| PCI | Payment Card Industry Standard |
Problem Description
Cards are a helpful payment method for SMEs. Increasingly SMEs have to pay providers that only accept cards (ie., online marketplaces, SaaS services, travel reservations, online ads). Some of those providers are abroad and will invoice in foreign currency. As an Ebury’s SME client, I would like to obtain a card to pay online in foreign currencies. This is the main need that we target to solve in the scope of this MVP.
In addition, clients may need cards for in-situ merchant payments while traveling abroad or when employees are posted temporarily to other countries. Furthermore, there a number of other needs that will be considered and potentially developed as additional follow-ups:
- Need for short-term financing / working capital optimization [could be solved by credit cards]
- Need for a credit card vs a debit card as some travel providers, such as hotels or car rentals, only accept credit
- Expense management solutions
What is needed is the ability for a customer in EBO to create cards (for MVP, only virtual cards), topup/defund to a card, see transactions and create statements, see card details (provider retrieve an url and token, so EBO can display it using an iframe, keeping the service and EBO out of the scope of PCI DSS) to use it in online payments, block/unblock a card (on demand or by background process such as block/unblock a customer in BOS) and cancel a card.
Provider is responsible for make/reject transaction/authorization of purchase by customers. But in case of 3DS authentication, Cards service will handle approve/request from user in EBO, and send response to provider.
Solution
Create a new microservice in charge of connect Ebury to different card providers. Following Ebury 2.0, cards service is a Outbound Gateway responsible for providing the transformation and integration between our platform and systems outside our platform. Those providers will be external and will manage all operations, following PCI standard. E.g. Creation of cards (an any other extra entities), retrieve card details, topup, defund, list transactions/authorizations, update card status, reporting...
General approach
This microservice will have the capability to be able to connect with Ebury and Provider(s) storing the minimum data needed to reproduce the required tasks (eg: customer relationship, reporting transactions...).
Alternative: microservice will store all data required, avoiding making request to External provider as much as possible. This will increase scope of the project, as we need to keep data consistency between different systems. Also, data will be stored in several places, which it is not very optimal and may be needed some process for data reconciliation.
The database will be used to store some parameters to be able to validate some operations characteristics (eg. some limit by country). These characteristics can include some features not available in provider.
Database and microservices, and other possible service running will have UTC timezone.
Microservice API will return to Ebury Online (EBO) success/error message from corresponding system (providers, BOS/BOS Ledger or internal). Successful response from provider will lead to store information in internal card service database, that will be used in future request/validations. Cases like topup/defund that requires a movement of money, will be done through Money movement service. A Kafka event with corresponding contract (TBD) will be publish to a Command to inform of defund/topup in a customer wallet. Money movements service will be in charge of persisting data into BOS. After success/error operation, a specific Reply format (TFD) topic will be send, where cards service will be continuous listening, and reacting correspondingly. Topup/defund/cancel card with balance actions are asynchronous. Kafka message to process and the response, will have to fulfill the Asynchronous Command Interface Pattern, as mentioned in Money Movement, so they will contain any extra information required by the pattern.
There will be logs with the request made to provider, and success/error responses. Connect to error tracking tool, like sentry to enable easier debugging.
Part of communication between BOS and cards service will be through event driven architecture via Kafka topics and messages. Other kind of communication will be via REST API. Card service will have a small consumer connected to a topic to read events (when an Ebury customer updates some data, such status, mobile number, address...), process, and then, make a request to corresponding API. Consumer will only prepare the request and send to API, as main logic will be inside API. Some of the endpoints available may be only needed internally by the consumer. Consumer won't be connected directly to provider or database. All communication in consumer will be through API. Similar use cases can be requested via API directly from BOS, EBO or other system instead of Kafka. Card service will process the request and connect to provider in real time. Different scenarios such change of name, when we may need to issue new card are out of MVP.
Permissions access to the card operations available for a certain client/contact in EBO will be manage inside BOS. No modification of current implementation, only at the time of delivering to the different environments, users must have corresponding permissions to access to the cards service from EBO (authorization stays in BOS). Also, from EBO admin area, there is a switch to enable/disable completely cards service.
Connection between EBO and cards service must have authentication, according to the security practices in COP007. Taking into account a service Mesh is not available, implementation of (Simple Authenticating Proxy for Zero Trust East-west Service-to-Service Authentication](https://blueprints.ebury.rocks/components/security/authenticating-proxy/) to enable authentication. It contains following security points: - Only proxies recognised requests - Authenticates all recognised requests - Authorises all recognised requests - Supports key rotation via namespaced user IDs - Passwords hashed with bcrypt
Regarding internal authorization, card service will validate the client/contact included in request headers. If is the corresponding owner of the card in the request, else it will raise a authorization error.
Card service is responsible for assigning providers to customers. This assignation will happens once, during card creation. Provider type will be stored in database, aside other details of the relationship between Ebury customer id and provider ids. This provider type will be use on future request to provider. For MVP, as only one provider will be available, no extra logic will be implemented (all customers will have same provider). When more providers are included, assignation from customer to providers needs to be review with the requirements.
Communication from providers towards Ebury, whenever is needed to send update notifications on different entities within provider system, will be through outgoing webhook endpoints. Entry point for webhooks will be in a Inbound Gateway including authentication to transform requests to Kafka messages meeting requirements in webhook pattern. Inbound Gateway can use a stream processing to transform HTTP requests for each provider into a generic event and schema (per each action), so Cards service could handle all these events no matter which provider generated them. Kong will handle authentication, while inbound gateway is in charge of the data format mapping from the external providers webhook into the generic Kafka event/schema, before publishing. Benthos can support data transformation towards Kafka. Benthos is a powerful tool to map request payload to the agreed ACL Cards service Kafka topics. It could contain complex rules, hard to maintain/configure manually, but we don't expect ACL to change often from provider side.
In case webhooks is not available from provider side, similar architecture should be in place, to avoid Card service to handle communication with different provides in several ways). Generic events/schema must be published to a specific topic, where Cards service will handle Command no matter how provider communicate with us.
Topup/defund transactions will be reflected in BOS ledger for data reconciliation with providers. Quantum treasure service, will also need to reflect these operations, reusing existing process.
For audit purposes, all actions made by user will be stored in logs. These logs will be stored and rotate according with the regulation specs, and periodically move to other location. AWS S3 will be the storage service candidate.


Monitoring
Card service API will provide an endpoint to offer monitoring metrics. Following use cases will be covered and the metrics and dashboards are still needed to be define.
Regarding data dashboard, we can have different approaches:
-
Data to display in data dashboard with metrics is send to Ebury at the end of every day in a datawarehouse file, sending all relevant changes inside provider (data from day - 1). Data team will receive this file, process and storing internally relevant information. Metrics won't be in real time.
-
Card service send data via events/queue/topic to notify Data dashboard with relevant information about customers, cards, accounts... Data team will process and store internally relevant information. Metrics will be in real time.
-
Card service calculates and stores metrics in card service database, and offer on demand via API (http request). Every new metric will need a development. Depending on the complexity of the metric, it will be real time or not.
Entities and relationships
- Customer (Provider): corporate | private - The actual users which are going to interact with the service.
- Account: Where the funds and balance are reflected.
- Card: main | supplementary - The actual card which user are going to operate.

For the MVP two approaches are taken in account:
Approach 1
One corporate customer holds multiple accounts and each account can only be linked with one card that belongs only to one user.

Approach 2
One corporate customer holds multiple accounts and each account can be linked to multiple cards and each card to only one user but a shared account.

Use Cases

Create new card
A customer and an account are needed in card provider system in order to perform the card creation.
To be more specific, a corporate customer must exists or be created. Then, for creating an account it must belong to that corporate customer.
To create the cards, the final customer (corporate or private) will create the card associated to the account previously created.
Corporate and private customers are representation of BOS Client and Contact entities (respectively). Data must be previously sync to cards service via CDC Events. Corresponding views inside cards service contains any information that must be provided (name, phone number, email, address...) for customer creation in provider.
A template is requiter to create an account in provider. That template needs to be configurable by environment and by region. Each template will have associated a main currency, also configurable. If there is no configuration for the provided template, or that configuration can not be loaded, the Card Creation should return an error.

Topup card
Add funds to the card in provider. This process is asynchronous, as it requires integration with Money Movement to withdraw amount from Ebury customer wallet by BOS before sending topup to provider. New pending transaction stored in cards-service, link to a Stack/Tasks related to topup operations. Response with unique transaction id is return, and stack executed. Using Listen-to-yourself pattern, where a consumer is listening to an internal topic, to orchestrate stacks and tasks.
First step will be handled by Money Movements service, where cards service will send a message via Kafka Command. A consumer in cards service is listening for Reply in the Kafka topic, waiting for successful/failure response from Money Movement. If Reply is successful, next step is requesting card topup to provider (with retry mechanism).
This request should be split in different atomic transactions:
- Claim debit to BOS (Wallet) through Money Movement. BOS ledger must be able to register 2 different actions, debit a client and credit provider.
- Listening for Reply for previous request. If success, request to provider to perform topup transaction.
Take in account that if any of the previous operations fails, we should revert it to the previous status. A rollback action will be implemented.

Retrieve card details
In this intended to retrieve card details url for payments. To follow PCI standard, for this request provider returns a url (in his domain) and a security token. With that information, EBO can create a call inside an iframe to display card details to customer such as card number (PAN), Expire date and CVV code.
Important to remind that card service is not going to store any data related to cards, neither retrieve directly from provider.

Retrieve card transactions/authorizations
List of all transaction/authorizations performed by this card.
Customer can check his/her transactions/authorizations on each card, and also request a PDF statement/receipt on demand for transactions. Logic regarding filtering/parsing transaction data to generate PDF belongs to Cards service, while PDF generation will be handled separated by PDF Generator Service (COP011).
Alternative: BOS to handle PDF generation. BOS already manages several endpoints for PDF generation, as it has all the PDF convert libraries required installed already and their proper configuration set up in place. Also, BOS includes Ebury corporate PDF template style and content, in addition to user locale. It is a very small development required, just create a new endpoint to handle the request, and a new html template. It is a minor effort, with no heavy impact/risk on BOS, as no current flow is impacted by this change.
Transaction/authorization will be stored locally in cards DB, so when a customer request to see his/her transactions, there is no need to call provider. As part of provider implementation, they provide a webhook, that send notification when entity changes. A new Inbound Gateway will capture the notification request from provider, and transform the request to a Kafka message in the ACL agreed. Cards will constantly listening for events, and reacting to them. At this stage, transaction details will be stored in DB card. In case not all transaction information is present via webhook, cards service will connect with provider with transaction id to get extra information. For successful transactions, cards will send a notification via email. Email address is fetched from BOS, and email notification pushed to MQ for later procedure by internal email service.
This flow with webhook can help us for data reconciliation for topup/defunds, in case of provider timeout request.
Get Transactions By CardId

Get Transactions Details

Block/Unblock card
Change card status in provider. It can be trigger on demand by customer, in case he/she wants to change the status of any of the cards. Also, it can be requested by ops team on demand. Finally, card status can also change in reaction to events, such as Ebury customer has been block/unblock. In that scenario, card service will be subscribed to corresponding Kafka topic, and react to events, calling to API to block/unblock cards belonging to customer in provider.
Alternative: change of customer status by CDC topic.
Blocking a card involves that no transactions can be done with that card. Unblocking a card will return the card to a normal operation status. A customer can unblock a blocked card only if he/she make the request to block it. If a card is blocked by someone else, like ops/fraud team, only ops team will have the possibility to unblock it.
While card is blocked no transactions will be allowed:
- no purchases
- no top ups
- no defunds


Withdraw/Defund card
This is intended to withdraw an available amount from the card. This process is asynchronous, as it requires integration with Money Movement to add amount to Ebury customer wallet by BOS after defund is made in provider. New pending transaction stored in cards-service, link to a Stack/Tasks related to topup operations. Response with unique transaction id is return, and stack executed. Using Listen-to-yourself pattern, where a consumer is listening to an internal topic, to orchestrate stacks and tasks.
First step is to deduct amount first from provider. On success operation, then, add same amount to Ebury customer wallet by BOS (orchestration on adding debit/credit to BOS Ledger by Money Movement). Cards service will send a message via Kafka Command. A consumer in cards service is listening for Reply in the Kafka topic, waiting for successful/failure response from Money Movement. If Reply is successful, next step is requesting card topup to provider (with retry mechanism).
This request should be split in different atomic transactions:
- Request to provider to perform defund transaction.
- Send increase amount to BOS (Wallet) through Money Movement Service. BOS ledger must be able to register 2 different actions, credit the client and debit provider.
Take in account that if any of the previous operations fails, we should revert it to the previous status. A rollback action will be implemented.

Cancel card
This is intended update card status to cancel, and to defund full amount of the card (if any), adding those funds to Ebury wallet.
Endpoint is always synchronous, no matter the scenario on the cancel request.
- As first step, cards service will update card status to cancel in provider.
- Then, another request to check balance of card/account in provider.
- If balance in provider is 0, return 204 response.
- If balance in provider is greater than 0, then defund total amount action is triggered as described in previous UC. When defund action is accepted/rejected, and before async process start, ok/ko response returned
Take in account that if any of the previous operations fails, we should revert it to the previous status. A rollback action will be implemented.

3DS authentication
3-D Secure is a protocol designed to be an additional security layer for online credit and debit card transactions. For transactions made at any merchant's website, it is required for that merchant to go through their Payment Service Provider/bank and request corresponding 3DS flow to the card issuer (Enfuce).
3DS flow starts by the merchant/PSP forwarding a request to the cards issuer. They perform a risk-based assessment to determine the risk score of the transaction. If risk is consider low, the transaction is automatically approved. But if is consider as high risk, the authorization should comply with Strong Customer Authentication (SCA) to reduce fraud in online operations. SCA requires authentication to use at least two of the following three elements:
- Something the customer KNOWS (e.g., password, pin)
- Something the customer HAS (e.g., phone, hardware token)
- Something the customer IS (e.g., fingerprint or face recognition)
Once a transaction is considered high risk, a pop up will be displayed for the user while doing the online purchase, with a redirect link to EBO log in page, or asking to log in to EBO. When a client is logged in EBO (with user and password that only the client knows), first SCA requirement is met.
In EBO, user will see a screen with the transaction pending, waiting to be verified. To approve a transaction, a verification code is required. An SMS is send to the clients's phone number (something the customer HAS) with the verification code to introduce in the same screen, meeting second SCA requirement. Sending the SMS and verifying the SMS code is EBO's responsibility, reusing as much as possible existing functionality (verify service).
Cards service will handle pending 3DS authentication request, receiving them from Enfuce via webhook and storing internally. Cards service provides the functionality to get authentication pending and approving/rejecting a particular pending authentication. Once a transaction is verified/rejected, Cards service is also responsible for sending back the result of the authentication (approved/rejected) to Enfuce. Also, for automatically rejecting requests if authentication already expired. Enfuce must send an ack on last stage from their side. Anything aside from ack, is consider an error (timeout, bad request...) and an alert must be raised and investigated further.

Caveats
Cards service connect to external provider to handle card data on their side to accomplish PCI. Connectivity to 3pp may impact the regular functionality of the service for those request towards it.
Cards service relies on connection to PostgreSQL database and Kafka server for its proper behavior.
Operation
The microservice will expose a REST API that will be able to communicate with providers. Also it'll notify interested Ebury services via Kafka.
Security Impact
Private service deployed in private network. No communication from public network will be allowed to the microservices, blocked in upper layer. Only exception allowed by upper layer is if provider needs to connect to card service via webhook. Any request from public network wont be directly to card service, but to the upper layer that will filter requests.
Card service is out of the scope of PCI, as no data related to card details (card number, CVV, expiry date...) will be stored/requested.
Performance Impact
Performance of this card service relates on 3rd party (external providers). If provider has low performance, it is going to impact card service.
A potential performance impact and should be review is calculating the current client balance on the ledger.
Developer Impact
EBO team needs to call card service with corresponding format. OpenAPI will be available to serve as reference to developers to query doubts.
No BOS API development needed as initial requirements.
For topup/defund, BOS Ledger and Quantum Treasury will reuse existing process.
Note that some development might be needed to accomplish tasks as block/unblock cards. BOS may need to publish topic events so card service can react.
Data Contracts
Cards is a completely new service, so new contracts will be implemented for the service, both API and Kafka.
Regarding API: - EBO is going to consume cards data, there is the need to develop a new client on EBO to connect with cards service.
Regarding Kafka: - No changes on events published on DB changes, clients table. - Meeting contracts regarding Money Movements (Command/Reply). - New Kafka messages will be published from Inbound Gateway to topic. Generic Contract transformation to kafka message, but no validation of data by stream processing. Main logic belongs to cards service.
Deployment
Under AWS k8s with three environments. Deployments with k8s:
DEV: DXP cluster. local environment for developers.STAGING: Integration with providers in staging.PROD: Live integration with real customers.
Following workflow for new service as described in developer handbook