mony (v1.0.0)

Daki financial operations service: manages refunds (manual and automatic), Brazilian invoices (NF-e via bravalara) and an order read model for the internal back-office (multi-country BR/CO/MX/PE/CL).

Service Overview

mony is Daki’s financial operations service, built with Go (Gin + gqlgen + MongoDB). It manages:

  • Refunds: manual refunds created by ops users (back-office) and automatic refunds triggered by order events (cancellation, underpicking), including split between payment method (cash leg via paym) and refund wallet (Talon.One)
  • Invoices: Brazilian NF-e generation via bravalara
  • Order read model: hydrated from order events, serving the internal back-office GraphQL API

It runs as two binaries: cmd/api (HTTP + Pub/Sub worker + refund auto-approve job) and cmd/consumer (Kafka consumers).

API Endpoints

Authentication: ops endpoints use Google OAuth (JWT + casbin RBAC); service-to-service endpoints use a static API key.

MethodPathAuthPurpose
GET/Liveness/readiness probe
GET/healthzHealthcheck (includes MongoDB check)
GET/oauth2/google (+ /callback)Google OAuth login for ops users
POST/graphqlJWT + RBACBack-office GraphQL — queries: orders, order, fetchInvoice, refunds, refund, customer, users, roles; mutations: calculateRefund, createRefund, updateRefund, approveRefund, rejectRefund, createUser, updateUserRoles
POST/graphql_internalAPI keyService-to-service GraphQL — query refund; mutation updateRefundStatus
POST/api/ordersAPI keyCreate order in the read model (HTTP hydration)
POST/api/orders/:order_id/messagesAPI keyAttach info/error message to an order
PUT/api/orders/:order_id/payment_detailsAPI keyUpdate order psp_reference and payment_deeplink
POST/api/invoicesAPI keyInvoice-created callback (bravalara async mode); persists and publishes new_invoice
POST/api/invoices/bigtAPI keyBatch invoice generation upload (BIGT)

Events Consumed

Kafka topic seller_orders.out (produced by seller-backend, contract v2 — messages with meta.version != 2 are discarded):

  • seller_order.created → upserts the order in the read model (order_version = "v2")
  • seller_order.delivered → hydrates the order; when unpicked_items is present, creates an automatic PARTIAL refund (underpicking) and executes the cash leg via paym HTTP (capture/cancel when pre_authorized, refund when paid)
  • seller_order.canceled → hydrates the order; when payment_status == "paid", creates an auto-approved FULL refund (cash target)

Kafka topic bills.out (produced by paym):

  • bill.refunded → marks the refund cash leg as REFUNDED
  • bill.failed_refund → marks the cash leg as FAILED; when terminal and the wallet leg succeeded, retries the refund on the wallet

GCP Pub/Sub subscription ordr-output-mony (legacy ordr flow, being removed in the Seller Order migration):

  • ordr_refund_completed → marks refund REFUNDED and stores pspReference
  • ordr_refund_refused → marks refund FAILED with reason
  • ordr_salesforce_order_status_update → read model upsert; BR + Picked triggers NF-e generation; Cancelled + paid triggers automatic FULL refund; Fulfilled + PartiallyPicked triggers PARTIAL refund

Events Produced

GCP Pub/Sub topic ordr-input (envelope tags{event_type, id, country_code, service_name: "mony", service_version: "v1", at}):

  • new_refund — published when a refund is approved (ops mutation approveRefund, the 1-minute auto-approve job, or automatic refund flows). Payload: {"new_refund": {"id": "<refund_id>"}}. Consumed by ordr, which delegates the PSP refund execution.
  • new_invoice — published when an NF-e is successfully generated. Payload: {"new_invoice": {orderId, invoiceNumber, invoiceSerial, invoiceAccessKey, invoiceFileUrlPdf, invoiceFileUrlXml, creationDate}}. Consumed by ordr.

Non-broker Integrations (HTTP outbound)

  • paym (payments_backend REST): refund cash leg (capture / cancel / refund)
  • Talon.One: refund wallet leg
  • bravalara (GraphQL): NF-e generation
  • ordr (GraphQL, deprecating), User Profile Service, checkout-calculator