What Should Happen When a Customer Accepts an Old Quote?
A customer opening an old quote should see whether that exact version is still available to accept. Before building a quoting portal, agree its expiry rule, how revised offers replace older ones and what happens when acceptance meets a cancellation or deadline. Do not let the button alone determine whether the business has accepted an order.
This is a software-workflow guide, not legal advice about when a contract forms or whether an offer may be withdrawn. Have the terms and customer wording reviewed for your business and jurisdiction.
Separate the offer from the current price list
A quote is a particular proposal, not simply a view of today's catalogue. For a custom app, ask to preserve the issued description, quantities, prices, currency, relevant terms and version identity. Otherwise a customer returning to the same link might see different work or a different amount without understanding that the offer changed.
Keep a draft editable. Define a distinct issue step that creates the customer-facing version. If you need to correct that issued offer, decide whether to withdraw it and issue a replacement or follow another explicit revision process. Do not silently overwrite the version someone is considering.
These are recommended requirements, not claims that every quoting product implements them.
Give validity a precise meaning
“Valid until Friday” leaves unanswered questions. Which time zone applies? Does the deadline mean the start or end of that day? What happens at the boundary? Put the complete deadline in the specification and show customers wording that matches it.
Stripe provides a concrete product example. Its Quote object defines expires_at as the date at which an open or draft quote will be canceled, measured in seconds since the Unix epoch. Its quote guide says canceled quotes cannot be accepted. That is Stripe's lifecycle, not a rule all custom portals inherit.
In your own system, choose the deadline and the boundary test explicitly. Require the service handling acceptance to check current eligibility rather than trusting a page that may have been open for hours. A countdown or disabled button is useful feedback, but should not be the only enforcement.
Decide what an old link tells the customer
An expired link should explain that the offer is no longer available and provide an appropriate way to request an updated proposal. It should not display a success message or silently substitute a new price.
If a revised quote exists, show the relationship clearly. Decide whether the old link may point to the replacement and what information it may reveal. Access to one proposal should not automatically expose unrelated customer records.
Keep withdrawal, expiry and replacement distinguishable in the staff history, even if the underlying platform groups some of them into one status. Staff need to explain what happened without guessing.
Resolve acceptance against the current version
Consider a hypothetical customer leaving a quote open while a staff member withdraws it. The customer's later click should be checked against the latest recorded state. Agree which operation wins when withdrawal and acceptance arrive together, and ask the developer to demonstrate that only a permitted transition can complete.
Also ask what happens after a repeated click or a lost confirmation response. A customer who is unsure whether acceptance succeeded should be able to retrieve the recorded outcome. Do not create another order merely because the first response failed to arrive.
This recommendation concerns the acceptance record and downstream work. It is not a claim that writing a status automatically makes every external payment or email action exactly once.
Acceptance is not the same as payment
Stripe's documented accepted status means the customer accepted the quote and an invoice, subscription or subscription schedule was created. It does not define that status as proof of payment.
Make the distinction equally clear in your app. Agree what follows acceptance: an order awaiting review, an invoice, a scheduling request or another defined next step. State whether work may begin and who confirms payment separately. A customer-facing message should describe the actual recorded outcome, not promise that every later step is complete.
Demonstrate the difficult journeys
Use these scenarios in your acceptance criteria:
- The customer accepts the current offer before its deadline and can reopen the confirmation.
- An expired offer explains the next step and cannot create an accepted order.
- An older version remains identifiable after a replacement is issued.
- A stale browser page cannot accept an offer that staff have withdrawn.
- Simultaneous withdrawal and acceptance produce one explainable recorded outcome.
- A repeated submission does not create duplicate downstream work.
- Accepted, awaiting payment and paid are not presented as interchangeable states.
For a custom quoting portal, bring an example of an expired quote and a revised quote, not just a successful new sale. Those examples expose the decisions that a simple accept button hides.
Sources
Stripe, quote lifecycle: https://docs.stripe.com/quotes
Stripe, Quote object and expiry field: https://docs.stripe.com/api/quotes/object
The cited product behaviours are specific to Stripe. Versioning, customer messaging and acceptance checks above are planning recommendations, subject to implementation and appropriate legal review.