Chargebee · API & Integration Development

The same webhook arrives seven times. Your consumer should find that boring.

Most billing integration bugs are not API bugs. They are consumers written as if an event arrives exactly once, against a platform that documents retries with increasing delays for up to two days. We build the integration code that handles the retry, the replay and the out-of-order delivery without charging anyone twice.

API & Event Architecture
PLATFORM SURFACE Chargebee REST API Resources · Actions · Pagination Webhook Events Event id · Payload · Retries Client Libraries Test Site Idempotency Keys TWOPIR DEVELOPMENT LAYER API Clients Backoff · Errors Rate handling Event Consumers Idempotent Dead-letter queue Observability Tracing · Alerts Safe replay EVERY EVENT ARRIVES TWICE · DESIGN FOR IT 2πr CODE YOU CAN TRUST No Double Charges A retried event changes nothing the second time Failures Surface Fast Dead-lettered and alerted, not silently dropped Safe To Hand Over Tested, documented, and replayable by anyone CLIENT · CONSUME · OBSERVE · REPLAY
12+
Years CRM & revenue delivery
500+
Clients served worldwide
40+
Consultants & engineers
250+
Deployments delivered

Trusted by 500+ organizations — including SaaS, subscription and usage-based businesses running their quote-to-revenue operations on Salesforce, HubSpot and Chargebee with Twopir Consulting.

Amberscript
RChilli
Spinify
Kacific
Mitratech

Engineering Scope

  • Salesforce Partner
  • HubSpot Partner
  • REST API v2
  • Webhook Consumers
  • Idempotency
  • Usage Pipelines
  • Provisioning Services
  • Apex & LWC
Bugs We Are Called In To Fix

The failure modes that only appear in production

These are not exotic. They are the predictable consequences of building against a billing API as if it were a database, and every one of them has cost somebody money.

The consumer is not idempotent

Chargebee retries a webhook that does not return a 2xx, with increasing delays, up to seven times over roughly two days. A consumer that provisions or charges on every delivery will do it again on the first retry.

Events are processed out of order

A subscription is changed twice in quick succession and the deliveries arrive reversed. Code that applies the payload blindly ends up with the older state winning.

Failures are swallowed

The consumer catches an exception, returns 200 to stop the retries, and logs nothing. The event is gone permanently and nobody finds out until a reconciliation months later.

API calls are retried without an idempotency key

A timeout on a create call is retried, and the resource is created twice. Chargebee supports an idempotency key header precisely so a retry is safe — it just has to be used.

Billing logic lives in the application

Proration, entitlement rules and price calculation re-implemented in product code, so the application and the billing system drift apart on every pricing change.

There is no way to reprocess

Something was wrong for a week. Without stored events and a replay path, correcting the downstream state means a bespoke script written under pressure.

The Event Contract

What the platform actually guarantees

These are documented platform behaviours, not opinions. A consumer that respects all five is dull to operate; one that respects four is an incident waiting for volume.

Chargebee notifies your systems through webhooks. Events record changes on your site, and each event carries data about the affected resources plus the time it occurred and an id that uniquely identifies it.

A webhook is only treated as delivered when your endpoint returns a status in the 2xx range. If it does not, Chargebee retries with increasing delays for up to two days, with up to seven retries per failed webhook. That is the reliability model your code has to be written against.

Platform behaviourWhat it means for your codeWhat happens if it is ignored
Webhooks retry on any non-2xx responseReturn 2xx as soon as the event is durably stored, and do the work afterwards. Never do slow work before acknowledging.A slow downstream call causes a timeout, which causes a retry, which causes duplicate work.
Up to seven retries with increasing delays, over about two daysDuplicate delivery is normal operation, not an edge case.Double provisioning, duplicate notifications, and in the worst case duplicate charges.
Each event has an id that uniquely identifies itDe-duplicate on the event id before processing. That is the documented mechanism.There is no other reliable way to tell a retry from a genuine second event.
The last retry lands roughly three days and seven hours after the triggerKeep processed event ids for at least that window before purging them.Purging earlier reopens the duplicate-processing window you just closed.
API requests accept an idempotency key headerSend one on every create or charge call, so a client-side retry after a timeout is safe. A replayed request is flagged in the response.A network timeout on a create call produces two subscriptions or two charges.
Behaviour verified against Chargebee's API documentation, September 2026. Re-verify before relying on specific retry counts — platform behaviour changes between releases.
Before You Write Any Of This

Check whether a supported connector already covers it — Chargebee integration services — connector and iPaaS options, configured rather than built Chargebee integration architecture guide — the ownership and consistency model this code implements Chargebee customization — and where configuration genuinely stops Chargebee consulting services — the wider Chargebee practice this work sits inside

When To Write Code At All

Connector, orchestration, or your own service

We are a development team telling you to write less code. Each step down this list costs more to build and considerably more to own.

Do not build

Use the supported integration

The Chargebee managed package for Salesforce, the HubSpot integration, the accounting connectors. Configured properly these cover the standard flows, and the vendor maintains them across their own releases rather than you.

  • Zero code, zero maintenance burden
  • Maintained through vendor releases
  • Covers the standard CRM and ledger flows
  • Bounded by the mappings it exposes
  • Always evaluated first
Orchestrate

Put the logic on an iPaaS

Workato, Celigo or similar give you retry queues, error visibility and a place to change logic without a deployment. For multi-system flows this is usually the right answer even for teams who could build it themselves.

  • Retry and error handling built in
  • Logic changes without a release
  • Visible to non-engineers
  • A licence and a skill to maintain
  • Right for most cross-system flows
Build

Write the service

Where your own logic genuinely has to sit in the path — a usage pipeline, a provisioning service, latency requirements an iPaaS cannot meet. This is code you own permanently, and we build it to be handed over.

  • Full control over behaviour and latency
  • Idempotent consumers, dead-letter queue, replay
  • Tests, runbook and documented interfaces
  • A permanent maintenance liability
  • Only where the first two cannot
What We Build

Development work against the Chargebee API

Six things we are routinely asked to build, and what a correct implementation of each one involves.

Webhook Consumers

The service that receives Chargebee events and turns them into changes in your systems. Correct means idempotent, fast to acknowledge, and safe to replay.

  • De-duplication on event id with a retention window
  • Acknowledge first, process asynchronously
  • Dead-letter queue for poison messages
  • Ordering handled by resource version, not arrival
  • Replay tooling for reprocessing a period

Usage Ingestion Pipelines

Getting raw product events into Chargebee as clean, billable usage — aggregated, de-duplicated and reconcilable against the source, because a usage bug is a billing bug your customer sees.

  • Event collection and normalisation
  • Aggregation into metered features
  • Late and duplicate event handling
  • Reconciliation against the source of truth
  • Backfill and correction paths

Provisioning & Entitlement Services

The bridge between a subscription change and what your application allows, so an upgrade takes effect immediately and a downgrade actually restricts access.

  • Entitlement reads from the billing record
  • Provisioning on subscription events, idempotently
  • Grandfathering for legacy plans
  • Failure handling that does not lock a paying customer out
  • Reconciliation between entitlement and access

API Clients & Middleware

The code that calls Chargebee, written with the failure modes handled rather than discovered — timeouts, rate limits, partial failures and retries.

  • Idempotency keys on every create and charge
  • Exponential backoff and rate-limit handling
  • Pagination handled correctly on large result sets
  • Structured error handling by response class
  • Client libraries wrapped with your conventions

Salesforce Development

The CRM half, where the managed package does not reach: custom objects, flows, Apex and Lightning components that make billing data usable inside the CRM.

  • Custom objects beyond the managed package
  • Apex services calling the Chargebee API
  • Flow and approval process development
  • Lightning components surfacing billing context
  • Bulk-safe, governor-limit-aware implementations

HubSpot Development

Custom-coded workflow actions, private apps and CRM cards where HubSpot's native Chargebee integration stops short of the requirement.

  • Private apps against the HubSpot and Chargebee APIs
  • Custom-coded workflow actions
  • CRM cards surfacing subscription context
  • Custom object and property design
  • Webhook handling on both sides
Engineering Standards

How we write integration code you will inherit

You are going to own this after we leave. These are the standards that make that realistic rather than theoretical.

Idempotent by default

Every consumer de-duplicates on event id with a retention window covering the full retry period, and every create or charge call carries an idempotency key so a client-side retry after a timeout cannot produce a second resource.

Acknowledge fast, process async

The endpoint stores the event durably and returns 2xx immediately, then processes from a queue. Slow downstream work never happens inside the webhook request, because a timeout there manufactures the retry storm.

Nothing fails silently

Poison messages go to a dead-letter queue with the payload intact and an alert attached. Returning 200 to make retries stop is how a week of missing events becomes a reconciliation project.

Observable and traceable

Structured logging keyed on event id and resource id, so a support question about one customer's invoice can be answered by searching rather than by reasoning about what the code probably did.

Replayable

Stored raw events and tooling to reprocess a time range. When something was wrong for a week, correction should be a documented operation rather than a script written under pressure.

Tested against a real test site

Chargebee provides a test site, and we exercise the awkward paths against it — duplicate delivery, out-of-order events, partial failures — because those are the paths production will find.

How We Deliver

Design the contract, then write the service

Step 01

Technical Discovery

We review the requirement, the existing systems and the data contracts, and establish whether code is genuinely needed or whether configuration covers it.

Step 02

Interface Design

Events consumed, API calls made, failure behaviour, idempotency strategy, retention windows and the replay path — documented before implementation starts.

Step 03

Build & Test

Implementation against a Chargebee test site, with the duplicate, out-of-order and partial-failure paths exercised explicitly rather than assumed.

Step 04

Deploy & Observe

Released with logging, alerting and dashboards in place from day one, so the first production anomaly is visible rather than inferred later.

Step 05

Hand Over

Runbook, tests, documented interfaces and a walkthrough with your engineers. Code only we understand is a dependency we would rather not create.

Related Work

Development engagements from the same practice

Custom development across connected commercial systems is a core part of Twopir's delivery work.

Case Study

Salesforce CPQ & Multi-Tool Integration

Custom integration work connecting quoting to the systems downstream, with the data contracts between them designed rather than improvised.

  • Multi-system integration development
  • Data contract and mapping design
  • Approval and workflow automation
  • Consolidated operational reporting
Read the CPQ Case Study
Case Study

Salesforce & HubSpot Integration

Two platform APIs reconciled with explicit ownership, conflict handling and sync direction rather than a bidirectional sync left on defaults.

  • Cross-platform API integration
  • Field ownership and conflict rules
  • Lifecycle stage synchronisation
  • Reporting across both systems
Read the Integration Story
Case Study

Accounting Seed & Salesforce Integration

Financial data synchronised bi-directionally with reconciliation designed into the flow rather than performed afterwards.

  • Bi-directional financial data sync
  • Billing automation on the CRM record
  • Reconciliation and close support
  • Reporting across ops and finance
Read the Integration Story
Why Twopir

We write less code, and hand over what we write

We help growing and mid-market companies solve complex CRM, integration and business system challenges, and we work with enterprise engineering teams on the same problems at higher transaction volume.

We try to talk you out of the build first

Every requirement is tested against configuration and supported connectors before we quote development. A development team that never recommends less development is selling, not advising.

Idempotency is not an optional extra

Every consumer we write de-duplicates on event id with a retention window covering the full retry period. We treat duplicate delivery as normal operation, because the platform documents it as such.

We test the paths production will find

Duplicate delivery, out-of-order events, partial failures and timeouts, exercised against a real test site. The happy path is not a test plan.

We build the CRM side too

As a Salesforce Partner and HubSpot Partner we write the Apex, flows, private apps and custom actions alongside the billing-side service — so there is no seam between two vendors for defects to live in.

Everything ships with a runbook

Tests, documented interfaces, structured logging, a dead-letter queue and a replay path, plus a walkthrough with your engineers. You should be able to operate it without us, and choose to keep us anyway.

Common Questions

Technical questions, answered technically

A webhook is only considered successful when your endpoint returns an HTTP status in the 2xx range. If it does not, Chargebee retries the call with increasing delays for up to two days, with up to seven retries per failed webhook at exponential intervals. That means your consumer will receive the same event more than once as a matter of normal operation, not as a rare failure.

De-duplicate on the event id, which uniquely identifies the event. Store the ids you have processed and skip anything you have seen before. Because the last retry lands roughly three days and seven hours after the original trigger, keep processed ids for at least that window before purging — purging earlier reopens the duplicate window you closed.

Use an idempotency key. Chargebee accepts one in a request header, and a replayed request is flagged as such in the response, so a client-side retry after a network timeout will not create a second subscription or a second charge. Without it, a timeout on a create call is genuinely ambiguous — you cannot tell whether the resource was created.

For anything beyond simple reads, a service. It gives you one place for idempotency keys, backoff, rate-limit handling and error classification, and one place to change when the API surface evolves. Scattering direct API calls through application code means every one of those concerns is implemented differently in each caller, usually incompletely.

Yes, and it is one of the most common genuinely-custom builds. Usage can be sent to Chargebee by API, bulk upload or the UI, and metered features aggregate those events into billable units. The engineering is in what happens before that: collecting product events, normalising and de-duplicating them, handling late arrivals, and reconciling what you sent against your own source of truth — because a usage bug becomes a billing error the customer sees.

Usually that is the arrangement we prefer. We typically own the integration surface and the billing-side services while your team owns the product, with the interface contract documented between us. We also do pure advisory engagements — design review, code review of an existing consumer, or a second opinion on an architecture before it is built.

You own it outright. It ships with tests, a runbook, documented interfaces, structured logging, a dead-letter queue and a replay path, plus a handover session with your engineers. We keep the custom surface as small as the requirement genuinely allows, because every line we write is a line you maintain.

Next Step

If your webhook consumer assumes events arrive once, it has a bug you have not found yet

We build Chargebee integration code that handles retries, replays and out-of-order delivery without charging anyone twice — and we hand it over with the tests, the runbook and the replay tooling.

Design review, build, or a second opinion before you commit