MeApi
Uma gem Ruby para integração completa com a API do Melhor Envio, permitindo calcular fretes, criar etiquetas, gerenciar envios e muito mais de forma simples e eficiente.
Funcionalidades
- ✅ Autenticação: Authorization code e refresh token
- ✅ Cotação de frete: Calcular preços de envio
- ✅ Gestão de etiquetas: Criar, pagar, gerar e imprimir etiquetas
- ✅ Consultas: Dados da conta, saldo, pedidos
- ✅ Suporte a sandbox: Ambiente de testes
- ✅ Classes auxiliares: Volume e Product para facilitar o uso
Instalação
Adicione esta linha ao Gemfile da sua aplicação:
gem 'me_api'
E então execute:
$ bundle install
Ou instale diretamente com:
$ gem install me_api
Configuração
Para usar a gem, você precisa ter credenciais da API do Melhor Envio. Você pode obter essas credenciais criando uma aplicação no painel do desenvolvedor do Melhor Envio.
Criando um cliente
A gem suporta dois modos de operação:
- Produção: Para uso em ambiente de produção
- Sandbox: Para testes (use
test_mode: true)
# Cliente de produção
client = MeApi::Client.new(
access_token: "seu_access_token",
refresh_token: "seu_refresh_token",
client_id: "seu_client_id",
client_secret: "seu_client_secret",
token_expires_at: Time.now + 3600
)
# Cliente de sandbox/teste
client = MeApi::Client.new(
access_token: "seu_access_token",
refresh_token: "seu_refresh_token",
client_id: "seu_client_id",
client_secret: "seu_client_secret",
token_expires_at: Time.now + 3600,
test_mode: true
)
Uso
Formato das respostas
Todas as respostas dos métodos da API retornam objetos AcObject ou arrays de AcObject. Esses objetos permitem acesso aos dados de duas formas:
- Notação de ponto:
response.access_token - Notação de hash:
response["access_token"] - Conversão para JSON:
response.json(retorna um hash Ruby)
# Exemplo com refresh_token
response = client.refresh_token(
client_id: "seu_client_id",
client_secret: "seu_client_secret",
refresh_token: "seu_refresh_token"
)
# Todas essas formas funcionam:
puts response.access_token # "novo_access_token"
puts response["access_token"] # "novo_access_token"
puts response.json["access_token"] # "novo_access_token"
# Para ver toda a resposta como hash
puts response.json
# => {"access_token"=>"...", "refresh_token"=>"...", "expires_in"=>21600, "token_type"=>"Bearer"}
Autenticação
Autorizando uma aplicação
response = client.(
client_id: "seu_client_id",
client_secret: "seu_client_secret",
code: "codigo_retornado_pela_api",
redirect_url: "sua_url_de_redirect"
)
# Acessando dados da resposta
puts response.access_token # "abcde12345"
puts response.refresh_token # "asdfghjk123456"
puts response.expires_in # 21600
puts response.token_type # "Bearer"
# Ou usando notação de hash
puts response["access_token"] # "abcde12345"
puts response["refresh_token"] # "asdfghjk123456"
Renovando token
response = client.refresh_token(
client_id: "seu_client_id",
client_secret: "seu_client_secret",
refresh_token: "seu_refresh_token"
)
# Acessando dados da resposta
puts response.access_token # "novo_access_token"
puts response.refresh_token # "novo_refresh_token"
puts response.token_type # "Bearer"
Cotação de frete
# Criar objeto de volume/dimensões
volume = MeApi::Volume.new(
width_cm: 20,
height_cm: 15,
length_cm: 30,
weight_kg: 1.5
)
# Calcular frete (retorna array de AcObject)
rates = client.rates(
from_postal_code: "13870329",
to_postal_code: "88063500",
volume: volume,
contents_value_brl: 50.00
)
# Acessando dados do primeiro resultado
puts rates.first.price # Preço do frete mais barato
puts rates.first.service_name # Nome do serviço (ex: "PAC")
puts rates.first.carrier_name # Nome da transportadora (ex: "Correios")
# Ou usando notação de hash
puts rates.first["price"] # Preço do frete
puts rates.first["service_name"] # Nome do serviço
Gestão de produtos e volumes
Criando produtos
products = [
MeApi::Product.new(
name: "Produto A",
quantity: 2,
unitary_value: 25.00
),
MeApi::Product.new(
name: "Produto B",
quantity: 1,
unitary_value: 50.00
)
]
Criando volumes
volumes = [
MeApi::Volume.new(
width_cm: 20,
height_cm: 15,
length_cm: 30,
weight_kg: 1.5
)
]
Gestão de etiquetas
Adicionando etiqueta ao carrinho
response = client.add_label_to_cart(
service_id: 1, # ID do serviço de entrega
from_name: "Remetente",
from_phone: "(11) 99999-9999",
from_email: "[email protected]",
from_address: "Rua do Remetente",
from_address_complement: "Apto 123",
from_address_number: "100",
from_address_district: "Centro",
from_address_city: "São Paulo",
from_postal_code: "01000000",
from_address_state_abbr: "SP",
from_tax_id: "12345678901", # CPF ou CNPJ
to_name: "Destinatário",
to_phone: "(11) 88888-8888",
to_email: "[email protected]",
to_address: "Rua do Destinatário",
to_address_complement: "",
to_address_number: "200",
to_address_district: "Vila Nova",
to_address_city: "Rio de Janeiro",
to_postal_code: "20000000",
to_address_state_abbr: "RJ",
to_tax_id: "98765432109", # CPF ou CNPJ
products: products,
volumes: volumes,
insurance_value: 100.00
)
# Acessando dados da resposta
order_id = response.id # ID do pedido
puts response.protocol # Protocolo do pedido
puts response["status"] # Status do pedido
Pagando etiqueta
payment_response = client.pay_label(order_id)
puts payment_response.purchase_id # ID da compra
puts payment_response["digitable_line"] # Linha digitável (se boleto)
Gerando etiqueta
generate_response = client.generate_label(order_id)
puts generate_response["status"] # Status da geração
Imprimindo etiqueta
pdf_response = client.print_label(order_id)
puts pdf_response.first # URL do PDF da etiqueta
Consultas
Dados da conta
account = client.get_account_data
puts account.firstname # Nome do usuário
puts account.email # Email da conta
puts account["document"] # CPF/CNPJ da conta
puts account.json # Todos os dados como hash
Saldo disponível
balance = client.get_balance
puts balance.current # Saldo atual
puts balance["currency"] # Moeda (BRL)
Detalhes de um pedido
order = client.get_label(order_id)
puts order.status # Status do pedido
puts order.tracking # Código de rastreamento
puts order["service_name"] # Nome do serviço utilizado
puts order.json # Todos os dados do pedido
Classes auxiliares
MeApi::Volume
Representa as dimensões e peso de um pacote:
volume = MeApi::Volume.new(
width_cm: 20, # Largura em centímetros
height_cm: 15, # Altura em centímetros
length_cm: 30, # Comprimento em centímetros
weight_kg: 1.5 # Peso em quilogramas
)
# Converte para formato da API
volume.to_api_format
# => { width: 20, height: 15, length: 30, weight: 1.5 }
MeApi::Product
Representa um produto a ser enviado:
product = MeApi::Product.new(
name: "Nome do produto", # Nome do produto
quantity: 2, # Quantidade
unitary_value: 25.00 # Valor unitário em reais
)
# Converte para formato da API
product.to_api_format
# => { name: "Nome do produto", quantity: 2, unitary_value: 25.0 }
Exemplo completo
require 'me_api'
# Configurar cliente
client = MeApi::Client.new(
access_token: "seu_access_token",
refresh_token: "seu_refresh_token",
client_id: "seu_client_id",
client_secret: "seu_client_secret",
token_expires_at: Time.now + 3600
)
# Calcular frete
volume = MeApi::Volume.new(width_cm: 20, height_cm: 15, length_cm: 30, weight_kg: 1.5)
rates = client.rates(
from_postal_code: "13870329",
to_postal_code: "88063500",
volume: volume,
contents_value_brl: 50.00
)
puts "Melhor preço: R$ #{rates.first.price}"
puts "Serviço: #{rates.first.service_name}"
# Criar pedido
products = [MeApi::Product.new(name: "Produto A", quantity: 1, unitary_value: 50.00)]
volumes = [volume]
response = client.add_label_to_cart(
service_id: rates.first.id,
from_name: "Loja Online",
from_phone: "(11) 99999-9999",
from_email: "[email protected]",
from_address: "Rua da Loja",
from_address_number: "123",
from_address_district: "Centro",
from_address_city: "São Paulo",
from_postal_code: "13870329",
from_address_state_abbr: "SP",
from_tax_id: "12345678000123",
to_name: "João Silva",
to_phone: "(11) 88888-8888",
to_email: "[email protected]",
to_address: "Rua do Cliente",
to_address_number: "456",
to_address_district: "Vila Nova",
to_address_city: "Florianópolis",
to_postal_code: "88063500",
to_address_state_abbr: "SC",
to_tax_id: "98765432109",
products: products,
volumes: volumes,
insurance_value: 50.00
)
order_id = response.id # Usando notação de ponto
puts "Pedido criado: #{response.protocol}"
# Pagar e gerar etiqueta
payment = client.pay_label(order_id)
puts "Pagamento: #{payment.purchase_id}"
generate = client.generate_label(order_id)
puts "Status geração: #{generate.status}"
# Obter URL do PDF
pdf_response = client.print_label(order_id)
puts "Etiqueta: #{pdf_response.first}"