# Connecting Stripe for Subscription Billing

> AcelleMail's Cashier ships Stripe as the first-class subscription gateway. This guide walks the connection end-to-end: API key configuration, the four webhook events that must be subscribed, the webhook URL location, and test-vs-live mode discipline. Covers both subscription billing (for SaaS operators) and one-off payment use cases.

- Canonical URL: https://acellesend.com/kb/articles/connecting-stripe-for-subscription-billing
- Author: Tom Becker, Developer Editor
- Category: Integrations — Stripe, PayPal, WordPress, WooCommerce, Zapier, webhooks, API
- Content type: tutorial · Difficulty: intermediate
- Tags: Acellemail
- Published: 2026-03-03 · Last updated: 2026-08-15
- Reading time: 8 min
- Publisher: AcelleMail Knowledge Base, https://acellesend.com/kb

---

## What this is for

AcelleMail's Cashier (the subscription billing layer) supports **Stripe as the first-class payment gateway**. PayPal and other gateways were removed in the recent Cashier consolidation — Stripe + Offline (manual) are what's supported today.

This guide walks the connection end-to-end. If you're setting up a [full SaaS platform](https://acellesend.com/kb/articles/setting-up-acellemail-as-a-saas-platform), Stripe is one step in that larger setup; this article covers the Stripe-specific configuration in depth.

## Prerequisites

- An AcelleMail install with the **Extended License** (required for SaaS / paid-subscription use)
- A Stripe account (https://dashboard.stripe.com) — start in **test mode**, switch to live after validating
- Comfortable with the Stripe Dashboard's basic navigation

## Step 1 — Get your Stripe API keys

In Stripe Dashboard:

1. Click **Developers → API keys**
2. Note your **Publishable key** (`pk_test_...` in test mode, `pk_live_...` in live mode)
3. Click **Reveal test key** next to "Secret key" to see your **Secret key** (`sk_test_...` / `sk_live_...`)

> **Test mode first, always.** Set up the whole integration in test mode (test cards, test webhooks). Validate every flow end-to-end. THEN switch to live mode — never go straight to live with new gateway code.

## Step 2 — Configure Stripe in AcelleMail

In AcelleMail Admin:

1. **Payment Gateways → Stripe → Edit**
2. Paste:
   - **Publishable Key** — from Step 1
   - **Secret Key** — from Step 1
   - **Mode** — `test` (for now)
   - **Currency** — must match your Stripe account default currency
3. Save (leave **Webhook Secret** blank for now — we'll set it after creating the webhook in Step 3)
4. Click **Enable** on the Stripe gateway

> **Disable other gateways you're not using.** AcelleMail shows every enabled gateway in the customer's plan-checkout flow. Leaving inactive ones enabled creates confusing UX.

## Step 3 — Set up the Stripe webhook

This is the most-skipped step, and **without it, renewals + cancellations don't sync** back to AcelleMail.

1. AcelleMail Admin → Payment Gateways → Stripe → after saving, AcelleMail shows the webhook URL you'll use. Format: `https://your-acellemail-domain.com/stripe/webhook`. Copy it.
2. Stripe Dashboard → **Developers → Webhooks → Add endpoint**
3. **Endpoint URL** — paste the URL from step 1
4. **Events to send** — select these 6 events (each one matters):

| Stripe event | Why AcelleMail needs it |
|---|---|
| `customer.subscription.created` | Initial subscription activation — flips customer's plan status to active |
| `customer.subscription.updated` | Plan changes, status changes (trialing → active) |
| `customer.subscription.deleted` | Cancellation — downgrades customer to default free plan |
| `invoice.paid` | Successful renewal — extends customer's billing period |
| `invoice.payment_failed` | Failed renewal — triggers dunning (retry + customer notification) |
| `payment_intent.succeeded` | One-off payment confirmation (for non-subscription flows) |

5. After clicking "Add endpoint", Stripe shows you a **Signing Secret** (`whsec_...`). Copy it.
6. Back in AcelleMail → Payment Gateways → Stripe → **paste the Signing Secret** into the Webhook Secret field
7. Save

## Step 4 — Test the round-trip

In test mode:

1. **Acelle: Admin → Plans → Add new** — create a test plan, e.g. `Test Plan` at $1/month
2. Log in as a test customer (or use a different browser)
3. Customer Dashboard → Subscribe to the test plan
4. Stripe Checkout opens → use test card `4242 4242 4242 4242`, any future expiry, any CVC, any ZIP
5. Click Pay
6. You should be redirected back to AcelleMail with subscription active

Verify each side:

- **Stripe Dashboard → Customers** — new customer with active subscription
- **Stripe Dashboard → Developers → Webhooks → click your endpoint** — should show 3 successful POST attempts (`customer.subscription.created`, `invoice.paid`, `payment_intent.succeeded`) within seconds
- **AcelleMail → Customers → your test customer** — Plan = Test Plan, Status = Active

If all three are green, the integration is working. Make a refund in Stripe (`Test Customer → Refund`) to verify the cancellation flow as well.

## Step 5 — Switch to live mode

When test mode is fully validated:

1. Stripe Dashboard → toggle **Test mode** to **Live mode** (top-right)
2. Get your live keys (Developers → API keys)
3. Create a NEW webhook endpoint in live mode (test webhooks don't carry over) — same URL, same 6 events
4. Get the live webhook signing secret
5. AcelleMail → Payment Gateways → Stripe → swap to live keys + live webhook secret
6. Save + repeat the Step 4 test using a real card (smallest amount — refund it after)
7. Watch the live webhook deliveries on Stripe Dashboard for the first day to catch any issues

## Plan design considerations

In AcelleMail's plan editor:

- **Price + currency** — must match the currency of your Stripe account
- **Frequency** — `1 month`, `1 year`, `3 months`, etc. — Stripe creates the right recurring price internally
- **Trial period** — e.g. `14` + `day` — Stripe handles the trial; customers aren't charged until trial end
- **Plans visible** — toggle off to hide a plan from the public pricing page (useful for legacy / promo plans)

> **Tip:** create both monthly + annual variants of each plan, with annual at ~17% discount. Annual conversion meaningfully reduces churn — see the [Building Your SaaS guide](https://acellesend.com/kb/articles/building-your-email-marketing-saas#step-3--the-three-tier-ladder) for pricing-ladder advice.

## Plan migrations

When you change a plan's price or limits **in Stripe**:

- Existing subscribers stay on their old terms until their next renewal
- New subscribers get the new terms immediately
- Acelle's `subscription:monitor` daily task reconciles state — usually within 24 hours

When you change a plan's `options` JSON (quotas) **in Acelle**:

- Changes apply to ALL subscribers (active and new) immediately
- This is one-way: dropping the customer's quota mid-billing-period is bad UX; bump quotas on new plans only

## Refunds + disputes

- **Refund** issued in Stripe → triggers `charge.refunded` event. AcelleMail does NOT auto-cancel the subscription on refund (refunding the latest charge doesn't necessarily end service). To stop service, also cancel the subscription in Stripe.
- **Dispute / chargeback** → triggers `charge.dispute.created`. Manual review required. Acelle doesn't auto-suspend on dispute, but you should suspend manually pending the dispute outcome.

## One-off payments (not subscriptions)

For Acelle's [sending-credit](https://acellesend.com/kb/category/integrations) / [email-verification-credit](https://acellesend.com/kb/category/integrations) products, Stripe handles one-off Payment Intents (not subscriptions). The webhook event for these is `payment_intent.succeeded` (you subscribed to it in Step 3).

## Common issues

| What you see | Likely cause | Fix |
|---|---|---|
| Stripe Checkout opens but customer is never charged | Test card declined OR webhook not configured (Acelle doesn't know it succeeded) | Use `4242 4242 4242 4242` for testing; verify Stripe Dashboard → Webhooks shows your endpoint with deliveries |
| Customer paid in Stripe but Acelle subscription status stays "new" | Webhook signing secret mismatch — Acelle rejects the webhook | Re-copy `whsec_...` from Stripe to AcelleMail; verify exact match |
| Renewal happens in Stripe but Acelle doesn't extend the period | `invoice.paid` event missing from webhook subscription | Edit webhook in Stripe → Add `invoice.paid` event |
| Failed payment doesn't trigger dunning emails | `invoice.payment_failed` missing OR Acelle's mail templates not configured | Add the event; verify **Admin → System Emails → Payment Failed** template exists |
| Customer downgrades plan but quotas don't drop | Acelle's `subscription:monitor` cron hasn't run yet | Wait for the next run (hourly), or trigger manually: `php artisan subscription:monitor` |
| 404 on the webhook URL | Acelle install URL changed OR `APP_URL` in `.env` is wrong | Check `https://your-domain/stripe/webhook` is reachable; verify `APP_URL` |
| Webhook works in test mode, breaks in live mode | Forgot to set up a separate live-mode webhook | Create live webhook in Stripe Dashboard live mode; swap signing secret |
| Stripe says "no such event" | Stripe API version mismatch — your account's default API version is too old | Stripe Dashboard → Developers → API version → Update to latest |
| Customer with 2FA on Stripe can't pay | 3DS challenge not handled correctly | Use Stripe's modern Checkout (default in 2026) which handles 3DS natively |

## FAQ

**Why is PayPal not supported?** The current Acelle Cashier (post-refactor) supports Stripe + Offline only. PayPal recurring subscriptions are operationally messier (no webhook for failed payments, currency conversion overhead, no first-class trial support). If you need PayPal, use Offline mode with manual reconciliation, OR set up Stripe's PayPal pass-through (Stripe can charge PayPal as a payment method on their side).

**Can I use Stripe Tax?** Yes — enable in Stripe Dashboard. Acelle's invoice flow uses Stripe's tax calculation automatically once enabled.

**Can I use Stripe Billing's coupons?** Yes — configure coupons in Stripe Dashboard; pass the coupon code via the customer's checkout URL. AcelleMail's UI doesn't have a coupon field directly; you'd need to extend the checkout flow (see [extending source code](https://acellesend.com/kb/articles/extending-acellemail-source-code)).

**Charging in multiple currencies?** Each AcelleMail plan has one currency. Create parallel plans in each currency (e.g. "Pro $79" and "Pro €72"). Customer's billing currency is locked to the plan they signed up on.

**Migrating from another billing system?** Export Stripe customer + subscription records via Stripe's CSV export. Acelle has no built-in import for Stripe data; you'd need a one-off script that creates Acelle customer records + links them via `stripe_customer_id` metadata field. Talk to support before doing this at scale.

**GDPR / right-to-erasure?** When a customer requests deletion: Stripe's data retention is governed by Stripe's own GDPR processes (you can request deletion via Stripe Dashboard → Customer → Actions → Forget). AcelleMail-side data deletion is via Admin → Customers → Delete.

**Is there a TestStripe / Stripe sandbox UI for verification?** Use Stripe's test mode (Step 1's `pk_test_` / `sk_test_` keys). Test cards from https://stripe.com/docs/testing.

## Related articles

- [Setting Up AcelleMail as a SaaS Platform](https://acellesend.com/kb/articles/setting-up-acellemail-as-a-saas-platform) — the parent setup (this is Step 2 of that)
- [Building Your Email Marketing SaaS](https://acellesend.com/kb/articles/building-your-email-marketing-saas) — pricing + GTM context
- [White-Label Customization Guide](https://acellesend.com/kb/articles/white-label-customization-guide) — branding the Stripe checkout experience
- [Webhook Events Reference](https://acellesend.com/kb/articles/webhook-events-reference) — Acelle's own customer-lifecycle webhooks (separate from Stripe webhooks)
- [Extending AcelleMail Source Code](https://acellesend.com/kb/articles/extending-acellemail-source-code) — for advanced Stripe Checkout customisation
- [REST API Authentication and Endpoints](https://acellesend.com/kb/articles/rest-api-authentication-and-endpoints) — for programmatically managing subscriptions
- [Configuring Amazon SES with AcelleMail](https://acellesend.com/kb/articles/configuring-amazon-ses-with-acellemail) — for the system emails (welcome, payment-failed) that Stripe triggers
- [GDPR Compliance Guide for Email Marketing](https://acellesend.com/kb/articles/gdpr-compliance-guide-for-email-marketing) — billing-data compliance

---

## Related articles

- [Integrating AcelleMail with WordPress and WooCommerce](https://acellesend.com/kb/articles/integrating-acellemail-with-wordpress-and-woocommerce): WordPress + WooCommerce is the most common stack people connect to AcelleMail. There's no first-class plugin — instead, you wire up the REST API from a few WordPress hooks. This guide walks the three integration patterns (user registration, WooCommerce purchase, optional unsubscribe sync) end-to-end, plus the choice of "API from theme/plugin" vs "embedded signup form" vs "third-party Zapier".
- [WordPress Subscriber Sync](https://acellesend.com/kb/articles/wordpress-subscriber-sync): Wire up the WordPress user_register hook to push every new account into an AcelleMail list. Twenty lines of PHP, no plugin dependency, real-time. This guide covers the production-ready snippet (with timeout / async / error handling) and the four common gotchas — field-name case, secrets in version control, slow page loads, duplicate subscribers.
- [Zapier Integration Guide for AcelleMail](https://acellesend.com/kb/articles/zapier-integration-guide): AcelleMail doesn't ship a native Zapier app, but the REST API + webhook system gives you everything you need to wire AcelleMail to the 7,000+ apps on Zapier. This guide walks both directions — AcelleMail as a Zapier action (POST to API), and AcelleMail as a Zapier trigger (webhook → Zap). Plus 6 production-tested Zap recipes.
- [WooCommerce Post-Purchase Emails](https://acellesend.com/kb/articles/woocommerce-post-purchase-emails): The window right after a WooCommerce purchase is the highest-engagement moment a customer ever has with you. A well-timed thank-you / usage-tips / review-request / cross-sell sequence quietly increases LTV without any additional ad spend. This guide walks the hook setup, the 4-step sequence template, the product-category tagging trick, and the AcelleMail automation that ties it all together.
- [BIMI with VMC — Cost, Process, and Whether It's Worth It](https://acellesend.com/kb/articles/bimi-with-vmc-cost-walkthrough): VMC (Verified Mark Certificate) costs $1,500/yr per domain and takes 4-8 weeks to obtain. This guide walks the cost math, the trademark requirements, the alternative paths, and a decision framework for whether VMC is right for your sending program.
