Documentation menu▾

Selling with Stripe

Connect Stripe and Keygate creates a license when a customer pays, renews it with the subscription and handles failed payments, refunds and the customer portal.

With Stripe connected, selling needs no code of your own. A customer pays on Stripe Checkout, Keygate creates the license and emails the key, and from then on the license follows the subscription: renewals extend it, failed payments trigger reminders, and cancellations end it at the right time.

Connect Stripe

Copy your secret key from the Stripe dashboard into .env and restart Keygate:

.env
STRIPE_SECRET_KEY=sk_live_...

On startup Keygate registers its own webhook endpoint in Stripe at BASE_URL/api/v1/webhook/stripe and stores the signing secret. You do not create the webhook yourself. Stripe has to reach that address, so BASE_URL must be your public HTTPS address; for testing on your own machine see local development below.

A test key (sk_test_...) puts the install in test mode, and it then accepts test events only. Use a separate install, or switch the key, when you go live.

Create the product and its prices in Stripe as usual. Then open each plan in Keygate and paste the matching price ID (price_...) into its Stripe price field.

  • A subscription plan needs a recurring price, monthly or yearly.
  • A perpetual plan needs a one time price.
  • A perpetual plan with an update period can add a second one time price for renewing it. See update periods.

Send customers to checkout

Every plan has a checkout link, shown on the plan in the dashboard. Put it behind the Buy button on your pricing page:

https://licenses.example.com/pay/k3x9q2mf

The link opens a fresh Stripe Checkout session for that plan and brings the customer back to a confirmation page on your Keygate address when they finish.

You can also sell through Stripe Payment Links or a Checkout integration of your own. Keygate looks at the price that was bought and finds the plan that uses it, so those purchases create licenses too.

After the payment

  1. Stripe reports the completed checkout to Keygate.
  2. Keygate creates the license on the plan that was bought, for the customer's email.
  3. The customer receives an email with the key, and a download button if the product has a download link.
  4. Your webhooks receive a license.created event, if you subscribed to it.

A missed webhook does not cost you a sale. Stripe sends it again, Keygate also confirms the purchase when the customer lands on the confirmation page, and every five minutes it checks Stripe for recent checkouts it has not seen. Each checkout creates exactly one license, however many of these paths report it.

The customer portal

Customers sign in to the portal at BASE_URL/portal with their email. They see their licenses and keys, and they can:

  • free a device they no longer use;
  • switch plans, for example from monthly to yearly, with Stripe working out the difference;
  • cancel a subscription;
  • download invoices and update their card through Stripe's billing portal;
  • renew the update period of a perpetual license.

Most of what would otherwise reach your inbox as a support request happens here.

Renewals and failed payments

When a subscription renews, the license's end date moves to the end of the new period. The day before a renewal, the customer gets a reminder that they will be charged.

If a payment fails, the license becomes past due but keeps working while Stripe retries the card. Keygate emails the customer one day, seven days and fourteen days into the problem. Once a payment goes through, the license is active again and the customer is told.

Subscriptions set to cancel

A subscription that will not renew gets expiry reminders instead of renewal reminders, by default seven, three and one day before it ends. You can change the days under email settings.

Cancellations and refunds

  • A customer who cancels keeps the license until the end of the period they paid for. Then it ends.
  • A full refund made in Stripe revokes the license. A partial refund leaves it working and is recorded in the audit log.
  • The Refund button on a license in the dashboard cancels the subscription in Stripe and revokes the license in one step. Return the money itself from the Stripe dashboard.

Local development

Stripe cannot deliver webhooks to localhost. Use the Stripe CLI to forward them:

bash
stripe listen --forward-to localhost:9000/api/v1/webhook/stripe

It prints a signing secret starting with whsec_. Put it in .env next to your test key and restart Keygate:

.env
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

Now buy a plan through its checkout link with the test card 4242 4242 4242 4242 and watch the license appear in the dashboard.

Last updated October 4, 2026