- Blog•
- •
- 20 min read
Referral Attribution Setup Without Stripe or Chargebee October 2026
Your referral program is probably built to listen for a billing event that never comes. If you're not on Stripe or Chargebee, that invoice.paid signal doesn't exist. That means your referral program manual billing workflow needs a different trigger entirely, whether that's a HubSpot deal stage or a direct API call from your backend.
- Why referral attribution breaks outside Stripe and Chargebee
- How referral programs track conversions without a native billing integration
- Using HubSpot deal stages as the conversion trigger
- Setting up the referral code to travel through your CRM
- Firing custom API events for non-CRM billing flows
- Manual invoicing and bank transfer: closing the attribution loop
- Org-level attribution when the payer and referrer differ
- Reward trigger configuration for sales-led conversion events
- Testing your non-standard attribution setup before going live
- How Cello handles referral attribution outside Stripe and Chargebee
- Final thoughts on referral attribution without a native billing integration
TLDR:
- Referral attribution breaks outside Stripe and Chargebee because no billing webhook fires to carry the referral code forward.
- Capture
cello_uccat link-click and write it to both a Contact and Deal property in HubSpot, or attribution is unrecoverable by payment time. - Two paths close the gap: HubSpot deal stage webhooks and direct REST API calls from your backend fired on payment confirmation.
- For bank transfer and ACH flows, middleware tools like Zapier or Make can route an accounting status change into a CRM trigger that fires attribution.
- Cello writes the referral code to the customer record at click time, so a 30-day or 60-day payment window does not break attribution provided the code was persisted correctly.
Why referral attribution breaks outside Stripe and Chargebee
Stripe and Chargebee make referral attribution straightforward because they fire predictable webhooks: invoice.paid lands, the system reads the cello_ucc metadata field on the customer object, and the reward triggers. The entire flow depends on that webhook existing.
When billing lives outside those systems, the webhook never fires. A sales rep closes a deal in HubSpot, the finance team sends a PDF invoice, the customer pays via bank transfer three weeks later. Nothing in that sequence produces an invoice.paid event. The referral code that traveled with the prospect has nowhere to land.
This is the structural gap: referral attribution expects a billing event as the conversion signal. Without one, attribution sits in an unresolved state indefinitely. The referral happened, the deal closed, but the system has no way to know.
Manual billing workflows, ACH transfers, net-30 invoices and custom ERP systems all share this broken referral tracking problem. They produce revenue without producing the machine-readable event that referral attribution depends on.
How referral programs track conversions without a native billing integration
When Stripe or Chargebee are absent, two substitution mechanisms cover the attribution gap: custom API events and CRM deal stage triggers.
A custom API event is any server-side call your system makes to Cello's API confirming a conversion has occurred. A CRM deal stage trigger fires when a deal moves to a defined stage in HubSpot (such as "Closed Won") and that transition is forwarded to Cello as a conversion signal.
Capture the referral code and associate it with the referred account before reporting conversion. Also record which identity represents the buying unit: an individual user or an organization. A CRM property alone is not an API request; your integration must map those records into the chosen Cello event version and include its required context.
The billing integration was never irreplaceable. It was simply a reliable, automated signal that a conversion occurred. Any event your stack can emit with equivalent reliability does the same job.
Using HubSpot deal stages as the conversion trigger
Use a CRM stage change as an input to your integration only when it represents the milestone your program actually rewards. Route it through an authenticated server-side request using the event contract for your Cello API version. A closed-won stage and a cleared payment are different facts; do not label an unpaid contract as a paid invoice.

The three-field object below is not a complete conversion request. Cello retains a V1 POST /events endpoint with a ReferralUpdated envelope containing payload and context; V2 uses a separate endpoint per business event. Check the current versioned reference before mapping CRM properties. The implementation checks below replace the incomplete JSON example, not provide executable code.
Implementation checks, not a request body:
- Identify the event API version and qualifying milestone.
- Retrieve the captured referral code and stable buying-unit identifier.
- Map fields to that version's authenticated event schema.
- Reconcile acceptance, attribution and reward eligibility separately.
Two failure modes cause silent misattribution here.
- Re-enrollment: HubSpot workflows do not re-enroll a deal by default if it has already passed through the trigger condition once. If a deal moves back to an earlier stage and then re-closes, the webhook does not fire again unless you explicitly turn on re-enrollment. This matters less for attribution and more for avoiding duplicate conversion events if you do turn it on.
- Stage name collisions across pipelines: if your HubSpot account has multiple pipelines each with a stage named "Closed Won," a workflow built without a pipeline filter fires for every deal in every pipeline that hits that stage name. Scope the trigger to a specific pipeline to prevent attribution firing for deal types your referral program was never meant to cover.
Setting up the referral code to travel through your CRM
The referral code must be written to your CRM the moment a prospect clicks the referral link. Capture it then, and it survives a six-month B2B sales cycle. Wait until signup or demo booking, and any deal that moves across stages without a re-touch loses its attribution.
When a prospect clicks a referral link, the cello_ucc value arrives as a URL parameter on your landing page. Read that parameter and pass it to HubSpot immediately via the HubSpot Forms API or a hidden field on the form the prospect completes. A workflow then stamps it onto the Contact record as a custom text property.
You need two custom properties:
- A Contact property named
cello_uccto store the code at lead capture - A Deal property with the same name, populated by a workflow that copies the Contact property when a deal is created and associated
That two-step copy matters because HubSpot webhooks post deal data when a deal stage changes. If the code lives only on the Contact, your conversion webhook cannot read it without an additional API call.
One constraint: if a prospect visits via a referral link but does not complete a form in that same session, the URL parameter is gone. A session cookie or localStorage write that persists cello_ucc and attaches it to the next form submission closes that gap.
Firing custom API events for non-CRM billing flows
For teams on custom billing engines or in-house invoicing systems, a direct POST to Cello's REST API from your own backend, fired once payment is confirmed, is the correct approach.
For V1 events, send the captured referral code in payload.ucc. The signup and purchase guides use payload.newUserId for the identifier being attributed; when attribution is at organization level, that value is the organization ID. context.newUser.id identifies the individual product user, with organization context supplied separately where applicable. Keep those meanings consistent across signup and purchase, and do not copy this V1 envelope into a V2 request.
The harder problem is asynchronous payment confirmation. In manual invoicing flows, account creation often happens before payment clears. Store the ucc value against the internal account record at signup, then fire the API event only when your payment-confirmed webhook or finance reconciliation marks the invoice as paid. Cello does not impose a hard expiry on unresolved referral codes, so a 30-day or 60-day payment window does not break attribution provided the code was captured and persisted correctly at click time.
Manual invoicing and bank transfer: closing the attribution loop
When payment arrives via bank transfer or ACH, there is no system-generated event. Finance confirms receipt in QuickBooks, Xero, or a spreadsheet, and that confirmation lives entirely outside any webhook pipeline.
Two paths close the attribution loop.
The first is middleware routing. Zapier, Make or n8n can watch for a status change in your accounting tool and forward it downstream, much like the webhook routing used for Stripe referral tracking. When an invoice moves to "Paid" in Xero, a Zap updates the HubSpot deal stage to "Closed Won," which triggers the attribution webhook. The middleware manufactures the CRM signal that a bank transfer cannot produce on its own.
The second is direct API attribution. Finance marks an invoice paid, a simple internal form or Slack-to-webhook integration fires the Cello API event with the stored cello_ucc and user ID, and attribution closes. It requires discipline, not engineering.
The part that breaks most often is not the trigger mechanism but referral code retrieval. By the time a bank transfer clears, the original prospect contact may have been merged, reassigned, or archived. If cello_ucc was never written to the deal record at lead capture, there is nothing to retrieve at payment time. Every manual invoicing workflow depends on that code being persisted correctly at the top of the funnel.
Org-level attribution when the payer and referrer differ
In a sales-led funnel, the evaluator who follows a referral link and the person arranging payment can be different contacts. Choose the buying unit before mapping events: an individual account, a workspace or a customer organization. Preserve that association when sales and finance add or merge contacts.
For organization-level attribution, Cello's signup and purchase guides specify the organization ID in V1 payload.newUserId. The context identifies the individual product user separately. The Stripe and Chargebee metadata key new_user_organization_id is not a universal API payload name, and the article should not impose a blanket rule that organization and user fields must differ.
A HubSpot Company ID can be an internal mapping key if your team uses one Company per buying organization. Match it to the same product organization represented at signup before reporting purchase. Do not substitute a deal owner, invoice contact or newly created Company record without checking that association.
Two configuration steps matter:
- Keep the captured referral code associated with the relevant lead or account record and retain the association when the deal acquires additional contacts. Document how duplicate Company records and workspace-to-company mappings are resolved.
- For V1 organization attribution, map the chosen organization identifier into
payload.newUserIdconsistently at signup and purchase. For V2, use the declared fields in that event's schema rather than sending the V1 envelope or adding a guessednewUserOrganizationIdfield.
Validate semantic consistency, not an invented inequality test: the event must identify the same referred buying unit established during signup. Check the individual user context separately and inspect field-validation feedback. API acceptance is not proof that the intended account received referral credit.
Reward trigger configuration for sales-led conversion events
Sales-led attribution fires on CRM events, so reward triggers need to match your conversion milestones, a configuration detail covered in broader referral tracking software comparisons for B2B teams. Configure Cello to treat specific events as reward-eligible: new-signup, demo-call-attended, or a custom API event representing closed-won.
If you reward at multiple milestones, use separate campaigns per conversion type. A demo booking and a closed contract carry different economics, so campaign separation is required as a single campaign cannot hold two distinct reward amounts across different trigger events.
Payout delays are the primary protection in manual billing workflows. Because payment confirmation can arrive weeks after deal closure, configure a delay window that holds the reward until revenue is confirmed. The Cello team sets this window; it is not self-serve in the portal.
Fraud controls in sales-led flows
Without automated billing event linkage, the manual review workflow carries more weight than in standard product-led growth setups. Flag deals where the referred contact's tenure is short, payment is unconfirmed, or the referrer churned before payout clears. Cello's risk-factor monitoring for unusual usage patterns runs across the review window, but the Review Referrals workflow is the primary control here.
Testing your non-standard attribution setup before going live
Non-standard integrations fail silently, a recurring theme in referral tracking overall. A Stripe webhook either fires or throws an error you can investigate. A HubSpot workflow that misfires just does nothing, and the deal closes with no attribution record.
Run these checks before launching:
- Use an isolated test account and the safest supported environment first. Exercise the intended pipeline and milestone mapping without changing real customer deals, then agree any controlled production validation with the team responsible for CRM automations.
- Confirm the webhook fired by checking HubSpot's workflow history. A green execution means HubSpot attempted delivery, not that the payload arrived correctly.
- Inspect the received event and compare its referral code, API version and attributed buying-unit identifier with the known test signup. For V1 organization attribution, check
payload.newUserIdagainst the intended organization ID rather than testing whether two differently named fields are unequal. - Check that the referral code in the event matches the test referrer's assigned code. A mismatch means the code was overwritten or not persisted correctly at lead capture.
If the event arrives but the reward does not trigger, check in this order: whether the campaign is active, whether the test user ID matches a recognized referrer, and whether a payout delay is holding the reward in review. Cello's Integration Status Page surfaces connection health across each component to isolate which layer broke before you escalate.
How Cello handles referral attribution outside Stripe and Chargebee
Cello's attribution architecture is built around one structural decision: the referral code is written to the customer record at the moment of link click, not at signup or payment. By the time a deal closes six weeks later via bank transfer, the cello_ucc value is already persisted in your CRM. Cello reads that value when the conversion signal arrives.
For HubSpot-driven funnels, Cello's HubSpot integration handles deal stage transition attribution without requiring visibility into deal amounts. Stage changes fire conversion signals directly to Cello, which suits sales teams with deal-value confidentiality requirements.
The three supported conversion event types map to the funnel milestones covered in this post:
|
Conversion event |
Funnel milestone |
|---|---|
|
|
Lead capture or trial start |
|
|
Qualified demo completed |
|
|
Closed contract or manual payment confirmed |
For fully custom billing systems, Cello's REST API accepts manual conversion events. Historical referrals can also be imported via the portal to backfill attribution during migrations from spreadsheet-based programs, which matters for accurate referral program ROI measurement.
Teams whose payments arrive via bank transfer or bespoke invoicing systems should configure manual reward processing mode. Attribution tracking and fraud detection run as normal; fulfillment routes through your own finance infrastructure instead of Cello's automated payout pipeline.
Final thoughts on referral attribution without a native billing integration
Manual billing, bank transfers, and custom invoicing systems are not obstacles to referral attribution. They just require a different trigger. The code travels with the prospect, your CRM holds it through the sales cycle, and your conversion event fires when payment confirms. That sequence works whether your billing runs through HubSpot, Xero, or a spreadsheet your finance team maintains. Set up your referral program with Cello and configure attribution around the conversion signals your team actually controls.
Can Cello track referral conversions when deals close through manual invoicing or bank transfer instead of Stripe?
Yes. Cello supports a REST API route for payment providers and custom systems outside its pre-built Stripe and Chargebee webhooks. Have your integration report the qualifying conversion when your source system confirms it, carrying the captured referral association and the correct buying-unit identity. A CRM stage change can supply that signal only when it matches the program's chosen milestone. Validate the complete request against your implemented API version.
How does the referral code survive a 60-day B2B sales cycle in a HubSpot-driven funnel?
Capture cello_ucc from the URL parameter the moment a prospect clicks a referral link, write it to the HubSpot Contact record via a hidden form field or the Forms API, then copy it to the associated Deal record via a workflow. Because Cello writes attribution at click time (not at signup or payment), the code is already in your CRM before the deal enters the pipeline. By the time a stage-change webhook fires at "Closed Won," the referral code is retrievable regardless of how many contacts, reassignments or stage reversals occurred in between.
What's the best way to handle referral attribution in a SaaS referral program when the person who signs the contract is different from the user who shared the referral link?
Choose the organization as the attribution unit and use the same organization identifier through signup and purchase. Cello's V1 guides put that identifier in `payload.newUserId`, while the individual product user is represented in the context. Do not treat a billing-provider metadata key as an API field or assume a payer contact automatically maps to the evaluator's organization. V2 requires its own event schema.
How do I test a non-standard HubSpot attribution setup before going live with my referral program?
Use an isolated test account in the safest supported environment. Confirm the CRM automation selected the intended milestone and API version, then inspect Cello's received event and validation feedback. Compare the referral code and buying-unit identifier with the known test signup. Check attribution and campaign eligibility separately from delivery; do not change live customer deals merely to test field mapping.
What happens to referral attribution when payment arrives via ACH or bank transfer and there is no system-generated event?
Middleware tools such as Zapier, Make or n8n can watch for an invoice status change in your accounting system — Xero, QuickBooks — and forward it to HubSpot as a stage update, which then fires the attribution webhook. Alternatively, a direct API call to Cello from your backend, triggered when finance marks an invoice paid, closes the loop without CRM involvement. The failure point in both paths is almost never the trigger mechanism — it is the referral code not being persisted on the deal record at lead capture. By the time a bank transfer clears, a contact may have been merged or archived; if `cello_ucc` was never written to the deal, there is nothing to retrieve at payment time.
Can I fire a referral conversion event from my own backend when we don't use Stripe or Chargebee at all?
Yes. Use the authenticated event endpoint for your implemented API version and supply its complete required body. V1 uses `POST /events` with `eventName`, `payload` and `context`; V2 uses event-specific endpoints with different schemas. Keep the attribution identifier consistent with signup, including the organization identifier when the buying unit is an organization. The three-field object formerly shown in this article was not a complete request.
Should the referral conversion event fire on demo booking or closed contract in a sales-led HubSpot funnel?
It depends on your reward economics. Cello supports both `demo-call-attended` and a closed-won deal stage trigger as distinct conversion event types, so you can reward at whichever funnel milestone your program is built around. If you want to reward at both milestones with different amounts, use separate campaigns — a single campaign cannot hold two distinct reward amounts across different trigger events.
How do I set up the HubSpot workflow so the referral code reaches the deal record before the stage-change webhook fires?
Create a contact-level custom property named `cello_ucc` and populate it via a hidden form field or the HubSpot Forms API the moment a prospect clicks a referral link. Then build a second workflow that copies the contact property to a matching deal property when a deal is created and associated with that contact. The stage-change webhook reads from the deal record — if the code only lives on the contact, it is not accessible when the webhook fires at Closed Won.
What's the right approach for referral attribution in a SaaS referral program when payments come in via net-30 or net-60 invoices?
Store `cello_ucc` against the deal or account record at lead capture, then fire the Cello API event only when your finance team confirms the invoice as paid — not at deal closure. Cello does not impose a hard expiry on unresolved referral codes, so a 60-day payment window does not break attribution provided the code was captured and persisted correctly at link-click time.
How does org-level attribution prevent misattribution when multiple contacts from the same company interact with a referral link at different points in a long sales cycle?
Establish which product organization the contacts belong to and keep that same organization identifier through signup and purchase. For V1 organization-level attribution, Cello's guides use `payload.newUserId`; the individual user remains in the event context. A CRM Company ID is useful only when it is mapped to the intended product organization. Check duplicate records and account merges instead of assuming a shared email domain or a field-name inequality proves the match.
Does Cello's referral attribution work if there's no Stripe customer object to write the referral code to?
Yes. When Stripe is absent, the referral code is stored in your own system — a CRM contact, deal property, or database record — rather than Stripe metadata. The write-at-click principle still applies: capture `cello_ucc` the moment a prospect clicks the referral link and persist it immediately. Your conversion signal then carries that stored code to Cello via a HubSpot deal stage webhook or a direct API call, closing attribution without any Stripe dependency.
What payout delay configuration exists to protect against rewarding referrals that come from manual invoices that later go unpaid or disputed?
Cello supports configurable payout delay windows that hold rewards until revenue is confirmed, protecting against unpaid invoices or reversed payments. The delay period is set by the Cello support team rather than configured self-serve in the portal, so customers with manual invoicing workflows should request a delay window during onboarding. Pending rewards are also automatically cancelled when a `charge.refunded` event fires from Stripe, though for non-Stripe flows the fraud review workflow carries more operational weight.
How do I verify that my custom API event or HubSpot webhook actually reached Cello before going live with the referral program?
Confirm delivery in the integration logs, then inspect the received event and field-validation feedback in Cello. Compare its referral code, API version and buying-unit identifier with the known signup record. A delivered or accepted request is not proof of completed attribution or an earned reward. Review the resulting referral association and campaign eligibility as separate checks.
Can historical referrals closed before Cello was set up be backfilled so commission attribution is correct from the start?
Yes. Historical referrals can be manually imported via the Cello portal to backfill partner attribution for pre-Cello relationships. This matters during migrations from spreadsheet-based programs where deals already closed but attribution was never machine-recorded — importing those records into Cello gives the program a clean, accurate baseline rather than starting with a gap in the referral history.