acts_as_subscription 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,2 @@
1
+ require 'autotest/growl'
2
+ require 'autotest/fsevent'
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format nested
2
+ --color
3
+ --drb
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.8.7@acts_as_subscription
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source :gemcutter
2
+
3
+ gem 'activemerchant', '~> 1.9.3'
4
+ gem 'chargify_api_ares', '~> 0.3.7'
5
+ gem 'hpricot', '>= 0.6'
6
+ gem 'mousetrap', '~> 0.5.0'
7
+ gem 'rails', '~> 3.0.3'
8
+ gem 'uuidtools'
9
+
10
+ group :development do
11
+ gem 'bundler', '~> 1.0.0'
12
+ gem 'jeweler', '~> 1.5.2'
13
+ gem 'rcov', '>= 0.9.9'
14
+ end
15
+
16
+ group :test do
17
+ gem 'autotest', '4.4.6'
18
+ gem 'autotest-fsevent', '0.2.4'
19
+ gem 'autotest-growl', '0.2.9'
20
+ gem 'rspec', '2.0.0.rc'
21
+ gem 'sqlite3-ruby', :require => 'sqlite3'
22
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Dave Perrett, http://recursive-design.com/
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,21 @@
1
+ = acts_as_subscription
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Dave Perrett. See LICENSE for details.
18
+
19
+ == Notes
20
+
21
+ * Make sure 'Require Credit Card at signup?' is *unchecked* for free plans on Chargify.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "acts_as_subscription"
8
+ gem.summary = "ActsAsSubscription is a plugin for rails that provides recurring subscription capabilities to a model."
9
+ gem.description = "With ActsAsSubscription, you can hook your model into several subscription services, such as CheddarGetter."
10
+ gem.email = "mail@recursive-design.com"
11
+ gem.homepage = "http://recursive-design.com/"
12
+ gem.authors = ["Dave Perrett"]
13
+ gem.rubyforge_project = 'nowarning'
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rspec/core/rake_task'
21
+ RSpec::Core::RakeTask.new('spec')
22
+ task :default => :spec
23
+
24
+ def version
25
+ File.exist?('VERSION') ? File.read('VERSION') : ""
26
+ end
27
+
28
+ require 'rake/rdoctask'
29
+ Rake::RDocTask.new do |rdoc|
30
+ rdoc.rdoc_dir = 'rdoc'
31
+ rdoc.title = "acts_as_subscription #{version}"
32
+ rdoc.rdoc_files.include('README*')
33
+ rdoc.rdoc_files.include('lib/**/*.rb')
34
+ end
35
+
36
+ namespace :gem do
37
+
38
+ desc 'Clean build products'
39
+ task :clean do
40
+ rm_f 'pkg'
41
+ end
42
+
43
+ desc 'Build the gem'
44
+ task :build => :clean do
45
+ system 'rake gemspec'
46
+ system 'rake build'
47
+ end
48
+
49
+ desc 'Push the gem to rubygems'
50
+ task :publish => [:clean, :build] do
51
+ system "gem push pkg/acts_as_subscription-#{version}.gem"
52
+ end
53
+
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,104 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{acts_as_subscription}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Dave Perrett"]
12
+ s.date = %q{2011-02-01}
13
+ s.description = %q{With ActsAsSubscription, you can hook your model into several subscription services, such as CheddarGetter.}
14
+ s.email = %q{mail@recursive-design.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".autotest",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "acts_as_subscription.gemspec",
29
+ "autotest/discover.rb",
30
+ "lib/acts_as_subscription.rb",
31
+ "lib/acts_as_subscription/backend.rb",
32
+ "lib/acts_as_subscription/backend/chargify_client.rb",
33
+ "lib/acts_as_subscription/backend/cheddar_getter_client.rb",
34
+ "lib/acts_as_subscription/backend/dummy_client.rb",
35
+ "lib/acts_as_subscription/backend/recurly_client.rb",
36
+ "lib/acts_as_subscription/error.rb",
37
+ "lib/acts_as_subscription/railtie.rb",
38
+ "lib/acts_as_subscription/subscription.rb",
39
+ "lib/acts_as_subscription/subscription_plan.rb",
40
+ "spec/backend/backend/chargify_client_spec.rb",
41
+ "spec/backend/backend/cheddar_getter_client_spec.rb",
42
+ "spec/backend/backend_spec.rb",
43
+ "spec/models/subscription_plan_spec.rb",
44
+ "spec/models/subscription_spec.rb",
45
+ "spec/spec_helper.rb",
46
+ "spec/support/backend.yml.example",
47
+ "spec/support/database.yml",
48
+ "spec/support/models.rb",
49
+ "spec/support/schema.rb"
50
+ ]
51
+ s.homepage = %q{http://recursive-design.com/}
52
+ s.require_paths = ["lib"]
53
+ s.rubyforge_project = %q{nowarning}
54
+ s.rubygems_version = %q{1.3.7}
55
+ s.summary = %q{ActsAsSubscription is a plugin for rails that provides recurring subscription capabilities to a model.}
56
+ s.test_files = [
57
+ "spec/backend/backend/chargify_client_spec.rb",
58
+ "spec/backend/backend/cheddar_getter_client_spec.rb",
59
+ "spec/backend/backend_spec.rb",
60
+ "spec/models/subscription_plan_spec.rb",
61
+ "spec/models/subscription_spec.rb",
62
+ "spec/spec_helper.rb",
63
+ "spec/support/models.rb",
64
+ "spec/support/schema.rb"
65
+ ]
66
+
67
+ if s.respond_to? :specification_version then
68
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
69
+ s.specification_version = 3
70
+
71
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
72
+ s.add_runtime_dependency(%q<activemerchant>, ["~> 1.9.3"])
73
+ s.add_runtime_dependency(%q<chargify_api_ares>, ["~> 0.3.7"])
74
+ s.add_runtime_dependency(%q<hpricot>, [">= 0.6"])
75
+ s.add_runtime_dependency(%q<mousetrap>, ["~> 0.5.0"])
76
+ s.add_runtime_dependency(%q<rails>, ["~> 3.0.3"])
77
+ s.add_runtime_dependency(%q<uuidtools>, [">= 0"])
78
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
79
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
80
+ s.add_development_dependency(%q<rcov>, [">= 0.9.9"])
81
+ else
82
+ s.add_dependency(%q<activemerchant>, ["~> 1.9.3"])
83
+ s.add_dependency(%q<chargify_api_ares>, ["~> 0.3.7"])
84
+ s.add_dependency(%q<hpricot>, [">= 0.6"])
85
+ s.add_dependency(%q<mousetrap>, ["~> 0.5.0"])
86
+ s.add_dependency(%q<rails>, ["~> 3.0.3"])
87
+ s.add_dependency(%q<uuidtools>, [">= 0"])
88
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
89
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
90
+ s.add_dependency(%q<rcov>, [">= 0.9.9"])
91
+ end
92
+ else
93
+ s.add_dependency(%q<activemerchant>, ["~> 1.9.3"])
94
+ s.add_dependency(%q<chargify_api_ares>, ["~> 0.3.7"])
95
+ s.add_dependency(%q<hpricot>, [">= 0.6"])
96
+ s.add_dependency(%q<mousetrap>, ["~> 0.5.0"])
97
+ s.add_dependency(%q<rails>, ["~> 3.0.3"])
98
+ s.add_dependency(%q<uuidtools>, [">= 0"])
99
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
100
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
101
+ s.add_dependency(%q<rcov>, [">= 0.9.9"])
102
+ end
103
+ end
104
+
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,173 @@
1
+ require 'chargify_api_ares'
2
+
3
+ module ActsAsSubscription::Subscription::Backend
4
+
5
+ # A backend for the Chargify recurring billing service.
6
+ #
7
+ # http://chargify.com
8
+ class ChargifyClient
9
+
10
+ # Initializes the backend, and authenticates with the subscription service.
11
+ #
12
+ # Required parameters are :
13
+ # * <tt>user</tt> : The login used to connect to the remote API.
14
+ # * <tt>password</tt> : The password used to connect to the remote API.
15
+ # * <tt>product_code</tt> : The code for the product being sold.
16
+ def initialize(user, password, product_code)
17
+ Chargify.configure do |c|
18
+ c.subdomain = user
19
+ c.api_key = password
20
+ end
21
+ end
22
+
23
+ # Creates a customer on the backend subscription service, using the settings from the given
24
+ # <tt>subscription</tt> instance.
25
+ #
26
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
27
+ # <tt>acts_as_subscription</tt> :
28
+ #
29
+ # class Subscription < ActiveRecord::Base
30
+ # acts_as_subscription
31
+ # end
32
+ #
33
+ # Returns true if the operation was successful, otherwise an error message.
34
+ def create_subscription(subscription)
35
+ customer_attributes = self.get_customer_attributes(subscription)
36
+ customer = Chargify::Customer.create(customer_attributes)
37
+ if customer.errors.length == 0
38
+ subscription_attributes = self.get_subscription_attributes(subscription)
39
+ subscription = Chargify::Subscription.create(subscription_attributes)
40
+ if subscription.errors.length > 0
41
+ return subscription.errors[:base][0]
42
+ else
43
+ return true
44
+ end
45
+ else
46
+ return customer.errors[:base][0]
47
+ end
48
+ return 'An unknown error occurred.'
49
+ rescue Exception => error
50
+ return error.message
51
+ end
52
+
53
+ # Updates a customer on the backend subscription service, using the settings from the given
54
+ # <tt>subscription</tt> instance.
55
+ #
56
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
57
+ # <tt>acts_as_subscription</tt> :
58
+ #
59
+ # class Subscription < ActiveRecord::Base
60
+ # acts_as_subscription
61
+ # end
62
+ #
63
+ # Returns true if the update was successful, otherwise an error message.
64
+ def update_subscription(subscription)
65
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
66
+ customer.first_name = subscription.first_name,
67
+ customer.last_name = subscription.last_name,
68
+ customer.email = subscription.email,
69
+ customer.reference = subscription.customer_code
70
+ if customer.save
71
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
72
+ sub.product_handle = subscription.plan_code
73
+ subscription_attributes = self.get_subscription_attributes(subscription)
74
+ # If the user is down-grading to a free plan, credit_card_attributes may not be available.
75
+ if subscription_attributes[:credit_card_attributes]
76
+ sub.credit_card_attributes = subscription_attributes[:credit_card_attributes]
77
+ end
78
+ if sub.save
79
+ return true
80
+ else
81
+ return sub.errors[:base][0]
82
+ end
83
+ else
84
+ return customer.errors[:base][0]
85
+ end
86
+ rescue Exception => error
87
+ return error.message
88
+ end
89
+
90
+ # Cancels the customer with the given <tt>customer_code</tt> on the backend subscription service.
91
+ #
92
+ # Returns true if the cancellation was successful, or false otherwise.
93
+ def cancel_subscription!(customer_code)
94
+ sub = Chargify::Subscription.find_by_customer_reference(customer_code)
95
+ response = sub.cancel
96
+ doc = Hpricot::XML(response.body)
97
+ return (response.code == "200" and (doc/:subscription/:state).text == 'canceled')
98
+ rescue Exception => error
99
+ return false
100
+ end
101
+
102
+ # Returns a list of subscription plans registered with the backend subscription service.
103
+ def plans
104
+ result = []
105
+ Chargify::Product.all.each do |product|
106
+ result << {
107
+ :name => product.name,
108
+ :code => product.handle,
109
+ :active => true, # Doesn't seem to be an option to make inactive.
110
+ :description => product.description,
111
+ :billing_frequency => product.interval_unit,
112
+ :recurring_charge => product.price_in_cents.to_f
113
+ }
114
+ end
115
+
116
+ return result
117
+ end
118
+
119
+ protected
120
+
121
+ # Converts a Subscription instance into a hash of parameters used to update a customer on
122
+ # the remote subscription service.
123
+ #
124
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
125
+ # <tt>acts_as_subscription</tt> :
126
+ #
127
+ # class Subscription < ActiveRecord::Base
128
+ # acts_as_subscription
129
+ # end
130
+ def get_customer_attributes(subscription)
131
+ attributes = {
132
+ :first_name => subscription.first_name,
133
+ :last_name => subscription.last_name,
134
+ :email => subscription.email,
135
+ :reference => subscription.customer_code
136
+ }
137
+
138
+ return attributes
139
+ end
140
+
141
+ # Converts a Subscription instance into a hash of parameters used to update a subscription on
142
+ # the remote subscription service.
143
+ #
144
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
145
+ # <tt>acts_as_subscription</tt> :
146
+ #
147
+ # class Subscription < ActiveRecord::Base
148
+ # acts_as_subscription
149
+ # end
150
+ def get_subscription_attributes(subscription)
151
+ attributes = {
152
+ :customer_reference => subscription.customer_code,
153
+ :product_handle => subscription.plan_code.downcase,
154
+ }
155
+
156
+ unless subscription.is_free_plan?
157
+ attributes[:credit_card_attributes] = {
158
+ :first_name => subscription.first_name,
159
+ :last_name => subscription.last_name,
160
+ :full_number => subscription.cc_number,
161
+ :expiration_month => subscription.cc_expiration_month,
162
+ :expiration_year => subscription.cc_expiration_year,
163
+ :billing_zip_code => subscription.zip_code,
164
+ }
165
+ end
166
+
167
+ return attributes
168
+ end
169
+
170
+ end
171
+
172
+ end
173
+
@@ -0,0 +1,151 @@
1
+ module ActsAsSubscription::Subscription::Backend
2
+
3
+ # A backend for the CheddarGetter recurring billing service.
4
+ #
5
+ # https://cheddargetter.com
6
+ class CheddarGetterClient
7
+
8
+ # Initializes the backend, and authenticates with the subscription service.
9
+ #
10
+ # Required parameters are :
11
+ # * <tt>user</tt> : The login used to connect to the remote API.
12
+ # * <tt>password</tt> : The password used to connect to the remote API.
13
+ # * <tt>product_code</tt> : The code for the product being sold.
14
+ def initialize(user, password, product_code)
15
+ Mousetrap.product_code = product_code
16
+ Mousetrap.authenticate(user, password)
17
+ end
18
+
19
+ # Creates a customer on the backend subscription service, using the settings from the given
20
+ # <tt>subscription</tt> instance.
21
+ #
22
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
23
+ # <tt>acts_as_subscription</tt> :
24
+ #
25
+ # class Subscription < ActiveRecord::Base
26
+ # acts_as_subscription
27
+ # end
28
+ #
29
+ # Returns true if the operation was successful, otherwise an error message.
30
+ def create_subscription(subscription)
31
+ customer_attributes = self.get_customer_attributes(subscription)
32
+ Mousetrap::Customer.create customer_attributes
33
+ return true
34
+ rescue Exception => error
35
+ return error.message
36
+ end
37
+
38
+ # Updates a customer on the backend subscription service, using the settings from the given
39
+ # <tt>subscription</tt> instance.
40
+ #
41
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
42
+ # <tt>acts_as_subscription</tt> :
43
+ #
44
+ # class Subscription < ActiveRecord::Base
45
+ # acts_as_subscription
46
+ # end
47
+ #
48
+ # Returns true if the update was successful, otherwise an error message.
49
+ def update_subscription(subscription)
50
+ customer_attributes = self.get_customer_attributes(subscription)
51
+ customer = Mousetrap::Customer.new(customer_attributes)
52
+ customer.save
53
+ return true
54
+ rescue Exception => error
55
+ return error.message
56
+ end
57
+
58
+ # Cancels the customer with the given <tt>customer_code</tt> on the backend subscription service.
59
+ #
60
+ # Returns true if the cancellation was successful, or false otherwise.
61
+ def cancel_subscription!(customer_code)
62
+ customer = Mousetrap::Customer[customer_code]
63
+ result = customer.try(:cancel)
64
+ return (result != nil)
65
+ end
66
+
67
+ # Returns a list of subscription plans registered with the backend subscription service.
68
+ def plans
69
+ result = []
70
+ Mousetrap::Plan.all.each do |plan|
71
+ result << {
72
+ :name => plan.name,
73
+ :code => plan.code,
74
+ :active => (plan.active == "1"),
75
+ :description => plan.description,
76
+ # CheddarGetter returns 'monthly' etc instead of 'month' - remove trailing 'ly'.
77
+ :billing_frequency => plan.billing_frequency.sub(/ly$/i, ''),
78
+ :recurring_charge => plan.recurring_charge.to_f
79
+ }
80
+ end
81
+
82
+ return result
83
+ end
84
+
85
+ protected
86
+
87
+ # Converts a Subscription instance into a hash of parameters used to update the remote
88
+ # subscription service.
89
+ #
90
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
91
+ # <tt>acts_as_subscription</tt> :
92
+ #
93
+ # class Subscription < ActiveRecord::Base
94
+ # acts_as_subscription
95
+ # end
96
+ def get_customer_attributes(subscription)
97
+ customer_attributes = {
98
+ :email => subscription.email,
99
+ :code => subscription.customer_code,
100
+ :first_name => subscription.first_name,
101
+ :last_name => subscription.last_name,
102
+ :subscription_attributes => {
103
+ :plan_code => subscription.plan_code,
104
+ :billing_first_name => subscription.first_name,
105
+ :billing_last_name => subscription.last_name,
106
+ }
107
+ }
108
+
109
+ customer_attributes[:subscription_attributes][:credit_card_number] = subscription.cc_number if subscription.cc_number
110
+ customer_attributes[:subscription_attributes][:credit_card_expiration_month] = subscription.cc_expiration_month if subscription.cc_expiration_month
111
+ customer_attributes[:subscription_attributes][:credit_card_expiration_year] = subscription.cc_expiration_year if subscription.cc_expiration_year
112
+ customer_attributes[:subscription_attributes][:billing_zip_code] = subscription.zip_code if subscription.zip_code
113
+
114
+ # The mousetrap gem doesn't actually support :credit_card_verification_value for some reason - try to send in a patch sometime.
115
+ #customer_attributes[:subscription_attributes][:credit_card_verification_value] = subscription.cc_verification_code if subscription.cc_verification_code
116
+
117
+ return customer_attributes
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+
125
+ # Need to patch Mousetrap::Plan to allow us some extra information about
126
+ # subscription plans. By default it only returns :name and :code.
127
+ module Mousetrap # :nodoc:
128
+ class Plan < Resource # :nodoc:
129
+ attr_accessor \
130
+ :active,
131
+ :code,
132
+ :name,
133
+ :description,
134
+ :billing_frequency,
135
+ :recurring_charge
136
+
137
+ protected
138
+
139
+ def self.attributes_from_api(attributes)
140
+ {
141
+ :active => attributes['isActive'],
142
+ :code => attributes['code'],
143
+ :name => attributes['name'],
144
+ :description => attributes['description'],
145
+ :billing_frequency => attributes['billingFrequency'],
146
+ :recurring_charge => attributes['recurringChargeAmount']
147
+ }
148
+ end
149
+ end
150
+ end
151
+
@@ -0,0 +1,49 @@
1
+ module ActsAsSubscription::Subscription::Backend
2
+
3
+ class DummyClient # :nodoc:
4
+
5
+ def initialize(user, password, product_code)
6
+ true
7
+ end
8
+
9
+ def create_subscription(options)
10
+ true
11
+ end
12
+
13
+ def update_subscription(options)
14
+ true
15
+ end
16
+
17
+ def cancel_subscription!(customer_code)
18
+ true
19
+ end
20
+
21
+ def plans
22
+ [{
23
+ :code =>'FREE',
24
+ :name =>'Free',
25
+ :active =>true,
26
+ :description =>'The price is right!',
27
+ :billing_frequency =>'month',
28
+ :recurring_charge =>0.0
29
+ }, {
30
+ :code =>'PERSONAL',
31
+ :name =>'Personal',
32
+ :active =>true,
33
+ :description =>'Single-user. can access calendars, reminders and to-dos.',
34
+ :billing_frequency =>'month',
35
+ :recurring_charge =>9.95
36
+ }, {
37
+ :code =>'PRO',
38
+ :name =>'Pro',
39
+ :active =>true,
40
+ :description =>'All the bells and whistles.',
41
+ :billing_frequency =>'month',
42
+ :recurring_charge =>19.95
43
+ }]
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
@@ -0,0 +1,58 @@
1
+ module ActsAsSubscription::Subscription::Backend
2
+
3
+ # A backend for the Recurly recurring billing service.
4
+ #
5
+ # http://recurly.com
6
+ class RecurlyClient
7
+
8
+ # Initializes the backend, and authenticates with the subscription service.
9
+ #
10
+ # Required parameters are :
11
+ # * <tt>user</tt> : The login used to connect to the remote API.
12
+ # * <tt>password</tt> : The password used to connect to the remote API.
13
+ # * <tt>product_code</tt> : The code for the product being sold.
14
+ def initialize(user, password, product_code)
15
+ false
16
+ end
17
+
18
+ # Creates a customer on the backend subscription service, using the settings from the given
19
+ # <tt>subscription</tt> instance.
20
+ #
21
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
22
+ # <tt>acts_as_subscription</tt> :
23
+ #
24
+ # class Subscription < ActiveRecord::Base
25
+ # acts_as_subscription
26
+ # end
27
+ #
28
+ # Returns true if the operation was successful, otherwise an error message.
29
+ def create_subscription(subscription)
30
+ false
31
+ end
32
+
33
+ # Updates a customer on the backend subscription service, using the settings from the given
34
+ # <tt>subscription</tt> instance.
35
+ #
36
+ # <tt>subscription</tt> should be a subclass of <tt>ActiveRecord::Base</tt> that implements
37
+ # <tt>acts_as_subscription</tt> :
38
+ #
39
+ # class Subscription < ActiveRecord::Base
40
+ # acts_as_subscription
41
+ # end
42
+ #
43
+ # Returns true if the update was successful, otherwise an error message.
44
+ def update_subscription(subscription)
45
+ false
46
+ end
47
+
48
+ # Cancels the customer with the given <tt>customer_code</tt> on the backend subscription service.
49
+ #
50
+ # Returns true if the cancellation was successful, or false otherwise.
51
+ def cancel_subscription!(customer_code)
52
+ false
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+