# QI Tech — Risk Solutions › Antifraude e-commerce

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

Índice:
- Status HTTP (/documentation/caas/card_order/http_status)
- Introdução (/documentation/caas/card_order/introduction)
- Objetos (/documentation/caas/card_order/objects)
- Order (/documentation/caas/card_order/order)
- Padrões (/documentation/caas/card_order/standards)
- Webhook (/documentation/caas/card_order/webhook)

---

# Status HTTP

URL: /documentation/caas/card_order/http_status

Todas as APIs da QI Tech utilizam a seguinte padronização nos status HTTP de retorno, de acordo com o RFC 7231 :

Status HTTP | Significado | Descrição
---------- | ------- | ---------------------------------
400 | Bad Request | A requisição enviada possui algum erro de formatação. Na maioria dos casos, retornamos no corpo da mensagem uma explicação de onde está o erro.
401 | Unauthorized | Houve algum problema na autenticação, verifique se a API Key está correta e no header correto, de acordo com a seção Autenticação .
403 | Forbidden | O endpoint acessado é de uso interno e não está disponível para esta API Key.
404 | Not Found | O dado requisitado não foi encontrado usando a chave utilizada. Este status também é retornado quando um endpoint inválido é requisitado.
405 | Method Not Allowed | O método HTTP utilizado não se aplica ao endpoint utilizado.
406 | Not Acceptable | Os dados enviados no corpo da requisição são inválidos. Em geral, isso significa que os dados enviados não são um JSON válido.
409 | Conflict | O id da requisição corresponde a um id já processado anteriormente. Este status é retornado no caso de requisições duplicadas enviadas ao servidor.
500 | Internal Server Error | Tivemos um problema para processar esta requisição, ao encontrarmos esse erro nossos especialistas são automaticamente notificados e iniciam a análise e solução imediatamente.
503 | Service Unavailable | Você se deparou com uma indisponibilidade, planejada ou não, de infraestrutura dos nossos servidores.

---

# Introdução

URL: /documentation/caas/card_order/introduction

Bem vindo à API de Prevenção a Fraudes em transações de cartões da QI Tech! Você pode utilizar a nossa API para acessar os endpoints, a fim de receber a resposta de uma transação, e enviar transações para a QI Tech gerar alertas de usuários fraudadores ou sellers fraudadores, além de utilizar para atualizar a situação de uma transação.

:::info **Atenção**

Atenção, esta API é direcionada para merchants que recebam transações de cartão não presente, que estão sujeitas a chargeback de fraude, ou seja, empresas que realizam suas vendas por meio de aplicativos ou de website e recebem o pagamento por meio de cartão de crédito ou débito.
:::

Abaixo, você pode observar a implementação da API utilizando cUrl. Com isso você possui exemplos para poder adaptar adequadamente à linguagem de programação da sua preferência.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso suporte e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. As URLs base das APIs são:

* Produção - `https://api.caas.qitech.app/card_order/`
* Sandbox - `https://api.sandbox.caas.qitech.app/card_order/`

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.  
:::

No ambiente de Sandbox, as análises enviadas não são cobradas e são respondidas de acordo com regras pré estabelecidas.

Para a análise de uma transação, a seguinte regra é aplicada sobre o valor da transação:

Mínimo | Máximo | Decisão
------ | ------ | -------
0 | 1000 | Aprovado Automaticamente
1001 | 2000 | Derivado para análise manual - Posteriormente aprovado
2001 | 3000 | Derivado para análise manual - Posteriormente reprovado
3001 | 4000 | Reprovado Automaticamente
4001 | 5000 | Não analisado
5001 | - | Pendente

## Somente HTTPS

Por questão de segurança, toda a comunicação com as APIs da QI Tech deve ser realizada utilizando a comunicação HTTPS. Para evitar que, por desatenção ou outro motivo, sejam feitas chamadas HTTP, este servidor somente disponibiliza a porta 443 com comunicação TLS 1.2. Chamadas realizadas utilizando outros protocolos serão automaticamente negadas.

## Autenticação

> Para autenticar uma chamada, utilize o código seguinte:

```shell
# No shell, você somente precisa adicionar o header adequado em cada requisição
curl "api_endpoint_here"
  -H "Authorization: EXAMPLE_API_KEY"
```

> Substitua a API key 'EXAMPLE_API_KEY' com a sua chave adquirida com o nosso suporte.

Utilizamos uma API Key para permitir acesso a nossa API. Ela provavelmente já foi enviada por e-mail para você. Caso você ainda não tenha recebido a sua chave, envie um e-mail para suporte.caas@qitech.com.br .

Nossa API espera receber a API Key em todas as requisições ao nosso servidor em um header como o abaixo:

`Authorization: EXAMPLE_API_KEY`

:::info **Atenção**

Você deve substituir EXAMPLE_API_KEY com a API Key recebida do suporte.
:::

---

# Objetos

URL: /documentation/caas/card_order/objects

## Objeto *address*

Request Body

```json
{
  "street": "Rua do Exemplo, 111",
  "neighborhood": "Bairro do Teste",
  "city": "Aparecida de Goiânia",
  "uf": "GO",
  "complement": "",
  "postal_code": "00000-000",
  "country": "BRA"
}
```

O objeto *address* é utilizado para representar endereços em toda a API, endereços no território brasileiro são representados da seguinte maneira:

nome | tipo | descrição
---- | :----: | ---------
street | string | *(obrigatório)* Rua do endereço, incluindo o logradouro, evitando, se possível, abreviações.
number | string | Número do imóvel, incluindo letras caso possua.
neighborhood | string | *(obrigatório)* Bairro, sem abreviações. **e.g.: Santa Felicidade**
city | string | *(obrigatório)* Nome completo da cidade, sem abreviações
uf | string | *(obrigatório)* A unidade federativa, com duas letras maiúsculas. **e.g.: SP**
complement | string | Quaisquer complementos para localizar o imóvel. **e.g.: Apartamento 101, Conjunto 12**
postal_code | string | *(obrigatório)* O código postal da localidade, contendo o hífen.
country | string | *(obrigatório)* Código ISO 3166-1 alfa-3 do país do endereço.

No caso dos endereços cujo país não seja Brasil ("BRA"), o postal_code e a unidade federativa poderão ser preenchidos livremente.

## Objeto *payment*

Request Body

```json
{
  "total_amount": 10000,
  "shipping_amount": 500,
  "currency": "BRL",
  "is_recurrence": false,
  "transactions": [ . . . ]
}
```

Um pagamento é representado pelo objeto *payment*, que possui os seguintes campos:

nome | tipo | descrição
---- | :----: | ---------
total_amount | inteiro | *(obrigatório)* Valor monetário total pago
shipping_amount | inteiro | Valor do frete cobrado para entrega
currency | Enumerador | *(obrigatório)* Moeda de pagamento de acordo com a ISO 4217
is_recurrence | boolean | *(obrigatório)* Caso este seja um pagamento de recorrência, indicar true nesta flag
transactions | Array de Transaction | *(obrigatório)* Lista de transações que foram realizadas para o pagamento do pedido (Pagamento com múltiplos cartões)

## Objeto *transaction* - Cartão de Crédito

Request Body

```json
{
  "id": "124234",
  "amount": 10000,
  "bin": "123456",
  "last_4": "1234",
  "cardholder_name": "JOHN SAMPLE",
  "card_fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  "expiration_date": "2020-11",
  "installments": 6,
  "processor": "stone",
  "payment_type": "credit"
}
```

Uma transação é representada pelo objeto *transaction*, que possui os seguintes campos:

nome | tipo | descrição
---- | :----: | ---------
id | string | *(obrigatório)* Um identificador no sistema do cliente da transação, deve ser único por pedido
amount | integer | *(obrigatório)* Valor monetário que representa o valor pago
bin | string | *(obrigatório)* BIN do cartão utilizado no pagamento
last4 | string | *(obrigatório)* Quatro últimos dígitos do cartão utilizado no pagamento
cardholder_name | string | *(obrigatório)* Nome do portador, como está escrito no cartão
card_fingerprint | string | *(obrigatório)* Identificador do cartão no sistema do cliente ("Token")
expiration_date | string | Data de vencimento definida pelo cartão (YYYY-DD)
installments | integer | *(obrigatório)* Número de parcelas do pagamento
processor | enumerador | *(obrigatório)* Adquirente ou subadquirente responsável pelo processamento da transação
payment_type | enumerador | *(obrigatório)* Tipo de meio de pagamento
status | enumerador | Opcional - Último status da transação no momento do envio para a QI Tech - Útil para envio de transações não autorizadas

Enumeradores disponíveis para processor:
* cielo
* rede
* stone
* getnet
* adyen
* global_payments
* pagseguro

## Objeto *transaction* - PIX

Request Body

```json
{
  "id": "124234",
  "amount": 10000,
  "payment_type": "pix"
}
```

Uma transação é representada pelo objeto *transaction*, que possui os seguintes campos:

nome | tipo | descrição
---- | :----: | ---------
id | string | *(obrigatório)* Um identificador no sistema do cliente da transação, deve ser único por pedido
amount | integer | *(obrigatório)* Valor monetário que representa o valor pago
payment_type | enumerador | *(obrigatório)* Tipo de meio de pagamento

## Objeto *dict_key*

Request Body

```json
  {
    "key_type": "cpf",
    "key_value": "09991222669"
  }
```

O objeto **dict_key**  é utilizado para representar os dados da chave de vínculo no DICT do cliente, seja ele o recebedor ou o pagador da transação. Os campos desse objeto são:

nome | tipo | descrição
:----: | :----: | ---------
key_type        | string | Enumerador que contém o tipo da chave de vinculo no DICT.
key_value       | string | Contém a chave de vínculo cadastrada no DICT.

Os enumeradores para o campo *key_type* são os mesmos definidos na API do DICT: `cpf`,`cnpj`,`email`,`phone` e `evp`.

## Objeto *account*

Request Body

```json
{
    "participant": "17315359",
    "branch": "0000",
    "account_number": "10442",
    "account_digit": "6",
    "account_type": "CACC"
}
```

Objeto que representa os dados de uma conta.

nome | tipo | descrição
:----:  | :----:  | ---------
participant                 | string | ISPB da instituição detentora da conta
branch                      | string | Agência da Conta
account_number              | string | Número da Conta sem o dígito
account_digit               | string | Dígito da conta
account_type                | enum | Tipo da conta de origem, possíveis valores: "CACC", "SLRY" e "SVGS"

## Objeto *phone*

Request Body

```json
{
  "international_dial_code": "1",
  "area_code": "11",
  "number": "999999999",
  "type": "mobile",
  "validated": false
}
```

Um objeto phone representa um número telefônico, dentro ou fora do Brasil e sua classificação. Para isso, os campos são:

nome | tipo | descrição
---- | :----: | ---------
international_dial_code | string | *(obrigatório)* Código de discagem internacional, sem zero ou +, somente números
area_code | string | *(obrigatório)* Código de área, sem zero, somente números
number | string | *(obrigatório)* Número do telefone, sem o hífen
type | enum | *(obrigatório)* Tipo de número: celular, residencial, comercial, etc.
validated | booleano | Caso o número de telefone tenha sido validado (SMS ou Ligação), enviar true neste campo

Existem os seguintes enumeradores para tipo de telefone: `residential`, `commercial`, `mobile`

## Objeto *seller*

Request Body

```json
{
  "id": "COD",
  "name": "Restaurante do Aeroporto de Congonhas",
  "type": "legal_person",
  "document_number": "00.000.000/0001-00",
  "email": "seller@gmail.com",
  "registration_date": "2019-12-20T15:23:12-03:00",
  "url": "https://www.qitech.com.br",
  "phone": {
      "international_dial_code": "1",
      "area_code": "11",
      "number": "999999999",
      "type": "mobile"
  },
  "address": {
    "street": "Rua do Exemplo",
    "neighborhood": "Bairro do Teste",
    "city": "Aparecida de Goiânia",
    "number": "1000",
    "uf": "GO",
    "complement": "Térreo",
    "postal_code": "00000-000"
  }
}
```

O objeto *seller* representa uma loja ou vendedor que realiza a venda ou entrega do pedido. Os dados a serem enviados podem ser vistos abaixo:

nome | tipo | descrição
---- | :----: | ---------
id | string | *(obrigatório)* O código identificador da loja (Ou vendedor em MarketPlace) no cliente
name | string | *(obrigatório)* O nome da loja (Ou vendedor em MarketPlace)
type | enum | Enumerador que representa se o seller é uma pessoa física ou pessoa jurídica
document_number | string | *(obrigatório)* O CNPJ ou CPF do seller
url | string | Endereço para a página do seller na plataforma
email | string | O e-mail do seller
registration_date | date | *(obrigatório)* A data de cadastro do seller
phone | *phone* | O telefone do seller
address | *address* | *(obrigatório)* O endereço da loja, caso seja uma loja física

Enumeradores de type:

* `natural_person`
* `legal_person`

## Objeto *customer*

Request Body

```json
{
  "id": "5ce7fab5-8165-44a5-9b89-bb2d6d61e4f4",
  "name": "Mary Sample",
  "gender": "female",
  "document_number": "000.000.000-00",
  "registration_date": "2019-12-20T15:23:12Z",
  "email": "test@sample.com",
  "birthdate": "1990-01-02",
  "address": { . . . },
  "phone": { . . . }
}
```

O objeto customer representa os dados de quem realizou a compra do pedido, com o próprio cartão de crédito. Ele é composto por:

nome | tipo | descrição
---- | :----: | ---------
id | string | *(obrigatório)* Um identificador único do comprador ou usuário
name | string | *(obrigatório)* Nome completo
gender | enum | O gênero do customer, de acordo com a lista de enumeradores.
document_number | string | *(obrigatório)* O CPF, formatado adequadamente
registration_date | date | A data quando o usuário se cadastrou no sistema do cliente
email | string | *(obrigatório)* O e-mail do usuário
birthdate | date | A data de nascimento do customer
address | *address* | *(obrigatório)* O endereço residencial do comprador/usuário
phone | *phone* | *(obrigatório)* O telefone colhidos do comprador/usuário

Enumeradores de gênero:

* `male`
* `female`

## Objeto *device*

Request Body

```json
{
  "session_id": "595c46c1-b8c2-449d-8a86-6aeba2e5b0da",
  "platform": "android",
  "browser": "chrome",
  "ip": "243.178.100.37"
}
```

O objeto device descreve dados do dispositivo usado para realizar a compra. Os seguintes dados são passados:

nome | tipo | descrição
---- | :----: | ---------
session_id | string | *(obrigatório)* O identificador da sessão, repassada também no device scan
platform | enumerador | Enumerador do sistema operacional em uso
browser | enumerador | Enumerador do browser em uso (Ou aplicativo)
ip | string | O ip de origem da compra, de acordo com a padronização desta documentação. **Atenção, IPs iniciados em 10.* , 172.16.* e 192.168.* em geral são internos e portanto não são aplicáveis para prevenção a fraudes**

Enumeradores de plataforma:
* `android`
* `ios`
* `windows`
* `linux`

Enumeradores de browser:
* `firefox`
* `chrome`
* `safari`
* `app`

---

# Order

URL: /documentation/caas/card_order/order

Antes de realizar a entrega/envio de um produto ou a liberação de créditos para o seu cliente ou seller, você deve enviar os dados do pedido para a nossa API para que possamos lhe responder a nossa recomendação com relação a fraude. É muito importante que os dados enviados sejam os dados finais, que não serão alterados. Isto é muito importante para garantir dois pontos:

* Consistência dos dados na base de dados do Antifraude
* Avaliação realista do risco

O processo de análise consiste em enviar uma Order no endpoint adequado e esperar a resposta. Existem quatro resultados possíveis, devolvido na flag **analysis_status**:

Resultado | Descrição
:---------: | ---------
Aprovado Automaticamente | Recomenda-se que este pedido seja aprovado
Negado Automaticamente | Recomenda-se que este pedido seja reprovado
Derivado para análise manual | Nossas regras ou modelos não estão confiantes da decisão e decidiram enviar este pedido para a análise manual.
Aprovado Manualmente | Após análise manual, o analista escolheu aprovar o pedido
Reprovado Manualmente | Após análise manual, o analista escolheu reprovar o pedido
Pendente | As consultas estão demorando mais do que o esperado, este pedido entrou em uma fila de análise automática e será respondido por meio de Webhook
Não analisado | A consulta foi enviada com a flag de análise falsa, ou trata-se de uma análise exclusivamente para geração de alertas, o que significa que nossos sistemas não deverão retornar recomendação na resposta da Order

:::info **Atenção**
Caso o seu modelo de negócio demande, o motor da QI Tech pode ser configurado para que nenhum pedido seja derivado para análise manual, e nem para o estado Pendente. Assim, o seu usuário poderá receber imediatamente a confirmação da transação.
:::

### Dinâmica dos Status

Ao recuperar um objeto do tipo Order os status estão disponíveis. Além dos status, um histórico de modificações também são retornados para que possa ser consultado no futuro. Estas modificações são entituladas events e possuem, além do novo status, as datas de modificação.

### Dinâmica dos Status - **payment_status**

O status **payment_status** relacionado a um Pedido indica a situação do pagamento relacionado a este pedido, isto é, se a transação foi efetivamente aprovada, se foi cancelada ou se recebeu um chargeback de fraude. Os seguintes status de pagamento estão disponíveis:

* open
* not_authorized
* authorized
* captured
* cancelled
* chargeback

:::info **Atenção**

É de suma importância que o status de pagamento seja enviado para a QI Tech pois ele é utilizado como base para treinamento dos nossos modelos. No caso de chargeback, é muito importante que o reason_code seja enviado corretamente, como será explicado em seguida.
:::

### Dinâmica dos Status - **analysis_status**

O status **analysis_status** indica o status da decisão do motor de fraude e possui uma máquina de estados bastante simples:

* created
* automatically_approved
* automatically_reproved
* in_manual_analysis
* manually_approved
* manually_reproved
* pending
* not_analyzed

## Definição do Objeto

Request Body

```json
{
	"id": "12345678",
	"is_one_dollar_auth": false,
	"seller": {
		"id": "COD",
		"name": "Restaurante do Aeroporto de Congonhas",
		"type": "legal_person",
		"document_number": "00.000.000/0001-00",
		"email": "seller@gmail.com",
		"registration_date": "2019-12-20T15:23:12-03:00",
		"url": "https://www.qitech.com.br",
		"phone": {
			"international_dial_code": "1",
			"area_code": "11",
			"number": "999999999",
			"type": "mobile",
			"validated": true
		},
		"address": {
			"street": "Rua do Exemplo",
			"neighborhood": "Bairro do Teste",
			"city": "Aparecida de Goiânia",
			"number": "1000",
			"uf": "GO",
			"complement": "Térreo",
			"postal_code": "00000-000",
			"country": "BRA"
		}
	},
	"payment": {
		"total_amount": 10000,
		"shipping_amount": 500,
		"currency": "BRL",
		"is_recurrence": false,
		"transactions": [{
			"id": "124234",
			"amount": 8000,
			"bin": "123456",
			"last_4": "1234",
			"cardholder_name": "JOHN SAMPLE",
			"card_fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
			"expiration_date": "2020-11",
			"installments": 6,
			"processor": "stone",
			"payment_type": "credit",
			"status": "not_authorized"
		}]
	},
	"shipping": {
		"name": "Mary Sample",
		"gender": "female",
		"document_number": "000.000.000-00",
		"birthdate": "1990-01-02",
		"email": "test@sample.com",
		"address": {
			"street": "Rua do Exemplo, 123",
			"neighborhood": "Bairro do Teste",
			"city": "Aparecida de Goiânia",
			"number": "1000",
			"uf": "GO",
			"complement": "",
			"postal_code": "00000-000",
			"country": "BRA"
		},
		"phone": {
			"international_dial_code": "1",
			"area_code": "11",
			"number": "999999999",
			"type": "mobile",
			"validated": true
		},
		"scheduled_date": "2020-01-10",
		"shipping_method": "regular"
	},
	"customer": {
		"id": "5ce7fab5-8165-44a5-9b89-bb2d6d61e4f4",
		"name": "Mary Sample",
		"gender": "female",
		"document_number": "000.000.000-00",
		"registration_date": "2019-12-20T15:23:12-03:00",
		"email": "test@sample.com",
		"birthdate": "1990-01-02",
		"address": {
			"street": "Rua do Exemplo, 123",
			"neighborhood": "Bairro do Teste",
			"city": "Aparecida de Goiânia",
			"number": "1000",
			"uf": "GO",
			"complement": "",
			"postal_code": "00000-000",
			"country": "BRA"
		},
		"phone": {
			"international_dial_code": "1",
			"area_code": "11",
			"number": "999999999",
			"type": "mobile",
			"validated": true
		}
	},
	"device": {
		"session_id": "595c46c1-b8c2-449d-8a86-6aeba2e5b0da",
		"platform": "android",
		"browser": "chrome",
		"ip": "243.178.100.37"
	},
	"products": [{
		"product_code": "latte-machiatto-30",
		"name": "Latte Machiatto 30cl",
		"description": "Latte Machiatto 30cl para levar, leite integral",
		"sku": "1234",
		"quantity": 2,
		"unit_cost": 5000
	}],
	"order_date": "2020-01-03T15:35:12.454-03:00"
}
```

Todas as trocas de informação de um pedido utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.

nome |                  tipo                  | descrição
:----: |:--------------------------------------:| ---------
id | string | Identificador do pedido no sistema do cliente. **É essencial que este valor seja único para cada pedido** (Obrigatório)
is_one_dollar_auth |                booleano                | Se esta for uma transação somente para validação do cartão, enviar com essa flag true (Obrigatório)
seller |             Objeto Seller              | Os dados da loja onde a venda está sendo realizada. No caso de um market place, são os dados do vendedor. No caso de um aplicativo, são os dados da loja de retirada (Obrigatório)
payment |             Objeto Payment             | Dados do pagamento do pedido (Obrigatório)
customer |            Objeto Customer             | Dados do cliente/usuário (Obrigatório)
shipping |            Objeto Shipping             | Dados da entrega do pedido - Deve ser preenchido em casos de produtos de entrega física 
device |             Objeto Device              | Dados do aparelho/navegador onde o pedido é realizado
products |            Array de Product            | Os produtos sendo comprados (Obrigatório)
order_date |          Data Hora            | Data e hora de realização do pedido (Obrigatório)

## Enviar um Pedido

Request Body

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

Response Body

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

Para realizar a avaliação de um pedido, basta enviar um objeto do tipo Order ao seguinte endpoint:

`POST https://api.caas.qitech.app/card_order/order`

## Atualizar o status de um Pedido

Request Body

```json
{
  "transaction_status": "chargeback"
}
```

Para garantir a retroalimentação das regras e do modelo de inteligência artificial implementado, é necessário informar ao sistema quando as transações são autorizadas, capturadas, canceladas ou recebem chargeback. Para isso, requisições com o método PUT devem ser utilizadas, autenticadas normalmente:

`PUT https://api.caas.qitech.app/card_order/order/12345678/transaction/124234`

Existem os seguintes enumeradores para *transaction_status*: `open`, `not_authorized`, `authorized`, `captured`, `cancelled`, `chargeback`

## Recuperar um Pedido

A fim de recuperar um Pedido específico, basta realizar uma requisição GET. O resultado retornado é o json mais atualizado do Pedido em questão. Caso este identificador não esteja relacionado a nenhum objeto, o HTTP Status 404 é retornado.

`GET https://api.caas.qitech.app/card_order/order/12345678`

```shell
curl "https://api.caas.qitech.app/card_order/order/12345678"
  -H "Authorization: EXAMPLE_API_KEY"
```

> O comando acima retorna o JSON que representa um objeto de CardOrder.

## Buscar CardOrders

Response Body

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

> Retorna um JSON que representa uma lista de objetos CardOrder.

Caso seja necessário buscar um CardOrder, um GET com parâmetros de query poderá ser utilizado. O resultado retornado é um JSON que representa uma lista de CardOrders. Caso nenhum objeto seja encontrado com os parâmetros enviados, o HTTP Status 200 é retornado com uma lista vazia no corpo da resposta.

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

Os seguintes parâmetros podem ser utilizados para buscar objetos de CardOrder:

Parâmetro | Padrão | Descrição
--------- | ----------- | --------------
initial_date | null | Primeira data que deve ser retornada a partir do campo order_date
final_date | null | Última data que deve ser retornada a partir do campo order_date
page_number | 1 | Número da página de resultados desejada
page_rows | 50 | Número de objetos máximo a ser retornados em uma consulta

---

# Padrões

URL: /documentation/caas/card_order/standards

Para facilitar a integração e garantir a integridade da informação, foram definidos alguns padrões que são seguidos em toda a API.

## Valores Monetários
> Exemplos:

```
10000
12345
98741
1223
1
0
```

As APIs assumem que todos os valores monetários enviados são em Reais Brasileiros. Os valores devem ser enviados como inteiro em centavos.

## Data e Hora com Fuso Horário
> Alguns exemplos:

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

É representada conforme a ISO 8601. Neste caso, o fuso-horário é colocado logo após o horário e deve representar o fuso do local onde aquele dado será valido. Por exemplo, se um aluguel estiver marcado para começar às 09:30 no aeroporto de Brasília, o horário enviado deverá ser representado por 09:30-03:00, se o aluguel estiver marcado para começar às 09:30 em Manaus, deverá ser representado por 09:30-04:00.

A máscara utilizada para validação é a seguinte:

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

## Data e Hora sem Fuso Horario
> Alguns exemplos:

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

É representada conforme a ISO 8601. Dados que independem de fuso-horário deverão ser enviados sem ele, sempre em UTC, com a letra Z indicando que este dado está em UTC. O seguinte formato, portanto, será validado:

`YYYY-MM-ddThh:mm:ssZ`

## Data
> Alguns exemplos

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

No caso de campos que recebem somente data, uma data de nascimento, por exemplo, somente a data, sem nenhum horário deve ser enviada com o seguinte formato:

`YYYY-MM-dd`
 

## Documentos
Uma vez que os números de documento são bastante variados e muitos deles possuem caracteres que não se enquadram como numéricos, definem-se todos os números de documento como string. Outro bom motivo para definí-los como string é evitar que os zeros à esquerda desapareçam. Documentos previstos nesta página possuem uma máscara bem definida e estarão sujeitos a validação. O restante dos documentos, como RG, dada sua falta de padronização, não serão validados.

## CPF

> Exemplos de CPFs válidos contra a máscara definida:

```
123.456.789-12
321.987.543-23
111.283.333-00
```

> Exemplos de CPFs inválidos contra a máscara definida:

```
8.577.477-8
08.104.627/0001-23
123.456.789-1
23.456.789-01
```

O CPF é sempre definido como uma string e será validado conta a máscara:

`###.###.###-##`

## CNPJ

> Exemplos de CNPJs válidos contra a máscara definida:

```
08.104.627/0001-02
01.079.210/0114-67
32.402.502/0001-35
```

> Exemplos de CNPJs inválidos contra a máscara definida:

```
8.577.477-8
123.456.789-12
321.987.543-23
32.402.502/0001-3
032.402.502/0001-3
```

O CNPJ é sempre definido como uma string e será validado conta a máscara:

`##.###.###/####-##`

## IP

> Exemplos de IPs válidos contra a máscara definida:

```
201.81.161.86
201.081.161.86
201.81.161.086
201.81.0.1
```

> Exemplos de IPs inválidos:

```
201.81..86
358.81.161.86
201.81.161
```

IPs deverão ser enviados sempre em IPv4, zeros à esquerda poderão ou não ser enviados, respeitando a seguinte máscara:

`###.###.###.###`

---

# Webhook

URL: /documentation/caas/card_order/webhook

Atualizações no status de fraude (Para Orders que sejam derivados para análise manual ou que sejam respondidos como Pendente) e para Sellers bloqueados, são notificados por meio de Webhook. Para tanto, é necessário, por meio da equipe do [suporte](mailto:suporte.caas@qitech.com.br), configurar um endereço do endpoint por onde vamos notificar as atualizações e também uma *signature_key* que será utilizada para assinar a requisição.

No caso da atualização do status do pedido, o cliente pode também utilizar a técnica de [polling](https://en.wikipedia.org/wiki/Polling_(computer_science)). Neste caso, basta não configurar o endpoint de webhook e utilizar os endpoints de recuperação de Order para proceder com o polling.

:::info **Atenção**

Por questões de segurança, todas as requisições de Webhook serão somente realizadas em endpoints servidos por HTTPS.
:::

## Assinatura

> Exemplo de cálculo de assinatura em Python

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

Para garantir que a requisição recebida no endpoint do webhook parte dos nossos servidores, uma assinatura HMAC é enviada no Header *Signature*, de maneira semelhante ao processo de autenticação.

Após realizar o cálculo do valor esperado da assinatura do lado do servidor, é necessário comparar a assinatura calculada com a enviada. Caso as assinaturas sejam compatíveis, isso significa que a requisição partiu dos nossos servidores e que é confiável.

## Webhook de Atualização de Order

Request Body

```json
    {
        "order_id": "123456",
        "fraud_status": "automatically_approved",
        "event_date": "2019-10-01T10:37:25-03:00"
    }
```

A requisição de atualização do status de análise de uma order possui o formato acima e notifica a mudança no status de fraude. O método utilizado é um PUT e o endereço do endpoint pode conter também o id do pedido, de acordo com a necessidade do cliente. É importante ressaltar que o corpo da requisição é enviado como texto codificado em UTF-8.

Exemplos de endpoints para atualização de pedido:

* https://apidocliente.com.br/order
* https://apidocliente.com.br/admin/order/1214

O campo event_date indica a data e hora em que a notificação foi criada e pode estar no passado caso envios de notificação anteriores tenham falhado.

## Webhook de Atualização de Seller

> Exemplo de requisição de bloqueio de liquidação

Request Body

```json
    {
        "document_number": "000.000.000-00",
        "settlement_status": "blocked",
        "event_date": "2019-10-01T10:37:25-03:00"
    }
```

> Exemplo de requisição de bloqueio transacional

Request Body

```json
    {
        "document_number": "000.000.000-00",
        "transactional_status": "blocked",
        "event_date": "2019-10-01T10:37:25-03:00"
    }
```

Caso o bloqueio ou desbloqueio de um seller seja necessário, o sistema da QI Tech realizará uma requisição com o formato acima. O método utilizado é um PUT realizado em um endpoint configurável e pode conter, a critério do cliente, o número do documento no endereço do endpoint.

:::info **Atenção**

É a presença do campo settlement_status ou do campo transactional_status que determina o tipo de bloqueio ou desbloqueio que deve ser realizado no seller.
:::

Exemplos de endpoints para atualização de seller:

* https://apidocliente.com.br/seller
* https://apidocliente.com.br/admin/seller/000.000.000-00

Os seguintes status de liquidação podem ser notificados:

enumerador | descrição
---- | ---------:
blocked | A liquidação do seller deve ser bloqueada
unblocked | A liquidação do seller deve ser liberada

O campo event_date indica a data e hora em que a notificação foi criada e pode estar no passado caso envios de notificação anteriores tenham falhado.

## Retentativas

A notificação é considerada realizada quando recebe como resposta um HTTP Status 200. Caso as notificações falhem, serão feitas 7 retentativas, com os seguintes intervalos, até que um 200 seja retornado ou as tentativas terminem:

* 10 segundos
* 40 segundos
* 160 segundos
* 640 segundos
* 2560 segundos
* 10240 segundos
* 40960 segundos