feat(payments): record an out-of-band gateway payment with its reference and date - #326
Open
modernitconsultants wants to merge 1 commit into
Open
Conversation
…nce and date Reconciling money means matching three things by id: what was due, what the ledger holds, and what the provider actually took. The payments table already has gateway_transaction_id, but CreatePaymentDto did not accept it and only the authorize/capture path could populate it. So a payment taken OUTSIDE the PMS — a payment link the guest paid, a terminal, a charge made in the provider's own dashboard — could only be recorded with no reference back to the provider at all, and nothing to reconcile against a settlement report. The settle-path guard is refined rather than relaxed, because it was conflating two opposites. A TOKEN is a chargeable instrument: presenting one here is an attempt to take money through the settle path and still goes via authorize. A TRANSACTION ID is evidence a charge already happened elsewhere. So a card method carrying a token is still refused, and a card method naming a gateway must now carry either a transaction id or use authorize — naming a provider with neither is what the original guard was really aimed at, and stays refused. processedAt is the same argument for time. A historical import stamped with the import date makes the ledger disagree with the settlement report it exists to be reconciled against. Optional, refused if in the future, and resolved explicitly rather than left to the object spread — where it would have been carried through as a string and then silently overwritten by the hardcoded new Date(). Specs cover both directions, including the negative control: omitting processedAt must still stamp now, or the positive test could pass while the field was ignored entirely. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reconciling money means matching three things by id: what was due, what the ledger holds, and what the provider actually took.
The
paymentstable already hasgateway_transaction_id— butCreatePaymentDtodoesn't accept it, and only the authorize/capture path can populate it. So a payment taken outside the PMS (a payment link the guest paid, a terminal, a charge made in the provider's own dashboard) can only be recorded with no reference back to the provider at all, and nothing to reconcile against a settlement report.The settle-path guard is refined, not relaxed
It was conflating two opposites:
POST /payments/authorize. Unchanged.So a card method carrying a token is still refused, and a card method naming a gateway must now carry either a transaction id or use authorize — naming a provider with neither is what the original guard was really aimed at, and stays refused.
processedAtis the same argument, for timeA historical import stamped with the import date makes the ledger disagree with the settlement report it exists to be reconciled against. Optional, refused if in the future, and resolved explicitly rather than left to the object spread — where it would have been carried through as a string and then silently overwritten by the hardcoded
new Date().Specs
Both directions, including the negative control: omitting
processedAtmust still stamp now, or the positive test could pass while the field was ignored entirely.Context: this came out of a two-week integration against a live property with real Square payments taken outside the PMS — the same work behind #321.