simple_recurring 1.0.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 +7 -0
- data/README.md +64 -0
- data/Rakefile +26 -0
- data/app/models/simple_recurring/credit_card.rb +36 -0
- data/app/models/simple_recurring/promotions.rb +8 -0
- data/app/models/simple_recurring/subscription.rb +8 -0
- data/lib/simple_recurring.rb +47 -0
- data/lib/simple_recurring/engine.rb +5 -0
- data/lib/simple_recurring/processor_adapters/base_adapter.rb +45 -0
- data/lib/simple_recurring/version.rb +3 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ecb0437091aaba530f0478afd59a7cbe2bd61ee1
|
4
|
+
data.tar.gz: 3ca37f15e666411b773a49846041a9e96f0c11c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 61021dd1163925347fe9696f03d1f8cf70dd8768565d1477ce9016ebb09b829d8ca18f0fd34589379be896e32a2dbe86b7c91173875756c5b94e58ff28086fa4
|
7
|
+
data.tar.gz: 293ecdb586aa47bf131ea41fde634a24fe8f2a17cee52ef3e1122b7d63da39186f0c2e6f88036571a8a9061633e5eaf58d7b645cabcab171fce9d7e5e1819d16
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# SimpleRecurring
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
A uniform and simple way to create recurring payments with supported providers.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
Add the gem to your Gemfile.
|
8
|
+
```
|
9
|
+
gem 'SimpleRecurring'
|
10
|
+
```
|
11
|
+
|
12
|
+
Install any payment gateway adapter gems by following instructions in their README.
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
Get a list of available adapters (including display name and version, for use in an admin panel or similar):
|
16
|
+
```
|
17
|
+
SimpleRecurring.adapters
|
18
|
+
```
|
19
|
+
|
20
|
+
Get the adapter class:
|
21
|
+
```
|
22
|
+
SimpleRecurring.adapter('adaptername')
|
23
|
+
```
|
24
|
+
|
25
|
+
Get an instance of the adapter:
|
26
|
+
```
|
27
|
+
SimpleRecurring.adapter('adaptername').new
|
28
|
+
```
|
29
|
+
|
30
|
+
Create a subscription:
|
31
|
+
```
|
32
|
+
# Create a credit card with a test number that expires Jan 2020 and has 123 as it's CVC.
|
33
|
+
# CVC is optional when using a card number (although, certain providers may require it).
|
34
|
+
credit_card = SimpleRecurring::CreditCard.new('4111111111111111', 1, 2020, 123)
|
35
|
+
# For providers that support tokens you can also pass in the token as the first parameter.
|
36
|
+
# Only the first parameter should be set when using a token.
|
37
|
+
# e.g.
|
38
|
+
# credit_card = SimpleRecurring::CreditCard.new('123abc_token_string123')
|
39
|
+
|
40
|
+
# Create a representation of the subscription.
|
41
|
+
subscription = SimpleRecurring::Subscription.new
|
42
|
+
# Set the billing frequency.
|
43
|
+
subscription.billing_frequency = :monthly # :daily, :weekly, :monthly or :annually
|
44
|
+
# Set the number of billing periods.
|
45
|
+
subscription.billing_periods_count = 6 # Length in billing periods, nil or 0 for indefinite
|
46
|
+
|
47
|
+
# Get an instance of the adapter.
|
48
|
+
adapter = SimpleRecurring.adapter('adaptername').new
|
49
|
+
|
50
|
+
# Create the subscription and get a string or integer back to reference it by in the future.
|
51
|
+
subscription_reference = adapter.create_subscription(credit_card, subscription)
|
52
|
+
```
|
53
|
+
|
54
|
+
Canceling a subscription:
|
55
|
+
```
|
56
|
+
# Subscription reference was returned from create_subscription and should have been stored.
|
57
|
+
subscription_reference = '123abc'
|
58
|
+
|
59
|
+
# Get an instance of the adapter.
|
60
|
+
adapter = SimpleRecurring.adapter('adaptername').new
|
61
|
+
|
62
|
+
# Cancel the subscription. Returns true or false for success / failure.
|
63
|
+
adapter.create_subscription(subscription_reference)
|
64
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
10
|
+
load 'rails/tasks/engine.rake'
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
Bundler::GemHelper.install_tasks
|
15
|
+
|
16
|
+
require 'rake/testtask'
|
17
|
+
|
18
|
+
Rake::TestTask.new(:test) do |t|
|
19
|
+
t.libs << 'lib'
|
20
|
+
t.libs << 'test'
|
21
|
+
t.pattern = 'test/**/*_test.rb'
|
22
|
+
t.verbose = false
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
task default: :test
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SimpleRecurring
|
2
|
+
class CreditCard
|
3
|
+
# String card_number - Credit Card Number
|
4
|
+
# Integer card_expiry_month - Credit Card Expiry Month (1 = January, 12 = December)
|
5
|
+
# Integer card_expiry_year - Credit Card Expiry Year (Full 4 digits, e.g. 2019)
|
6
|
+
# Integer card_cvc - Credit Card Verification Code
|
7
|
+
# String card_token - Token from the provider identifying the credit card.
|
8
|
+
attr_reader :card_number, :card_expiry_month, :card_expiry_year, :card_cvc, :card_token
|
9
|
+
|
10
|
+
# Create a CreditCard object based on a token or card number.
|
11
|
+
#
|
12
|
+
# Params:
|
13
|
+
# String|Integer card_number_or_token
|
14
|
+
# Integer card_expiry_month
|
15
|
+
# Integer card_expiry_year
|
16
|
+
# Integer card_cvc
|
17
|
+
def initialize(card_number_or_token, card_expiry_month = nil, card_expiry_year = nil, card_cvc = nil)
|
18
|
+
if card_expiry_month == nil
|
19
|
+
@card_token = card_number_or_token
|
20
|
+
else
|
21
|
+
@card_number = card_number_or_token
|
22
|
+
@card_expiry_month = card_expiry_month
|
23
|
+
@card_expiry_year = card_expiry_year
|
24
|
+
@card_cvc = card_cvc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Checks if this CreditCard object uses a token representing the card number on the provider side.
|
29
|
+
#
|
30
|
+
# Returns:
|
31
|
+
# TRUE if a token is used, FALSE if not.
|
32
|
+
def is_token?
|
33
|
+
!@card_token.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module SimpleRecurring
|
2
|
+
class Promotions
|
3
|
+
# Integer trial_period - Trial period in days.
|
4
|
+
# Integer discount_amount - Discount amount as an integer (e.g. 100 = $1.00)
|
5
|
+
# Integer discount_billing_periods - The number of billing periods the discount should apply to, or 0 for indefinite.
|
6
|
+
attr_accessor :trial_period, :discount_amount, :discount_billing_periods
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module SimpleRecurring
|
2
|
+
class Subscription
|
3
|
+
# Symbol billing_frequency - Symbol representing billing frequency, :daily, :weekly, :monthly, :annually
|
4
|
+
# Integer billing_periods_count - Length in billing periods, 0 for indefinite
|
5
|
+
# Integer amount - Price as an integer (e.g. 100 - $1.00)
|
6
|
+
attr_accessor :billing_frequency, :billing_periods_count
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'simple_recurring/engine'
|
2
|
+
|
3
|
+
module SimpleRecurring
|
4
|
+
# Load adapter by name.
|
5
|
+
#
|
6
|
+
# Params:
|
7
|
+
# String adapter
|
8
|
+
#
|
9
|
+
# Returns:
|
10
|
+
# Implementation of SimpleRecurring::ProcessorAdapters::BaseAdapter
|
11
|
+
def self.adapter(adapter)
|
12
|
+
"SimpleRecurring::ProcessorAdapters::#{adapter.capitalize}".constantize
|
13
|
+
end
|
14
|
+
|
15
|
+
# Finds all adapters and versions.
|
16
|
+
# Warning: This is appropriate for use in an admin panel where the processor might be selected. It is NOT appropriate
|
17
|
+
# for use on user facing pages as it searches the file system for all available adapters and loads them.
|
18
|
+
#
|
19
|
+
# Returns:
|
20
|
+
# Hash of adapters with their display name and version.
|
21
|
+
def self.adapters
|
22
|
+
require_adapters
|
23
|
+
SimpleRecurring::ProcessorAdapters.constants.select { |c|
|
24
|
+
SimpleRecurring::ProcessorAdapters.const_get(c).is_a?(Class) &&
|
25
|
+
SimpleRecurring::ProcessorAdapters.const_get(c) != SimpleRecurring::ProcessorAdapters::BaseAdapter &&
|
26
|
+
SimpleRecurring::ProcessorAdapters.const_get(c).ancestors.include?(SimpleRecurring::ProcessorAdapters::BaseAdapter)
|
27
|
+
}.reduce({}) { |h, a| h[a] = { display_name: adapter(a).display_name, version: adapter(a).version }; h }
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
# Search autoload paths in each engine for all available process adapters.
|
32
|
+
def self.require_adapters
|
33
|
+
autoload_paths = Rails.application.send(:_all_autoload_paths)
|
34
|
+
Rails::Engine.subclasses.map(&:instance).each do |engine|
|
35
|
+
autoload_paths << engine.send(:_all_autoload_paths)
|
36
|
+
end
|
37
|
+
autoload_paths.flatten!
|
38
|
+
adapter_files = []
|
39
|
+
autoload_paths.each do |p|
|
40
|
+
adapter_files << Dir["#{p}simple_recurring/processor_adapters/*.rb"]
|
41
|
+
end
|
42
|
+
adapter_files.flatten!
|
43
|
+
adapter_files.each do |f|
|
44
|
+
require f
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module SimpleRecurring
|
2
|
+
module ProcessorAdapters
|
3
|
+
class BaseAdapter
|
4
|
+
# Create the subscription.
|
5
|
+
#
|
6
|
+
# Params:
|
7
|
+
# SimpleRecurring::CreditCard credit_card
|
8
|
+
# SimpleRecurring::Subscription subscription
|
9
|
+
# SimpleRecurring::Promotions promotions (optional)
|
10
|
+
#
|
11
|
+
# Returns:
|
12
|
+
# String|Integer Reference id or string for use in cancelling the subscription.
|
13
|
+
def create_subscription(credit_card, subscription, promotions = nil)
|
14
|
+
raise 'Invalid Provider'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Cancel the subscription.
|
18
|
+
#
|
19
|
+
# Params:
|
20
|
+
# String|Integer Reference
|
21
|
+
#
|
22
|
+
# Returns:
|
23
|
+
# TRUE or FALSE determined by success
|
24
|
+
def cancel_subscription(reference)
|
25
|
+
raise 'Invalid Provider'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Display name of the adapter / provider.
|
29
|
+
#
|
30
|
+
# Returns:
|
31
|
+
# String with the display name of the adapter / provider.
|
32
|
+
def self.display_name
|
33
|
+
raise 'Invalid Provider'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Version of the adapter.
|
37
|
+
#
|
38
|
+
# Returns:
|
39
|
+
# String with version of the adapter.
|
40
|
+
def self.version
|
41
|
+
raise 'Invalid Provider'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_recurring
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Dunbar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-01-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
description:
|
28
|
+
email: matt@buildrx.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- README.md
|
34
|
+
- Rakefile
|
35
|
+
- app/models/simple_recurring/credit_card.rb
|
36
|
+
- app/models/simple_recurring/promotions.rb
|
37
|
+
- app/models/simple_recurring/subscription.rb
|
38
|
+
- lib/simple_recurring.rb
|
39
|
+
- lib/simple_recurring/engine.rb
|
40
|
+
- lib/simple_recurring/processor_adapters/base_adapter.rb
|
41
|
+
- lib/simple_recurring/version.rb
|
42
|
+
homepage:
|
43
|
+
licenses: []
|
44
|
+
metadata: {}
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 2.2.2
|
62
|
+
signing_key:
|
63
|
+
specification_version: 4
|
64
|
+
summary: A uniform and simple way to create recurring payments with supported providers.
|
65
|
+
test_files: []
|