Quick Answer
Build an invoice API flow around a durable invoice obligation: prepare the draft, validate required legal and tax data, complete any required clearance, then issue and deliver. Track payments and allocations separately from invoice status, and make local posting plus outbound ERP work recoverable. One invoice can have several payments, and one payment can cover several invoices.
Key Takeaways
- Validate required jurisdiction data and clearance before legal issuance, rather than finalize globally and correct later.
- Persist operation identity before dispatch and recover unknown outcomes before retrying with a new identity.
- A received webhook is not yet processed; local accounting and outbound ERP work need a recoverable commit.
- Payments and invoice balances have many-to-many relationships through explicit allocations.
- Correct issued invoices through the applicable adjustment process; a refund and a credit note are different events.
Set the operating scope before writing code#
An invoice API creates a receivable that finance must be able to explain later. The integration needs to preserve who was billed, what was issued, how payments were applied, and which records reached accounting. A successful create call is only the first part of that work.
Name the systems of record for invoice lifecycle, payment status, local journals, and ERP posting. Define whether your platform or the invoicing provider owns numbering and legal issuance. If the ERP is the final accounting record, specify how it receives issued invoices, receipts, adjustments and reversals.
Decide whether the product needs issuance only or broader accounts-receivable workflows such as delivery, reminders, collection and dunning. A PDF generator provides an output document; it does not automatically provide invoice state, collection, or reconciliation.
| Integration choice | When it may fit | Work that still needs ownership |
|---|---|---|
| Invoice API embedded in your product | Customers need to create and manage invoices inside your platform | Your team owns the interface, lifecycle handling and customer support handoffs. |
| External invoicing application with API integration | Finance already works in another invoicing system | Keep identity, status and accounting synchronized across the two systems. |
| Jurisdiction submission connector | The invoice must follow a regulated format or clearance process | Validate coverage, submission state, rejection handling and permitted corrections for each market. |
These choices can be combined. A product can embed an invoice interface while using a specialized connector for a country’s required submission. Compare the actual APIs and responsibilities, rather than assume an embedded interface gives more legal coverage.
Define the records and lifecycle#
Keep a stable internal invoice ID and the originating business reference, such as an order or billing-period obligation. Store supplier entity, customer, currency, line amounts, tax treatment, totals, due date, legal invoice number when assigned, provider ID, and applicable jurisdiction profile. Preserve the issued version separately from mutable draft data.
Stripe’s invoice workflow is a concrete API example: invoices begin as drafts and can become open on finalization, then paid, void or uncollectible according to the operation. Keep provider state separate from your legal-clearance, delivery and accounting states; their meanings are not interchangeable.
| State dimension | What it tells you |
|---|---|
| Draft and issuance | Whether details are editable and whether the invoice has been legally issued. |
| Submission or clearance | Whether a required jurisdiction process is pending, accepted or rejected. |
| Delivery | Whether the customer received or can access the invoice. |
| Collection | Which payments are processing, confirmed, returned or refunded. |
| Allocation and balance | How much of each payment applies to each invoice and what remains due. |
| Accounting and ERP | Whether the local entries and corresponding remote accounting records exist. |
An invoice can be issued before its customer pays. Post the receivable and any revenue or tax entries at the point required by the accounting policy; do not wait for cash by default. A later receipt reduces the relevant receivable through an allocation. Provider fees and settlement transfers have their own records.
Validate jurisdiction requirements before issuance#
Build a draft first. Determine the supplier entity, transaction jurisdiction and applicable profile, then validate required identity, tax, numbering, format and submission data. If the regime requires clearance before issuance or delivery, obtain it before treating the invoice as issued or sending it to the buyer. Control automatic finalization so it cannot bypass this sequence.
Separate country adapters in the software, but keep the required checks in the affected invoice’s critical path. A connector outage should leave that invoice in a visible pending state. It need not stall unrelated invoices in markets that do not use the connector. A request timeout requires recovery of the submission result before resubmission.
The EU’s e-invoicing guidance distinguishes structured electronic invoices from ordinary document files and describes the European standard in public-procurement contexts. Directive 2014/55/EU is not a universal mandate covering every private B2B invoice. Country and transaction requirements must be assessed separately.
For markets such as Mexico or Malaysia, use the current authority and connector specifications for the actual invoice type, accepted data, submission process and correction windows. Do not copy one country’s cancellation period or receiver fields into a global policy. Keep profile versions with the invoice so later investigations can identify the rules used.
Incomplete drafts may be saved for completion, but required issuance fields must be checked before the irreversible step. Reject invalid values with a precise field error and a next action. Tax-status documents for a separate payout or reporting workflow should not become a universal condition for creating every sales invoice.
Make each outbound operation recoverable#
Before calling create, finalize, submit, refund or export, persist a durable operation ID, the stable business key, and the exact payload. Record which invoice version the operation applies to. Prevent concurrent workers from creating a second operation for the same intended effect.
Stripe’s idempotency documentation describes saving the first result for a key and comparing repeated request parameters. Keys can be removed after they are at least 24 hours old, so protection is not indefinite. Check each API’s documented behavior instead of assuming every provider accepts the same controls.
If the response is lost, mark the operation’s result unknown. Retrieve the provider object or operation using the saved reference, or replay the same request and key while that guarantee remains valid. Do not generate a fresh key and create another invoice just because the original request timed out. After a protection window expires, reconcile the original outcome before a new action.
Persist the returned object ID and response, then move the operation forward. Your business key should remain stable even when a retry changes the transport attempt. Keep separate operations for a genuinely new effect, such as an authorized credit note or second payment, rather than reuse the original create key.
Receive webhooks without losing work#
Stripe’s webhook guidance requires signature verification against the raw request body and warns that events can be duplicated or delivered out of order. Its live-mode automatic retries can last up to three days. Those are Stripe-specific delivery behaviors, not guarantees for every invoice provider.
Authenticate the event and durably store its receipt before returning a successful acknowledgment. A receipt can be waiting, processing, processed, or failed. Receiving a duplicate should return safely while ensuring any earlier unprocessed receipt still has work scheduled. Do not mark an event processed merely because it was inserted into the inbox.
In one local database transaction, apply the valid state change, create the uniquely keyed local accounting effect, record any outbound ERP work, and mark the receipt processed. A crash before commit leaves the work recoverable; a crash after commit leaves the stored result and pending outbound work available. This is a recommended integration pattern, not an automatic feature supplied by the invoice API.
Dispatch the stored outbound work after the local commit. A remote ERP call cannot be part of the same atomic database transaction. If its response is lost, recover the remote posting by the durable operation reference before creating another journal. Track remote acknowledgment separately from local processing.
For out-of-order events, use valid lifecycle transitions and the provider’s current object or documented version where necessary. Arrival time alone cannot determine the latest state. A legitimate refund or return can change balances after payment success, so do not discard every later adverse event as a forbidden backward transition.
Model payments and allocations separately#
One invoice may have multiple payments, and one payment may settle multiple invoices. Use an allocation record linking a payment, an invoice, an amount and currency, with any conversion details needed for accounting. Do not make invoice ID plus a single payment reference your entire collection model.
Stripe’s partial-payment documentation describes multiple invoice payments and remaining balances. Use the provider’s supported flow and track each payment independently. A payment still processing is not confirmed cash, and an invoice marked paid outside the processor may have no processor collection to settle.
Worked example: a partial payment and later refund#
Consider a €1,000 invoice, with tax detail already recorded in its issued total. The customer pays €400, leaving €600 due, then €600, leaving zero. There are two receipt records and two allocations to one invoice. If a processor deducts €12 in fees, the net €988 settlement is not evidence that the customer still owes €12; account for the fee separately.
Later, the business approves a €100 price reduction and returns €100. Record the authorized invoice adjustment, such as the applicable credit note, and the separate cash refund. Applied correctly, the revised obligation and net customer payments are both €900. If the €100 was only a payment reversal without a price reduction, the receivable could instead reopen. The event’s business meaning determines the accounting.
An incoming transfer with an unknown customer or invoice belongs in an unmatched-receipt queue or suspense account under your accounting policy. Record the cash even while allocation is pending. Do not invent a paid invoice or omit the receipt because it cannot yet be matched.
Correct issued invoices through the proper adjustment process#
Draft fields can be edited within the provider’s supported lifecycle. Issued or finalized invoices may have restricted fields and legal correction rules. Use the permitted void, cancellation, credit-note or replacement process rather than overwrite the original invoice and erase its history.
Stripe’s credit-note API distinguishes reducing an invoice balance from refunding an already-paid amount or giving other forms of credit. Preserve the connection between the original invoice, adjustment and any refund operation. A credit note is not itself proof that money reached the customer.
Reconcile returns and disputes as separate events too. Keep the original receipt, the adverse event, its allocation reversal where appropriate, and the resulting balance. Finance should be able to explain the change without deleting the payment history.
Reconcile to ERP and settlement#
At close, compare issued invoices and adjustments with outstanding balances, confirmed receipts and allocations, unmatched funds, fees, settlement cash, local journals and remote ERP records. Investigate differences with a named owner and next action. A product status of paid does not prove that accounting export succeeded.
| Exception | What to inspect first |
|---|---|
| Invoice issued, receivable missing | Issuance operation and accounting policy; recover the missing posting without reissuing. |
| Payment confirmed, allocation missing | Receipt and processing status; recover allocation work. |
| Receipt unmatched | Customer and payment references, amount and permitted matching rules. |
| Local journal exists, ERP result unknown | Outbound operation reference and remote record before another create call. |
| Invoice paid, settlement lower | Fees, reserves, other balance movements and settlement composition. |
| Refund or return after payment | Adjustment basis, cash movement and any allocation reversal. |
For Stripe bank-transfer invoicing, receiving details and customer-balance reconciliation form a particular provider workflow. Map the documented provider references to your own customer and invoice records. Do not assume that every provider issues one unique receiving account per invoice.
Test the recovery cases before volume grows#
Use representative invoices from the actual products and jurisdictions you support. Test duplicate create requests, a lost finalize response, a crash after webhook receipt, duplicate events, a lost ERP response, and partial payments followed by adjustments. Also test a rejected required submission and a payment that cannot be matched immediately.
The useful result is a traceable record for every intended effect, with no duplicate issuance, receipt, refund or posting. Keep ordinary recovery work separate from cases that require a legal or accounting decision, and give each exception an owner.
Frequently Asked Questions
How is an invoice API different from generating a PDF?
An invoice API can manage lifecycle, delivery and collection records. A PDF generator creates a document output. Neither a PDF nor a successful create response proves that legal issuance, payment allocation and accounting are complete.
Should jurisdiction validation happen after finalization?
Required validation and any pre-issuance clearance belong before legal issuance. Keep an affected invoice pending if that required process fails; separate country adapters can prevent the failure from stopping unrelated markets.
Can one invoice have several payments?
Yes. Keep individual payments and their invoice allocations, rather than force a one-invoice-to-one-payment relationship. Fees and settlement totals must be reconciled separately.
When should a webhook be marked processed?
After its local state, accounting effects and outbound work have committed durably. Authenticate and store receipt before acknowledgment, then recover any unprocessed receipt. Remote ERP completion is a separate state.
What should happen after an unknown API result?
Use the saved operation identity to retrieve or safely replay the original request. Resolve whether it already succeeded before using a new identity that could create a duplicate.
Is a refund the same as a credit note?
No. A credit note adjusts the invoice obligation; a refund moves money back to the customer. Link both when the business event requires both, and record their independent outcomes.
Try a related tool
Where Gruv fits
See reconciliation and mismatch review
Compare ledger entries, provider payment records, and statement rows to see what matches and what finance needs to review.
See invoice-linked collection
Issue a payment request against an invoice, open hosted checkout, and keep provider status and finance references connected.
Researched and edited by the Gruv editorial team. Gruv builds cross-border billing, payouts, and finance-operations software for global businesses.
Sources
Educational content only. Not legal, tax, or financial advice.
Related Posts

ACH API Integration to Programmatically Initiate and Track Transfers in Your Platform
Treat this as an architecture guide, not an ACH 101. An ACH API lets your platform initiate, send, and track ACH payments. The harder part is often not the first create-transfer call. It is deciding where transfer intent lives, how asynchronous status updates enter your application, and which records you keep when finance or support asks what happened to a specific payment.

Embedded Working Capital: Factoring, Financing, or Cash Advance
Treat this as a product design choice first and a funding feature second. The model you pick changes who controls the invoice asset, who collects repayment, what your support team has to explain, and how the economics hold up once disputes and exceptions show up. That is the real lens for embedded working capital.

ERP Sync Architecture for Payment Platforms Using Webhooks, APIs, and Event-Driven Patterns
If you run payouts into an ERP, "just use an API and a webhook" is not enough. The design has to survive retries, late events, and finance scrutiny without creating duplicate payouts or broken reconciliation. The real question is not which transport looks modern. It is which pattern keeps postings correct, traceable, and recoverable when delivery gets messy.

