Documentation
¶
Overview ¶
Package billing wraps the slice of the Razorpay API the managed cloud needs: creating subscriptions, verifying the client-side checkout payment signature, cancelling subscriptions, and verifying inbound webhook signatures. It talks to Razorpay over plain HTTP so the project takes on no third-party SDK dependency, and it degrades to a clean no-op when no API keys are configured (self-hosted / OSS).
Index ¶
- Variables
- type Client
- func (c *Client) CancelSubscription(ctx context.Context, subscriptionID string, atCycleEnd bool) error
- func (c *Client) CreateSubscription(ctx context.Context, p SubscribeParams) (string, error)
- func (c *Client) Enabled() bool
- func (c *Client) HasPlan(plan domain.Plan) bool
- func (c *Client) KeyID() string
- func (c *Client) PlanForPlanID(planID string) (domain.Plan, bool)
- func (c *Client) UpdateSubscriptionPlan(ctx context.Context, subscriptionID string, plan domain.Plan, atCycleEnd bool) error
- func (c *Client) VerifyAndParse(payload []byte, sigHeader string) (*Event, error)
- func (c *Client) VerifyPaymentSignature(paymentID, subscriptionID, signature string) bool
- type Event
- type SubscribeParams
Constants ¶
This section is empty.
Variables ¶
var ErrNoPlan = errors.New("no plan configured for tier")
ErrNoPlan is returned when the requested plan has no configured Razorpay plan id.
var ErrNotConfigured = errors.New("billing not configured")
ErrNotConfigured is returned by subscription/cancel calls when Razorpay is disabled.
var ErrPlanChangeUnsupported = errors.New("plan change not supported for this payment method")
ErrPlanChangeUnsupported is returned when Razorpay refuses an in-place plan change because the subscription's payment method (UPI/eMandate) can't be updated.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a minimal Razorpay REST client.
func New ¶
New builds a Razorpay client. planIDs is keyed by plan tier name (developer/team/growth). When keyID or keySecret is empty the client reports Enabled() == false and all calls no-op.
func (*Client) CancelSubscription ¶
func (c *Client) CancelSubscription(ctx context.Context, subscriptionID string, atCycleEnd bool) error
CancelSubscription cancels a Razorpay subscription. When atCycleEnd is true the subscription stays active until the end of the current billing cycle (the org keeps the access it paid for); the downgrade to free arrives via the subscription.cancelled webhook.
func (*Client) CreateSubscription ¶
CreateSubscription creates a Razorpay subscription in the "created" state and returns its id. The browser then opens the Checkout modal with this id + the public key to collect payment.
func (*Client) HasPlan ¶
HasPlan reports whether a self-serve Razorpay plan is configured for the tier.
func (*Client) KeyID ¶
KeyID returns the public Razorpay key id, safe to hand to the browser to open the Checkout modal.
func (*Client) PlanForPlanID ¶
PlanForPlanID reverse-maps a Razorpay plan id to a plan tier. Returns ("", false) when the plan id is unknown.
func (*Client) UpdateSubscriptionPlan ¶
func (c *Client) UpdateSubscriptionPlan(ctx context.Context, subscriptionID string, plan domain.Plan, atCycleEnd bool) error
UpdateSubscriptionPlan changes the plan on an existing subscription in place. When atCycleEnd is true the change applies at the end of the current billing cycle (downgrades — the org keeps what it already paid for); otherwise it applies immediately (upgrades). Razorpay only permits this for card mandates; UPI/eMandate subscriptions return ErrPlanChangeUnsupported.
func (*Client) VerifyAndParse ¶
VerifyAndParse checks the X-Razorpay-Signature header against the configured webhook secret, then decodes the event. It fails closed: without a configured webhook secret the event cannot be authenticated, so it is rejected rather than processed — otherwise anyone could POST forged subscription events (the webhook route is public) to grant themselves a paid plan or cancel a victim's.
func (*Client) VerifyPaymentSignature ¶
VerifyPaymentSignature checks the signature returned by the Checkout modal's success handler. For subscriptions Razorpay signs "<payment_id>|<subscription_id>" with the key secret (note the order differs from one-off orders). Returns true when the signature is valid.
type Event ¶
type Event struct {
Type string // e.g. subscription.activated, subscription.charged
TenantID string // from the subscription's notes[tenant_id]
CustomerID string
SubscriptionID string
Status string // subscription status (active, pending, halted, cancelled, ...)
PlanID string
}
Event is the decoded slice of a Razorpay webhook we act on, flattened from the subscription entity carried by subscription.* events.
type SubscribeParams ¶
type SubscribeParams struct {
Plan domain.Plan
TenantID string // stored in notes[tenant_id], echoed back on webhooks
CustomerEmail string // pre-fills the customer's email on Razorpay notifications
}
SubscribeParams configures a subscription created for the embedded Checkout modal.