Este documento tem como objetivo detalhar o fluxo de pagamento, estratégia de implementação, modelagem das entidades e escolha de tecnologia para o protótipo funcional do fluxo de pagamento.
Dada a característica do problema em consistir de um desafio de modelagem e boas práticas fazendo uso de Domain Driven Design.
A escolha foi utilizar uma linguagem que faça uso de programação funcional e orientação a objeto. Por isso, a escolha do Kotlin com runtime da JVM.
Para o empacotamento da solução foi utilizado gradle com objetivo de rodar os testes unitários do protótipo funcional.
A IDE utilizada para o desenvolvimento deste protótipo funcional foi o Intellij
Todas as entidades foram modeladas com atributos com a característica val, ou seja, imutáveis. A escolha deste modelo foi para uso do paradigma puramente funcional, pois assim não há estados mutáveis e conseguimos atingir um modelo de reprocessamento.
Seguem as definições das entidades envolvidas no fluxo de pagamento:
Família de Produtos
- Interface Product: entidade abstrata para representar um produto e seu respectivo método de pagamento.
- Physical: entidade que extende a interface procuct e representa um produto física que emite shipping label.
- Book: entidade que extende a interface product e representa um lívro físico que emite shipping label isento de impostos conforme disposto na Constituição Art. 150, VI, d.
- Digital: entidade que extende a interface product e representa um produto digital que deve notificar por email o cliente e conceder um voucher de R$10 ao comprador.
- Menbership: entidade que extende a interface product e representa um produto de assinatura que deve notificar o cliente por email.
Família de Meios de Pagamentos
- Interface PaymentMethod: entidade abstrata de tipo base para representar um meio de pagamento
- CreditCard: entidade que extende a interface PaymentMethod e representa o meio de pagamento de um cartão de crédito.
Família de Clientes
- Customer: Entidade que represente um cliente. Um cliente por meio de suas compras tem associado diretamente a sua conta os produtos digitais, suas respectivas assinaturas e vouchers.
- Voucher: Entidade que representa um voucher concedido durante uma compra de um produto digital. O voucher está associado diretamente a um cliente.
Família de Pedidos
- Order: Entidade que representa um pedido. Um pedido é composto dos itens do pedido, cliente, endereço e shipping label emito.
- OrderItem: Entidade que representa um item do pedido. O item do pedido é composto de um produto, quantidade e preço.
- ShippingLabel: Entidade que representa o shipping label emitido para um pedido em caso de conter produtos físicos.
- Address: Entidade que representa um endereço. O endereço é utilizado em um pedido com o endereço de entrega e de cobrança.
Pagamento
- Payment: Entidade principal do fluxo e representa o pagamento de um pedido. O pagamento é composto por um número de autorização, quantidade a ser paga, endereço de entrega, endereço de cobrança, email e o pedido.
O fluxo de pagamento acontece da seguinte forma:
- Um novo objeto pagamento é criado recebendo o pedido;
- O método de pagar (pay) é executado;
- É gerado o número de autorização para o pagamento;
- O valor total do pagamento é computado a partir do preço de cada item multiplicado pela respectiva quantidade;
- Endereço de entrega e endereço de cobrança é obtido a partir do endereço do pedido;
- Executa o pagamento de cada produto de forma iterativa por meio de polimorfismo da interface de produto;
- Cada tipo de produto realiza a função específica de pagamento, podendo: emitir shipping label no pedido, envio de email para produtos digitais ou ativar assinatura para um cliente;
- Imprimi shipping label, caso exista um produto físico;
- Envia email de confirmação de compra digital, caso exista produtos digitais no pedido;
- Envia um email de ativação de assinatura, caso exista produtos de assinaturas no pedido;
- Finaliza o pedido com a data atual;
- Finaliza o pagamento com a data atual.
Segue a lista dos principais métodos para o fluxo de pagamento:
- Payment.pay
- Product.pay
- Digital.pay
- Physical.pay
- Book.pay
- Menbership.pay
- Order.printShippingLabel
- Order.sendDigitalPurchaseConfirmation
- Order.sendMenbershipPurchaseConfirmation
- Product.pay
Para rodar os testes unitários, execute o seguinte comando:
./gradlew test
Para maiores informações sobre a execução do teste, pode se acessar o relatório no formato html em:
./build/reports/tests/test/index.html