The aim of this guide is to help you map card and transaction data using the Business API to aid reconciliation.
Use cases
- You have a card transaction and need to map it to the card it was made with
- You have a transaction and need to map it to the original transaction that it relates to, for example:
- For a refund transaction, the transaction that was refunded
- For a cashback transaction, the transaction for which the cashback was earned
Card and Transaction data
When you have a card transaction, you might typically want to know the following:
| Transaction | Card |
|---|---|
| - The state of the transaction: if it's pending, completed, rejected, etc. - The type of the transaction: transfer, card payment, refund, card chargeback, etc. - The related transaction: the original transaction that this transaction relates to - The card: which card was used for the transaction - Other transaction details: for example, reason code, when the transaction was created, updated, and completed, information about the merchant associated with the card transaction, transaction reference, the balance of the account associated with the transaction, the amount, currency and fees, the name and phone number of the card holder For the full list of available properties, see: API reference: Retrieve a transaction | - The state of the card: if it's created, pending, active, frozen or locked - The label of the card: the name given to the card, displayed in the app and printed on the card above the business name - Card PAN (sensitive detail): The Primary Account Number for the card, usually referred to as card number - Other card details: for example, the spending limits, the spend program*, the card product*, the expiry date, whether the card is virtual or physical, the accounts linked to the card, the categories available for spending, the ID of the card holder, and when the card was created and updated *These properties are not available by default. If you would like to use them, please contact our API Support team. For the full list of available properties, see: API reference: Retrieve card details API reference: Retrieve sensitive card details |
The properties in the table are divided according to the resource they belong to (Transaction or Card). This means that to obtain such a property, you must retrieve the details of its parent resource.
In the following sections, we show examples of how to retrieve and combine this data depending on the scenario.
Match transaction with card
To map a transaction to a card, first, get the transaction details, and then, get the details of the card associated with the transaction.
In this example, we'll use a transaction of type card_payment.
-
Get the transaction details.
To get the details of the card transaction, make a
GETrequest to thetransaction/{id}endpoint and replace{id}with the ID of your transaction.For this example, we'll go with
/transaction/640c2b97-aaaa-1234-aaaa-c47a165c2e7e.API reference: Retrieve a transaction
As a response, you get the transaction details:
Sample transaction details for a card payment{ "id": "640c2b97-aaaa-1234-aaaa-c47a165c2e7e", "type": "card_payment", "state": "completed", "request_id": "REVP:8988a9a0-aaaa-1234-aaaa-5bcc66d938bf", "created_at": "2024-08-11T07:19:51.302559Z", "updated_at": "2024-08-12T02:13:36.842322Z", "completed_at": "2024-08-12T02:13:36.836595Z", "merchant": { "name": "Acme Corp.", "city": "New York", "category_code": "7311", "country": "USA" }, "legs": [ { "leg_id": "640c2b97-aaaa-1234-aaaa-c47a165c2e7e", "account_id": "f52c6c84-26b9-4e95-bbcf-99ed6523fb51", "amount": -47.8, "fee": 0.66, "currency": "AED", "bill_amount": -13, "bill_currency": "USD", "description": "Acm *1234mn1ha2", "balance": 7.74 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234" } } -
Extract the ID of the card associated with the transaction from those details.
It is provided as the
card.idproperty. For your convenience, we highlighted it in the sample above.For the example we're using here, the ID of the card that was used to make the payment is
2b1a31bc-4795-4f95-b939-ae9cf911dc6e. -
Use this ID to get the details for this card.
To do that, make a
GETrequest to the/cards/{id}endpoint and replace{id}with the ID of your card.For the example we're using, it is
/cards/2b1a31bc-4795-4f95-b939-ae9cf911dc6e.API reference: Retrieve card details
As a response, you get the basic card details:
Sample card details{ "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "last_digits": "2671", "expiry": "09/2027", "state": "active", "holder_id": "173ab846-de2a-1234-5678-160bd2e660e6", "label": "John's card", "virtual": true, "accounts": [ "f52c6c84-26b9-4e95-bbcf-99ed6523fb51" ], "categories": [ "restaurants", "groceries" ], "spending_limits": { "single": { "amount": 200.22, "currency": "GBP" }, "week": { "amount": 200.44, "currency": "GBP" } }, "created_at": "2022-09-15T11:04:11.047305Z", "updated_at": "2022-09-15T11:04:11.047305Z" } -
(Optional) If you also need to know the card's PAN, you must additionally retrieve the sensitive card details.
To do that, make a
GETrequest to the/cards/{id}/sensitive-detailsendpoint, again, replacing{id}with the ID of your card. For this example, it is/cards/2b1a31bc-4795-4f95-b939-ae9cf911dc6e/sensitive-details.This endpoint requires a dedicated
READ_SENSITIVE_CARD_DATAsecurity scope.API reference: Retrieve sensitive card details
As a response, you get the sensitive card details:
Sample sensitive card details{ "pan": "5167601111111234", "cvv": "123", "expiry": "09/2027" }The card number (PAN) is highlighted in the sample above. For this example, it's
5167601111111234. -
Combine the data according to your needs.
The method and end result will differ depending on your needs and implementation. To give you some examples, we provide two sample Python scripts below.
The scripts require the
requestslibrary to be installed to work.Sample Python script 1
Retrieves the transaction and card data and combines selected properties into a new single object. Does not include sensitive card details.
retrieve_data_and_combine_selected_properties.pyimport requests # Function to get transaction details def get_transaction_details(transaction_id, token): txn_url = f"https://b2b.revolut.com/api/1.0/transaction/{transaction_id}" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(txn_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to get card details def get_card_details(card_id, token): card_url = f"https://b2b.revolut.com/api/1.0/cards/{card_id}" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(card_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to combine transaction and card data def combine_selected_data(transaction_id, token): # Retrieve transaction details transaction = get_transaction_details(transaction_id, token) # Retrieve card details using the card ID from the transaction card_id = transaction['card']['id'] card = get_card_details(card_id, token) # Combine the required details into a new object combined_data = { 'transaction_id': transaction['id'], 'transaction_state': transaction['state'], 'transaction_type': transaction['type'], 'card_id': card['id'], 'card_state': card['state'], 'card_label': card['label'], 'card_exp': card['expiry'], 'cardholder_full_name': f"{transaction['card']['first_name']} {transaction['card']['last_name']}" } return combined_data # Example usage transaction_id = '640c2b97-aaaa-1234-aaaa-c47a165c2e7e' # Transaction ID from our example token = '<YOUR_ACCESS_TOKEN>' result = combine_selected_data(transaction_id, token) print(result)Result: selected data combined{ "transaction_id": "640c2b97-aaaa-1234-aaaa-c47a165c2e7e", "transaction_state": "completed", "transaction_type": "card_payment", "card_id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_state": "active", "card_label": "John's card", "card_exp": "09/2027", "cardholder_full_name": "John Smith" }Sample Python script 2
Retrieves the transaction data, card data, and sensitive card details, and merges all the data.
retrieve_data_and_merge_all_properties.pyimport requests # Function to get transaction details def get_transaction_details(transaction_id, token): txn_url = f"https://b2b.revolut.com/api/1.0/transaction/{transaction_id}" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(txn_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to get card details def get_card_details(card_id, token): card_url = f"https://b2b.revolut.com/api/1.0/cards/{card_id}" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(card_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to get sensitive card details def get_sensitive_card_details(card_id, token): card_sens_url = f"https://b2b.revolut.com/api/1.0/cards/{card_id}/sensitive-details" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(card_sens_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to merge all transaction and card data, including sensitive details def combine_all_data(transaction_id, token): # Retrieve transaction details transaction = get_transaction_details(transaction_id, token) # Retrieve card details using the card ID from the transaction card_id = transaction['card']['id'] card = get_card_details(card_id, token) # Retrieve sensitive card details using the card ID again sensitive_card_details = get_sensitive_card_details(card_id, token) # Combine all card details into one object transaction_card_details = transaction['card'] merged_card_details = {**card, **sensitive_card_details} new_transaction_card_details = {**transaction_card_details, **merged_card_details} # Update transaction data to include all card details transaction['card'] = new_transaction_card_details return transaction # Example usage transaction_id = '640c2b97-aaaa-1234-aaaa-c47a165c2e7e' # Transaction ID from our example token = '<YOUR_ACCESS_TOKEN>' result = combine_all_data(transaction_id, token) print(result)Result: all data merged{ "id": "640c2b97-aaaa-1234-aaaa-c47a165c2e7e", "type": "card_payment", "state": "completed", "request_id": "REVP:8988a9a0-aaaa-1234-aaaa-5bcc66d938bf", "created_at": "2024-08-11T07:19:51.302559Z", "updated_at": "2024-08-12T02:13:36.842322Z", "completed_at": "2024-08-12T02:13:36.836595Z", "merchant": { "name": "Acme Corp.", "city": "New York", "category_code": "7311", "country": "USA" }, "legs": [ { "leg_id": "640c2b97-aaaa-1234-aaaa-c47a165c2e7e", "account_id": "f52c6c84-26b9-4e95-bbcf-99ed6523fb51", "amount": -47.8, "fee": 0.66, "currency": "AED", "bill_amount": -13, "bill_currency": "USD", "description": "Acm *1234mn1ha2", "balance": 7.74 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234", "last_digits": "2671", "expiry": "09/2027", "state": "active", "holder_id": "173ab846-de2a-1234-5678-160bd2e660e6", "label": "John's card", "virtual": true, "accounts": [ "f52c6c84-26b9-4e95-bbcf-99ed6523fb51" ], "categories": [ "restaurants", "groceries" ], "spending_limits": { "single": { "amount": 200.22, "currency": "GBP" }, "week": { "amount": 200.44, "currency": "GBP" } }, "created_at": "2022-09-15T11:04:11.047305Z", "updated_at": "2022-09-15T11:04:11.047305Z", "pan": "5167601111111234", "cvv": "123" } }
Match transaction with another related transaction
Certain transactions, such as refunds or transactions related to cashback, originate from different transactions.
When you retrieve those transactions' details, if provided by the merchant, the details include related_transaction_id, that is, the ID of the transaction they originated from.
This ID lets you map the transaction at hand to the original transaction.
The related_transaction_id field is populated with information that comes from the merchant.
If the merchant does not provide this information, this field is not available and is omitted from the transaction details.
To map these transactions, you must first get the details of the transaction at hand, and then get the details of the related transaction.
In this example, we'll use a transaction of type card_refund and map it to the related transaction that was refunded.
-
Get transaction details.
To get the details of the refund transaction, make a
GETrequest to thetransaction/{id}endpoint and replace{id}with the ID of your transaction.For this example, we'll go with
/transaction/172884ea-a529-4d5f-8a81-8ebab9f23e33.API reference: Retrieve a transaction
As a response, you get the card refund details:
Sample transaction details for a card refund{ "id": "172884ea-a529-4d5f-8a81-8ebab9f23e33", "type": "card_refund", "state": "completed", "request_id": "card_payment_refund_79fb7626-df83-46eb-b89a-b31b1e1ae2d7", "created_at": "2024-08-15T16:36:29.289670Z", "updated_at": "2024-08-16T03:25:00.481980Z", "completed_at": "2024-08-16T03:25:00.481980Z", "related_transaction_id": "640c1963-aaaa-1234-aaaa-a6b451197c6a", "merchant": { "name": "Google", "city": "London", "category_code": "7311", "country": "GBR" }, "legs": [ { "leg_id": "172884ea-a529-4d5f-8a81-8ebab9f23e33", "account_id": "74d4d6cb-aaaa-1234-aaaa-9604b94e3019", "amount": 3, "currency": "GBP", "description": "Refund from Google", "balance": 109.74 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234" } } -
Extract the ID of the related transaction that was refunded from those details.
It is provided as the
related_transaction_idproperty. For your convenience, we highlighted it in the sample above.For the example we're using here, the ID of the related transaction is
640c1963-aaaa-1234-aaaa-a6b451197c6a. -
Use this ID to get the details for this original transaction.
To do that, make another
GETrequest to thetransaction/{id}endpoint and replace{id}with the related transaction ID.For the example we're using, it is
/transaction/640c1963-aaaa-1234-aaaa-a6b451197c6a.API reference: Retrieve a transaction
As a response, you get the details of the related card transaction that was refunded:
Sample transaction details for a card payment{ "id": "640c1963-aaaa-1234-aaaa-a6b451197c6a", "type": "card_payment", "state": "completed", "request_id": "79fb7626-df83-46eb-b89a-b31b1e1ae2d7", "created_at": "2024-08-13T10:36:29.289670Z", "updated_at": "2024-08-14T03:25:00.481980Z", "completed_at": "2024-08-14T03:25:00.481980Z", "merchant": { "name": "Google", "city": "London", "category_code": "7311", "country": "GBR" }, "legs": [ { "leg_id": "c95f8697-7629-40c7-ae2f-c9dd6d47b631", "account_id": "74d4d6cb-aaaa-1234-aaaa-9604b94e3019", "amount": -3, "fee": 0.25, "currency": "GBP", "description": "A random card payment to Google", "balance": 106.59 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234" } } -
Combine the data according to your needs.
The method and end result will differ depending on your needs and implementation. To give you an example, we provide a sample Python script below.
Sample Python script
Retrieves the data for two related transactions and combines it into a single object.
Optionally, removes the
related_transaction_idproperty, which gets replaced withrelated_transaction.id.retrieve_related_transactions_data_and_combine.pyimport requests # Function to get transaction details def get_transaction_details(transaction_id, token): txn_url = f"https://b2b.revolut.com/api/1.0/transaction/{transaction_id}" headers = { 'Accept': 'application/json', 'Authorization': f'Bearer {token}' } response = requests.get(txn_url, headers=headers) response.raise_for_status() # Raise an exception for bad responses return response.json() # Function to combine related transactions data into one object def combine_transaction_data(transaction_id, token): # Retrieve transaction details (in our example, refund) transaction = get_transaction_details(transaction_id, token) # Retrieve related transaction details (in our example, original transaction that was refunded) related_transaction_id = transaction.get('related_transaction_id') if not related_transaction_id: return transaction related_transaction = get_transaction_details(related_transaction_id, token) # Prepare related transaction details to be merged into transaction details related_transaction_property = { 'related_transaction' : related_transaction } # Combine all the details of the related transaction with the main transaction details (refund details) combined_transaction_data = {**transaction, **related_transaction_property} # Optionally, remove the `related_transaction_id` property, as it now exists as `id` under the `related_transaction` property del combined_transaction_data['related_transaction_id'] return combined_transaction_data # Example usage transaction_id = '172884ea-a529-4d5f-8a81-8ebab9f23e33' # Transaction ID from our example token = '<YOUR_ACCESS_TOKEN>' result = combine_transaction_data(transaction_id, token) print(result)Result: details of related transactions combined{ "id": "172884ea-a529-4d5f-8a81-8ebab9f23e33", "type": "card_refund", "state": "completed", "request_id": "card_payment_refund_79fb7626-df83-46eb-b89a-b31b1e1ae2d7", "created_at": "2024-08-15T16:36:29.289670Z", "updated_at": "2024-08-16T03:25:00.481980Z", "completed_at": "2024-08-16T03:25:00.481980Z", // If you keep the optional command to remove the `related_transaction_id`, this field won't be incldued // "related_transaction_id": "640c1963-aaaa-1234-aaaa-a6b451197c6a", "merchant": { "name": "Google", "city": "London", "category_code": "7311", "country": "GBR" }, "legs": [ { "leg_id": "172884ea-a529-4d5f-8a81-8ebab9f23e33", "account_id": "74d4d6cb-aaaa-1234-aaaa-9604b94e3019", "amount": 3, "currency": "GBP", "description": "Refund from Google", "balance": 109.74 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234" }, "related_transaction": { "id": "640c1963-aaaa-1234-aaaa-a6b451197c6a", "type": "card_payment", "state": "completed", "request_id": "79fb7626-df83-46eb-b89a-b31b1e1ae2d7", "created_at": "2024-08-13T10:36:29.289670Z", "updated_at": "2024-08-14T03:25:00.481980Z", "completed_at": "2024-08-14T03:25:00.481980Z", "merchant": { "name": "Google", "city": "London", "category_code": "7311", "country": "GBR" }, "legs": [ { "leg_id": "c95f8697-7629-40c7-ae2f-c9dd6d47b631", "account_id": "74d4d6cb-aaaa-1234-aaaa-9604b94e3019", "amount": -3, "fee": 0.25, "currency": "GBP", "description": "A random card payment to Google", "balance": 106.59 } ], "card": { "id": "2b1a31bc-4795-4f95-b939-ae9cf911dc6e", "card_number": "516760******1234", "first_name": "John", "last_name": "Smith", "phone": "+12412341234" } } }Depending on your use case, you can modify the script to omit the related transaction data that it shares with the main transaction data, such as
card, to avoid unnecessary duplication.
What's next
Here we provide just a few examples of transaction mapping. Depending on your use case, you can adjust them to your needs.
In a similar fashion, you can also map transactions to other data, such as your accounts (legs.account_id) or counterparties (legs.counterparty.id).