docs: add design document for customer-portal receipts#11188
docs: add design document for customer-portal receipts#11188psincraian wants to merge 1 commit intomainfrom
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Preview Environment |
|
|
||
| ## Briefing | ||
|
|
||
| The customer portal already exposes "Download Invoice" on every paid Order, but invoice generation requires `billing_name` and `billing_address`. Customers who never fill those in (indie devs, wallet payers, anyone topping up balance credit) get nothing. Support sees regular requests for proof of payment, and some customers actually require it for bookkeeping, expense reimbursement, or compliance. They don't need a tax invoice, just confirmation that the charge happened. |
There was a problem hiding this comment.
Customers who never fill those in (indie devs, wallet payers, anyone topping up balance credit) get nothing.
That's not true :) Invoices are generated automatically and attached to the confirmation email. It shows the billing info we have (so the customer name and country at the bare minimum).
I think the heart of the problem is people who want a proof of payment.
There was a problem hiding this comment.
That's my fault and wrong assumption then. Will fix it
|
|
||
| The customer portal already exposes "Download Invoice" on every paid Order, but invoice generation requires `billing_name` and `billing_address`. Customers who never fill those in (indie devs, wallet payers, anyone topping up balance credit) get nothing. Support sees regular requests for proof of payment, and some customers actually require it for bookkeeping, expense reimbursement, or compliance. They don't need a tax invoice, just confirmation that the charge happened. | ||
|
|
||
| A **receipt** is the missing artifact: a PDF proving the payment event without the billing-details gate. It mirrors Stripe's `charge.receipt_url`. The PDF is mutable, so refunds are reflected in the same document over time. |
There was a problem hiding this comment.
This isn't how it should work.
Receipts should match bank transactions (for the end customer).
So if you as the buyer have on April 23 a charge of $29.94 and on May 7 a refund incoming of $29.94, you will need two receipts.
There was a problem hiding this comment.
That's not right :)
Stripe charge.receipt.url is a mutable document that's keep up to date with the latest payment information.
With François, we discovered that when a refund is made the url gets up to date. For the refund one, the original payment is shown and the refunded amount.
There was a problem hiding this comment.
But it's still two different documents, right? Surely the receipt.url reference is updated, but I'm pretty sure both still exist in Stripe's records somewhere somehow.
There was a problem hiding this comment.
Yes, in the S3 we are gonna store all documents just in case.
The idea is to store them in {orgId}/{orderIt}/{timestamp}.pdf
|
|
||
| ### Refund regeneration | ||
|
|
||
| When a refund is finalized, the refund hook calls into the receipt service to enqueue a render. The old `receipt_path` keeps serving until the new file is uploaded and the column is swapped. There is no null gap: customers downloading mid-window get the previous PDF, and the next download gets the new one with the Refunds section. |
|
|
||
| None outstanding for v0. The following are explicitly deferred: | ||
|
|
||
| - Receipts for Orders without a succeeded Payment. Could be revisited if support volume justifies it. |
There was a problem hiding this comment.
I believe this is not a thing? What would the receipt be for?
There was a problem hiding this comment.
I don't think this would be needed, the receipt will mainly show: "Discount applied. Free order" or similar. I don't think this is needed that's why I deferred it
| None outstanding for v0. The following are explicitly deferred: | ||
|
|
||
| - Receipts for Orders without a succeeded Payment. Could be revisited if support volume justifies it. | ||
| - Email delivery. |
There was a problem hiding this comment.
I think it was Isac who raised a good point here: if we generate receipts but we don't give merchants the option to send them automatically, customers will keep asking for it over support instead of actually fixing the problem we're trying to self-serve. So it's worth considering if we should email them, and if so, when and how. In other words, can they be bundled in with an existing email? Theoretically, that should be possible for one-time purchases and subscription starts (as the payment proceeds), for subscription renewals, it's harder.
There was a problem hiding this comment.
At the beginning, I was thinking to add only a to the order view in the customer portal. So the user can click it if they need to download it.
Summary
handbook/engineering/design-documents/receipts.mdxfor the upcoming customer-portal Receipts feature.RCPT-number prefix.No code changes — documentation only.
Test plan
🤖 Generated with Claude Code