Stripe Subscriptions
A managed Stripe webhook endpoint with signature verification, idempotent retries, and customer portal support — merged into a single lifecycle stream alongside your App Store and Play Store events.
Ship the integration in minutes with the Stubkit SDK — the receipt flow, retries, and idempotency are handled server-side.
// Paste the Stubkit webhook URL into Stripe → Developers → Webhooks,
// upload your webhook signing secret, and the Stripe subscription
// lifecycle merges into your unified Stubkit event stream.
import { Stubkit } from '@stubkit/js';
const stubkit = new Stubkit({ apiKey: process.env.STUBKIT_SECRET_KEY });
// One webhook for Apple, Google, AND Stripe — same event shape.
app.post('/webhooks/stubkit', async (req, res) => {
const event = stubkit.verifyWebhook(req.body, req.headers['stubkit-signature']);
if (event.type === 'subscription.activated') {
await grantEntitlement(event.data.user_id, event.data.entitlement);
}
if (event.type === 'subscription.refunded') {
await revokeEntitlement(event.data.user_id, event.data.entitlement);
}
res.sendStatus(200);
});You can — but most apps end up writing the same scaffolding: signature verification, idempotency keyed on event.id, a durable queue for retries, a mapping from Stripe event names to entitlement state, and separate handling for customer portal events versus checkout events. Stubkit ships all of this, and merges it with your Apple and Google streams into one API.
Yes. Stubkit listens to the full set of Stripe subscription events (customer.subscription.*, invoice.*, charge.refunded, checkout.session.completed) plus Portal-originated changes like plan swaps and cancellations. The outbound normalised event reflects the effective entitlement state regardless of which surface triggered it.
On the inbound path, Stubkit verifies the Stripe-Signature header against your webhook signing secret before accepting the event. On the outbound path, every webhook Stubkit sends you carries a stubkit-signature header that you verify with a single SDK call.
Stripe retries failed deliveries for up to 3 days. Stubkit's ingestion is idempotent on event.id, so replays are silently de-duplicated. If Stubkit's outbound webhook to your backend fails, Stubkit retries with exponential backoff for up to 24 hours — you can inspect the full delivery log in the admin dashboard.
That's the core use case. A single Stubkit app can have Apple, Google Play, and Stripe subscriptions all pointing at the same entitlement ledger — so a user who subscribed on your website via Stripe is treated identically to a user who subscribed through the App Store, and the paywall / entitlement API serves both transparently.
Stubkit fires a subscription.refunded event the moment Stripe reports a charge.refunded, charge.dispute.created, or a credit note that zeroes out an invoice. Your entitlement is revoked automatically, with the reason exposed in the event payload for analytics.
Free forever on the starter tier. Full SDK support for iOS, Android, web, and server environments.
Start freeAlready integrated? See pricing