created → active → cancelled → expired.
Environment overview
Sniko supports asandbox and live payment environment, controlled by:
.env
sandbox, Sniko uses test keys for Stripe and test mode flags for Razorpay and Paystack. The Stripe configuration automatically selects the correct key set based on this value.
Stripe
Credentials
Stripe uses separate key sets for test and live environments. Configure all six values — Sniko selects the active set based onPAYMENT_ENVIRONMENT:
.env
The legacy single-key variables
STRIPE_KEY, STRIPE_SECRET, and STRIPE_WEBHOOK_SECRET (from config/services.php) are also read and used by the refund and customer management services. Set them to match your active environment’s keys.- Publishable key must start with
pk_ - Secret key must start with
sk_ - Webhook secret must start with
whsec_
Webhook endpoint
Register the following endpoint in your Stripe Dashboard under Developers → Webhooks → Add endpoint:| Event | Effect |
|---|---|
customer.subscription.created | Creates or updates local subscription record |
customer.subscription.updated | Syncs plan, status, and period dates |
customer.subscription.deleted | Marks subscription as cancelled |
invoice.payment_succeeded | Marks subscription as active |
invoice.payment_failed | Marks subscription as past due |
customer.created | Stores Stripe customer ID on the user |
customer.updated | Syncs customer metadata |
payment_method.attached | Records the new payment method |
STRIPE_TEST_WEBHOOK_SECRET or STRIPE_LIVE_WEBHOOK_SECRET (matching your environment).
Currency
The default billing currency is USD. Override it with:.env
Razorpay
Razorpay is recommended for customers in India (INR billing). Sniko automatically routes Indian users to Razorpay when it is the active provider.Credentials
.env
Webhook endpoints
Razorpay sends event notifications to two routes in Sniko:{APP_URL}/webhooks/razorpay in your Razorpay Dashboard under Settings → Webhooks. Add your RAZORPAY_WEBHOOK_SECRET as the webhook secret.
Currency conversion
Razorpay charges in INR. Sniko uses a live exchange rate service to convert USD plan prices to INR at checkout. A fallback rate of ₹83 per USD is used if the exchange rate API is unavailable.Paystack
Paystack is recommended for customers in Nigeria (NGN), Ghana, South Africa, and Kenya. Sniko automatically routes users from these countries to Paystack when it is an active provider.Credentials
.env
Webhook endpoint
{APP_URL}/webhooks/paystack in your Paystack Dashboard under Settings → API Keys & Webhooks.
Enabling and disabling providers
All three providers are managed from the admin panel:Add or edit a provider
Click Add Provider or select an existing one. Enter the provider name, type (
stripe, razorpay, or paystack), and credentials. Credentials entered here are stored in the database and take precedence over matching env vars.Set a default provider
Mark one provider as the default. This provider is used when no location-based routing rule applies. Only one provider can be the default at a time.
Plan mapping
Each pricing plan must be linked to a product ID in each active payment provider. This mapping tells Sniko which provider-side product to use when creating a subscription. Navigate to Admin → Payments → Plan Mapping (/admin/payments/plan-mapping):
- Stripe: Sniko automatically creates Stripe Products and Prices when you create or update a plan. The
stripe_product_id,stripe_monthly_price_id, andstripe_yearly_price_idare stored on thePricingPlanmodel. - Razorpay: Enter the Razorpay Plan ID for monthly and yearly billing cycles.
- Paystack: Enter the Paystack Plan Code for monthly and yearly billing cycles.
Subscription lifecycle
All providers follow the same subscription state machine inside Sniko:| Status | Description |
|---|---|
incomplete | Payment initiated but not yet confirmed (Stripe only) |
active | Subscription is paid and valid |
trialing | In a free trial period |
past_due | Last payment failed; access may be restricted |
canceled | Subscription cancelled; access ends at period end |
expired | Subscription has ended |
Cancellation
Subscriptions can be cancelled immediately or at the end of the current billing period:- Cancel at period end: the subscription remains
activebutcancel_at_period_endis set totrue. Access continues until the period ends. - Immediate cancellation: the subscription status is set to
canceledinstantly.
external_id) are cancelled locally without any provider API call.
Refunds
Refunds are processed through the subscription’s original payment provider. Navigate to Admin → Payments → Subscriptions, select a subscription, and click Refund. You can also issue a refund via the API:Stripe refunds
Stripe refunds
Stripe refunds are processed immediately through the Stripe API. The refund ID is logged and stored in the subscription metadata. Stripe returns the refunded amount and status in the response.
Razorpay refunds
Razorpay refunds
Razorpay refunds are initiated via the Razorpay API against the original payment ID stored in the subscription’s
external_id. Processing time is typically 5–7 business days.Paystack refunds
Paystack refunds
Paystack refunds are submitted to the Paystack refund endpoint. The transaction reference from the original payment is required and is stored in subscription metadata at checkout.