invoice API for SaaS billing
Invoice API for SaaS billing
Create a customer invoice when a subscription renews, then mark your own ledger from the invoice.paid webhook. InvoiceTXT sends the invoice. Your app still owns the subscription.
Base URL https://invoicetxt.com Auth Authorization: Bearer itxt_live_…
When a renewal succeeds
Your billing worker already knows the customer, the period and the amount. Create one InvoiceTXT invoice for that charge. Store the returned id on the renewal row so a retry does not create a second invoice. Check your own database before you call the API again.
Use a clear description such as "Pro plan, November 2026" rather than an internal price id. The customer sees that description on the invoice and in the text message.
{
"client": "Acme Ltd",
"due": "on receipt",
"currency": "USD",
"items": [
{"description": "Pro plan, November 2026", "quantity": 1, "rate": 19}
]
}Close the loop with a webhook
Subscribe to invoice.paid and invoice.signed on an https endpoint. When invoice.paid arrives, find the renewal by data.id and mark it paid in your ledger. Verify the signature before you trust the body.
Compare the HMAC of the raw request body with X-InvoiceTXT-Signature. Use a constant-time compare. Reject the request if the signature does not match, and do not follow a redirect when you first saved the webhook URL. InvoiceTXT will not post to a private IP.
signature = request.headers['X-InvoiceTXT-Signature']
expected = 'sha256=' + OpenSSL::HMAC.hexdigest('SHA256', secret, request.raw_post)
head :forbidden unless ActiveSupport::SecurityUtils.secure_compare(signature, expected)What this does not replace
This API creates and tracks the invoice. It does not calculate proration, run your subscription state machine, or file your sales tax return. Keep that logic in your billing service and send InvoiceTXT the final lines you want the customer to see.