Payment processor
Card charges, invoicing, and refunds run through your own payment processor account. heliumOS provides the integration layer and never holds funds — money lands in your balance.
Like carrier and tax credentials, the payment connection is configured from the operator dashboard, not from the API. Operator API keys cannot read, rotate, or delete processor credentials. It is environment-scoped and resolved on every call, so sandbox and live each carry their own processor and their own credentials — one processor account per environment.
Sandbox vs live
- Sandbox can use a built-in stub that charges, invoices, and refunds deterministically with no external calls, so you can build your billing integration before you have processor credentials. It can equally hold your processor's test credentials if you would rather exercise the real integration.
- Live uses Stripe with your account's live secret key. On save, heliumOS runs a verify round-trip and surfaces any credential problem before the connection goes active.
Stripe connections also carry an inbound webhook signing secret
so heliumOS can reconcile invoice, payment, and refund status
back from Stripe. The endpoint URL and the event list to register are
shown on the connection's detail page; the whsec_… secret Stripe
issues for it is added afterward, on the same page. Until it is set,
the connection can charge cards but will not reconcile.
Subscriber email verification
The connection carries one setting that is not a credential: "We verify a subscriber's email address before we create the subscriber." It is off by default and it changes one thing — whether a returning subscriber keeps the processor customer record they already have.
What it changes
The first time heliumOS needs a processor customer for a subscriber, it creates one. That is right for a genuinely new person and wrong for someone who cancelled and came back: they already have a customer record on your processor account, carrying their saved cards, their credit balance, and their payment history. Creating a second one splits that person across two records that look identical in the processor's dashboard.
With this setting on, heliumOS first looks the person up on this environment's processor account by exact email address, and gives them the record they already have.
What you are asserting, and why we ask
The email address arrives on POST /v1/subscribers under your API key.
heliumOS has no way to check that the person on the other end of
your signup owns it — only you do. So turning this on is an assertion
about your signup flow, made per environment, alongside the
credentials for the processor account it authorizes searching.
If the address is not verified, whoever holds your API key can attach a
new subscriber to any unclaimed customer on your processor account by
naming its email address, and reach the payment methods saved on it
through POST /v1/subscribers/:subscriber_id/payment_sessions. That is
why the default is off. Leave it off if you are not certain.
The records heliumOS will not take
Even with the setting on, an existing record is only adopted when all of these hold. Otherwise a new customer is created, exactly as before:
- the record's own email address matches the subscriber's;
- no other heliumOS subscriber in this environment already holds it, and it is not tagged as belonging to a different subscriber;
- it carries no debit balance — money the person owes would otherwise be applied silently to their first heliumOS invoice, with no line explaining it. A credit balance is inherited;
- it carries no live processor subscription — one on each record would bill the person twice, from two systems;
- the lookup itself succeeded. Not being able to tell whether someone owes money is not treated as evidence that they don't.
Nothing here can fail the billing operation that triggered it: every refusal falls back to creating a new customer.
Turning it on
From the dashboard: Payment processor → your connection → Subscriber email verification. Owner and admin roles only, and it is its own confirmation step rather than something that rides along with a credential change.
The assertion names one processor account, so anything that could point the connection at a different account withdraws it and asks again: replacing the connection, and rotating its secret key (or its Connect account id). Adding the inbound webhook signing secret does not — it cannot move the account.
Related
- Subscribers & subscriptions — the
payment_sessionsbootstrap for the on-device card-add flow. - Environments & mode — why sandbox and live each carry their own credentials.
- Carrier connections and Tax — the same dashboard-managed, environment-scoped credential pattern.