usage_credits 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.simplecov +48 -0
- data/AGENTS.md +5 -0
- data/Appraisals +43 -0
- data/CHANGELOG.md +20 -0
- data/CLAUDE.md +5 -0
- data/README.md +81 -7
- data/gemfiles/pay_10.0.gemfile +41 -0
- data/gemfiles/pay_11.0.gemfile +41 -0
- data/gemfiles/pay_8.3.gemfile +41 -0
- data/gemfiles/pay_9.0.gemfile +41 -0
- data/gemfiles/rails_7.2.gemfile +41 -0
- data/gemfiles/rails_8.1.gemfile +41 -0
- data/lib/generators/usage_credits/templates/initializer.rb +30 -2
- data/lib/usage_credits/configuration.rb +50 -3
- data/lib/usage_credits/helpers/period_parser.rb +43 -5
- data/lib/usage_credits/models/allocation.rb +2 -0
- data/lib/usage_credits/models/concerns/pay_charge_extension.rb +92 -44
- data/lib/usage_credits/models/concerns/pay_subscription_extension.rb +376 -33
- data/lib/usage_credits/models/credit_pack.rb +51 -4
- data/lib/usage_credits/models/credit_subscription_plan.rb +115 -14
- data/lib/usage_credits/models/transaction.rb +1 -0
- data/lib/usage_credits/models/wallet.rb +15 -10
- data/lib/usage_credits/services/fulfillment_service.rb +15 -6
- data/lib/usage_credits/version.rb +1 -1
- metadata +27 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 42e2dcff2633bf14d2390d436ab14f724fb1142bc6de5adf2b410ab36e13b785
|
|
4
|
+
data.tar.gz: fef29f9815fa2cb241ed30c342083f98003a607b9b6c95dfd1d86ed1df7a5753
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 59be8e233c0a004cc6ab205a5f80aa2c17ce38d64df2b7bd99f2521ab9a185779c309ca376b5ceee684420c27d1fe3111907aa5c26c52f3c96c2dba50187895f
|
|
7
|
+
data.tar.gz: 22cdd9089c33e9d50ecf598442d6aff6acd4924662542951e81eebbc3657d6300b8c66a746290aae6339b922d2ef7ef83caa097113aa3876a19cb3265c4ee0c4
|
data/.simplecov
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SimpleCov.start 'rails' do
|
|
4
|
+
# Coverage directory
|
|
5
|
+
coverage_dir 'coverage'
|
|
6
|
+
|
|
7
|
+
# Enable branch coverage (must be before minimum_coverage)
|
|
8
|
+
enable_coverage :branch
|
|
9
|
+
|
|
10
|
+
# Set minimum coverage threshold to prevent coverage regression
|
|
11
|
+
# Current coverage: Line 84.38%, Branch 71.9%
|
|
12
|
+
# Note: Some paths (PostgreSQL JSON operators, error fallbacks) may not be exercised in SQLite tests
|
|
13
|
+
minimum_coverage line: 75, branch: 60
|
|
14
|
+
|
|
15
|
+
# Add custom groups for better organization
|
|
16
|
+
add_group 'Models', 'lib/usage_credits/models'
|
|
17
|
+
add_group 'Services', 'lib/usage_credits/services'
|
|
18
|
+
add_group 'Helpers', 'lib/usage_credits/helpers'
|
|
19
|
+
add_group 'Jobs', 'lib/usage_credits/jobs'
|
|
20
|
+
add_group 'Concerns', 'lib/usage_credits/models/concerns'
|
|
21
|
+
add_group 'DSL', ['lib/usage_credits/operation.rb', 'lib/usage_credits/credit_pack.rb', 'lib/usage_credits/credit_subscription_plan.rb']
|
|
22
|
+
|
|
23
|
+
# Filter out files we don't want to track
|
|
24
|
+
add_filter '/test/'
|
|
25
|
+
add_filter '/spec/'
|
|
26
|
+
add_filter '/config/'
|
|
27
|
+
add_filter '/db/'
|
|
28
|
+
add_filter '/vendor/'
|
|
29
|
+
add_filter '/bin/'
|
|
30
|
+
|
|
31
|
+
# Track all Ruby files in lib
|
|
32
|
+
track_files 'lib/**/*.rb'
|
|
33
|
+
|
|
34
|
+
# Disambiguate parallel test runs
|
|
35
|
+
command_name "Job #{ENV['TEST_ENV_NUMBER']}" if ENV['TEST_ENV_NUMBER']
|
|
36
|
+
|
|
37
|
+
# Use different formatters for CI vs local
|
|
38
|
+
if ENV['CI']
|
|
39
|
+
# CI: Use simple formatter for console output
|
|
40
|
+
formatter SimpleCov::Formatter::SimpleFormatter
|
|
41
|
+
else
|
|
42
|
+
# Local: Use HTML formatter for detailed report
|
|
43
|
+
formatter SimpleCov::Formatter::HTMLFormatter
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Merge results from parallel runs
|
|
47
|
+
merge_timeout 3600
|
|
48
|
+
end
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to AI Agents (like OpenAI's Codex, Claude Code, etc) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
Please go ahead and read the full context for this project at `.cursor/rules/0-overview.mdc` and `.cursor/rules/1-quality.mdc` now. Also read the README for a good overview of the project.
|
data/Appraisals
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Test minimum supported Rails version (with latest Pay)
|
|
4
|
+
appraise "rails-7.2" do
|
|
5
|
+
gem "rails", "~> 7.2.0"
|
|
6
|
+
gem "pay", "~> 11.0"
|
|
7
|
+
gem "stripe", "~> 18.0"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Test latest Rails version (with latest Pay) - this is the default/main Gemfile anyway
|
|
11
|
+
appraise "rails-8.1" do
|
|
12
|
+
gem "rails", "~> 8.1.0"
|
|
13
|
+
gem "pay", "~> 11.0"
|
|
14
|
+
gem "stripe", "~> 18.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Test minimum supported Pay version (with latest Rails)
|
|
18
|
+
appraise "pay-8.3" do
|
|
19
|
+
gem "pay", "~> 8.3.0"
|
|
20
|
+
gem "stripe", "~> 13.0"
|
|
21
|
+
gem "rails", "~> 8.1.0"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Test Pay 9.0 (popular stable version with latest Rails)
|
|
25
|
+
appraise "pay-9.0" do
|
|
26
|
+
gem "pay", "~> 9.0.0"
|
|
27
|
+
gem "stripe", "~> 13.0"
|
|
28
|
+
gem "rails", "~> 8.1.0"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Test Pay 10.0 (with latest Rails)
|
|
32
|
+
appraise "pay-10.0" do
|
|
33
|
+
gem "pay", "~> 10.0.0"
|
|
34
|
+
gem "stripe", "~> 15.0"
|
|
35
|
+
gem "rails", "~> 8.1.0"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Test latest Pay version (with latest Rails)
|
|
39
|
+
appraise "pay-11.0" do
|
|
40
|
+
gem "pay", "~> 11.0"
|
|
41
|
+
gem "stripe", "~> 18.0"
|
|
42
|
+
gem "rails", "~> 8.1.0"
|
|
43
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## [0.2.1] - 2026-01-15
|
|
2
|
+
|
|
3
|
+
- Add custom `create_checkout_session` options (like `success_url`) to credit pack purchases by @yshmarov in https://github.com/rameerez/usage_credits/pull/5
|
|
4
|
+
|
|
5
|
+
## [0.2.0] - 2025-12-29
|
|
6
|
+
|
|
7
|
+
- Add Claude Code GitHub Workflow by @rameerez in https://github.com/rameerez/usage_credits/pull/14
|
|
8
|
+
- Add test suite by @rameerez in https://github.com/rameerez/usage_credits/pull/15
|
|
9
|
+
- Update Pay gem dependency to support versions 8.3 to 9.x by @rameerez in https://github.com/rameerez/usage_credits/pull/16
|
|
10
|
+
- Update Pay gem dependency to support version 8.3 to < 10.0 by @kaka-ruto in https://github.com/rameerez/usage_credits/pull/10
|
|
11
|
+
- Add Pay version matrix testing with Appraisal by @rameerez in https://github.com/rameerez/usage_credits/pull/17
|
|
12
|
+
- Upgrade Pay dependency to support version 10.x by @rameerez in https://github.com/rameerez/usage_credits/pull/18
|
|
13
|
+
- Upgrade Pay dependency to support version 11.x by @rameerez in https://github.com/rameerez/usage_credits/pull/19
|
|
14
|
+
- Remove payment intent metadata from Subscription checkout session by @cole-robertson in https://github.com/rameerez/usage_credits/pull/2
|
|
15
|
+
- Handle subscription plan changes (upgrades & downgrades) by @rameerez in https://github.com/rameerez/usage_credits/pull/20
|
|
16
|
+
- Add configurable minimum fulfillment period for dev/test flexibility by @rameerez in https://github.com/rameerez/usage_credits/pull/21
|
|
17
|
+
- Add multi-period Stripe price support for subscription plans by @rameerez in https://github.com/rameerez/usage_credits/pull/22
|
|
18
|
+
- Fix a bug where very fast fulfillment periods would cause credits not to expire fast enough by @rameerez in https://github.com/rameerez/usage_credits/pull/23
|
|
19
|
+
- Fix incomplete fulfillment update on subscription plan upgrade by @rameerez in https://github.com/rameerez/usage_credits/pull/24
|
|
20
|
+
|
|
1
21
|
## [0.1.1] - 2025-01-14
|
|
2
22
|
|
|
3
23
|
- Rename `Wallet#subscriptions` to `Wallet.credit_subscriptions` so that it doesn’t override the Pay gem’s own subscriptions association on `User`
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
Please go ahead and read the full context for this project at `.cursor/rules/0-overview.mdc` and `.cursor/rules/1-quality.mdc` now. Also read the README for a good overview of the project.
|
data/README.md
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
# 💳✨ `usage_credits` - Add usage-based credits to your Rails app
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/usage_credits)
|
|
3
|
+
[](https://badge.fury.io/rb/usage_credits) [](https://github.com/rameerez/usage_credits/actions)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> [!TIP]
|
|
6
|
+
> **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com)**, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks.
|
|
7
|
+
|
|
8
|
+
`usage_credits` allows your users to have in-app credits / tokens they can use to perform operations.
|
|
6
9
|
|
|
7
10
|
✨ Perfect for SaaS, AI apps, games, and API products that want to implement usage-based pricing.
|
|
8
11
|
|
|
12
|
+
[ 🟢 [Live interactive demo website](https://usagecredits.com/) ] [ 🎥 [Quick video overview](https://x.com/rameerez/status/1890419563189195260) ]
|
|
13
|
+
|
|
9
14
|
Refill user credits with Stripe subscriptions, allow your users to top up by purchasing booster credit packs at any time, rollover unused credits to the next billing period, expire credits, implement PAYG (pay-as-you-go) billing, award free credits as bonuses (for referrals, giving feedback, etc.), get a detailed history and audit trail of every transaction for billing / reporting, and more!
|
|
10
15
|
|
|
11
16
|
All with a simple DSL that reads just like English.
|
|
@@ -383,6 +388,31 @@ end
|
|
|
383
388
|
|
|
384
389
|
For now, only Stripe subscriptions are supported (contribute to the codebase to help us add more payment processors!)
|
|
385
390
|
|
|
391
|
+
#### Subscriptions with a monthly + yearly price
|
|
392
|
+
|
|
393
|
+
For plans that offer multiple billing periods (e.g., monthly and yearly pricing), you can specify multiple Stripe price IDs using a hash:
|
|
394
|
+
|
|
395
|
+
```ruby
|
|
396
|
+
subscription_plan :pro do
|
|
397
|
+
# Multi-period pricing: same plan, different billing frequencies
|
|
398
|
+
stripe_price month: "price_pro_monthly", year: "price_pro_yearly"
|
|
399
|
+
|
|
400
|
+
gives 10_000.credits.every(:month)
|
|
401
|
+
# ...
|
|
402
|
+
end
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
The gem automatically handles plan matching for webhook events - when Stripe sends subscription events, the plan will be correctly identified regardless of which billing period was selected.
|
|
406
|
+
|
|
407
|
+
**Note:** Single-price plans (the traditional format) continue to work as before for backward compatibility:
|
|
408
|
+
|
|
409
|
+
```ruby
|
|
410
|
+
subscription_plan :basic do
|
|
411
|
+
stripe_price "price_basic_monthly" # Single price ID (still works)
|
|
412
|
+
gives 1_000.credits.every(:month)
|
|
413
|
+
end
|
|
414
|
+
```
|
|
415
|
+
|
|
386
416
|
### Specify a fulfillment period
|
|
387
417
|
|
|
388
418
|
Next, specify how many credits a user subscribed to this plan gets, and when they get them.
|
|
@@ -413,6 +443,49 @@ subscription_plan :pro do
|
|
|
413
443
|
end
|
|
414
444
|
```
|
|
415
445
|
|
|
446
|
+
### Grace period for credit expiration
|
|
447
|
+
|
|
448
|
+
When credits expire (i.e., `unused_credits :expire`), there's a configurable **grace period** to ensure smooth transitions between fulfillment cycles. This prevents users from seeing zero credits between the moment old credits expire and new credits are fulfilled.
|
|
449
|
+
|
|
450
|
+
```ruby
|
|
451
|
+
UsageCredits.configure do |config|
|
|
452
|
+
# Grace period for credit expiration (default: 5 minutes)
|
|
453
|
+
# Should match the frequency of your UsageCredits::FulfillmentJob runs
|
|
454
|
+
config.fulfillment_grace_period = 5.minutes
|
|
455
|
+
end
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
> [!NOTE]
|
|
459
|
+
> **Automatic grace period capping:** If your fulfillment period is shorter than the grace period (e.g., credits every 15 seconds with a 5-minute grace period), the grace period is **automatically capped** to the fulfillment period. This prevents balance accumulation where credits pile up faster than they expire.
|
|
460
|
+
>
|
|
461
|
+
> For example, with `gives 100.credits.every(15.seconds)` and a 5-minute grace period, the effective grace period will be 15 seconds, not 5 minutes. A warning will be logged during initialization to alert you of this behavior.
|
|
462
|
+
>
|
|
463
|
+
> This is typically only relevant for development/testing with very short fulfillment periods. In production with monthly or daily fulfillment cycles, the default 5-minute grace period works perfectly.
|
|
464
|
+
|
|
465
|
+
### Upgrades, downgrades, and plan changes
|
|
466
|
+
|
|
467
|
+
`usage_credits` reacts to plan changes (via the `pay` gem), and we handle automatically credit issuing for upgrades & downgrades:
|
|
468
|
+
|
|
469
|
+
- **Upgrades**: credits are granted immediately for the new plan. If the new plan expires credits, upgrade credits expire too.
|
|
470
|
+
- **Downgrades**: scheduled for the end of the current period; users keep current benefits until then.
|
|
471
|
+
- **Non-credit plan changes**: moving from credit → non-credit stops fulfillment at period end (no clawback).
|
|
472
|
+
- **Reactivation**: moving back to a credit plan reactivates fulfillment and grants credits (no signup bonus on reactivation).
|
|
473
|
+
- **Pending downgrades**: if a user returns to their current plan before the downgrade takes effect, we cancel the pending change and do **not** grant extra credits.
|
|
474
|
+
- **Credit gaming prevention**: we take measures to protect against user gaming the credit system by repeatedly upgrading/downgrading their subscription.
|
|
475
|
+
|
|
476
|
+
This happens automatically thanks to our Pay Subscription extension (changes to the `Subscription` model in the `pay` gem trigger `usage_credits` issuing the right credits based on the subscription change)
|
|
477
|
+
|
|
478
|
+
### What we handle vs. what we don't (brief)
|
|
479
|
+
|
|
480
|
+
Handled:
|
|
481
|
+
- Subscription create, renew, cancel, upgrade, downgrade, non-credit transitions
|
|
482
|
+
- Pending downgrade application on renewal
|
|
483
|
+
- Credit expiration and rollover
|
|
484
|
+
|
|
485
|
+
Not handled (yet):
|
|
486
|
+
- Plan changes while **trialing** (we only handle `status == "active"`)
|
|
487
|
+
- Paused subscriptions (see TODO in code)
|
|
488
|
+
|
|
416
489
|
## Transaction history & audit trail
|
|
417
490
|
|
|
418
491
|
Every transaction (whether adding or deducting credits) is logged in the ledger, and automatically tracked with metadata:
|
|
@@ -469,6 +542,10 @@ Which will get you:
|
|
|
469
542
|
|
|
470
543
|
It's useful if you want to name your credits something else (tokens, virtual currency, tasks, in-app gems, whatever) and you want the name to be consistent.
|
|
471
544
|
|
|
545
|
+
## Demo Rails app
|
|
546
|
+
|
|
547
|
+
There's a demo Rails app showcasing the features in the `usage_credits` gem under `test/dummy`. It's currently deployed to `usagecredits.com`. If you want to run it yourself locally, you can just clone this repo, `cd` into the `test/dummy` folder, and then `bundle` and `rails s` to launch it. You can examine the code of the demo app to better understand the gem.
|
|
548
|
+
|
|
472
549
|
## Technical notes on architecture and how this gem is built
|
|
473
550
|
|
|
474
551
|
Building a usage credits system is deceptively complex.
|
|
@@ -558,9 +635,7 @@ Real billing systems usually find edge cases when handling things like:
|
|
|
558
635
|
Please help us by contributing to add tests to cover all critical paths!
|
|
559
636
|
|
|
560
637
|
## TODO
|
|
561
|
-
|
|
562
|
-
- [ ] Write a comprehensive `minitest` test suite that covers all critical paths (both happy paths and weird edge cases)
|
|
563
|
-
- [ ] Handle subscription upgrades and downgrades (upgrade immediately; downgrade at end of billing period? Cover all scenarios allowed by the Stripe Customer Portal?)
|
|
638
|
+
No open TODOs here right now. If you find an edge case, please open an issue or PR.
|
|
564
639
|
|
|
565
640
|
## Testing
|
|
566
641
|
|
|
@@ -574,8 +649,7 @@ To install this gem onto your local machine, run `bundle exec rake install`.
|
|
|
574
649
|
|
|
575
650
|
## Contributing
|
|
576
651
|
|
|
577
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/usage_credits. Our code of conduct is: just be nice and make your mom proud of what
|
|
578
|
-
you do and post online.
|
|
652
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/usage_credits. Our code of conduct is: just be nice and make your mom proud of what you do and post online.
|
|
579
653
|
|
|
580
654
|
## License
|
|
581
655
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "pay", "~> 10.0.0"
|
|
7
|
+
gem "stripe", "~> 15.0"
|
|
8
|
+
gem "rails", "~> 8.1.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "pay", "~> 11.0"
|
|
7
|
+
gem "stripe", "~> 18.0"
|
|
8
|
+
gem "rails", "~> 8.1.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "pay", "~> 8.3.0"
|
|
7
|
+
gem "stripe", "~> 13.0"
|
|
8
|
+
gem "rails", "~> 8.1.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "pay", "~> 9.0.0"
|
|
7
|
+
gem "stripe", "~> 13.0"
|
|
8
|
+
gem "rails", "~> 8.1.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 7.2.0"
|
|
7
|
+
gem "pay", "~> 11.0"
|
|
8
|
+
gem "stripe", "~> 18.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 8.1.0"
|
|
7
|
+
gem "pay", "~> 11.0"
|
|
8
|
+
gem "stripe", "~> 18.0"
|
|
9
|
+
|
|
10
|
+
group :development do
|
|
11
|
+
gem "appraisal"
|
|
12
|
+
gem "web-console"
|
|
13
|
+
gem "standard"
|
|
14
|
+
gem "rubocop", "~> 1.0"
|
|
15
|
+
gem "rubocop-minitest", "~> 0.35"
|
|
16
|
+
gem "rubocop-performance", "~> 1.0"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
group :test do
|
|
20
|
+
gem "minitest", "~> 5.0"
|
|
21
|
+
gem "mocha"
|
|
22
|
+
gem "simplecov", require: false
|
|
23
|
+
gem "vcr"
|
|
24
|
+
gem "webmock"
|
|
25
|
+
gem "braintree", ">= 2.92.0"
|
|
26
|
+
gem "lemonsqueezy", "~> 1.0"
|
|
27
|
+
gem "paddle", "~> 2.6"
|
|
28
|
+
gem "prawn"
|
|
29
|
+
gem "receipts"
|
|
30
|
+
gem "sqlite3"
|
|
31
|
+
gem "pg"
|
|
32
|
+
gem "bootsnap", require: false
|
|
33
|
+
gem "puma"
|
|
34
|
+
gem "importmap-rails"
|
|
35
|
+
gem "sprockets-rails"
|
|
36
|
+
gem "stimulus-rails"
|
|
37
|
+
gem "turbo-rails"
|
|
38
|
+
gem "rdoc", ">= 7.0"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
gemspec path: "../"
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
UsageCredits.configure do |config|
|
|
4
|
+
#
|
|
5
|
+
# Minimum fulfillment period for subscription plans (default: 1.day)
|
|
6
|
+
# In development/test, you can set this to a shorter period for faster testing:
|
|
7
|
+
#
|
|
8
|
+
# config.min_fulfillment_period = 2.seconds if Rails.env.development?
|
|
9
|
+
#
|
|
10
|
+
#
|
|
4
11
|
#
|
|
5
12
|
# Define your credit-consuming operations below
|
|
6
13
|
#
|
|
@@ -55,6 +62,9 @@ UsageCredits.configure do |config|
|
|
|
55
62
|
# gives 1000.credits.every(:month)
|
|
56
63
|
# signup_bonus 100.credits
|
|
57
64
|
# unused_credits :expire # Credits reset each month
|
|
65
|
+
#
|
|
66
|
+
# # Single price (backward compatible)
|
|
67
|
+
# stripe_price "price_basic_monthly"
|
|
58
68
|
# end
|
|
59
69
|
#
|
|
60
70
|
# subscription_plan :pro do
|
|
@@ -62,6 +72,13 @@ UsageCredits.configure do |config|
|
|
|
62
72
|
# signup_bonus 1_000.credits
|
|
63
73
|
# trial_includes 500.credits
|
|
64
74
|
# unused_credits :expire # Credits expire at the end of the fulfillment period (use :rollover to roll over to next period)
|
|
75
|
+
#
|
|
76
|
+
# # Multi-period pricing (monthly + yearly)
|
|
77
|
+
# stripe_price month: "price_pro_monthly", year: "price_pro_yearly"
|
|
78
|
+
#
|
|
79
|
+
# # When creating checkout sessions with multi-period plans, specify the period:
|
|
80
|
+
# # plan.create_checkout_session(user, success_url: "/success", cancel_url: "/cancel", period: :month)
|
|
81
|
+
# # plan.create_checkout_session(user, success_url: "/success", cancel_url: "/cancel", period: :year)
|
|
65
82
|
# end
|
|
66
83
|
#
|
|
67
84
|
#
|
|
@@ -81,11 +98,22 @@ UsageCredits.configure do |config|
|
|
|
81
98
|
#
|
|
82
99
|
#
|
|
83
100
|
#
|
|
84
|
-
#
|
|
101
|
+
# Grace period for credit expiration (default: 5.minutes)
|
|
102
|
+
#
|
|
103
|
+
# This is for how long expiring credits from the previous fulfillment cycle will "overlap" the following fulfillment period.
|
|
85
104
|
# During this time, old credits from the previous period will erroneously count as available balance.
|
|
86
105
|
# But if we set this to 0 or nil, user balance will show up as zero some time until the next fulfillment cycle hits.
|
|
87
106
|
# A good default is to match the frequency of your UsageCredits::FulfillmentJob
|
|
88
|
-
#
|
|
107
|
+
#
|
|
108
|
+
# config.fulfillment_grace_period = 5.minutes
|
|
109
|
+
#
|
|
110
|
+
# NOTE: If your fulfillment period is shorter than the grace period (e.g., credits
|
|
111
|
+
# every 15 seconds with a 5-minute grace), the grace period is AUTOMATICALLY CAPPED
|
|
112
|
+
# to the fulfillment period. This prevents balance accumulation where credits pile
|
|
113
|
+
# up faster than they expire. A warning will be logged during initialization.
|
|
114
|
+
#
|
|
115
|
+
# This is typically only relevant for development/testing with very short periods.
|
|
116
|
+
# In production with monthly/daily fulfillment cycles, the default should work just fine.
|
|
89
117
|
#
|
|
90
118
|
#
|
|
91
119
|
#
|