Stripe setup guide
Set up your Stripe account in six steps; the last proves the sync works. The Stripe integration page covers what the connector does and what each Stripe event changes in Oclavex; this page covers the Stripe account itself.
You need someone who can create API keys and webhook endpoints in the Stripe Dashboard, and an Oclavex administrator for step 3. Do everything in a Stripe sandbox — test mode — first: a connector keeps the mode of the key it was registered with, so the live account gets its own connector at the end, under Going live.
What you are setting up
Section titled “What you are setting up”| In Stripe | What Oclavex uses it for |
|---|---|
| A restricted API key | Re-reading the subscription, invoice or customer behind every event; creating the Stripe Customer, the Checkout and the billing portal session when your application sells; the connector’s Probe |
| Products and prices | The Oclavex plan behind each price, and the prices your application may sell |
| A webhook endpoint | Telling Oclavex within seconds that a subscription started, was paid, failed to pay, paused or ended |
| Account settings | What Checkout and the billing portal need: your terms of service, Stripe Tax, the Customer portal, what happens after a failed payment |
Step 1 — Create a restricted API key
Section titled “Step 1 — Create a restricted API key”Developers → API keys → Create restricted key. Give it a name that says what it is
for, such as Oclavex, and grant:
| Resource | Permission |
|---|---|
| Customers | Write |
| Checkout Sessions | Write |
| Customer portal | Write |
| Subscriptions | Read |
| Invoices | Read |
| Products, Prices | Read |
| Charges, Disputes | Read |
| Events | Read |
| Connect → Accounts | Read |
Everything else stays at None; write permission includes read. Copy the key when
Stripe shows it — it is shown once. A secret key, sk_…, works too, at the price of
granting everything.
The key’s prefix fixes the connector’s mode: rk_test_ registers a test-mode connector,
rk_live_ a live one.
Step 2 — Create the products and prices
Section titled “Step 2 — Create the products and prices”Under Product catalog, add one product per Oclavex plan you sell through Stripe, and give it this metadata:
| Key | Value |
|---|---|
oclavex_plan |
The plan’s name in Oclavex, character for character |
oclavex_deployment |
oclavex |
oclavex_offer |
The offer a new entitlement is created from; it must be Published. Needed for subscriptions you create in the Dashboard or through a Quote; a checkout from your application attaches to the entitlement it was started for |
Metadata on the product applies to every price under it, so a discounted or negotiated price needs no mapping of its own.
Then add a recurring price per billing interval you sell and give each a lookup key,
such as pro_month and pro_year. The lookup key is what your application names when it
starts a checkout, and the same keys go into the connector’s allowed list in step 3.
An add-on gets a product of its own with oclavex_addon set to the add-on’s code in
Oclavex instead of oclavex_plan, and a recurring price with a lookup key like any plan’s.
See selling an add-on.
A one-time price sells credits, not a plan: give it a lookup key and the metadata
oclavex_credits (how many credits it buys) and oclavex_credit_metric (the credit
balance they land on). See selling top-ups.
A one-time price without both keys is refused at checkout.
Checkout calculates tax automatically, so set the tax code on the product and, on each price, whether tax is included in the amount or added on top — or supply both as defaults in your Stripe Tax settings.
Step 3 — Register the connector in Oclavex
Section titled “Step 3 — Register the connector in Oclavex”In Oclavex, under Settings → Stripe billing, choose Register Stripe connector and
fill in the fields described under Register the connector:
the key from step 1, the lookup keys from step 2 as the allowed price lookup keys,
your policy for a failed payment and an ended subscription, and a placeholder signing
secret such as whsec_placeholder — the real one exists only after the next step.
The connector’s card then shows its webhook URL:
https://<your tenant>.<host>/api/v1/connectors/stripe/<connector id>/webhookCopy it; step 4 needs it.
Step 4 — Register the webhook endpoint
Section titled “Step 4 — Register the webhook endpoint”In Stripe, open Workbench → Webhooks and create a new destination:
- Listen to events on your account.
- Set the API version to
2026-08-26.dahlia, the version the connector speaks: it re-reads every object from Stripe at that version, and an endpoint on another version is not supported. - Select these event types:
checkout.session.completed,checkout.session.async_payment_succeeded,customer.created,customer.updated,customer.deleted,customer.subscription.created,customer.subscription.updated,customer.subscription.deleted,customer.subscription.paused,customer.subscription.resumed,customer.subscription.pending_update_expired,invoice.paid,invoice.payment_failed,invoice.payment_action_required,invoice.voided,charge.refundedand everycharge.dispute.*event. - Choose a webhook endpoint as the destination and paste the connector’s webhook URL as the Endpoint URL.
- On the endpoint’s page, reveal the signing secret and copy the
whsec_…value.
Back in Oclavex, on the connector’s card, Rotate signing secret and paste it. From then on the connector accepts Stripe’s deliveries.
A delivery that fails is retried — three times over a few hours in a sandbox, for up to three days in live mode — and every six hours the connector re-reads your subscriptions from Stripe, so a delivery that never arrives delays a change rather than losing it.
Step 5 — Account settings
Section titled “Step 5 — Account settings”Three settings Checkout and the billing portal need, and one policy that decides what a failed payment does — all in the Stripe Dashboard:
- Terms of service URL — Settings → Business → Public details. Checkout asks the buyer to accept your terms, and Stripe refuses to start a checkout without the URL: You cannot collect consent to your terms of service unless a URL is set. Stripe accepts the URL once the account is activated, so a checkout from your application works from that point.
- Stripe Tax — Checkout calculates tax automatically and collects tax ids, so Stripe Tax must be active, with your origin address and the registrations you hold.
- Customer portal — Settings → Billing → Customer portal. The connector opens your account’s default configuration, so enable what your application offers: updating the payment method, cancelling, and switching plans with the products from step 2 as the options. Let customers edit their billing information too: a change of address or tax id made there is written back to their organization in Oclavex.
- Failed payments — Settings → Billing → Subscriptions and emails → Manage failed payments. Choose the retry schedule and, after the last retry, cancel the subscription. The connector pauses the entitlement on a failed payment, under the default policy, and applies your cancellation policy when Stripe cancels; if Stripe instead marks the subscription unpaid or leaves it as it is, the entitlement stays paused until a payment goes through or you end the subscription yourself.
Step 6 — Prove it works
Section titled “Step 6 — Prove it works”Still in the sandbox, run one subscription through end to end:
- Create a Customer in the Dashboard, with a name and an email address. Its
customer.createddelivery is the first row on the endpoint’s Event deliveries tab: 200 means the URL is reachable and the signing secret matches. A 400 means the secret in the connector is not this endpoint’s; a 404, that the URL is not a connector’s; a 503, that the connector is disabled or has no API key. - Look for it in Oclavex. Within a few seconds the customer appears under Customers → Organizations. This alone proves the key, the endpoint and the connector agree — if it fails, nothing later will succeed.
- Add a test card to that customer —
4242 4242 4242 4242, any future expiry — and create a subscription for it on one of the products from step 2, charged automatically. - Check Oclavex. Once the first invoice is paid, Settings → Stripe billing lists the subscription with its paid plan, the entitlements list holds a new entitlement created from the offer, on that plan, and the entitlement’s Billing tab shows what Stripe reported.
- Cancel the subscription in the Dashboard, immediately rather than at the end of the period. The entitlement follows your policy for an ended subscription — disabled, under the default — and the Billing tab shows the cancellation.
Going live
Section titled “Going live”Products, prices and webhook endpoints exist per mode, and a connector keeps the mode of its key, so the live account is a second setup rather than a switch:
- Activate the Stripe account and set the terms of service URL (step 5).
- Create a live restricted key with the permissions of step 1, and register a second connector in Oclavex with it; add the lookup keys.
- Create the products and prices again on the live account (step 2), with the same metadata and lookup keys.
- Register a webhook endpoint on the live account against the new connector’s URL and put its signing secret in that connector (step 4).
- Point your application at the live connector’s id, and run step 6 once more with a real card. Cancel and refund that subscription from the Dashboard afterwards: the cancellation ends the entitlement under your policy, the refund on its own changes nothing in Oclavex.
When something doesn’t sync
Section titled “When something doesn’t sync”Work down this list in order — it’s roughly most to least common.
| What you see | Almost always |
|---|---|
| Probe fails and the connector reads Degraded | The key lacks Connect → Accounts: Read (step 1) |
| Last sync reads failed, or the connector reads Needs attention after three failed syncs in a row | The card names why. Stripe refused the API key: the key was revoked or rolled — rotate it. No API key is stored: rotate one in. The API key lacks a permission the sync needs: grant the restricted key what step 1 lists. Stripe could not be reached or an error on its side: nothing to do, the next sync tries again. Either way the next sync that succeeds clears Needs attention |
| The card reads Not synced, or Needs attention after a subscription failed three syncs in a row | Show which names each subscription and why. Oclavex could not accept its details: check the subscription and its Customer in the Dashboard, such as a name or an email that is too long. It changed while the sync was saving it, Oclavex could not save it, An unexpected error stopped it, Stripe could not be reached or an error on its side: nothing to do, the next sync tries again. The next sync that gets the subscription through clears it |
| Event deliveries read 400 | The signing secret in the connector is not this endpoint’s (step 4), or a live-mode event reached a test-mode connector |
| Event deliveries read 404 | The endpoint URL is not the connector’s webhook URL — check the connector id |
| Event deliveries read 503 | The connector is disabled, or it has no API key |
| Deliveries read 200, but the subscription is not listed under Stripe billing | None of the oclavex_* keys is on the subscription, its price or its product, or oclavex_deployment is missing or not oclavex (step 2) |
| The subscription is listed as Unmapped | No entitlement is linked to it. If none exists: no oclavex_offer on the product and no default offer on the connector, or the Stripe Customer has no email address (step 2) |
| The subscription names an offer, but no entitlement is created from it | The offer is not Published: a Draft offer is not open to orders yet, and a Disabled or Archived one no longer is. The offer’s Audit log has a warning naming the subscription. Set the offer to Published under Catalog → Offers. A refused event is not retried: a paid subscription is sent again by the connector’s check every six hours, and any other creates its entitlement on the subscription’s next Stripe event |
| The subscription is listed, the plan is not applied | oclavex_plan does not match a plan name (step 2), or Apply a plan only on a paid invoice is on and the invoice is still open |
| A checkout from your application is refused | The price’s lookup key is not in the connector’s allowed list (step 3), the account has no terms of service URL yet (step 5), or a return URL is on a host that is neither your tenant’s nor one of the connector’s Return hosts (checkout.invalid_return_url) |
A checkout answers 424 (stripe.refused) |
Stripe refused the request: the key is wrong or lacks a permission, or an account setting the checkout needs is missing. The problem’s detail names what Stripe said; see when Stripe refuses or is unavailable |
A checkout answers 503 (stripe.unavailable) |
Stripe could not be reached or is failing. Try again later, after the Retry-After wait when the answer names one |
| Billing details edited in the portal never reach the organization | customer.updated is not among the endpoint’s events (step 4) |
| An entitlement stays paused for weeks | Stripe leaves a subscription unpaid after the retries instead of cancelling it (step 5) |
Settings → Stripe billing shows every subscription the connector has observed and what it did with it; a delivery Stripe could not make is on the endpoint’s Event deliveries tab, with the status the connector answered. A 200 there means Oclavex received the event: it is processed a moment later, off Stripe’s request, and retried by Oclavex itself for a few hours if that fails, so a failure after the 200 never shows in Stripe’s dashboard.
Selling through Salesforce as well? The Salesforce setup guide prepares the org the same way, step by step.