Pulse
ISO 8583 Payment Gateway

Pulse API

Gateway de pagamentos ISO 8583 de alta performance construido em Go. Processa transacoes de cartao de credito e debito com Visa e Mastercard via conexoes TCP persistentes, abstraindo toda a complexidade do protocolo binario em uma API REST simples.

Como funciona

O Pulse recebe requisicoes JSON via REST, converte em mensagens ISO 8583 binarias, envia para as bandeiras (Visa/Mastercard) via TCP, decodifica a resposta e retorna JSON. Voce nao precisa conhecer ISO 8583 para usar a API.

Arquitetura

O Pulse opera como um gateway de traducao de protocolos entre sua aplicacao (REST/JSON) e as redes de cartoes (ISO 8583/TCP):

Sua App (JSON)          Axon Pulse                    Bandeiras (ISO 8583)
┌──────────┐     ┌─────────────────────┐     ┌──────────────────────┐
│          │     │  API    Service     │     │                      │
│  POST    │────>│  Layer   Layer      │     │  Visa (TCP :10000)   │
│  /v1/    │     │    │       │        │────>│                      │
│  trx/    │     │    │   ISO 8583     │     └──────────────────────┘
│  auth    │     │    │   Builder      │
│          │<────│    │       │        │     ┌──────────────────────┐
│  JSON    │     │    │   ISO 8583     │     │                      │
│  resp    │     │    │   Parser       │<────│  Mastercard          │
│          │     │    │       │        │     │  (TCP :10000)        │
└──────────┘     │    └───────┘        │     └──────────────────────┘
                 │        │            │
                 │   ┌────▼────┐       │
                 │   │ Postgres│       │
                 │   │ (state) │       │
                 │   └─────────┘       │
                 └─────────────────────┘

Funcionalidades

Autorizacao

Autoriza transacoes de credito e debito. Envia ISO 8583 MTI 0100 e recebe 0110. Suporta parcelamento (1-12x) e auto-capture.

Captura

Captura transacoes previamente autorizadas. Envia MTI 0200, recebe 0210. Suporta captura parcial.

Estorno

Reverte autorizacoes ou capturas. Envia MTI 0400, recebe 0410. Funciona tanto para transacoes autorizadas quanto capturadas.

Consulta

Consulta o estado atual de qualquer transacao. Retorna status, valores, codigos de autorizacao e timestamps.

Base URL

Sandbox:    https://sandbox.pulse.axon.com
Production: https://pulse.axon.com

Endpoints

Autorizar transacao

POST
/v1/transactions/authorize

Autoriza uma transacao de cartao. Envia ISO 8583 0100 (Authorization Request) para a bandeira.

Requestjson
{
  "card_token": "vault_card_abc123def456",
  "amount": 25990,
  "currency": "BRL",
  "merchant_id": "LOJA_ONLINE_01",
  "terminal_id": "ECOMM001",
  "installments": 3,
  "capture": false
}
CampoTipoObrigatorioDescricao
card_tokenstringSimToken do cartao no Vault. O PAN real e resolvido internamente.
amountintegerSimValor em centavos. Ex: 10000 = R$ 100,00
currencystringSimISO 4217: BRL, USD
merchant_idstringSimIdentificador do estabelecimento (max 15 chars)
terminal_idstringNaoIdentificador do terminal POS (max 8 chars)
installmentsintegerNaoParcelas (1-12). Default: 1 (a vista)
capturebooleanNaoAuto-capture. Default: false
Response (201 Created)json
{
  "id": "txn_f7g8h9i0j1k2",
  "status": "authorized",
  "amount": 25990,
  "currency": "BRL",
  "auth_code": "789012",
  "response_code": "00",
  "response_message": "Transacao aprovada",
  "brand": "mastercard",
  "merchant_id": "LOJA_ONLINE_01",
  "installments": 3,
  "created_at": "2026-02-07T14:00:00Z"
}
Response - Negada (200 OK)json
{
  "id": "txn_f7g8h9i0j1k2",
  "status": "declined",
  "amount": 25990,
  "currency": "BRL",
  "auth_code": "",
  "response_code": "51",
  "response_message": "Saldo insuficiente",
  "brand": "mastercard",
  "merchant_id": "LOJA_ONLINE_01",
  "installments": 3,
  "created_at": "2026-02-07T14:00:00Z"
}

Capturar transacao

POST
/v1/transactions/{id}/capture

Captura transacao autorizada. Envia ISO 8583 0200 (Financial Presentment).

Somente transacoes com status authorized podem ser capturadas. Suporta captura parcial (valor menor que o autorizado).

Request (opcional)json
{
  "amount": 25990
}
Response (200 OK)json
{
  "id": "txn_f7g8h9i0j1k2",
  "status": "captured",
  "amount": 25990,
  "captured_amount": 25990,
  "currency": "BRL",
  "auth_code": "789012",
  "response_code": "00",
  "response_message": "Captura realizada com sucesso",
  "brand": "mastercard",
  "merchant_id": "LOJA_ONLINE_01",
  "captured_at": "2026-02-08T09:00:00Z"
}

Estornar transacao

POST
/v1/transactions/{id}/void

Estorna transacao autorizada ou capturada. Envia ISO 8583 0400 (Reversal Request).

Nenhum body e necessario. O estorno reverte o valor total da transacao.

Response (200 OK)json
{
  "id": "txn_m3n4o5p6q7r8",
  "status": "voided",
  "amount": 5000,
  "currency": "BRL",
  "auth_code": "345678",
  "response_code": "00",
  "response_message": "Estorno realizado com sucesso",
  "brand": "visa",
  "merchant_id": "RESTAURANTE_42",
  "voided_at": "2026-02-07T15:30:00Z"
}

Consultar transacao

GET
/v1/transactions/{id}

Retorna o estado atual de uma transacao.

Response (200 OK)json
{
  "id": "txn_f7g8h9i0j1k2",
  "status": "captured",
  "amount": 25990,
  "currency": "BRL",
  "auth_code": "789012",
  "response_code": "00",
  "response_message": "Transacao aprovada",
  "brand": "mastercard",
  "merchant_id": "LOJA_ONLINE_01",
  "terminal_id": "ECOMM001",
  "installments": 3,
  "created_at": "2026-02-07T14:00:00Z",
  "updated_at": "2026-02-08T09:00:00Z"
}

Health Check

GET
/health

Verifica se o servico esta operacional.

Ciclo de vida da transacao

Cada transacao segue uma maquina de estados bem definida:

                  ┌──────────┐
                  │ declined │  (response_code != "00")
                  └──────────┘
                       ▲
                       │
 ┌─────────┐     ┌────┴──────┐     ┌──────────┐
 │ pending  │────>│authorized │────>│ captured  │
 └─────────┘     └─────┬─────┘     └─────┬─────┘
                       │                  │
                       │    ┌────────┐    │
                       └───>│ voided │<───┘
                            └────────┘
StatusDescricaoAcoes permitidas
authorizedTransacao aprovada pela bandeiracapture, void
capturedValor confirmado para liquidacaovoid
voidedTransacao revertidanenhuma (estado final)
declinedTransacao negada pelo emissornenhuma (estado final)

Exemplos completos

Fluxo autorizacao + captura

authorize-and-capture.shbash
# 1. Autorizar transacao (3x de R$ 259,90)
curl -X POST https://pulse.axon.com/v1/transactions/authorize \
  -H "Content-Type: application/json" \
  -d '{
    "card_token": "vault_card_abc123def456",
    "amount": 25990,
    "currency": "BRL",
    "merchant_id": "LOJA_ONLINE_01",
    "installments": 3
  }'

# Response: { "id": "txn_f7g8h9i0j1k2", "status": "authorized", ... }

# 2. Capturar apos envio do produto
curl -X POST https://pulse.axon.com/v1/transactions/txn_f7g8h9i0j1k2/capture \
  -H "Content-Type: application/json" \
  -d '{ "amount": 25990 }'

# Response: { "id": "txn_f7g8h9i0j1k2", "status": "captured", ... }

Fluxo autorizacao + estorno

authorize-and-void.shbash
# 1. Autorizar
curl -X POST https://pulse.axon.com/v1/transactions/authorize \
  -H "Content-Type: application/json" \
  -d '{
    "card_token": "vault_card_xyz789uvw012",
    "amount": 5000,
    "currency": "BRL",
    "merchant_id": "RESTAURANTE_42"
  }'

# Response: { "id": "txn_m3n4o5p6q7r8", "status": "authorized", ... }

# 2. Estornar (cliente desistiu)
curl -X POST https://pulse.axon.com/v1/transactions/txn_m3n4o5p6q7r8/void

# Response: { "id": "txn_m3n4o5p6q7r8", "status": "voided", ... }

Exemplo em Go

main.gogo
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

type AuthRequest struct {
    CardToken  string `json:"card_token"`
    Amount     int    `json:"amount"`
    Currency   string `json:"currency"`
    MerchantID string `json:"merchant_id"`
}

type Transaction struct {
    ID              string `json:"id"`
    Status          string `json:"status"`
    Amount          int    `json:"amount"`
    AuthCode        string `json:"auth_code"`
    ResponseCode    string `json:"response_code"`
    ResponseMessage string `json:"response_message"`
    Brand           string `json:"brand"`
}

func main() {
    req := AuthRequest{
        CardToken:  "vault_card_abc123def456",
        Amount:     10000, // R$ 100,00
        Currency:   "BRL",
        MerchantID: "LOJA_01",
    }

    body, _ := json.Marshal(req)
    resp, err := http.Post(
        "https://pulse.axon.com/v1/transactions/authorize",
        "application/json",
        bytes.NewReader(body),
    )
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var txn Transaction
    json.NewDecoder(resp.Body).Decode(&txn)

    if txn.ResponseCode == "00" {
        fmt.Printf("Aprovada! Auth code: %s\n", txn.AuthCode)
    } else {
        fmt.Printf("Negada: %s\n", txn.ResponseMessage)
    }
}

Exemplo em Node.js

pulse-client.jsjavascript
const authorize = async (cardToken, amount, merchantId) => {
  const response = await fetch(
    'https://pulse.axon.com/v1/transactions/authorize',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        card_token: cardToken,
        amount,        // centavos: 10000 = R$ 100,00
        currency: 'BRL',
        merchant_id: merchantId,
      }),
    }
  );

  const txn = await response.json();

  if (txn.response_code === '00') {
    console.log('Aprovada!', txn.id, txn.auth_code);

    // Capturar quando pronto
    await fetch(
      `https://pulse.axon.com/v1/transactions/${txn.id}/capture`,
      { method: 'POST', headers: { 'Content-Type': 'application/json' } }
    );
  }

  return txn;
};

ISO 8583 - Por baixo dos panos

O Pulse abstrai o protocolo ISO 8583 para que voce nao precise lidar com mensagens binarias. Mas se voce quer entender o que acontece internamente:

MTIs suportados

OperacaoRequestResponseDescricao
Autorizacao01000110Authorization Request/Response
Captura02000210Financial Presentment Request/Response
Estorno04000410Reversal Request/Response
Keepalive08000810Network Management (interno)

Data Elements principais

DENomeFormatoDescricao
DE2PANn LLVARNumero do cartao (resolvido via token vault)
DE3Processing Coden6Tipo de transacao (000000 = compra)
DE4Amountn12Valor em centavos (000000010000 = R$ 100)
DE11STANn6Trace number (gerado automaticamente)
DE37RRNan12Retrieval Reference Number
DE38Auth Codean6Codigo de autorizacao do emissor
DE39Response Codean2"00" = aprovado
DE41Terminal IDans8Identificador do terminal POS
DE42Merchant IDans15Identificador do estabelecimento
DE49Currency Coden3Moeda ISO 4217 (986=BRL, 840=USD)

Fluxo de autorizacao (internamente)

1. POST /v1/transactions/authorize (JSON)
2. Resolve card_token -> PAN via Vault
3. Identifica bandeira pelo BIN (4xxx=Visa, 51-55xxx=MC)
4. Gera STAN e RRN
5. Monta ISO 8583 0100 (MTI + bitmap + data elements)
6. Envia bytes via TCP para bandeira
7. Recebe resposta 0110 (bytes)
8. Parseia: extrai DE38 (auth_code), DE39 (response_code)
9. Persiste transacao no PostgreSQL
10. Retorna JSON para o chamador

Codigos de resposta

O campo response_code retorna o codigo ISO 8583 DE39 da bandeira:

CodigoMensagem
00Aprovado
01Consulte o emissor
05Nao autorizada
14Cartao invalido
51Saldo insuficiente
54Cartao vencido
55Senha invalida
57Transacao nao permitida
91Emissor fora do ar
96Erro no sistema

Erros HTTP

StatusQuando
400Request invalida (JSON malformado, campos ausentes)
404Transacao nao encontrada
409Status invalido para a operacao (ex: capturar transacao ja estornada)
502Falha na conexao TCP com a bandeira
504Timeout aguardando resposta da bandeira
Formato de errojson
{
  "error": {
    "code": "INVALID_AMOUNT",
    "message": "O valor da transacao deve ser maior que zero",
    "details": {
      "field": "amount",
      "value": -100
    }
  }
}

Seguranca

PCI DSS Compliant

O Pulse nunca armazena dados de cartao (PAN). Trabalha exclusivamente com card_token que referencia dados no Axon Vault. O PAN e resolvido em memoria apenas no momento da montagem da mensagem ISO 8583.

Conexoes TCP Persistentes

Pool de conexoes TCP com keepalive para Visa e Mastercard. Reconexao automatica em caso de falha. Identificacao da bandeira pelo BIN do cartao.

Valores em Centavos

Todos os valores monetarios sao inteiros em centavos (10000 = R$ 100,00), eliminando problemas de arredondamento com ponto flutuante.

Configuracao

VariavelDefaultDescricao
Servidor
PULSE_PORT8080Porta HTTP
PULSE_DATABASE_URL-Connection string PostgreSQL
Visa
PULSE_VISA_HOST-Host do servidor ISO 8583 Visa
PULSE_VISA_PORT10000Porta TCP Visa
PULSE_VISA_POOL_SIZE5Conexoes TCP no pool Visa
PULSE_VISA_TIMEOUT30Timeout por mensagem (segundos)
Mastercard
PULSE_MASTER_HOST-Host do servidor ISO 8583 Mastercard
PULSE_MASTER_PORT10000Porta TCP Mastercard
PULSE_MASTER_POOL_SIZE5Conexoes TCP no pool Mastercard
PULSE_MASTER_TIMEOUT30Timeout por mensagem (segundos)
Logging
PULSE_LOG_LEVELinfoNivel de log (debug, info, warn, error)
PULSE_LOG_FORMATjsonFormato de log (json, text)

Tokenizacao obrigatoria

O Pulse nao aceita numeros de cartao diretamente. Use o Axon Vault para tokenizar o cartao antes de enviar transacoes. Isso garante conformidade PCI DSS e separa responsabilidades de custodia de dados sensiveis.