Connect your agency’s own Stripe account so client workspaces can subscribe and pay you online, and set up the webhook that keeps DMLY in sync.
This page is about the Stripe account you, the agency, connect so your client workspaces
can pay you for their plans. It is not the Stripe gateway a business connects under
Finance to collect invoice payments from its own customers — for that, see
Payments & gateways.
You can run an agency without Stripe: you assign plans to clients by hand from
Sub-accounts, grant add-ons, and collect payment however you like outside DMLY. What
Stripe adds is the self-serve loop — clients subscribing and paying you online, without you
touching anything.
Without Stripe
Your clients’ Plans & billing page shows your plans, but every button is disabled
and the page reads Online billing isn’t available yet. with your support email. You
assign plans manually from Sub-accounts and handle money outside DMLY.
With Stripe
Choose plan goes live. A client picks a cycle, lands on a Stripe-hosted checkout
against your Stripe account, and pays you directly. DMLY never sees the money and
takes no cut.
Two things stay the same either way: add-ons for client workspaces are always granted by
you from Sub-accounts — clients can’t buy them at checkout — and charges, refunds,
disputes, and payouts live in your Stripe dashboard, not in DMLY.Connecting Stripe has two halves, and both matter. The keys let DMLY start a checkout;
the webhook is how Stripe tells DMLY the payment happened. Skip the webhook and clients can
pay you while DMLY never hears about it.
In your Stripe Dashboard, find your API keys under the developers section. You need two
values: the secret key (starts sk_live_) and the publishable key (starts
pk_live_).
2
Open the Stripe panel in your agency settings
In your agency dashboard, go to Configuration → Settings and find the
Stripe (charge your customers) panel. The badge next to the heading reads
Not connected until a secret key is saved.
3
Paste the keys and save
Fill in Secret key and Publishable key, then select Save Stripe keys. You
can leave Webhook signing secret empty for now — you’ll get that value from Stripe
in the next section and come back.On success you see Stripe keys saved. Your customers will be billed through your own
Stripe account. and the badge switches to Connected.
Your keys are stored encrypted. The Secret key and Webhook signing secret are never
shown back to you — those fields always render empty — and only the publishable key is
prefilled on your next visit.
DMLY does not test your keys when you save them. A mistyped secret key saves fine and the
badge still says Connected — the error only surfaces later, when a client tries to
check out. Copy the keys carefully, and run the end-to-end test below before pointing a
real client at the page.
After a client pays, Stripe reports the subscription back to DMLY over a webhook. Without
it, DMLY records nothing — no subscription, no receipts — even though the charge went
through.
1
Copy your webhook URL
Your webhook URL is shown in the same Stripe panel, under Your webhook endpoint —
copy it from there. It looks like:
Use the URL exactly as shown. It’s built on DMLY’s own host on purpose, so it keeps
working even if you later change your agency’s custom domain.
2
Add the endpoint in Stripe
In your Stripe Dashboard, create a new webhook endpoint (under the developers /
webhooks section) and paste the URL above as the destination.
3
Select exactly these event types
When Stripe asks which events to send, select these seven — this is the part that most
often goes wrong:
invoice.payment_succeeded — records a payment receipt in DMLY
customer.subscription.created — records the new subscription
customer.subscription.updated — keeps its status, price, and trial in sync
customer.subscription.deleted — marks the subscription cancelled
customer.updated — refreshes the stored payment method
customer.deleted — clears the customer link from the workspace
payment_method.automatically_updated — keeps card details current
Don’t select “all events” instead: DMLY quietly accepts event types it doesn’t handle,
so every delivery looks successful in Stripe while the noise buries the ones that
matter.
4
Copy the signing secret back into DMLY
Stripe shows a signing secret for the new endpoint, starting whsec_. Copy it,
return to Configuration → Settings → Stripe (charge your customers), paste it into
Webhook signing secret, re-enter your Secret key, and select Save Stripe
keys again.
Saving the Stripe panel replaces all three values at once. The Secret key and
Webhook signing secret fields always start empty, so whenever you save — to rotate a
key, to fix a typo — fill in both again. Saving with a blank Webhook signing secret
silently erases the stored one, and from that moment every webhook delivery is rejected
until you paste it back.
A plan can only be bought online when its billing cycle carries a Stripe price. In Stripe,
create a recurring price for each plan and cycle you sell; then, on your agency Plans
page, paste each price’s ID (starts price_) into Monthly Stripe price ID or
Yearly Stripe price ID on the matching plan. A cycle without both a price ID and an
amount shows a disabled Unavailable button on your clients’ billing page.See Price and bill your clients for building plans and setting
their limits.
Most Stripe webhook tooling lets you send a test event to an endpoint. Send one — any
of the seven types — and check the response DMLY returns:
2xx — the URL and signing secret are both right. You’re wired up.
403 Invalid webhook signature — the signing secret saved in DMLY doesn’t match
this endpoint (or was never saved). Re-copy it and re-save.
404 Unknown agency — the agency ID in the URL is wrong.
422 Agency Stripe is not configured — no secret key is saved in DMLY yet.
2
Run a real checkout
From a client workspace (a test sub-account works well — see
Client workspaces), open Plans & billing and select
Choose plan on a priced plan. You should land on a Stripe-hosted checkout page
showing your plan’s price. Complete the payment.
3
Confirm the deliveries
In your Stripe dashboard: the subscription exists, and each webhook delivery for it
shows a 2xx response with the body Webhook Handled — that body means DMLY
processed the event. An empty response body is still a 2xx, but it means the event
type isn’t one DMLY handles. DMLY records the payment internally but doesn’t
currently display it to you, so the Stripe delivery log is your confirmation. If
Stripe shows the money but the deliveries failed — or never happened — work through
the failure modes below.
4
Assign the plan
Paying does not switch the client’s plan by itself. After checkout, open
Sub-accounts and assign the plan the client bought — that is what applies the
plan’s limits and updates the Current badge on their billing page. Make this part
of your routine whenever a client subscribes or changes plan.
A checkout against live keys charges the card for real — if you test with your own card,
refund it afterwards from your Stripe dashboard. DMLY also accepts Stripe test-mode
keys (sk_test_), which run the whole flow in Stripe’s test mode with test cards. If you
rehearse that way, remember keys, price IDs, webhook endpoint, and signing secret all
belong to one mode: switching to live means re-entering live keys, live price IDs, and a
live-mode webhook endpoint with its own signing secret.
The nastiest one, because checkout itself works: the money is in your Stripe account, but
DMLY has no record of the subscription or payment. It means Stripe’s events never reached
DMLY — the webhook endpoint was never created, points at the wrong URL, or doesn’t
include the subscription events.Diagnose it from your Stripe dashboard, in the webhook deliveries for your endpoint —
DMLY has no log of traffic that never arrived. No endpoint at all? Create it as above.
Deliveries listed but failing? Match the response code against the test step above.
Deliveries succeeding but nothing recorded? Check the event types — see below.The client is not locked out while you sort this out: a client workspace’s access follows
your agency’s standing, not its own subscription state. Once the webhook is fixed, Stripe
can resend the missed events from the delivery history, and DMLY records each event only
once — resending is safe.
Every webhook delivery returns 403 Invalid webhook signature
The signing secret saved in DMLY doesn’t match the endpoint — or was never saved at all.
The Webhook signing secret field is optional at save time, so it’s easy to save your
keys without it and not notice: everything else says Connected, and every single
delivery is rejected.This also happens after a key rotation, because re-saving the panel with a blank
Webhook signing secret erases the stored one (see the warning above).Fix: copy the whsec_ secret from the endpoint in Stripe and re-save the Stripe panel in
DMLY with the secret key and the signing secret both filled in.
Deliveries succeed in Stripe, but subscriptions never appear
DMLY returns a success response even for event types it doesn’t handle, so a
wrongly-configured endpoint can look healthy in Stripe while doing nothing. Open the
endpoint in Stripe and check the selected events against the list of seven above — in
particular, customer.subscription.created and invoice.payment_succeeded must be
selected, or no subscription or receipt is ever recorded.
A client hits an error when choosing a plan
If the page flashes This agency has not connected Stripe yet., no secret key is saved —
finish the first section above. If it flashes a missing-price message, the plan’s cycle
has no Stripe price ID — add it on Plans.If checkout fails with a generic server error, the saved secret key is wrong, or the key
and the plan’s price IDs belong to different modes (a live key with test-mode price_
IDs, or the reverse). DMLY doesn’t validate keys at save time, so this is where a bad key
first shows itself. Re-enter the key and confirm every price ID comes from the same
Stripe mode as the key.
The client paid but their plan and limits didn't change
Expected — payment and plan assignment are separate steps. Checkout records the
subscription and the payment; it does not change the workspace’s plan. Assign the plan
from Sub-accounts after the payment lands. Until you do, the client’s Plans &
billing page keeps the old Current badge and their limits stay as they were.
A client stopped paying but still has access
Also expected: a client workspace is never locked out automatically over its own failed
or cancelled payments — access follows your agency’s standing with DMLY. Chasing payment
and suspending the workspace is your call, from Sub-accounts. See
Client workspaces.