Skip to content

Stripe

Setup guide for the stripe payments provider. The shared API (initiate_payment, verify_payment, refund_payment, webhooks, hooks, saved methods) is documented in Payments.

1. Get credentials. In the Stripe Dashboard, under Developers -> API keys, copy the Secret key (sk_test_... in test mode, sk_live_... in production).

2. Set environment variables:

Terminal window
KIRAK_PAYMENT_STRIPE_SECRET_KEY=sk_test_...
KIRAK_PAYMENT_STRIPE_WEBHOOK_SECRET=whsec_... # from step 3

3. Configure the webhook. Under Developers -> Webhooks -> Add endpoint, point it at https://your-domain.com/payments/webhook/stripe and select at minimum: checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, invoice.payment_succeeded, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted, charge.refunded. The two async_payment events report payments made with a delayed method such as a bank debit; without them those payments stay PENDING. Copy the endpoint’s Signing secret into KIRAK_PAYMENT_STRIPE_WEBHOOK_SECRET; without it every webhook fails with WEBHOOK_SECRET_NOT_CONFIGURED (500). For saved methods, also send payment_method.detached, payment_method.updated, payment_method.automatically_updated and customer.updated to the webhook endpoint. For off-session charges, also send payment_intent.succeeded and payment_intent.payment_failed.

One Stripe account, several Kirak databases (two apps, or staging and production, often in test mode): Stripe sends every event to every endpoint, so each app also receives the others’ events. A checkout completes only the row that stored its session id when the session was created (so if that id cannot be stored, initiate_payment fails and no checkout url is returned), an off-session charge only the row whose random reference (kirak_ref in payment_meta, sent in the PaymentIntent’s metadata) it carries (one made before references carries none and matches only a row without one), and a setup session saves a card only for the user whose Stripe customer this instance created; everything else is acknowledged and left alone. Several Stripe instances in one app record processed events per instance.

4. Use it:

# One-time payment
result = await kirak.payments.initiate_payment({
"provider": "stripe",
"user_id": "42", "amount": 2999, "currency": "USD",
"name": "Pro Plan", "type": "one_time",
})
# Subscription -- subscription_plan_id is a Stripe Price ID
result = await kirak.payments.initiate_payment({
"provider": "stripe",
"user_id": "42", "amount": 2999, "currency": "USD",
"name": "Pro Plan", "type": "subscription",
"subscription_plan_id": "price_abc123",
"interval": "month", "interval_count": 1, # optional, default monthly
})

after_webhook receives these provider-neutral event names (see Webhook Hooks):

data["event"] Gateway events
payment_completed checkout.session.completed (only when paid), checkout.session.async_payment_succeeded, payment_intent.succeeded (off-session charges only)
payment_failed invoice.payment_failed, checkout.session.async_payment_failed, payment_intent.payment_failed (off-session, declined)
subscription_renewed invoice.payment_succeeded
subscription_updated customer.subscription.updated (other statuses)
subscription_past_due customer.subscription.updated with status past_due or unpaid
subscription_cancelled customer.subscription.deleted
refund_completed charge.refunded
refund_pending – (reserved)
dispute_created charge.dispute.created
dispute_updated charge.dispute.closed
payment_method_saved checkout.session.completed of a setup session
payment_method_removed payment_method.detached
payment_action_required payment_intent.payment_failed with authentication_required (off-session)

A Stripe checkout session paid by a delayed method (a bank debit) is reported as checkout.session.completed with the payment still unpaid. Kirak records it as PENDING and reports no event; payment_completed is reported when checkout.session.async_payment_succeeded arrives, and payment_failed on checkout.session.async_payment_failed.