Campos personalizados no checkout
TLDR: permitir que o admin defina campos extras por checkout — tamanho de camisa, cor, número do sapato — em texto livre ou opções pré-definidas, e guardar a resposta do comprador junto do pagamento.
Contexto
Alguns produtos precisam coletar informação que não faz parte do cadastro padrão do comprador. Hoje não há onde colocar esse dado no checkout, e o time acaba tratando isso fora do sistema.
Objetivos
- No admin de um checkout, o administrador pode criar campos customizados.
- O administrador escolhe entre campo aberto e opções pré-definidas.
- O administrador marca o campo como múltipla escolha ou escolha única (padrão).
- O administrador agrupa campos por nome — ex.: “Tamanhos de Camisa” — para facilitar a seleção.
Fora de escopo
— (não registrado na spec original)
Mudanças
Modelos
Checkout ganha has_many :custom_fields.
CustomField
| Campo | Nome | Descrição |
|---|---|---|
checkout_id |
ID do checkout | Referência para o Checkout |
title |
Nome exibido ao cliente | O texto que aparece no label |
value |
Valor agregado | Ex.: 50, casa, short |
options_group_title |
(Opcional) Grupo de opções | Nome do grupo de opções usado. Ex.: Tamanho de Camisa, Número de sapato |
CustomFieldOption
| Campo | Nome | Descrição |
|---|---|---|
group_title |
(Opcional) Nome do grupo | Agrupador de opções, ex.: Tamanho de Camisa |
slug |
(Opcional) Nome do grupo parametrizado | Gerado automaticamente no create, para agrupar facilmente e ser usado na API |
title |
Nome exibido ao cliente | Ex.: P, M ou G |
value |
Valor agregado | Ex.: P, M ou G |
PaymentCustomFieldAnswer
| Campo | Nome | Descrição |
|---|---|---|
custom_field |
Referência para o Custom Field | Referência para o Custom Field |
payment |
Referência para o Pagamento | Referência para o Pagamento |
answer |
Resposta | A resposta do comprador |
Nota da spec original: poderia existir uma tabela polimórfica aqui, sem prefixar por pagamento, mas não há utilidade para isso no momento.
Controller e API
- O endpoint
/checkout/:idretorna o campocustom_fields, para a UI montar o formulário. - Ao montar o serializer do checkout, é preciso trazer as options do checkout com base no
group_titleescolhido — isso não é trivial (a intenção é evitar mais uma tabela). - O
POSTda UI deve respeitar os strong params. Os campos são enviados no arraycustom_fields. - Para campos de resposta fixa (não aberta) com
group_titleenvolvido, validar se o valor enviado bate com ovaluedas options. Possivelmente um model customizado para isso, como já é feito emPaymentDetails.
json
{
"custom_field_answers": [
{ "custom_field_id": 56, "answer": "Resposta de campo aberto" },
{ "custom_field_id": 56, "answer": "M" }
]
}
ActiveAdmin
Para não criar uma tabela só para o grupo de opções, a exibição dos grupos no admin pode ser uma consulta GROUP BY sobre o group_title das options.
Roadmap
- [x] Modelo
CustomField - [x] Modelo
PaymentCustomFieldAnswer - [x] Modelo
CustomFieldOption - [x] Mudanças de checkout no ActiveAdmin
- [x] API/controller — retorno das options no checkout
- [x] API/controller —
POSTdas respostas - [x] API/controller — validação (única, múltipla, etc.)
- [x] Exibir os campos personalizados nos detalhes do pagamento
- [x] Permitir alterações nos detalhes do pagamento
- [ ] IBFT Web — mudanças de UI
Como verificar
— (não registrado na spec original)
Sugestão a partir do estado atual do código: criar um checkout com campos abertos e com grupo de opções, submeter uma compra pela API e conferir os PaymentCustomFieldAnswer gravados e exibidos nos detalhes do pagamento.
Documentação
Implementação: app/models/custom_field.rb, app/models/custom_field_option.rb, app/models/payment_custom_field_answer.rb.