micah_chargify_api_ares 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +80 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/chargify_api_ares.gemspec +68 -0
- data/lib/chargify_api_ares.rb +167 -0
- data/samples/customers.rb +51 -0
- data/samples/metered_components.rb +35 -0
- data/samples/products.rb +24 -0
- data/samples/subscriptions.rb +56 -0
- data/samples/transactions.rb +17 -0
- data/spec/base_spec.rb +10 -0
- data/spec/components_spec.rb +48 -0
- data/spec/customer_spec.rb +23 -0
- data/spec/factories.rb +62 -0
- data/spec/mocks/fake_resource.rb +82 -0
- data/spec/product_spec.rb +23 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/subscription_spec.rb +67 -0
- data/spec/subscriptions_component_spec.rb +82 -0
- metadata +95 -0
data/.gitignore
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Grasshopper Group, LLC
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
Chargify API wrapper for Ruby (using ActiveResource)
|
2
|
+
====================================================
|
3
|
+
|
4
|
+
chargify_api_ares
|
5
|
+
-----------------
|
6
|
+
|
7
|
+
This is a Ruby wrapper for the [Chargify](http://chargify.com) API that leverages ActiveResource.
|
8
|
+
It allows you to interface with the Chargify API using simple ActiveRecord-like syntax, i.e.:
|
9
|
+
|
10
|
+
Chargify::Subscription.create(
|
11
|
+
:customer_reference => 'moklett',
|
12
|
+
:product_handle => 'chargify-api-ares-test',
|
13
|
+
:credit_card_attributes => {
|
14
|
+
:first_name => "Michael",
|
15
|
+
:last_name => "Klett",
|
16
|
+
:expiration_month => 1,
|
17
|
+
:expiration_year => 2010,
|
18
|
+
:full_number => "1234-1234-1234-1234"
|
19
|
+
}
|
20
|
+
)
|
21
|
+
|
22
|
+
subscription.credit_card_attributes = {:expiration_year => 2013}
|
23
|
+
subscription.save
|
24
|
+
|
25
|
+
subscription.cancel
|
26
|
+
|
27
|
+
See the `samples` directory for more usage examples.
|
28
|
+
|
29
|
+
|
30
|
+
### Installation
|
31
|
+
|
32
|
+
This library can be installed as a gem. It is hosted on [Gemcutter](http://gemcutter.org).
|
33
|
+
|
34
|
+
If you don't have your system set up to use gemcutter, follow the instructions on their site
|
35
|
+
<http://gemcutter.org>, i.e.:
|
36
|
+
|
37
|
+
$ gem install gemcutter
|
38
|
+
$ gem tumble
|
39
|
+
|
40
|
+
This will install Gemcutter and set your gem sources to search the gemcutter repos.
|
41
|
+
|
42
|
+
Then you can install this library as a gem:
|
43
|
+
|
44
|
+
$ gem install chargify_api_ares
|
45
|
+
|
46
|
+
|
47
|
+
### Requirements
|
48
|
+
|
49
|
+
This library requires ActiveResource version 2.3.4 or greater.
|
50
|
+
|
51
|
+
$ gem install activeresource
|
52
|
+
|
53
|
+
|
54
|
+
### Usage
|
55
|
+
|
56
|
+
Simply require this library before you use it:
|
57
|
+
|
58
|
+
require 'chargify_api_ares'
|
59
|
+
|
60
|
+
|
61
|
+
If you're using Rails, you could include this gem in your configuration, i.e. in `environment.rb`
|
62
|
+
|
63
|
+
config.gem 'chargify_api_ares'
|
64
|
+
|
65
|
+
|
66
|
+
Now you'll have access to classes the interact with the Chargify API, such as:
|
67
|
+
|
68
|
+
`Chargify::Product`
|
69
|
+
`Chargify::Customer`
|
70
|
+
`Chargifiy::Subscription`
|
71
|
+
|
72
|
+
Check out the examples in the `samples` directory. If you're not familiar with how ActiveResource works,
|
73
|
+
you may be interested in some [ActiveResource Documentation](http://apidock.com/rails/ActiveResource/Base)
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
### Contributors
|
78
|
+
|
79
|
+
* Michael Klett (Grasshopper Labs and Chargify)
|
80
|
+
* The Lab Rats @ Phase Two Labs
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "micah_chargify_api_ares"
|
5
|
+
gemspec.summary = "A Chargify API wrapper for Ruby using ActiveResource"
|
6
|
+
gemspec.description = ""
|
7
|
+
gemspec.email = "mklett@grasshopper.com"
|
8
|
+
gemspec.homepage = "http://github.com/grasshopperlabs/chargify_api_ares"
|
9
|
+
gemspec.authors = ["Michael Klett", "The Lab Rats @ Phase Two Labs", "Brian Rose","Nathan Verni","Micah Wedemeyer"]
|
10
|
+
Jeweler::GemcutterTasks.new
|
11
|
+
end
|
12
|
+
rescue LoadError
|
13
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
14
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.4
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{chargify_api_ares}
|
8
|
+
s.version = "0.3.3"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Michael Klett", "The Lab Rats @ Phase Two Labs", "Brian Rose", "Nathan Verni"]
|
12
|
+
s.date = %q{2010-06-24}
|
13
|
+
s.description = %q{}
|
14
|
+
s.email = %q{mklett@grasshopper.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE.txt",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"chargify_api_ares.gemspec",
|
26
|
+
"lib/chargify_api_ares.rb",
|
27
|
+
"samples/customers.rb",
|
28
|
+
"samples/metered_components.rb",
|
29
|
+
"samples/products.rb",
|
30
|
+
"samples/subscriptions.rb",
|
31
|
+
"spec/base_spec.rb",
|
32
|
+
"spec/components_spec.rb",
|
33
|
+
"spec/customer_spec.rb",
|
34
|
+
"spec/factories.rb",
|
35
|
+
"spec/mocks/fake_resource.rb",
|
36
|
+
"spec/product_spec.rb",
|
37
|
+
"spec/spec_helper.rb",
|
38
|
+
"spec/subscription_spec.rb",
|
39
|
+
"spec/subscriptions_component_spec.rb"
|
40
|
+
]
|
41
|
+
s.homepage = %q{http://github.com/grasshopperlabs/chargify_api_ares}
|
42
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.6}
|
45
|
+
s.summary = %q{A Chargify API wrapper for Ruby using ActiveResource}
|
46
|
+
s.test_files = [
|
47
|
+
"spec/base_spec.rb",
|
48
|
+
"spec/components_spec.rb",
|
49
|
+
"spec/customer_spec.rb",
|
50
|
+
"spec/factories.rb",
|
51
|
+
"spec/mocks/fake_resource.rb",
|
52
|
+
"spec/product_spec.rb",
|
53
|
+
"spec/spec_helper.rb",
|
54
|
+
"spec/subscription_spec.rb",
|
55
|
+
"spec/subscriptions_component_spec.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
63
|
+
else
|
64
|
+
end
|
65
|
+
else
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# Chargify API Wrapper using ActiveResource.
|
2
|
+
#
|
3
|
+
begin
|
4
|
+
require 'active_resource'
|
5
|
+
rescue LoadError
|
6
|
+
begin
|
7
|
+
require 'rubygems'
|
8
|
+
require 'active_resource'
|
9
|
+
rescue LoadError
|
10
|
+
abort <<-ERROR
|
11
|
+
The 'activeresource' library could not be loaded. If you have RubyGems
|
12
|
+
installed you can install ActiveResource by doing "gem install activeresource".
|
13
|
+
ERROR
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# Version check
|
19
|
+
module Chargify
|
20
|
+
MIN_VERSION = '2.3.4'
|
21
|
+
end
|
22
|
+
require 'active_resource/version'
|
23
|
+
unless ActiveResource::VERSION::STRING >= Chargify::MIN_VERSION
|
24
|
+
abort <<-ERROR
|
25
|
+
ActiveResource version #{Chargify::MIN_VERSION} or greater is required.
|
26
|
+
ERROR
|
27
|
+
end
|
28
|
+
|
29
|
+
# Patch ActiveResource version 2.3.4
|
30
|
+
if ActiveResource::VERSION::STRING == '2.3.4'
|
31
|
+
module ActiveResource
|
32
|
+
class Base
|
33
|
+
def save
|
34
|
+
save_without_validation
|
35
|
+
true
|
36
|
+
rescue ResourceInvalid => error
|
37
|
+
case error.response['Content-Type']
|
38
|
+
when /application\/xml/
|
39
|
+
errors.from_xml(error.response.body)
|
40
|
+
when /application\/json/
|
41
|
+
errors.from_json(error.response.body)
|
42
|
+
end
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
module Chargify
|
51
|
+
|
52
|
+
class << self
|
53
|
+
attr_accessor :subdomain, :api_key, :site, :format
|
54
|
+
|
55
|
+
def configure
|
56
|
+
yield self
|
57
|
+
|
58
|
+
Base.user = api_key
|
59
|
+
Base.password = 'X'
|
60
|
+
|
61
|
+
if site.blank?
|
62
|
+
Base.site = "https://#{subdomain}.chargify.com"
|
63
|
+
Subscription::Component.site = "https://#{subdomain}.chargify.com/subscriptions/:subscription_id"
|
64
|
+
else
|
65
|
+
Base.site = site
|
66
|
+
Subscription::Component.site = site + "/subscriptions/:subscription_id"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Base < ActiveResource::Base
|
72
|
+
class << self
|
73
|
+
def element_name
|
74
|
+
name.split(/::/).last.underscore
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_xml(options = {})
|
79
|
+
options.merge!(:dasherize => false)
|
80
|
+
super
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Customer < Base
|
85
|
+
def self.find_by_reference(reference)
|
86
|
+
Customer.new get(:lookup, :reference => reference)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Subscription < Base
|
91
|
+
def self.find_by_customer_reference(reference)
|
92
|
+
customer = Customer.find_by_reference(reference)
|
93
|
+
find(:first, :params => {:customer_id => customer.id})
|
94
|
+
end
|
95
|
+
|
96
|
+
# Strip off nested attributes of associations before saving, or type-mismatch errors will occur
|
97
|
+
def save
|
98
|
+
self.attributes.delete('customer')
|
99
|
+
self.attributes.delete('product')
|
100
|
+
self.attributes.delete('credit_card')
|
101
|
+
super
|
102
|
+
end
|
103
|
+
|
104
|
+
def cancel
|
105
|
+
destroy
|
106
|
+
end
|
107
|
+
|
108
|
+
def component(id)
|
109
|
+
Component.find(id, :params => {:subscription_id => self.id})
|
110
|
+
end
|
111
|
+
|
112
|
+
def components(params = {})
|
113
|
+
params.merge!({:subscription_id => self.id})
|
114
|
+
Component.find(:all, :params => params)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Perform a one-time charge on an existing subscription.
|
118
|
+
# For more information, please see the one-time charge API docs available
|
119
|
+
# at: http://support.chargify.com/faqs/api/api-charges
|
120
|
+
def charge(attrs = {})
|
121
|
+
post :charges, :charge => attrs
|
122
|
+
end
|
123
|
+
|
124
|
+
# Give a credit on an existing subscription.
|
125
|
+
# For more information, see the API docs available at
|
126
|
+
# http://support.chargify.com/faqs/api/api-credits
|
127
|
+
def credit(attrs = {})
|
128
|
+
post :credits, :credit => attrs
|
129
|
+
end
|
130
|
+
|
131
|
+
def transactions()
|
132
|
+
Transaction.find(:all, :params =>{:subscription_id => self.id})
|
133
|
+
end
|
134
|
+
|
135
|
+
class Component < Base
|
136
|
+
# All Subscription Components are considered already existing records, but the id isn't used
|
137
|
+
def id
|
138
|
+
self.component_id
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class Product < Base
|
144
|
+
def self.find_by_handle(handle)
|
145
|
+
Product.new get(:lookup, :handle => handle)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class ProductFamily < Base
|
150
|
+
end
|
151
|
+
|
152
|
+
class Usage < Base
|
153
|
+
def subscription_id=(i)
|
154
|
+
self.prefix_options[:subscription_id] = i
|
155
|
+
end
|
156
|
+
def component_id=(i)
|
157
|
+
self.prefix_options[:component_id] = i
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class Component < Base
|
162
|
+
end
|
163
|
+
|
164
|
+
class Transaction < Base
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'chargify_api_ares'
|
4
|
+
|
5
|
+
# You could load your credentials from a file...
|
6
|
+
chargify_config = YAML::load_file(File.join(File.dirname(__FILE__), '..', 'config', 'chargify.yml'))
|
7
|
+
|
8
|
+
Chargify.configure do |c|
|
9
|
+
c.subdomain = chargify_config['subdomain']
|
10
|
+
c.api_key = chargify_config['api_key']
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Retrieve a list of all your customers
|
15
|
+
Chargify::Customer.find(:all)
|
16
|
+
# => [#<Chargify::Customer:0x102d0cef8 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Mon Nov 16 23:19:25 UTC 2009, "id"=>325, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Mon Nov 16 23:19:25 UTC 2009}>]
|
17
|
+
|
18
|
+
|
19
|
+
customer = Chargify::Customer.find(325)
|
20
|
+
|
21
|
+
customer.first_name
|
22
|
+
# => Michael
|
23
|
+
|
24
|
+
customer.last_name
|
25
|
+
# => Klett
|
26
|
+
|
27
|
+
# Update a customer - success!
|
28
|
+
customer.first_name = "Miguel"
|
29
|
+
customer.save
|
30
|
+
# => true
|
31
|
+
|
32
|
+
customer.first_name
|
33
|
+
# => Miguel
|
34
|
+
|
35
|
+
# Update a customer - fail!
|
36
|
+
customer.first_name = ""
|
37
|
+
customer.save
|
38
|
+
# => false
|
39
|
+
|
40
|
+
customer.errors.full_messages.inspect
|
41
|
+
# => ["First name: cannot be blank."]
|
42
|
+
|
43
|
+
|
44
|
+
# Create a new customer - success!
|
45
|
+
Chargify::Customer.create(
|
46
|
+
:first_name => "Charlie",
|
47
|
+
:last_name => "Bull",
|
48
|
+
:email => "charlie@example.com",
|
49
|
+
:organization => "Chargify"
|
50
|
+
)
|
51
|
+
# => #<Chargify::Customer:0x102c27970 @prefix_options={}, @attributes={"reference"=>nil, "updated_at"=>Mon Nov 16 23:43:33 UTC 2009, "id"=>327, "organization"=>"Chargify", "first_name"=>"Charlie", "last_name"=>"Bull", "created_at"=>Mon Nov 16 23:43:33 UTC 2009, "email"=>"charlie@example.com"}>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'chargify_api_ares'
|
4
|
+
|
5
|
+
# You could load your credentials from a file...
|
6
|
+
chargify_config = YAML::load_file(File.join(File.dirname(__FILE__), '..', 'config', 'chargify.yml'))
|
7
|
+
|
8
|
+
Chargify.configure do |c|
|
9
|
+
c.subdomain = chargify_config['subdomain']
|
10
|
+
c.api_key = chargify_config['api_key']
|
11
|
+
if chargify_config['site']
|
12
|
+
c.site = chargify_config['site']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# This assumes you have a product family with a metered component setup
|
18
|
+
#
|
19
|
+
product_family = Chargify::ProductFamily.find(:first)
|
20
|
+
component = Chargify::Component.find(:first, :params => {:product_family_id => product_family.id})
|
21
|
+
subscription = Chargify::Subscription.find(:first)
|
22
|
+
|
23
|
+
|
24
|
+
u = Chargify::Usage.new
|
25
|
+
u.subscription_id = subscription.id
|
26
|
+
u.component_id = component.id
|
27
|
+
u.quantity = 5
|
28
|
+
d = DateTime.now.to_s
|
29
|
+
u.memo = d
|
30
|
+
puts d
|
31
|
+
u.save
|
32
|
+
|
33
|
+
|
34
|
+
x = Chargify::Usage.find(:last, :params => {:subscription_id => subscription.id, :component_id => component.id})
|
35
|
+
puts x.memo == d
|
data/samples/products.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'chargify_api_ares'
|
4
|
+
|
5
|
+
# You could load your credentials from a file...
|
6
|
+
chargify_config = YAML::load_file(File.join(File.dirname(__FILE__), '..', 'config', 'chargify.yml'))
|
7
|
+
|
8
|
+
Chargify.configure do |c|
|
9
|
+
c.subdomain = chargify_config['subdomain']
|
10
|
+
c.api_key = chargify_config['api_key']
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Retrieve a list of all your products
|
15
|
+
products = Chargify::Product.find(:all)
|
16
|
+
# => [#<Chargify::Product:0x102cdcac8 @prefix_options={}, @attributes={"name"=>"Chargify API Ares Test", "price_in_cents"=>0, "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x102cdbad8 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>78, "accounting_code"=>nil}>, "id"=>152, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>]
|
17
|
+
|
18
|
+
# Find a single product by id
|
19
|
+
product = Chargify::Product.find(products.first.id)
|
20
|
+
# => #<Chargify::Product:0x102ce7540 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x102ce6ca8 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>78, "accounting_code"=>nil}>, "id"=>152, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>
|
21
|
+
|
22
|
+
# Find a single product by its handle
|
23
|
+
product = Chargify::Product.find_by_handle(products.first.handle)
|
24
|
+
# => #<Chargify::Product:0x102c7a828 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x102c798b0 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>78, "accounting_code"=>nil}>, "id"=>152, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'chargify_api_ares'
|
4
|
+
|
5
|
+
# You could load your credentials from a file...
|
6
|
+
chargify_config = YAML::load_file(File.join(File.dirname(__FILE__), '..', 'config', 'chargify.yml'))
|
7
|
+
|
8
|
+
Chargify.configure do |c|
|
9
|
+
c.subdomain = chargify_config['subdomain']
|
10
|
+
c.api_key = chargify_config['api_key']
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Retrieve a list of all your customers
|
15
|
+
subscription = Chargify::Subscription.find(:all)
|
16
|
+
# => [#<Chargify::Subscription:0x1020fff70 @prefix_options={}, @attributes={"cancellation_message"=>nil, "activated_at"=>Tue Nov 17 15:51:42 UTC 2009, "expires_at"=>nil, "updated_at"=>Tue Nov 17 15:51:41 UTC 2009, "credit_card"=>#<Chargify::Subscription::CreditCard:0x1020f24d8 @prefix_options={}, @attributes={"card_type"=>"bogus", "expiration_year"=>2015, "masked_card_number"=>"XXXX-XXXX-XXXX-2", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "product"=>#<Chargify::Product:0x1020f5a70 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x1020f48f0 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>79, "accounting_code"=>nil}>, "id"=>153, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>, "trial_ended_at"=>nil, "id"=>328, "current_period_ends_at"=>Thu Dec 17 15:51:41 UTC 2009, "trial_started_at"=>nil, "customer"=>#<Chargify::Customer:0x1020f6d80 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Tue Nov 17 15:51:02 UTC 2009, "id"=>331, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Tue Nov 17 15:51:02 UTC 2009}>, "balance_in_cents"=>0, "current_period_started_at"=>Tue Nov 17 15:51:41 UTC 2009, "state"=>"canceled", "created_at"=>Tue Nov 17 15:51:41 UTC 2009}>]]
|
17
|
+
|
18
|
+
|
19
|
+
# Create a subscription from a customer reference
|
20
|
+
subscription = Chargify::Subscription.create(
|
21
|
+
:customer_reference => 'moklett',
|
22
|
+
:product_handle => 'chargify-api-ares-test',
|
23
|
+
:credit_card_attributes => {
|
24
|
+
:first_name => "Michael",
|
25
|
+
:last_name => "Klett",
|
26
|
+
:expiration_month => 1,
|
27
|
+
:expiration_year => 2020,
|
28
|
+
:full_number => "1"
|
29
|
+
}
|
30
|
+
)
|
31
|
+
# => #<Chargify::Subscription:0x1020ed4b0 @prefix_options={}, @attributes={"cancellation_message"=>nil, "activated_at"=>Tue Nov 17 16:00:17 UTC 2009, "expires_at"=>nil, "updated_at"=>Tue Nov 17 16:00:17 UTC 2009, "credit_card"=>#<Chargify::Subscription::CreditCard:0x102046b10 @prefix_options={}, @attributes={"card_type"=>"bogus", "expiration_year"=>2020, "masked_card_number"=>"XXXX-XXXX-XXXX-1", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "product"=>#<Chargify::Product:0x10204a2d8 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x1020490b8 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>79, "accounting_code"=>nil}>, "id"=>153, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>, "credit_card_attributes"=>#<Chargify::Subscription::CreditCardAttributes:0x1020ecab0 @prefix_options={}, @attributes={"expiration_year"=>2020, "full_number"=>"1", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "trial_ended_at"=>nil, "id"=>331, "current_period_ends_at"=>Thu Dec 17 16:00:17 UTC 2009, "product_handle"=>"chargify-api-ares-test", "trial_started_at"=>nil, "customer"=>#<Chargify::Customer:0x10204b688 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Tue Nov 17 15:51:02 UTC 2009, "id"=>331, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Tue Nov 17 15:51:02 UTC 2009}>, "balance_in_cents"=>0, "current_period_started_at"=>Tue Nov 17 16:00:17 UTC 2009, "state"=>"active", "created_at"=>Tue Nov 17 16:00:17 UTC 2009, "customer_reference"=>"moklett"}>
|
32
|
+
|
33
|
+
|
34
|
+
# Lookup up existing Subscription using the Customer's reference
|
35
|
+
Subscription.find_by_customer_reference('moklett')
|
36
|
+
# => #<Chargify::Subscription:0x1020ed4b0 @prefix_options={}, @attributes={"cancellation_message"=>nil, "activated_at"=>Tue Nov 17 16:00:17 UTC 2009, "expires_at"=>nil, "updated_at"=>Tue Nov 17 16:00:17 UTC 2009, "credit_card"=>#<Chargify::Subscription::CreditCard:0x102046b10 @prefix_options={}, @attributes={"card_type"=>"bogus", "expiration_year"=>2020, "masked_card_number"=>"XXXX-XXXX-XXXX-1", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "product"=>#<Chargify::Product:0x10204a2d8 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x1020490b8 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>79, "accounting_code"=>nil}>, "id"=>153, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>, "trial_ended_at"=>nil, "id"=>331, "current_period_ends_at"=>Thu Dec 17 16:00:17 UTC 2009, "product_handle"=>"chargify-api-ares-test", "trial_started_at"=>nil, "customer"=>#<Chargify::Customer:0x10204b688 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Tue Nov 17 15:51:02 UTC 2009, "id"=>331, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Tue Nov 17 15:51:02 UTC 2009}>, "balance_in_cents"=>0, "current_period_started_at"=>Tue Nov 17 16:00:17 UTC 2009, "state"=>"active", "created_at"=>Tue Nov 17 16:00:17 UTC 2009, "customer_reference"=>"moklett"}>
|
37
|
+
|
38
|
+
|
39
|
+
# Update credit card information
|
40
|
+
subscription.credit_card_attributes = {:full_number => "2", :expiration_year => "2015"}
|
41
|
+
subscription.save
|
42
|
+
# => #<Chargify::Subscription:0x1020ed4b0 @prefix_options={}, @attributes={"cancellation_message"=>nil, "activated_at"=>Tue Nov 17 16:00:17 UTC 2009, "expires_at"=>nil, "updated_at"=>Tue Nov 17 16:00:17 UTC 2009, "credit_card"=>#<Chargify::Subscription::CreditCard:0x1023ba878 @prefix_options={}, @attributes={"card_type"=>"bogus", "expiration_year"=>2015, "masked_card_number"=>"XXXX-XXXX-XXXX-2", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "product"=>#<Chargify::Product:0x1023baa80 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x1023c04d0 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>79, "accounting_code"=>nil}>, "id"=>153, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>, "credit_card_attributes"=>{:full_number=>"2", :expiration_year=>"2015"}, "trial_ended_at"=>nil, "id"=>331, "current_period_ends_at"=>Thu Dec 17 16:00:17 UTC 2009, "product_handle"=>"chargify-api-ares-test", "customer"=>#<Chargify::Customer:0x1023bae40 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Tue Nov 17 15:51:02 UTC 2009, "id"=>331, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Tue Nov 17 15:51:02 UTC 2009}>, "trial_started_at"=>nil, "balance_in_cents"=>0, "current_period_started_at"=>Tue Nov 17 16:00:17 UTC 2009, "state"=>"active", "created_at"=>Tue Nov 17 16:00:17 UTC 2009, "customer_reference"=>"moklett"}>
|
43
|
+
|
44
|
+
|
45
|
+
# Perform a one-time charge against an existing subscription
|
46
|
+
subscription.charge(:amount => 10.00, :memo => 'Extra service')
|
47
|
+
# => #<Net::HTTPCreated>
|
48
|
+
|
49
|
+
# Give a credit to an existing subscription
|
50
|
+
subscription.credit(:amount_in_cents => 1000, :memo => 'Free subscription time')
|
51
|
+
# => #<Net::HTTPCreated>
|
52
|
+
|
53
|
+
# Cancel a subscription
|
54
|
+
subscription.cancel
|
55
|
+
subscription.reload
|
56
|
+
# => #<Chargify::Subscription:0x1020ed4b0 @prefix_options={}, @attributes={"cancellation_message"=>nil, "activated_at"=>Tue Nov 17 16:00:17 UTC 2009, "expires_at"=>nil, "updated_at"=>Tue Nov 17 16:00:17 UTC 2009, "credit_card"=>#<Chargify::Subscription::CreditCard:0x10234f168 @prefix_options={}, @attributes={"card_type"=>"bogus", "expiration_year"=>2015, "masked_card_number"=>"XXXX-XXXX-XXXX-2", "first_name"=>"Michael", "expiration_month"=>1, "last_name"=>"Klett"}>, "product"=>#<Chargify::Product:0x10234f370 @prefix_options={}, @attributes={"price_in_cents"=>0, "name"=>"Chargify API Ares Test", "handle"=>"chargify-api-ares-test", "product_family"=>#<Chargify::Product::ProductFamily:0x102354708 @prefix_options={}, @attributes={"name"=>"Chargify API ARes Test", "handle"=>"chargify-api-ares-test", "id"=>79, "accounting_code"=>nil}>, "id"=>153, "accounting_code"=>nil, "interval_unit"=>"month", "interval"=>1}>, "credit_card_attributes"=>{:full_number=>"2", :expiration_year=>"2015"}, "trial_ended_at"=>nil, "id"=>331, "current_period_ends_at"=>Thu Dec 17 16:00:17 UTC 2009, "product_handle"=>"chargify-api-ares-test", "customer"=>#<Chargify::Customer:0x10234f730 @prefix_options={}, @attributes={"reference"=>"moklett", "updated_at"=>Tue Nov 17 15:51:02 UTC 2009, "id"=>331, "first_name"=>"Michael", "organization"=>"Chargify", "last_name"=>"Klett", "email"=>"moklett@example.com", "created_at"=>Tue Nov 17 15:51:02 UTC 2009}>, "trial_started_at"=>nil, "balance_in_cents"=>0, "current_period_started_at"=>Tue Nov 17 16:00:17 UTC 2009, "state"=>"canceled", "created_at"=>Tue Nov 17 16:00:17 UTC 2009, "customer_reference"=>"moklett"}>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'chargify_api_ares'
|
4
|
+
|
5
|
+
# You could load your credentials from a file...
|
6
|
+
chargify_config = YAML::load_file(File.join(File.dirname(__FILE__), '..', 'config', 'chargify.yml'))
|
7
|
+
|
8
|
+
Chargify.configure do |c|
|
9
|
+
c.subdomain = chargify_config['subdomain']
|
10
|
+
c.api_key = chargify_config['api_key']
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# Retrieve a list of all your customers
|
15
|
+
subscription = Chargify::Subscription.find(:all).first
|
16
|
+
|
17
|
+
transactions = subscription.transactions
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Base do
|
4
|
+
|
5
|
+
it 'parses element names' do
|
6
|
+
Chargify::Base.stub!(:name).and_return("Test::Namespace::ElementName")
|
7
|
+
Chargify::Base.element_name.should eql('element_name')
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Component do
|
4
|
+
describe "Recording usage" do
|
5
|
+
before do
|
6
|
+
@subscription = Factory(:subscription)
|
7
|
+
@component = Factory(:component)
|
8
|
+
@now = DateTime.now.to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should create a usage record" do
|
12
|
+
u = Chargify::Usage.new
|
13
|
+
u.subscription_id = @subscription.id
|
14
|
+
u.component_id = @component.id
|
15
|
+
u.quantity = 5
|
16
|
+
u.memo = @now
|
17
|
+
u.save
|
18
|
+
|
19
|
+
component = Chargify::Usage.find(:last, :params => {:subscription_id => @subscription.id, :component_id => @component.id})
|
20
|
+
component.memo.should == @now
|
21
|
+
component.quantity.should == 5
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "Listing usages" do
|
26
|
+
before do
|
27
|
+
@subscription = Factory(:subscription)
|
28
|
+
@component = Factory(:component)
|
29
|
+
@now = DateTime.now.to_s
|
30
|
+
create_usage
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return all usages for a component and subscription" do
|
34
|
+
component = Chargify::Usage.find(:last, :params => {:subscription_id => @subscription.id, :component_id => @component.id})
|
35
|
+
component.quantity.should == 5
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_usage
|
40
|
+
u = Chargify::Usage.new
|
41
|
+
u.subscription_id = @subscription.id
|
42
|
+
u.component_id = @component.id
|
43
|
+
u.quantity = 5
|
44
|
+
u.memo = @now
|
45
|
+
u.save
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Customer do
|
4
|
+
|
5
|
+
context 'find by reference' do
|
6
|
+
before do
|
7
|
+
@reference = 'ref0123'
|
8
|
+
@existing_customer = Factory(:customer, :reference => @reference, :id => Factory.next(:customer_id))
|
9
|
+
FakeWeb.register_uri(:get, "#{test_domain}/customers/lookup.xml?reference=#{@existing_customer.reference}", :body => @existing_customer.attributes.to_xml)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'finds the correct customer by reference' do
|
13
|
+
customer = Chargify::Customer.find_by_reference(@reference)
|
14
|
+
customer.should eql(@existing_customer)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is an instance of Chargify::Customer' do
|
18
|
+
customer = Chargify::Customer.find_by_reference(@reference)
|
19
|
+
customer.should be_instance_of(Chargify::Customer)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/factories.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
Factory.sequence :email do |n|
|
2
|
+
"customer#{n}@example.com"
|
3
|
+
end
|
4
|
+
|
5
|
+
Factory.sequence :customer_id do |n|
|
6
|
+
n
|
7
|
+
end
|
8
|
+
|
9
|
+
Factory.define :customer, :class => Chargify::Customer do |c|
|
10
|
+
c.first_name { Faker::Name.first_name }
|
11
|
+
c.last_name { Faker::Name.last_name }
|
12
|
+
c.email { Factory.next(:email) }
|
13
|
+
c.organization { Faker::Company.name }
|
14
|
+
c.created_at { 2.days.ago }
|
15
|
+
c.updated_at { 1.hour.ago }
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
Factory.sequence :product_id do |n|
|
20
|
+
n
|
21
|
+
end
|
22
|
+
|
23
|
+
Factory.sequence :product_name do |n|
|
24
|
+
"Product #{n}"
|
25
|
+
end
|
26
|
+
|
27
|
+
Factory.define :product, :class => Chargify::Product do |p|
|
28
|
+
p.name { Factory.next(:product_name) }
|
29
|
+
end
|
30
|
+
|
31
|
+
Factory.sequence :subscription_id do |n|
|
32
|
+
n
|
33
|
+
end
|
34
|
+
|
35
|
+
Factory.define :subscription, :class => Chargify::Subscription do |s|
|
36
|
+
s.balance_in_cents 500
|
37
|
+
s.current_period_ends_at 3.days.from_now
|
38
|
+
end
|
39
|
+
|
40
|
+
Factory.define :subscription_with_extra_attrs, :parent => :subscription do |swea|
|
41
|
+
swea.customer Chargify::Customer.new
|
42
|
+
swea.product Chargify::Product.new
|
43
|
+
swea.credit_card "CREDIT CARD"
|
44
|
+
end
|
45
|
+
|
46
|
+
Factory.define :component, :class => Chargify::Component do |f|
|
47
|
+
f.name { Faker::Company.bs }
|
48
|
+
f.unit_name 'unit'
|
49
|
+
end
|
50
|
+
|
51
|
+
Factory.define :quantity_based_component, :class => Chargify::Component do |f|
|
52
|
+
f.name { Faker::Company.bs }
|
53
|
+
f.unit_name 'unit'
|
54
|
+
f.pricing_scheme 'tiered'
|
55
|
+
f.component_type 'quantity_based_component'
|
56
|
+
end
|
57
|
+
|
58
|
+
Factory.define :subscriptions_component, :class => Chargify::Subscription::Component do |f|
|
59
|
+
f.name { Faker::Company.bs }
|
60
|
+
f.unit_name 'unit'
|
61
|
+
f.component_type 'quantity_based_component'
|
62
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# Taken from https://gist.github.com/238158/487a411c392e1fb2a0c00347e32444320f5cdd49
|
2
|
+
require 'FakeWeb'
|
3
|
+
|
4
|
+
module ActiveResource
|
5
|
+
|
6
|
+
#
|
7
|
+
# The FakeResource fakes ActiveResources so that no real resources are transferred. It catches the creation methods
|
8
|
+
# and stores the resources internally instead of sending to a remote service and responds these resources back on
|
9
|
+
# request.
|
10
|
+
#
|
11
|
+
# Additionally it adds a save! method and can be used in conjunction with Cucumber/Pickle/FactoryGirl to fully
|
12
|
+
# fake a back end service in the BDD cycle
|
13
|
+
#
|
14
|
+
module FakeResource
|
15
|
+
|
16
|
+
@@fake_resources = []
|
17
|
+
|
18
|
+
def self.clean
|
19
|
+
FakeWeb.clean_registry
|
20
|
+
@@fake_resources = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.included(base)
|
24
|
+
base.class_eval do
|
25
|
+
|
26
|
+
def save
|
27
|
+
@@fake_resources << self
|
28
|
+
update_fake_responses
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy
|
32
|
+
@@fake_resources.delete(self)
|
33
|
+
update_fake_responses
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.delete(id, options = {})
|
37
|
+
puts "delete"
|
38
|
+
@@fake_resources.delete_if {|r| r.id == id }
|
39
|
+
#update_fake_responses
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.exists?(id, options = {})
|
43
|
+
not @@fake_resources.select {|r| r.id == id}.blank?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def save!
|
50
|
+
save
|
51
|
+
end
|
52
|
+
|
53
|
+
def save
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def update_fake_responses
|
60
|
+
FakeWeb.clean_registry
|
61
|
+
|
62
|
+
@@fake_resources.each do |r|
|
63
|
+
FakeWeb.register_uri(:get, element_uri, :body => r.to_xml)
|
64
|
+
end
|
65
|
+
|
66
|
+
FakeWeb.register_uri(:get, collection_uri, :body => @@fake_resources.to_xml)
|
67
|
+
end
|
68
|
+
|
69
|
+
def element_uri
|
70
|
+
"#{base_uri}#{element_path}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def collection_uri
|
74
|
+
"#{base_uri}#{collection_path}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def base_uri
|
78
|
+
"#{connection.site.scheme}://#{connection.user}:#{connection.password}@#{connection.site.host}:#{connection.site.port}"
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Product do
|
4
|
+
|
5
|
+
context 'find by handle' do
|
6
|
+
before do
|
7
|
+
@handle = 'handle1'
|
8
|
+
@existing_product = Factory(:product, :handle => @handle, :id => Factory.next(:product_id))
|
9
|
+
FakeWeb.register_uri(:get, "#{test_domain}/products/lookup.xml?handle=#{@existing_product.handle}", :body => @existing_product.attributes.to_xml)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'finds the correct product by handle' do
|
13
|
+
product = Chargify::Product.find_by_handle(@handle)
|
14
|
+
product.should eql(@existing_product)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is an instance of Chargify::Product' do
|
18
|
+
product = Chargify::Product.find_by_handle(@handle)
|
19
|
+
product.should be_instance_of(Chargify::Product)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
|
6
|
+
require 'chargify_api_ares'
|
7
|
+
|
8
|
+
require 'fakeweb'
|
9
|
+
require 'mocks/fake_resource'
|
10
|
+
ActiveResource::Base.send :include, ActiveResource::FakeResource
|
11
|
+
FakeWeb.allow_net_connect = false
|
12
|
+
require 'factory_girl'
|
13
|
+
require 'faker'
|
14
|
+
|
15
|
+
Chargify.configure do |c|
|
16
|
+
c.subdomain = 'test'
|
17
|
+
c.api_key = 'test'
|
18
|
+
end
|
19
|
+
|
20
|
+
Spec::Runner.configure do |config|
|
21
|
+
config.after(:each) do
|
22
|
+
ActiveResource::FakeResource.clean
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_domain
|
27
|
+
"#{Chargify::Base.connection.site.scheme}://#{Chargify::Base.connection.user}:#{Chargify::Base.connection.password}@#{Chargify::Base.connection.site.host}:#{Chargify::Base.connection.site.port}"
|
28
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Subscription do
|
4
|
+
|
5
|
+
context 'strips nested association attributes before saving' do
|
6
|
+
before do
|
7
|
+
@subscription = Factory.build(:subscription_with_extra_attrs)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'strips customer' do
|
11
|
+
@subscription.attributes['customer'].should_not be_blank
|
12
|
+
@subscription.save!
|
13
|
+
@subscription.attributes['customer'].should be_blank
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'strips product' do
|
17
|
+
@subscription.attributes['product'].should_not be_blank
|
18
|
+
@subscription.save!
|
19
|
+
@subscription.attributes['product'].should be_blank
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'strips credit card' do
|
23
|
+
@subscription.attributes['credit_card'].should_not be_blank
|
24
|
+
@subscription.save!
|
25
|
+
@subscription.attributes['credit_card'].should be_blank
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'doesn\'t strip other attrs' do
|
29
|
+
subscription = Factory.build(:subscription)
|
30
|
+
|
31
|
+
lambda { subscription.save! }.should_not change(subscription, :attributes)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'creates a one-time charge' do
|
36
|
+
id = Factory.next(:subscription_id)
|
37
|
+
subscription = Factory(:subscription, :id => id)
|
38
|
+
expected_response = {:charge => {:amount_in_cents => 1000, :memo => "one-time charge", :success => true}}.to_xml
|
39
|
+
FakeWeb.register_uri(:post, "#{test_domain}/subscriptions/#{id}/charges.xml?charge%5Bamount%5D=10.00&charge%5Bmemo%5D=one-time+charge", :status => 201, :body => expected_response)
|
40
|
+
|
41
|
+
response = subscription.charge(:amount => "10.00", "memo" => "one-time charge")
|
42
|
+
|
43
|
+
response.body.should == expected_response
|
44
|
+
response.should be_a(Net::HTTPCreated)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'finds by customer reference' do
|
48
|
+
customer = Factory(:customer, :reference => 'roger', :id => 10)
|
49
|
+
subscription = Factory(:subscription, :id => 11, :customer_id => customer.id, :product => Factory(:product))
|
50
|
+
|
51
|
+
expected_response = [subscription.attributes].to_xml(:root => 'subscriptions')
|
52
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions.xml?customer_id=#{customer.id}", :status => 200, :body => expected_response)
|
53
|
+
|
54
|
+
Chargify::Customer.stub!(:find_by_reference).with('roger').and_return(customer)
|
55
|
+
Chargify::Subscription.find_by_customer_reference('roger').should eql(subscription)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'cancels the subscription' do
|
59
|
+
@subscription = Factory(:subscription, :id => 1)
|
60
|
+
find_subscription = lambda { Chargify::Subscription.find(1) }
|
61
|
+
|
62
|
+
find_subscription.should_not raise_error
|
63
|
+
@subscription.cancel
|
64
|
+
find_subscription.should raise_error
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Chargify::Subscription::Component do
|
4
|
+
before(:each) do
|
5
|
+
@subscription = Chargify::Subscription.new(:id => 1)
|
6
|
+
@sc1 = Chargify::Subscription::Component.new(
|
7
|
+
:subscription_id => @subscription.id,
|
8
|
+
:component_id => 1,
|
9
|
+
:allocated_quantity => 0,
|
10
|
+
:name => "Paying Customers",
|
11
|
+
:unit_name => "customers",
|
12
|
+
:component_type => "quantity_based_component",
|
13
|
+
:pricing_scheme => "stairstep"
|
14
|
+
)
|
15
|
+
@sc2 = Chargify::Subscription::Component.new(
|
16
|
+
:subscription_id => @subscription.id,
|
17
|
+
:component_id => 2,
|
18
|
+
:unit_balance => 0,
|
19
|
+
:name => "Text Messages",
|
20
|
+
:unit_name => "text message",
|
21
|
+
:component_type => "metered_component"
|
22
|
+
)
|
23
|
+
@subscriptions_components = [@sc1, @sc2]
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "listing subscription components" do
|
27
|
+
before(:each) do
|
28
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}.xml", :body => @subscription.to_xml)
|
29
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}/components.xml", :body => @subscriptions_components.to_xml(:root => 'components'))
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns an array of components from Chargify::Subscription::Component.find(:all, :params => {:subscription_id => @subscription.id})" do
|
33
|
+
Chargify::Subscription::Component.find(:all, :params => {:subscription_id => @subscription.id}).should == @subscriptions_components
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns an array of components from Chargify::Subscription.find(2).components" do
|
37
|
+
subscription = Chargify::Subscription.find(@subscription.id)
|
38
|
+
subscription.components.should == @subscriptions_components
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "reading a subscription component" do
|
43
|
+
before(:each) do
|
44
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}.xml", :body => @subscription.to_xml)
|
45
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}/components/#{@sc1.component_id}.xml", :body => @sc1.to_xml)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the subscription's component resource from Chargify::Subscription::Component.find(1, :params => {:subscription_id => 1})" do
|
49
|
+
Chargify::Subscription::Component.find(@sc1.component_id, :params => {:subscription_id => @subscription.id}).should == @sc1
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns the subscription's component resource from Chargify::Subscription.find(1).component(1)" do
|
53
|
+
subscription = Chargify::Subscription.find(@subscription.id)
|
54
|
+
subscription.component(@sc1.component_id).should == @sc1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "updating a subscription component" do
|
59
|
+
before(:each) do
|
60
|
+
@new_allocated_quantity = @sc1.allocated_quantity + 5
|
61
|
+
|
62
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}.xml", :body => @subscription.to_xml)
|
63
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}/components/#{@sc1.component_id}.xml", :body => @sc1.to_xml)
|
64
|
+
|
65
|
+
@sc1_prime = @sc1
|
66
|
+
@sc1_prime.allocated_quantity = @new_allocated_quantity
|
67
|
+
|
68
|
+
FakeWeb.register_uri(:put, "#{test_domain}/subscriptions/#{@subscription.id}/components/#{@sc1.component_id}.xml", :body => @sc1_prime.to_xml)
|
69
|
+
FakeWeb.register_uri(:get, "#{test_domain}/subscriptions/#{@subscription.id}/components/#{@sc1.component_id}.xml", :body => @sc1_prime.to_xml)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "updates the subscription's component allocated quantity" do
|
73
|
+
component = Chargify::Subscription::Component.find(@sc1.component_id, :params => {:subscription_id => @subscription.id})
|
74
|
+
component.allocated_quantity = @new_allocated_quantity
|
75
|
+
|
76
|
+
result = component.save
|
77
|
+
result.should be_true
|
78
|
+
|
79
|
+
Chargify::Subscription::Component.find(@sc1.component_id, :params => {:subscription_id => @subscription.id}).should == @sc1_prime
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: micah_chargify_api_ares
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 4
|
9
|
+
version: 0.3.4
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Michael Klett
|
13
|
+
- The Lab Rats @ Phase Two Labs
|
14
|
+
- Brian Rose
|
15
|
+
- Nathan Verni
|
16
|
+
- Micah Wedemeyer
|
17
|
+
autorequire:
|
18
|
+
bindir: bin
|
19
|
+
cert_chain: []
|
20
|
+
|
21
|
+
date: 2010-06-27 00:00:00 -04:00
|
22
|
+
default_executable:
|
23
|
+
dependencies: []
|
24
|
+
|
25
|
+
description: ""
|
26
|
+
email: mklett@grasshopper.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE.txt
|
33
|
+
- README.md
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- LICENSE.txt
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- VERSION
|
40
|
+
- chargify_api_ares.gemspec
|
41
|
+
- lib/chargify_api_ares.rb
|
42
|
+
- samples/customers.rb
|
43
|
+
- samples/metered_components.rb
|
44
|
+
- samples/products.rb
|
45
|
+
- samples/subscriptions.rb
|
46
|
+
- samples/transactions.rb
|
47
|
+
- spec/base_spec.rb
|
48
|
+
- spec/components_spec.rb
|
49
|
+
- spec/customer_spec.rb
|
50
|
+
- spec/factories.rb
|
51
|
+
- spec/mocks/fake_resource.rb
|
52
|
+
- spec/product_spec.rb
|
53
|
+
- spec/spec_helper.rb
|
54
|
+
- spec/subscription_spec.rb
|
55
|
+
- spec/subscriptions_component_spec.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/grasshopperlabs/chargify_api_ares
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: A Chargify API wrapper for Ruby using ActiveResource
|
86
|
+
test_files:
|
87
|
+
- spec/base_spec.rb
|
88
|
+
- spec/components_spec.rb
|
89
|
+
- spec/customer_spec.rb
|
90
|
+
- spec/factories.rb
|
91
|
+
- spec/mocks/fake_resource.rb
|
92
|
+
- spec/product_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
94
|
+
- spec/subscription_spec.rb
|
95
|
+
- spec/subscriptions_component_spec.rb
|