O checkout-api ignora as cobranças do acordo criadas pelo nectar-charges

TLDR: o webhook do Asaas no checkout-api só reconhece cobranças cujo externalReference é o reference de um Payment dele. As cobranças do reparcelamento criadas pelo nectar-charges caem em “Payment not found” e ninguém devolve o acesso do aluno quando ele paga o acordo.

O que aconteceu

Ao analisar o reparcelamento manual do checkout-api para desenhar o Debits::Repayment, apareceram dois efeitos que o novo fluxo herda.

O que vale saber

  • Payments::FindByExternalReference faz Payment.find_by!(reference:) e, se não acha, falha em silêncio (context.fail!, sem exceção e sem retry). As cobranças do acordo geram só uma linha de log lá. Por isso o externalReference do acordo usa o prefixo nectar_negotiation_.
  • No reparcelamento manual, o pagamento novo tem original_payment, e é isso que faz o ApoloService conceder acesso quando o aluno paga. No fluxo do nectar-charges esse vínculo não existe: se o aluno perdeu o acesso por atraso, pagar o acordo não o devolve.
  • O cancelamento do parcelamento original dispara PAYMENT_DELETED no checkout-api, que marca o pagamento original como cancelado. No ApoloService um pagamento cancelado não concede nem remove acesso. CbtrgService e OnionService não foram lidos.

O que fazer

Resolver junto do spec de webhooks do nectar-charges (negotiated e volta para pending): definir quem pede a devolução de acesso ao Apolo quando a 1ª parcela do acordo é paga.

O mesmo spec precisa tratar o PAYMENT_DELETED das cobranças do acordo. O Debits::Repayment confia no provider_installment_id gravado e não reconsulta o provedor, então uma exclusão feita direto no painel do Asaas passa despercebida e deixa o débito aguardando um pagamento que não existe mais.