Documentation
¶
Overview ¶
Package cashier is a multi-gateway billing plugin for Nimbus, modeled on Laravel Cashier but gateway-agnostic. One app can register several payment gateways (Stripe, Razorpay, PayU, …), pick a default, select a gateway per request, verify webhooks, and gate access with a paywall.
app.Use(cashier.NewPlugin(cashier.Config{
FromEnv: true, // register gateways whose env keys are set
Default: "razorpay", // default gateway
OnWebhook: func(e cashier.WebhookEvent) error {
switch events.Normalize(e) {
case events.PaymentSucceeded: // grant paywall access
case events.SubscriptionCancelled: // revoke
}
return nil
},
}))
Layout:
cashier.go – plugin + facade config.go – Config manager.go – GatewayManager paywall.go – Paywall engine routes.go – webhook routes contracts/ – PaymentGateway interface gateways/ – Stripe/Razorpay/PayU models/ – transactions, subscriptions events/ – canonical events views/ – checkout templates
Index ¶
- type Cashier
- type Charge
- type ChargeParams
- type Config
- type Entitlement
- type EntitlementStore
- type Gateway
- type GatewayManager
- func (m *GatewayManager) Default() Gateway
- func (m *GatewayManager) DefaultName() string
- func (m *GatewayManager) Gateway(name string) (Gateway, error)
- func (m *GatewayManager) Names() []string
- func (m *GatewayManager) Register(g Gateway) *GatewayManager
- func (m *GatewayManager) SetDefault(name string) *GatewayManager
- func (m *GatewayManager) Use(name string) (Gateway, error)
- type MemoryEntitlementStore
- type PaymentProof
- type Paywall
- func (p *Paywall) Grant(subject, plan string, expires time.Time) error
- func (p *Paywall) HasAccess(subject, plan string) bool
- func (p *Paywall) RequirePlan(plan string, subjectFn func(*nhttp.Context) string) router.Middleware
- func (p *Paywall) Revoke(subject, plan string) error
- func (p *Paywall) Store() EntitlementStore
- type Plugin
- type WebhookEvent
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cashier ¶
type Cashier struct {
Gateways *GatewayManager
Paywall *Paywall
}
Cashier is the facade tying the gateway manager to the paywall. Resolve it from the container ("cashier") or hold the plugin's instance.
type Charge ¶
Re-exported contract types so callers use the cashier package without importing contracts directly.
type ChargeParams ¶
type ChargeParams = contracts.ChargeParams
Re-exported contract types so callers use the cashier package without importing contracts directly.
type Config ¶
type Config struct {
// Manager is the gateway registry. Nil → a new empty one is created.
Manager *GatewayManager
// Default gateway name. Falls back to PAYMENTS_DEFAULT_GATEWAY, then the
// first registered gateway.
Default string
// FromEnv auto-registers gateways whose credentials are present in the
// environment (Stripe: STRIPE_KEY[/STRIPE_WEBHOOK_SECRET]; Razorpay:
// RAZORPAY_KEY_ID/RAZORPAY_KEY_SECRET[/RAZORPAY_WEBHOOK_SECRET]; PayU:
// PAYU_MERCHANT_KEY/PAYU_MERCHANT_SALT).
FromEnv bool
// Paywall backs entitlement checks (nil → in-memory store).
Paywall *Paywall
// WebhookPrefix mounts per-gateway webhooks at "<prefix>/<gateway>/webhook".
// Default "/payments".
WebhookPrefix string
// OnWebhook runs for every verified webhook (any gateway). Use
// events.Normalize(evt) to branch on canonical events and grant/revoke
// paywall access.
OnWebhook func(WebhookEvent) error
}
Config configures the Cashier plugin.
type Entitlement ¶
Entitlement grants a subject (usually a user id) access to a plan until ExpiresAt. A zero ExpiresAt means it never expires.
type EntitlementStore ¶
type EntitlementStore interface {
Grant(e Entitlement) error
Revoke(subject, plan string) error
Active(subject, plan string) (bool, error)
List(subject string) ([]Entitlement, error)
}
EntitlementStore persists entitlements. Implement it to back the paywall with a database; MemoryEntitlementStore is the default in-memory implementation.
type Gateway ¶
type Gateway = contracts.PaymentGateway
Re-exported contract types so callers use the cashier package without importing contracts directly.
type GatewayManager ¶
type GatewayManager struct {
// contains filtered or unexported fields
}
GatewayManager holds the app's registered gateways and the default selection. It is safe for concurrent use — one app can serve many gateways at once and pick per request.
func NewGatewayManager ¶
func NewGatewayManager() *GatewayManager
NewGatewayManager creates an empty gateway registry.
func (*GatewayManager) Default ¶
func (m *GatewayManager) Default() Gateway
Default returns the default gateway, or nil when none are registered.
func (*GatewayManager) DefaultName ¶
func (m *GatewayManager) DefaultName() string
DefaultName returns the default gateway's name.
func (*GatewayManager) Gateway ¶
func (m *GatewayManager) Gateway(name string) (Gateway, error)
Gateway returns the gateway registered under name.
func (*GatewayManager) Names ¶
func (m *GatewayManager) Names() []string
Names returns the registered gateway names, sorted.
func (*GatewayManager) Register ¶
func (m *GatewayManager) Register(g Gateway) *GatewayManager
Register adds a gateway. The first one registered becomes the default until SetDefault is called. Re-registering the same name replaces it.
func (*GatewayManager) SetDefault ¶
func (m *GatewayManager) SetDefault(name string) *GatewayManager
SetDefault selects the default gateway by name (no-op if not registered).
type MemoryEntitlementStore ¶
type MemoryEntitlementStore struct {
// contains filtered or unexported fields
}
MemoryEntitlementStore is a concurrency-safe in-memory EntitlementStore. Use a database-backed store in production (entitlements should survive a restart).
func NewMemoryEntitlementStore ¶
func NewMemoryEntitlementStore() *MemoryEntitlementStore
NewMemoryEntitlementStore creates an empty in-memory store.
func (*MemoryEntitlementStore) Active ¶
func (s *MemoryEntitlementStore) Active(subject, plan string) (bool, error)
func (*MemoryEntitlementStore) Grant ¶
func (s *MemoryEntitlementStore) Grant(e Entitlement) error
func (*MemoryEntitlementStore) List ¶
func (s *MemoryEntitlementStore) List(subject string) ([]Entitlement, error)
func (*MemoryEntitlementStore) Revoke ¶
func (s *MemoryEntitlementStore) Revoke(subject, plan string) error
type PaymentProof ¶
type PaymentProof = contracts.PaymentProof
Re-exported contract types so callers use the cashier package without importing contracts directly.
type Paywall ¶
type Paywall struct {
// contains filtered or unexported fields
}
Paywall gates access to plans/features based on entitlements. Grant on a successful payment (typically in a webhook handler); gate routes with RequirePlan.
func NewPaywall ¶
func NewPaywall(store EntitlementStore) *Paywall
NewPaywall builds a paywall over a store (nil → in-memory).
func (*Paywall) RequirePlan ¶
RequirePlan returns middleware that blocks a route unless the current subject has active access to plan. subjectFn extracts the subject (e.g. the user id) from the request; return "" for an anonymous/unknown user. Blocked requests receive HTTP 402 Payment Required.
func (*Paywall) Store ¶
func (p *Paywall) Store() EntitlementStore
Store returns the underlying store.
type Plugin ¶
type Plugin struct {
nimbus.BasePlugin
Cashier *Cashier
// contains filtered or unexported fields
}
Plugin wires Cashier into Nimbus.
func (*Plugin) DefaultConfig ¶
func (*Plugin) Migrations ¶
Migrations creates the cashier tables (transactions, subscriptions).
func (*Plugin) RegisterRoutes ¶
RegisterRoutes mounts a signature-verified webhook endpoint per gateway at "<WebhookPrefix>/<gateway>/webhook" (e.g. /payments/razorpay/webhook).
type WebhookEvent ¶
type WebhookEvent = contracts.WebhookEvent
Re-exported contract types so callers use the cashier package without importing contracts directly.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package contracts defines the payment-gateway contract and the shared value types every gateway and the manager operate on.
|
Package contracts defines the payment-gateway contract and the shared value types every gateway and the manager operate on. |
|
Package events defines canonical, gateway-agnostic payment events and maps each gateway's raw webhook types onto them — so paywall logic (grant/revoke) is written once regardless of which gateway delivered the event.
|
Package events defines canonical, gateway-agnostic payment events and maps each gateway's raw webhook types onto them — so paywall logic (grant/revoke) is written once regardless of which gateway delivered the event. |
|
Package gateways holds the concrete payment gateways (Stripe, Razorpay, PayU, …).
|
Package gateways holds the concrete payment gateways (Stripe, Razorpay, PayU, …). |
|
Package models holds the persisted Cashier tables (transactions, subscriptions) and their migrations.
|
Package models holds the persisted Cashier tables (transactions, subscriptions) and their migrations. |