Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProcesosAgilesUMSS/sansistore/llms.txt

Use this file to discover all available pages before exploring further.

Payment reconciliation in SansiStore is the process by which administrators verify that the cash or digital payments collected by couriers match the order totals registered in the system. The PaymentReconciliationPanel provides a real-time, filterable view of delivered orders that have discrepancies against the payments collection. Alongside reconciliation, a per-order payment audit trail is maintained in the immutable paymentActivityLogs collection.

PaymentReconciliationPanel

The panel is powered by listenPaymentReconciliation from paymentReconciliationService.ts, which opens two simultaneous Firestore onSnapshot listeners — one on orders and one on payments — and calls buildReconciliationItems whenever either collection changes. Only delivered orders are included in reconciliation. An order is considered delivered when its deliveryStatus normalizes to "delivered" or its status normalizes to "entregado". For each delivered order the service looks up a matching payment document by orderId and classifies the discrepancy:
Issue TypeLabelCondition
missing-paymentSin pago registradoNo payments document found for the order
pending-paymentPago no cobradoPayment exists but status is not in the collected set
amount-mismatchMonto diferentePayment collected but Math.abs(order.total - payment.amount) > 0.01
Collected payment statuses (case/accent-insensitive): cobrado, pagado, paid, verified, verificado, validado.

PaymentReconciliationItem Fields

FieldTypeDescription
orderIdstringOrder identifier
customerNamestringCustomer display name
customerPhonestringCustomer phone number
orderTotalnumberExpected amount (from orders.total)
paymentAmountnumber | nullActual collected amount (null if no payment record)
differencenumberorderTotal - paymentAmount (0 if no payment)
orderStatusstringOrder status string
deliveryStatusstringDelivery status string
paymentStatusstringPayment status string
paymentMethodstringPayment method string
deliveredAtDate | nullDelivery timestamp
updatedAtDate | nullLast update timestamp (fallback sort key)
issueTypeReconciliationIssueTypeClassification of the discrepancy
Results are sorted by deliveredAt descending (falling back to updatedAt). The panel updates automatically as Firestore data changes — no manual refresh is needed.

Reconciliation Workflow

1

Courier closes their session

At the end of their shift the courier submits a session closure from the courier portal. This creates a document in messenger_shift_closures with status: 'closed', a summary.totalCollected amount, and snapshots of completed, pending, and incident orders.
2

Admin opens the reconciliation panel

The admin navigates to the Reconciliation section of /admin. The PaymentReconciliationPanel loads all delivered orders with discrepancies from Firestore in real time.
3

Admin reviews total collected vs. expected

For each flagged order the panel shows orderTotal (expected), paymentAmount (collected), and difference. The summary cards at the top display aggregate counts: total inconsistencies, missing payments, uncollected payments, and amount mismatches.
4

Admin validates or disputes the courier session

For session-level validation, the admin opens the Courier Sessions panel and calls PATCH /api/admin/courier_sessions with { closureId, action: "approve" | "reject", rejectionReason? }. The sessionsService.validateShiftClosure function handles the request.
5

Session status is updated

On approval the messenger_shift_closures document is updated to status: 'validated', and validatedBy (admin UID), validatedAt (server timestamp), and validatedByName are written. On rejection, status becomes 'rejected' and rejectionReason is stored. A session already in validated or rejected state cannot be modified (API returns 409).

Payment Methods and Statuses

SansiStore supports four payment methods:
ConstantLabel
EFECTIVOEfectivo (cash)
QRQR payment
TRANSFERENCIABank transfer
TARJETACard payment
Payments in the payments collection follow a lifecycle:
PENDIENTE  →  VERIFICADO
           →  RECHAZADO
Verification writes verifiedBy (admin UID) and verifiedAt (timestamp) to the payment document. The order_history API surfaces these fields in the payment sub-object returned per order.

PaymentAuditPanel (per-order audit)

The PaymentAuditPanel component in pedidos/payment-audit/ subscribes to the paymentActivityLogs collection via escucharHistorialCobros from paymentAuditService.ts. It shows the per-order history of every collection event — useful for tracing disputed charges back to the collector. Filter support: orderId, collectedById, paymentMethod (EFECTIVO | QR | TRANSFERENCIA | TARJETA | ALL), and startDate/endDate. escucharEncargadosCobros derives the unique collector list from existing log entries, enabling a “filter by collector” dropdown without an extra users query.

paymentActivityLogs Collection (Immutable Audit Trail)

Every payment collection event — regardless of whether it was made by a seller, courier, or admin — is appended to paymentActivityLogs by registrarActividadCobro.

Document Fields

FieldTypeDescription
orderIdstringAssociated order ID
collectedByPaymentCollectorObject: { id, nombre, email, rol }
collectedByIdstringCollector UID (legacy flat field)
collectedByNamestringCollector display name (legacy flat field)
collectedByEmailstringCollector email (legacy flat field)
collectedByRole'VENDEDOR' | 'MENSAJERO' | 'ADMIN'Collector role at time of event
amountnumberAmount collected
paymentMethodPaymentMethodOne of EFECTIVO, QR, TRANSFERENCIA, TARJETA
statusPaymentStatusPENDIENTE, VERIFICADO, or RECHAZADO
timestampDateServer-side Firestore timestamp
paymentActivityLogs is a write-once collection. Firestore security rules set allow update: if false and allow delete: if false on these documents. Only admins can read the collection. New entries must pass schema validation; partial or malformed writes are rejected. Never attempt to modify or delete an existing audit log entry — treat it as an immutable ledger.

Database Management

For edge cases that require direct intervention, the OrdersManagementPanel (under Database Management in the admin sidebar) provides EditOrderModal and DeleteOrderModal components backed by ordersAdminService.ts. These operations bypass the normal order state machine and should only be used by admins to correct data integrity issues.
Direct order edits and deletions are logged server-side. Use this panel only when the standard seller/courier workflow cannot resolve the issue, and document the reason for the change in your internal ticketing system.

Build docs developers (and LLMs) love