# Criar transação

> Cria uma única transação de venda. Para criar várias transações de uma vez, consulte a página Envio em lote.

Página: https://doc.rapidchargeback.com/canais/transactions/criar-transacao/

Cria uma única transação de venda. Para criar várias transações de uma vez, consulte a página [Envio em lote](https://doc.rapidchargeback.com/canais/transactions/envio-em-lote/).

## Endpoint

```
POST https://api.rapidchargeback.com/api/v1/transactions
```

## Autenticação

```
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/json
```

---

## Campos obrigatórios

| Campo | Tipo | Descrição |
|---|---|---|
| `merchant_id` **ou** `merchant_ref` | string | Informe **exatamente um**: `merchant_id` (UUID do merchant na Rapid, deve pertencer à sua empresa) **ou** `merchant_ref` (ID do vendedor no **seu** sistema, até 100 caracteres, para canais/plataformas com vários vendedores). Se `merchant_ref` for desconhecido, o merchant é **criado** automaticamente com `merchant_name` (opcional, até 255 caracteres; ignorado quando o merchant já existe). Enviar os dois → `422 VALIDATION_ERROR`. Os seus merchants e os `merchant_id` estão em [Listar merchants](https://doc.rapidchargeback.com/canais/merchants/listar-merchants/). |
| `external_id` | string | ID da transação no sistema de origem |
| `amount` | number | Valor da transação (deve ser positivo) |
| `currency` | string | Código ISO 4217 com 3 letras maiúsculas (ex: `USD`, `BRL`) |
| `transaction_date` | string | Data da transação em formato ISO 8601 (ex: `2026-04-01T15:30:00Z`) |
| `card_last4` | string | Últimos 4 dígitos do cartão (exatamente 4 dígitos numéricos) |
| `items` | array | Ao menos 1 item (veja campos do item abaixo) |

## Campos do item

### Obrigatórios

| Campo | Tipo | Descrição |
|---|---|---|
| `product_description` | string | Descrição do produto (até 1000 caracteres; acima disso a requisição falha) |
| `unit_price` | number | Preço unitário |

### Opcionais

| Campo | Tipo | Descrição |
|---|---|---|
| `product_name` | string | Nome do produto |
| `quantity` | number | Quantidade |
| `unit_of_measure` | string | Unidade de medida |
| `category` | string | Categoria do produto |

---

## Campos opcionais

| Campo | Tipo | Descrição |
|---|---|---|
| `external_source` | string | Sistema de origem (default: `custom`) |
| `order_number` | string | Número do pedido |
| `transaction_id` | string | ID da transação no gateway de pagamento. Ver a nota abaixo |
| `arn` | string | Acquirer Reference Number |
| `banknet_ref` | string | Referência Banknet (Mastercard) |
| `auth_code` | string | Código de autorização |
| `network` | string | Bandeira: `visa`, `mastercard`, `amex`, `discover`, `other` |
| `card_bin` | string | BIN do cartão (6 a 8 dígitos numéricos) |
| `ip_address` | string | Endereço IP do comprador |
| `clearing_datetime` | string | Data de compensação (ISO 8601) |
| `mcc` | string | Merchant Category Code |
| `eci` | string | Electronic Commerce Indicator |
| `pos_entry_mode` | string | Modo de entrada POS |
| `descriptor` | string | Descritor de cobrança |
| `correlation_id` | string | ID de correlação |
| `device_id` | string | ID do dispositivo (mín. 15 caracteres) |
| `device_fingerprint` | string | Fingerprint do dispositivo (mín. 20 caracteres) |
| `customer` | object | Dados do comprador (veja abaixo) |
| `addresses` | array | Endereços de entrega e/ou cobrança (veja abaixo) |
| `payments` | array | Dados de pagamento (veja abaixo) |
| `refunds` | array | Dados de reembolso (veja abaixo) |

### Limites de tamanho

Todo campo de texto tem teto. Acima dele a resposta é `422 VALIDATION_ERROR` apontando o campo, nunca um erro de servidor.

| Limite | Campos |
|---|---|
| 1000 | `product_description` |
| 255 | `descriptor`, `merchant_name`, `product_name`, `device_fingerprint`, `street`, `reason` (refund) |
| 200 | `billing_name` |
| 100 | `external_id`, `order_number`, `transaction_id`, `arn`, `banknet_ref`, `correlation_id`, `merchant_ref`, `device_id`, `first_name`, `last_name`, `city`, `state`, `category` |
| 64 | `method_masked`, `reference_number` |
| 45 | `ip_address` (cabe IPv6) |
| 50 | `external_source`, `auth_code`, `account_id` |
| 32 | `unit_of_measure` |
| 30 | `phone`, `postal_code`, `wallet_indicator` |
| 20 | `number` (endereço) |
| 16 | `payment_type` |
| 10 | `mcc`, `pos_entry_mode` |
| 7 | `card_expiry` |
| 5 | `eci` |
| 2 | `cvv2_presence_indicator`, `avs_result` |

`email` segue o limite de 255 e precisa ter formato válido. `currency`, `card_bin`, `card_last4`, `country` e `network` têm formato fixo, descrito na tabela de campos.

### Nota sobre `transaction_id`

É opcional, mas preencha sempre que a cobrança passou por um gateway de pagamento: é por esse campo que a Rapid liga um chargeback futuro à transação. Mande o identificador da cobrança no gateway, não o seu número de pedido (esse é o `order_number`).

Se você usa um gateway cujas disputas chegam à Rapid e o campo vem vazio, o chargeback ainda é recebido, mas sem transação associada: sem histórico, sem evidência anexada e sem os dados de autenticação, que é justamente o material da defesa. Alternativa equivalente: enviar `external_source` com o nome do gateway e `external_id` com o id da cobrança.

---

## Objeto `customer` (todos opcionais)

| Campo | Tipo | Descrição |
|---|---|---|
| `first_name` | string | Primeiro nome |
| `last_name` | string | Sobrenome |
| `email` | string | E-mail (formato válido) |
| `billing_name` | string | Nome no cartão |
| `account_id` | string | ID da conta do comprador no seu sistema |
| `phone` | string | Telefone |

## Objeto `address` (dentro do array `addresses`)

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `type` | string | Sim | `shipping` ou `billing` |
| `street` | string | Não | Rua |
| `number` | string | Não | Número |
| `city` | string | Não | Cidade |
| `state` | string | Não | Estado/Região |
| `postal_code` | string | Não | CEP |
| `country` | string | Não | Código do país ISO 3166-1, 2 ou 3 letras maiúsculas (`BR`/`BRA`, `US`/`USA`). Recomendado alpha-3. |

## Campos de autenticação do pagamento (raiz, todos opcionais)

Insumos da [proteção contra fraude](https://doc.rapidchargeback.com/produtos/prevencao/integracao/#para-a-proteção-contra-fraude) e de 3-DS. Quanto mais preencher, mais forte a deflexão e a defesa.

| Campo | Tipo | Descrição |
|---|---|---|
| `cvv2_presence_indicator` | string | Indicador de presença do CVV2 na autorização |
| `cvv2_result` | string | Resultado da verificação do CVV2: `M`, `N`, `P`, `S`, `U` ou `Y`, como veio na resposta da autorização |
| `avs_result` | string | Resultado do AVS (verificação de endereço) |
| `cardholder_verification_approved` | boolean | 3-DS/verificação do portador aprovada |
| `authentication_response_type` | string | Tipo de resposta da autenticação 3-DS: `attempt` (tentativa) ou `confirm` (autenticação confirmada) |
| `wallet_indicator` | string | Carteira digital usada (ex.: Apple Pay, Google Pay) |

### Conta do comprador (dentro de `customer`, todos opcionais)

Dizem se a compra foi feita por uma conta conhecida, e desde quando ela existe. São o material mais forte da defesa em disputa de fraude: comprador com conta antiga e logado é difícil de contestar como "não reconheço".

| Campo | Tipo | Descrição |
|---|---|---|
| `registered_at` | string (ISO 8601) | Quando a conta do comprador foi criada no seu sistema |
| `registered_at_source` | string | De onde vem `registered_at`: `merchant_api` (registro da conta no seu sistema) ou `client_declared` (declaração sua, sem esse registro) |
| `account_authenticated` | boolean | O comprador estava logado na conta ao comprar |
| `account_authenticated_source` | string | Como você sabe disso: `per_account` (verificado nesta compra) ou `onboarding_flag` (regra da sua loja, por exemplo, toda compra exige login) |
| `account_authenticated_at` | string (ISO 8601) | Quando foi o login |
| `auth_method` | string | Como o comprador entrou: `password`, `otp`, `2fa`, `biometric`, `oauth` ou `other` |
| `account_source_method` | string | De onde vêm os dados de conta: `merchant_api` ou `client_declared` |
| `checkout_type` | string | Como a compra foi feita: `guest` (sem conta), `authenticated` (conta existente, logado) ou `registered_at_checkout` (conta criada durante a compra) |

Valor fora das listas responde `422 VALIDATION_ERROR`.

## Objeto `payment` (todos opcionais)

| Campo | Tipo | Descrição |
|---|---|---|
| `payment_type` | string | Tipo de pagamento (credit, debit, pix, etc.) |
| `method_masked` | string | Número mascarado |
| `matched_payment` | boolean | Se este pagamento foi o utilizado (default: true) |
| `card_bin` | string | BIN (6-8 dígitos) |
| `card_last4` | string | Últimos 4 dígitos (4 dígitos numéricos) |
| `installments` | integer | Número de parcelas |
| `card_expiry` | string | Validade (MM/YYYY) |

## Objeto `refund`

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `amount` | number | Sim | Valor do reembolso (positivo) |
| `currency` | string | Sim | Moeda (3 letras maiúsculas, ISO 4217) |
| `reference_number` | string | Não | Identificador do reembolso |
| `reason` | string | Não | Motivo do reembolso |
| `refund_datetime` | string | Não | Data do reembolso (ISO 8601) |

---

## Validações

- `transaction_date` deve estar em ISO 8601 com timezone
- `currency` deve ser um código ISO 4217 (3 letras maiúsculas)
- `amount` deve ser maior que zero
- `card_last4` deve ter exatamente 4 dígitos numéricos
- `card_bin` deve ter 6 a 8 dígitos numéricos
- `device_id` deve ter no mínimo 15 caracteres
- `device_fingerprint` deve ter no mínimo 20 caracteres
- A combinação `external_source + external_id` não pode duplicar transação existente da sua empresa

## Warnings

A API retorna avisos (sem bloquear a criação) quando campos opcionais importantes estão ausentes:

| Quando | Aviso |
|---|---|
| Sem `card_bin` | `card_bin missing: reduces match accuracy` |
| Sem `order_number` | `order_number missing: recommended to identify the order in dispute responses` |
| Sem `ip_address`, `device_id` **e** `device_fingerprint` | `ip_address, device_id and device_fingerprint missing: recommended, fraud protection relies on them` |

Basta **um** dos três identificadores para o último aviso sumir: o IP não é obrigatório. E não há aviso de endereço de propósito: quem vende bem digital não deve enviar endereço de entrega (ver [proteção contra fraude](https://doc.rapidchargeback.com/produtos/prevencao/integracao/#digital-goods-não-envie-endereço-de-entrega)).

A chave `warnings` **só aparece** na resposta quando há ao menos um aviso. Não conte com `warnings: []`.

---

## Exemplo de requisição

As credenciais vêm de variáveis de ambiente (`RAPID_CLIENT_ID` e `RAPID_CLIENT_SECRET`), nunca escritas no código.

**cURL**

```bash
curl -X POST https://api.rapidchargeback.com/api/v1/transactions \
  -H "Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_id": "00000000-0000-0000-0000-000000000001",
    "external_source": "shopify",
    "external_id": "TXN-2026-001",
    "transaction_date": "2026-04-01T15:30:00Z",
    "amount": 150.00,
    "currency": "USD",
    "card_last4": "4242",
    "card_bin": "424242",
    "order_number": "ORD-001",
    "auth_code": "AUTH999",
    "network": "visa",
    "descriptor": "LOJA EXEMPLO",
    "ip_address": "203.0.113.10",
    "items": [
      {
        "product_description": "Assinatura Premium - Mensal",
        "product_name": "Plano Premium",
        "quantity": 1,
        "unit_price": 150.00
      }
    ],
    "customer": {
      "first_name": "João",
      "last_name": "Silva",
      "email": "joao@exemplo.com"
    },
    "addresses": [
      {
        "type": "shipping",
        "street": "Rua das Flores",
        "number": "123",
        "city": "São Paulo",
        "state": "SP",
        "postal_code": "01001000",
        "country": "BRA"
      }
    ]
  }'
```

**Node.js**

```javascript
const credenciais = Buffer.from(`${process.env.RAPID_CLIENT_ID}:${process.env.RAPID_CLIENT_SECRET}`).toString('base64')

const resposta = await fetch('https://api.rapidchargeback.com/api/v1/transactions', {
  method: 'POST',
  headers: { Authorization: `Basic ${credenciais}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    merchant_id: '00000000-0000-0000-0000-000000000001',
    external_source: 'shopify',
    external_id: 'TXN-2026-001',
    transaction_date: '2026-04-01T15:30:00Z',
    amount: 150.0,
    currency: 'USD',
    card_last4: '4242',
    card_bin: '424242',
    order_number: 'ORD-001',
    auth_code: 'AUTH999',
    network: 'visa',
    descriptor: 'LOJA EXEMPLO',
    ip_address: '203.0.113.10',
    items: [
      {
        product_description: 'Assinatura Premium - Mensal',
        product_name: 'Plano Premium',
        quantity: 1,
        unit_price: 150.0,
      },
    ],
    customer: {
      first_name: 'João',
      last_name: 'Silva',
      email: 'joao@exemplo.com',
    },
    addresses: [
      {
        type: 'shipping',
        street: 'Rua das Flores',
        number: '123',
        city: 'São Paulo',
        state: 'SP',
        postal_code: '01001000',
        country: 'BRA',
      },
    ],
  }),
})

const corpo = await resposta.json()
if (!resposta.ok) throw new Error(`${resposta.status} ${corpo.error.code}: ${corpo.error.message}`)

console.log('Transação criada:', corpo.data.id)
for (const aviso of corpo.warnings ?? []) console.warn('Aviso:', aviso)
```

**Python**

```python
import os

import requests

resposta = requests.post(
    "https://api.rapidchargeback.com/api/v1/transactions",
    auth=(os.environ["RAPID_CLIENT_ID"], os.environ["RAPID_CLIENT_SECRET"]),
    json={
        "merchant_id": "00000000-0000-0000-0000-000000000001",
        "external_source": "shopify",
        "external_id": "TXN-2026-001",
        "transaction_date": "2026-04-01T15:30:00Z",
        "amount": 150.00,
        "currency": "USD",
        "card_last4": "4242",
        "card_bin": "424242",
        "order_number": "ORD-001",
        "auth_code": "AUTH999",
        "network": "visa",
        "descriptor": "LOJA EXEMPLO",
        "ip_address": "203.0.113.10",
        "items": [
            {
                "product_description": "Assinatura Premium - Mensal",
                "product_name": "Plano Premium",
                "quantity": 1,
                "unit_price": 150.00,
            }
        ],
        "customer": {
            "first_name": "João",
            "last_name": "Silva",
            "email": "joao@exemplo.com",
        },
        "addresses": [
            {
                "type": "shipping",
                "street": "Rua das Flores",
                "number": "123",
                "city": "São Paulo",
                "state": "SP",
                "postal_code": "01001000",
                "country": "BRA",
            }
        ],
    },
    timeout=30,
)

corpo = resposta.json()
if not resposta.ok:
    raise RuntimeError(f"{resposta.status_code} {corpo['error']['code']}: {corpo['error']['message']}")

print("Transação criada:", corpo["data"]["id"])
for aviso in corpo.get("warnings", []):
    print("Aviso:", aviso)
```

**PHP**

```php
<?php
$transacao = [
    'merchant_id' => '00000000-0000-0000-0000-000000000001',
    'external_source' => 'shopify',
    'external_id' => 'TXN-2026-001',
    'transaction_date' => '2026-04-01T15:30:00Z',
    'amount' => 150.00,
    'currency' => 'USD',
    'card_last4' => '4242',
    'card_bin' => '424242',
    'order_number' => 'ORD-001',
    'auth_code' => 'AUTH999',
    'network' => 'visa',
    'descriptor' => 'LOJA EXEMPLO',
    'ip_address' => '203.0.113.10',
    'items' => [
        [
            'product_description' => 'Assinatura Premium - Mensal',
            'product_name' => 'Plano Premium',
            'quantity' => 1,
            'unit_price' => 150.00,
        ],
    ],
    'customer' => [
        'first_name' => 'João',
        'last_name' => 'Silva',
        'email' => 'joao@exemplo.com',
    ],
    'addresses' => [
        [
            'type' => 'shipping',
            'street' => 'Rua das Flores',
            'number' => '123',
            'city' => 'São Paulo',
            'state' => 'SP',
            'postal_code' => '01001000',
            'country' => 'BRA',
        ],
    ],
];

$ch = curl_init('https://api.rapidchargeback.com/api/v1/transactions');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_USERPWD => getenv('RAPID_CLIENT_ID') . ':' . getenv('RAPID_CLIENT_SECRET'),
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode($transacao),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
]);

$bruto = curl_exec($ch);
if ($bruto === false) {
    throw new RuntimeException('Falha de rede: ' . curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$corpo = json_decode($bruto, true);

if ($status >= 400) {
    throw new RuntimeException("$status {$corpo['error']['code']}: {$corpo['error']['message']}");
}

echo 'Transação criada: ', $corpo['data']['id'], PHP_EOL;
foreach ($corpo['warnings'] ?? [] as $aviso) {
    echo 'Aviso: ', $aviso, PHP_EOL;
}
```

---

## Exemplos de resposta

### Sucesso

```json
{
  "data": {
    "id": "00000000-0000-0000-0000-000000000042",
    "company_id": "...",
    "merchant_id": "00000000-0000-0000-0000-000000000001",
    "external_id": "TXN-2026-001",
    "amount": 150.00,
    "currency": "USD",
    "transaction_date": "2026-04-01T15:30:00.000Z",
    "card_last4": "4242",
    "created_at": "2026-04-01T15:31:00.000Z",
    "transaction_items": [...],
    "transaction_customers": [...],
    "transaction_addresses": [...]
  }
}
```

### Duplicata

```json
{
  "error": {
    "code": "TRANSACTION_DUPLICATE",
    "message": "Transaction already exists"
  }
}
```

### Erro de validação

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "card_last4 must be exactly 4 digits"
  }
}
```
