Guia: Comercial
Fluxo para criar negociações, registrar entregas e rastreabilidade.
Mapa de dependências
A negociação (order-commitment) é o ponto central. A entrega pode ser independente (basta um contract_id conhecido) e a rastreabilidade exige uma negociação existente.
Pré-requisitos
Antes de criar uma negociação, os seguintes registros do guia de Cadastros devem existir:
| Registro | Usado em | Referência |
|---|---|---|
Produtor (producer_id) | order-commitments, traceability | Cadastros §1 |
Emissor (issuer_id — UUID de um usuário) | order-commitments | — |
Carteira vinculada ao Produtor (wallet_id) | order-commitments | Cadastros §4 |
Local de Entrega (delivery_place_id) | order-commitments | Cadastros §6 |
1. Criar negociação
Endpoint:
POST /api/v1/integration/order-commitments
Campos obrigatórios em qualquer order_type: amount, producer_id, issuer_id, product, delivery_place_id, haverst, unit_of_measurement, order_type, order_date, wallet_id. Os campos currency, price, modality, payday, payment_type, initial_delivery_date e end_delivery_date são condicionais, e a regra muda conforme o order_type:
order_type | Campos condicionais exigidos |
|---|---|
COMPRA, VENDA | currency, price, modality, payday, payment_type, initial_delivery_date, end_delivery_date |
FIXACAO_COMPRA, FIXACAO_VENDA, FIXACAO_DEPOSITO | currency, price, modality, payday, payment_type — as datas de entrega não são exigidas |
A_FIXAR, ANTECIPACAO | nenhum — todos os condicionais são opcionais |
O objeto shipping tem regra própria: é obrigatório quando order_type = COMPRA (e, dentro dele, type também é obrigatório; se type = FOB, state e city passam a ser obrigatórios). Para os demais order_type ele é opcional.
Campo de shipping | Tipo | Obrigatório |
|---|---|---|
type | Enum: CIF, FOB, TPT, SOT | Sim quando order_type = COMPRA |
state | String | Sim quando type = FOB |
city | String | Sim quando type = FOB |
description | String | Não |
price | Number (maior que zero) | Não |
Opcionais em qualquer order_type: internal_id (sua referência interna, usada depois em PUT /order-commitments/-/internal-ids/{internal_id}:cancel), description e price_unit_of_measurement.
Atenção ao campo
haverst(sim, com esse nome no contrato): é o nome oficial do atributo da safra na API.
curl -X POST \
https://api.merx.tech/api/v1/integration/order-commitments \
-H "Authorization: {SUA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000.00,
"producer_id": "{producer_id}",
"issuer_id": "{user_id}",
"product": "SOJA",
"delivery_place_id": "{delivery_place_id}",
"haverst": "2024/2025",
"unit_of_measurement": "SC",
"order_type": "COMPRA",
"order_date": "2024-06-30",
"wallet_id": "{wallet_id}",
"currency": "BRL",
"price": 85.00,
"initial_delivery_date": "2024-10-01",
"end_delivery_date": "2024-11-30",
"modality": "DISPONIVEL",
"payday": "2024-12-15",
"payment_type": "DINHEIRO",
"shipping": {
"type": "FOB",
"state": "MT",
"city": "Sorriso"
}
}'
Enums fechados do contrato — um valor fora da lista falha na desserialização e devolve 400 com {"messages": ["message.malformed-request"]}:
order_type:FIXACAO_COMPRA,FIXACAO_VENDA,COMPRA,VENDA,FIXACAO_DEPOSITO,ANTECIPACAO,A_FIXARmodality:BALCAO,DISPONIVEL,FUTURO,EXPORTACAOpayment_type:DINHEIRO,TROCA
Campos String resolvidos por catálogo — não são enums no contrato: o valor enviado é procurado pelo nome/código nas tabelas da plataforma.
product: nome do produto (ex.:SOJA,MILHO,TRIGO)unit_of_measurement: unidade da negociação (ex.:SC,KG,TON)currency: código da moeda (ex.:BRL)price_unit_of_measurement: unidade usada no preço (opcional)
Datas: order_date, initial_delivery_date, end_delivery_date e payday são enviadas como String no formato yyyy-MM-dd.
Response: {"id": "uuid-da-negociação"} — guarde como order_commitment_id. Detalhes completos em Criar Negociação.
2. Registrar entrega
Endpoint:
POST /api/v1/integration/deliveries
A entrega se associa a uma negociação pelo contract_id, que é o código ERP da negociação (String): a API procura o order-commitment por esse código dentro da cooperativa. Sem correspondência, a resposta é 404 com {"messages": ["message.order-commitment.not-found"]}.
curl -X POST \
https://api.merx.tech/api/v1/integration/deliveries \
-H "Authorization: {SUA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"contract_id": "000122",
"delivered_volume": 10,
"delivered_volume_unit_of_measure": "ton",
"delivery_date": "2026-03-02",
"car": "MT-5107602-ABC123456789"
}'
Campos obrigatórios: contract_id (String), delivered_volume (Number, maior que zero), delivered_volume_unit_of_measure (String — exatamente kg, sc ou ton, em minúsculas) e delivery_date (String no formato YYYY-MM-DD). Opcionais: car (String) e delivery_mode (FULL ou PARTIAL, padrão PARTIAL).
Response 201 Created: {"id": "...", "contract_id": "...", "delivered_volume": ..., "delivered_volume_unit_of_measure": "...", "delivery_date": "...", "car": "..."} — o corpo é o eco dos dados enviados.
Atenção: este endpoint não cria um registro de entrega consultável. O que ele faz é somar o volume entregue na negociação identificada pelo
contract_id. Oidda resposta é gerado no momento da chamada e não existe rota para consultá-lo depois. Ocartambém é apenas ecoado: não vincula a entrega a nenhuma propriedade.
Detalhes em Registrar Entrega.
3. Registrar rastreabilidade
Endpoint:
POST /api/v1/integration/traceability/-/commitments/{order_commitment_id}
O order_commitment_id vai no path. No body, producer_id e user_id (ambos UUID) são obrigatórios; farm_id (UUID), allocated_volume (Number), unit_of_measurement (String), invoice_import_id (UUID), esg_report_request_id (UUID), eudr_report_request_id (UUID) e use_pre_generated_reports (Boolean) são opcionais.
Regra condicional: quando
use_pre_generated_reportsétrue,esg_report_request_ideeudr_report_request_idpassam a ser obrigatórios.
curl -X POST \
https://api.merx.tech/api/v1/integration/traceability/-/commitments/{order_commitment_id} \
-H "Authorization: {SUA_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"farm_id": "{farm_id}",
"producer_id": "{producer_id}",
"user_id": "{user_id}",
"allocated_volume": 123.12,
"unit_of_measurement": "SC"
}'
unit_of_measurement é String; quando vem ausente ou vazia, a API assume TON. Valores usuais: SC, KG, TON.
Response: {"id": "uuid-da-rastreabilidade"}. Detalhes em Criar Rastreabilidade.
4. Consultar negociação
curl -X GET \
https://api.merx.tech/api/v1/integration/order-commitments/{order_commitment_id} \
-H "Authorization: {SUA_API_KEY}"
Ver também: listagem paginada e detalhes por código ERP.
Erros comuns
| Erro | Causa | Solução |
|---|---|---|
{"messages": ["message.wallet.not-found"]} | wallet_id inválido | Crie a carteira em Cadastros §4 |
{"messages": ["message.wallet.producer-not-linked"]} | Produtor não vinculado à carteira | Execute o POST de vínculo em Cadastros §4 |
{"messages": ["message.producer.not-found"]} | producer_id inválido | Verifique o UUID do produtor |
{"messages": ["message.delivery-place.not-found"]} | delivery_place_id inválido | Cadastre o local em Cadastros §6 |
{"messages": ["message.currency.mandatory"]} (400) | Falta um campo condicional do order_type enviado. A chave segue o padrão message.<campo-em-kebab-case>.mandatory — ex.: message.initial-delivery-date.mandatory, message.payment-type.mandatory | Consulte a tabela de campos condicionais do §1 e inclua os exigidos pelo seu order_type |
{"messages": ["message.shipping.mandatory"]} (400) | order_type = COMPRA sem o objeto shipping | Envie shipping com pelo menos type; com type = FOB, envie também state e city (message.shipping.state.mandatory / message.shipping.city.mandatory) |
{"messages": ["message.order-commitment.not-found"]} (404) | O contract_id enviado em POST /deliveries não corresponde ao código ERP de nenhuma negociação da cooperativa | Confira o código ERP da negociação |