# QI Tech — Risk Solutions › Card Transaction Anti-Fraud

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
5 página(s).

Índice:
- Cardholder Alerts (/en/documentation/caas/card_issuance/alerts)
- HTTP Status Codes (/en/documentation/caas/card_issuance/http_status)
- Introduction (/en/documentation/caas/card_issuance/introduction)
- Standards (/en/documentation/caas/card_issuance/standards)
- Transaction (/en/documentation/caas/card_issuance/transaction)

---

# Cardholder Alerts

URL: /en/documentation/caas/card_issuance/alerts

Alerts generated by the antifraud tool are notified via Webhook. To do so, it is necessary to configure an endpoint address through which we will send the notifications, as well as a *secret_token* that will be used to sign the request. This configuration must be done through our [support team](mailto:suporte.caas@qitech.com.br).

In this notification we will send information about the generated alerts, as well as which cardholder they refer to, so that the client can take action—for example, sending a *push notification* to the cardholder.

## Request

Request Body

```json
    {
        "alert_key": "123456",
        "cardholder_id": "ef47bc3f-61ac-4b85-ad67-0cfa3a422201",
        "company_name": "Cliente 1",
        "irregularity_type" : "fraud",
        "risk_level": "critical"
    }
```

The request has the format above and notifies the opening of a new alert for a Cardholder — identified by *cardholder_id*.

## Webhook Signature

> Example of signature calculation in Python

```python
    hmac_obj = hmac.new(signature_key.encode('utf-8'), (endpoint + method + payload).encode('utf-8'), hashlib.sha1)
    return hmac_obj.hexdigest()
```

To ensure that the request received at the webhook endpoint comes from our servers, an HMAC signature is sent in the Signature header, similar to the authentication process.

After calculating the expected signature value on the server side, you must compare the calculated signature with the one sent. If the signatures match, this means that the request came from our servers and is trustworthy.

## Retries

The notification is considered successful when it receives an HTTP Status 200 as response. If the notifications fail, 5 retries will be made with the following intervals until a 200 is returned or the attempts are exhausted:

* 30 seconds
* 60 seconds
* 120 seconds
* 240 seconds
* 360 seconds

---

# HTTP Status Codes

URL: /en/documentation/caas/card_issuance/http_status

All QI Tech APIs follow the standard HTTP status codes as defined in the [RFC 7231](https://tools.ietf.org/html/rfc7231):

HTTP Status | Meaning | Description
----------- | ------- | ---------------------------------
400 | Bad Request | The request sent contains a formatting error. In most cases, we return a message body explaining where the error is.
401 | Unauthorized | There was a problem with authentication. Check if the API Key is correct and placed in the proper header, as explained in the [Authentication](https://docs.qitech.com.br/en/documentation/caas/card_issuance/authentication/index.html) section.
403 | Forbidden | The accessed endpoint is for internal use and not available for this API Key.
404 | Not Found | The requested data could not be found using the provided key. This status is also returned when an invalid endpoint is requested.
405 | Method Not Allowed | The HTTP method used is not supported by the requested endpoint.
406 | Not Acceptable | The data sent in the request body is invalid. Usually, this means the payload is not valid JSON.
409 | Conflict | The request ID corresponds to an ID that has already been processed. This status is returned in case of duplicate requests.
500 | Internal Server Error | We encountered an issue while processing the request. When this happens, our specialists are automatically notified and begin investigating immediately.
503 | Service Unavailable | You encountered an infrastructure outage, whether planned or unplanned, on our servers.

---

# Introduction

URL: /en/documentation/caas/card_issuance/introduction

Welcome to QI Tech's Card Issuance Fraud Prevention API! You can use our API to access the endpoints to receive the response of a transaction, as well as to update the status of a transaction.

:::info **Attention**

Please note that this API is intended for card issuers — that is, companies that issue the card to the cardholder so they can transact. Its purpose is to perform all security analysis on your client's transactions, preventing fraud and other types of incidents (such as transactions resulting from robberies).
:::

Below, you can see the API implementation using cURL. This gives you examples that you can adapt to the programming language of your choice.

## Issues?

We're not a company that hides behind an API! Reach out to our support team and we'll get back to you as soon as possible. Feel free to give us a call if you want a quicker answer!

### We love feedbacks

Even if you've already solved your issue or it is something simple (like a typo or a small organizational detail), feel free to send us an email. That way, we can keep improving our documentation and help the next person avoid the same difficulties you faced!

## Environments

We provide two environments for our clients. The base URLs for the APIs are:

* Production - `https://api.caas.qitech.app/card_issuance/`
* Sandbox - `https://api.sandbox.caas.qitech.app/card_issuance/`

:::danger Important Warning!
Real personal or company data must not be used in QI Tech's Sandbox environments.  
:::

In the Sandbox environment, submitted analyses are not charged and are responded to according to predefined rules.

For transaction analysis, the following rule is applied based on the transaction amount:

Minimum | Maximum | Decision
------ | ------ | -------
10000 | - | automatically_approved
0 | 9999 | automatically_declined

## Only HTTPS

For security reasons, all communication with QI Tech's APIs must be conducted over HTTPS. To ensure that no HTTP calls are made, whether by oversight or any other reason, this server only makes port 443 available with TLS 1.2 communication. Requests using other protocols will be automatically rejected.

## Authentication

> To authenticate a request, use the following code:

```shell
# In the shell, you only need to add the appropriate header to each request
curl "api_endpoint_here"
  -H "Authorization: EXAMPLE-OF-API-KEY"
```

> Replace the API Key 'EXAMPLE-OF-API-KEY' with your own key, which should be obtained from our support team.

We use an API Key to grant access to our API. It was likely sent to you by email. If you haven't received your key yet, please send an email to suporte.caas@qitech.com.br .

Our API expects to receive the API Key in all requests to our server in a header like the one below:

`Authorization: EXAMPLE-OF-API-KEY`

:::info **Attention**

You must replace EXAMPLE-OF-API-KEY with your own key, which should be obtained from our support team.
:::

---

# Standards

URL: /en/documentation/caas/card_issuance/standards

To simplify integration and ensure data integrity, some standards have been defined and are followed throughout the API.

## Monetary Values

> Examples:

```
10000
12345
98741
1223
1
0
```
Values must be sent as integers in cents.

## Date and Time with Timezone

> Some examples:

```
2019-10-15T22:35:12-03:00
2018-05-01T13:32:11+00:00
2019-05-01T00:00:00+00:00
```

It is represented according to the ISO 8601 standard. In this case, the timezone is placed immediately after the time and should represent the timezone of the location where that data will be valid. For example, if a rental is scheduled to start at 09:30 at Brasília airport, the time sent should be represented as 09:30-03:00; if the rental is scheduled to start at 09:30 in Manaus, it should be represented as 09:30-04:00.

The validation mask is as follows:

`YYYY-MM-ddThh:mm:ss±hh:mm`

## Date and Time without Timezone

> Some examples:

```
2019-10-15T22:35:12Z
2018-05-01T13:32:11Z
2019-05-01T00:00:00Z
```

It is represented according to the ISO 8601 standard. Data that is independent of timezones should be sent without one, always in UTC, using the letter Z to indicate that the data is in UTC. Therefore, the following format will be validated:

`YYYY-MM-ddThh:mm:ssZ`

## Date

> Some examples:

``` 
2019-10-15
2019-01-01
2017-03-20
```

For fields that only receive a date—such as a birthdate—only the date, without any time, should be sent in the following format:

`YYYY-MM-dd`

---

# Transaction

URL: /en/documentation/caas/card_issuance/transaction

When the cardholder initiates a transaction, the data must be sent to our server so that we can perform a risk analysis on that set of data.

## Object Definition

Request Body

```json
{
  "id": "678",
  "cardholder_id": "b812da2e-e6be-4712-8e57-6f3f2791625b",
  "group_id" : "8507884b-c30f-4b45-951c-f0bf366926fc",
  "amount": 13725,
  "currency": "BRL",
  "brl_converted_amount": 13725,
  "installments": 6,
  "authorization_date": "2019-11-10T13:25:42.123-03:00",
  "authorization_type": "authorization",
  "transaction_type": "credit",
  "pan_entry_mode": "chip",
  "pin_sent": true,
  "source_account": "saving_account",
  "location": {
    "latitude": -45.2753548,
    "longitude": -15.24587
  },
  "terminal": {
    "id": "123456",
    "country_code": "BRA",
    "terminal_type": "2",
    "pin_entry_capability": true,
    "magnetic_stripe_capability": true,
    "contactless_capability": false,
    "chip_capability": true
  },
  "merchant": {
    "acquirer_id": "250",
    "merchant_id": "123456",
    "name": "VASP LINHAS AEREAS",
    "street" : "RUA CMDTE X, 127",
    "city" : "SAO PAULO, SP",
    "region": "BRA",
    "postal_code": "04570-140",
    "mcc": "3036"
  },
  "card": {
    "brand": "visa",
    "category": "black",
    "issuing_date": "2019-10-08T07:13:12.333-03:00",
    "unblock_date": "2019-10-12T07:13:12.333-03:00",
    "expiration_date": "2019-12-31",
    "bin": "498406",
    "last4": "1234",
    "total_credit_limit": 2500000,
    "used_credit_limit": 732625,
    "issuer_country_code": "BRA"
  },
  "transaction_status" : "authorized",
  "response_code": "05"
}
```

A transaction must be sent to the API before the transaction is authorized and can be used to make the decision to generate (or not) an authorization code. The data sent can also be used to generate alerts based on the cardholder's transaction history, so that if there is behavior different from expected, the alert triggers an appropriate action to mitigate the impact of the transactions.

The fraud statuses (**fraud_status** and **transaction_status**) represent, respectively, the decision returned by the model for that transaction and whether the transaction was completed, cancelled, or became a dispute.

The following statuses are used in **transaction_status**:

* `not_authorized`
* `authorized`
* `cleared`
* `cancelled`
* `partially_cancelled`
* `chargeback`
* `partial_chargeback`

The following statuses are used in **fraud_status**:

* `automatically_approved`
* `automatically_declined`
* `not_analyzed`

Below are the meanings of each decision returned in the **fraud_status** field:

Result | Description
:---------: | ---------
automatically_approved | This transaction is recommended to be approved
automatically_declined | This transaction is recommended to be declined
not_analyzed | The request was sent with the analysis flag set to false, meaning our systems should not return a decision

name | type | description | 
:----: | :----: | ---------
id | string | *(required)* Transaction identifier in the client's system. **It is essential that this number be unique for each authorization process**
cardholder_id | string | *(required)* Cardholder identifier in the client's system — as registered in the Onboarding API
group_id | string | *(optional)* Identifier of which group or category that user belongs to within the client's system
amount | integer | *(required)* The transaction amount — as described in the "Standards" section
currency | string | *(required)* The currency used in the transaction — ISO 4217 and ApplicationCurrencyCode from 8583
brl_converted_amount | integer | *(required)* The transaction amount converted to Brazilian Reais — as described in the "Standards" section
installments | integer | *(required)* The number of installments used in the transaction
authorization_date | datetime | *(required)* The date and time when the transaction started, with timezone
authorization_type | enumerator | *(required)* Authorization or pre-authorization transaction?
transaction_type | enumerator | *(required)* Credit, Debit or Voucher
pan_entry_mode | enumerator | *(required)* PAN entry mode — Chip, Keyed, Magnetic Stripe, Fallback, Contactless—Field from ISO 8583 (DE 22 - Sub Field 1)
pin_sent | boolean | *(required)* Was a PIN entered at the terminal? — Field from entry_mode in ISO 8583
source_account | enumerator | *(optional)* Whether the transaction amount should be taken from the bill, checking account or savings—Field from Processing Code in ISO 8583
location.latitude | number | *(optional)* The latitude where the transaction occurred—if there is a linked mobile device or another means of capturing the location
location.longitude | number | *(optional)* The longitude where the transaction occurred
terminal.id | string | *(optional)* The terminal identifier sent by the acquirer in the authentication messaging
terminal.country_code | string | *(required)* The country code of the terminal, sent in the authorization message per ISO 3166-1 alpha-3, field from Terminal Country Code in ISO 8583
terminal.terminal_type | string | *(required)* The terminal type as received in the authorization messaging — Field from TerminalType in ISO 8583
terminal.pin_entry_capability | boolean | *(required)* Is it possible to enter the card PIN at the terminal? — Field from TerminalPINEntryCapability in ISO 8583
terminal.magnetic_stripe_capability | boolean | *(optional)* Can the terminal read magnetic stripe? — Field TerminalPANEntryCapability (DE 123) in ISO 8583
terminal.contactless_capability | boolean | *(optional)* Can the terminal initiate contactless transactions? — Field TerminalPANEntryCapability (DE 123) in ISO 8583
terminal.chip_capability | boolean |*(required)* Can the terminal initiate transactions using the EMV chip? — Field TerminalPANEntryCapability (DE 123) in ISO 8583
merchant.acquirer_id | string | *(required)* The acquirer identifier as per authorization messaging — Field Acquirer Identifier (DE 32) in ISO 8583
merchant.merchant_id | string | *(required)* The merchant identifier at the acquirer as per authorization messaging — Field Merchant Identifier in ISO 8583
merchant.name | string | *(optional)* The merchant name according to authorization messaging—Field Merchant Name in ISO 8583
merchant.street | string | *(optional)* The street address of the merchant — Field Card Acceptor Street Address
merchant.city | string | *(optional)* The city of the merchant's address — Field Card Acceptor City
merchant.region | string | *(optional)* The region of the merchant's address — Field Card Acceptor Region Code
merchant.postal_code | string | *(optional)* The postal code of the merchant's address — Field Card Acceptor Postal Code
merchant.mcc | string | *(required)* Merchant Category Code, according to ISO 18245 and ISO 8583
card.brand | enumerator | *(required)* The card brand (visa, mastercard, elo...)
card.category | enumerator | *(required)* The card category (classic, gold, platinum, black, infinite, corporate)
card.issuing_date | datetime | *(required)* The date and time when the card was issued, with timezone
card.unblock_date | datetime | *(optional)* The date and time when the card was unblocked by the cardholder, with timezone
card.expiration_date | date | *(required)* The card expiration date (last day of the month)
card.bin | string | *(required)* The BIN of the card being used
card.last4 | string | *(required)* The last four digits of the card, used to identify the card within the issuer
card.total_credit_limit | number | *(optional)* The total credit limit granted to the cardholder. If the card is prepaid, the existing credit balance on the card
card.used_credit_limit | number | *(optional)* The amount of limit already used (before the transaction in question)
card.issuer_country_code | string | *(required)* The issuer country per ISO 3166-1 alpha-3
transaction_status | enumerator | *(optional)* The transaction status, when sent with ***analyze=false*** flag and authorization decision has already been made.
response_code | enumerator | *(optional)* The transaction response code per the Response Code field in ISO 8583, when sent with ***analyze=false*** flag and authorization decision has already been made.

## Enumerators

The enumerators of the card transaction object are authorization_type, transaction_type, pan_entry_mode, source_account, brand and category. The possible values for each can be seen below:

## authorization_type

enumerator | meaning
---------- | -----------
authorization | A purchase authorization — MTI x1xx (DMS) and x2xx (SMS)
pre_authorization | A pre-authorization to reserve limit on the card (Hotel, Vehicle Rental, Equipment Rental, Fuel Machines) — MTI x1xx (DMS) and Transaction Type (first 2 digits of Processing Code) "60"
reversal | A cancellation authorization (to release limit on the card and subsequently proceed with Clearing/BASE II) — MTI x4xx

## transaction_type

enumerator | meaning
---------- | ----------
credit | A transaction made on the credit function
debit | A transaction made on the debit function
prepaid | A transaction made on the prepaid function

## pan_entry_mode

enumerator | ISO 8583 | meaning
---------- | -------- | -----------
unknown | 00 | PAN entry mode unknown.
typed | 01 | PAN entered manually (keyed).
bar_code | 03 | PAN entered by barcode reader
ocr | 04 | PAN entered by OCR (Optical Character Recognition)
chip | 05 | PAN entered by card with integrated circuit (Chip)
track_1 | 06 | PAN entered by Track 1 of the magnetic stripe card
contactless | 07 | PAN entered by Contactless EMV
fallback_typed | 79 | An attempt was made to use the card or stripe reader on the device and the card but the transaction could not be processed with that information (possibly a device or card issue), so the PAN was keyed. In some cases the acquirer is not certified to use CHIP or stripe and sends this code.
fallback_magnetic_stripe | 80 | An attempt was made to use the device's card reader and the card but the transaction could not be processed with that information (possibly a device or card issue), so the card's magnetic stripe was used.
ecommerce | 81 | E-commerce / card-not-present transaction
magnetic_stripe | 90 | Magnetic stripe transaction (Card has no chip or device has no reader/is not certified)

Other PAN_ENTRY_MODE values exist; however, they are generally not used.

## source_account

enumerator | ISO 8583 | meaning
---------- | -------- | -----------
default | 00 | Default or unspecified
saving_account | 10 | Savings account
checking_account | 20 | Checking account
credit_facility | 30 | Bill
universal_account | 40 | Universal Account
investment_account | 50 | Investment account
electronic_purse | 60 | Balance stored on the card chip (Electronic Purse)

## brand

enumerator | meaning
---------- | -----------
visa | Visa
mastercard | MasterCard
diners_club | Diners Club
elo | Elo
american_express | American Express

## category

enumerator | meaning
---------- | -----------
classic | Classic
gold | Gold
platinum | Platinum
black | Black/Infinite
travel | Travel
corporate | Corporate/Business
prepaid | Prepaid

## terminal_type

enumerator | meaning
---------- | -----------
0 | Unknown
1 | No terminal used
2 | Magnetic stripe reader
3 | Bar code (reserved for future use)
4 | Optical Character Recognition (reserved for future use)
5 | Magnetic stripe reader and EMV specification compatible integrated circuit card (ICC) reader
6 | Key entry only
7 | Magnetic stripe reader and key entry
8 | Magnetic stripe reader and key entry and EMV-compatible ICC reader
9 | EMV compatible ICC reader

## Send a Transaction

Request Body

```json
  {
    "id": "12345",
    ...
  }
```

Response Body

```json
  {
    "id": "12345",
    "fraud_status": "automatically_approved"
  }
```

To evaluate a transaction, simply send a Transaction object to the following endpoint with the flag set appropriately:

`POST https://api.caas.qitech.app/card_issuance/transaction?analyze=true`

The *analyze* parameter exists to prevent transactions that do not need to be analyzed from going through the fraud engines and polluting the database. The default value of this parameter is **true**, so only transactions explicitly marked will not be analyzed.

## Update the status of a Transaction

Request Body: When authorizing a transaction

```json
{
  "transaction_status": "authorized",
  "response_code": "05"
}
```

Request Body: When partially cancelling a transaction

```json
{
  "transaction_status": "partially_cancelled",
  "partial_amount" : 3000,
  "response_code": "05"
}
```

To ensure feedback to the rules and the implemented artificial intelligence model, it is necessary to inform the system when transactions are cancelled. For this, requests with the PUT method must be used, authenticated as usual:

`PUT https://api.caas.qitech.app/card_issuance/transaction/123456`

## Retrieve a Transaction

To retrieve a specific Transaction, simply make a GET request. The result returned is the most up-to-date JSON of the Transaction in question. If this identifier is not linked to any object, HTTP Status 404 is returned.

`GET https://api.caas.qitech.app/card_issuance/transaction/12345678`

```shell
curl "https://api.caas.qitech.app/card_issuance/transaction/12345678"
  -H "Authorization: EXAMPLE-OF-API-KEY"
```

> The command above returns the JSON that represents a Transaction object.

## Search Transactions

Response Body: List of Transaction objects.

```json
[
  {
    "id": "12345",
    ...
  },
  {
    "id": "12345",
    ...
  }
]
```

If you need to search for Transactions, a GET with query parameters can be used. The result returned is a JSON representing a list of Transactions. If no object is found with the parameters sent, HTTP Status 200 is returned with an empty list in the response body.

`GET https://api.caas.qitech.app/card_issuance/transactions?initial_date=2019-10-01&final_date=2019-10-05&page_number=2&page_rows=20`

The following parameters can be used for the search:

Parameter | Default | Description
--------- | ----------- | --------------
initial_date | null | First date to be returned from the transaction_date field
final_date | null | Last date to be returned from the transaction_date field
cardholder_id | null | Cardholder identifier at the issuer
page_number | 0 | Page number of desired results, starting at zero
page_rows | 50 | Maximum number of objects to be returned in a query