pay-gem
<essential_principles>
How Pay Gem Works
Pay is a payments engine for Rails that abstracts Stripe (and other processors) into a Rails-friendly interface.
1. Payment Processor Pattern
Always set a payment processor before any payment operations:
@user.set_payment_processor :stripe
# OR set default on model
class User < ApplicationRecord
pay_customer default_payment_processor: :stripe
end
Access the processor via @user.payment_processor for all operations.
2. Amounts in Cents
All amounts are in cents (smallest currency unit):
@user.payment_processor.charge(15_00) # $15.00
@user.payment_processor.charge(99_99) # $99.99
3. Webhooks Are Required
Pay relies on Stripe webhooks to sync subscription status, payment confirmations, and more. Without webhooks, your local records will be stale.
# Development: Use Stripe CLI
stripe listen --forward-to localhost:3000/pay/webhooks/stripe
4. SCA/3D Secure Handling
Stripe requires Strong Customer Authentication for EU payments. Pay handles this via:
Pay::ActionRequiredexception for charges needing confirmation- Built-in
/pay/payments/:idconfirmation route - Automatic webhook sync for async confirmations
5. Fake Processor for Testing
Use the fake processor to test without hitting Stripe:
@user.set_payment_processor :fake_processor, allow_fake: true
@user.payment_processor.subscribe(plan: "fake")
</essential_principles>
What would you like to do?
- Set up Pay gem in a new project
- Create a subscription
- Manage subscriptions (cancel, pause, resume, swap)
- Create a one-time charge
- Set up Stripe Checkout
- Set up Billing Portal
- Configure webhooks
- Implement metered/usage-based billing
- Set up Stripe Connect (marketplace)
- Debug payment issues
- Write tests
- Something else
Then read the matching workflow from workflows/ and follow it.
| Response | Workflow |
|---|---|
| 1, "setup", "install", "new project" | workflows/setup-pay-gem.md |
| 2, "subscribe", "subscription", "create subscription" | workflows/create-subscription.md |
| 3, "cancel", "pause", "resume", "swap", "manage" | workflows/manage-subscription.md |
| 4, "charge", "one-time", "payment" | workflows/create-charge.md |
| 5, "checkout", "stripe checkout", "hosted" | workflows/setup-stripe-checkout.md |
| 6, "portal", "billing portal", "customer portal" | workflows/setup-billing-portal.md |
| 7, "webhook", "webhooks", "events" | workflows/setup-webhooks.md |
| 8, "metered", "usage", "usage-based" | workflows/implement-metered-billing.md |
| 9, "connect", "marketplace", "platform" | workflows/setup-stripe-connect.md |
| 10, "debug", "not working", "error", "fix" | workflows/debug-payments.md |
| 11, "test", "tests", "testing" | workflows/write-tests.md |
<verification_loop>
After Every Change
# 1. Does it load?
bin/rails runner "Pay::Subscription"
# 2. Do tests pass?
bin/rails test test/models/
# 3. Check webhook forwarding (development)
stripe listen --forward-to localhost:3000/pay/webhooks/stripe
Report to the user:
- "Pay models load: OK"
- "Tests: X pass, Y fail"
- "Webhooks: forwarding to localhost"
</verification_loop>
<reference_index>
Domain Knowledge
All in references/:
Setup: installation.md, configuration.md Core: customers.md, payment-methods.md, charges.md, subscriptions.md Stripe Features: stripe-checkout.md, billing-portal.md, sca-payment-intents.md Advanced: webhooks.md, metered-billing.md, stripe-connect.md Quality: testing.md, anti-patterns.md
</reference_index>
<workflows_index>
Workflows
All in workflows/:
| File | Purpose |
|---|---|
| setup-pay-gem.md | Install and configure Pay with Stripe |
| create-subscription.md | Create subscriptions with trials |
| manage-subscription.md | Cancel, pause, resume, swap |
| create-charge.md | One-time charges and refunds |
| setup-stripe-checkout.md | Stripe Checkout integration |
| setup-billing-portal.md | Customer self-service portal |
| setup-webhooks.md | Webhook configuration |
| implement-metered-billing.md | Usage-based pricing |
| setup-stripe-connect.md | Marketplace payments |
| debug-payments.md | Troubleshooting |
| write-tests.md | Testing with fake processor |
</workflows_index>
More from faqndo97/ai-skills
kamal-deployment
Deploy containerized applications (especially Rails) to VPS using Kamal 2. Covers deploy.yml configuration, accessories (PostgreSQL, Redis, Sidekiq), SSL/TLS, secrets management, CI/CD with GitHub Actions, database backups, server hardening, debugging, and scaling. Use when setting up Kamal, configuring deployments, troubleshooting deploy issues, or managing production infrastructure with Kamal.
31stimulus
Build Stimulus controllers from scratch through production. Full lifecycle - create, debug, test, optimize, integrate with Turbo. Covers targets, values, actions, outlets, and UI patterns.
22ruby-llm
Build AI-powered Ruby applications with RubyLLM. Full lifecycle - chat, tools, streaming, Rails integration, embeddings, and production deployment. Covers all providers (OpenAI, Anthropic, Gemini, etc.) with one unified API.
20ruby-on-rails
Build Ruby on Rails features from scratch through production. Full lifecycle - build, debug, test, optimize, refactor. Follows Vanilla Rails philosophy (37signals/DHH), SOLID principles, and Rails 8 patterns.
19noticed
Build Rails notifications with the noticed gem. Full lifecycle - create notifiers, configure delivery methods (email, Slack, push, SMS, ActionCable), debug, and test. Covers individual and bulk delivery patterns.
15shadcn-ui
Build production-ready React/Next.js UIs with shadcn/ui components. Full lifecycle - install, customize, compose, debug, optimize. Covers components, forms, tables, theming, animations, and hooks.
14