stripe-rails 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md ADDED
@@ -0,0 +1,11 @@
1
+ ## 0.1.0 (2012-11-14)
2
+
3
+ * add config/stripe/plans.rb to define and create plans
4
+ * use `STRIPE_API_KEY` as default value of `config.stripe.api_key`
5
+ * require stripe.js from asset pipeline
6
+ * autoconfigure stripe.js with config.stripe.publishable_key.
7
+ * add rake stripe:verify to ensure stripe.com authentication is configured properly
8
+
9
+ ## 0.0.1 (2012-10-12)
10
+
11
+ * basic railtie
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Stripe::Rails
1
+ # Stripe::Rails: A Full-Featured Rails Engine for Use with stripe.com
2
2
 
3
- TODO: Write a gem description
3
+ [stripe.com](http://stripe.com) integration for your rails application
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,22 +8,82 @@ Add this line to your application's Gemfile:
8
8
 
9
9
  gem 'stripe-rails'
10
10
 
11
- And then execute:
11
+ If you are going to be using [stripe.js][1] to securely collect credit card information
12
+ on the client, then add the following to app/assets/javascripts/application.js
12
13
 
13
- $ bundle
14
+ //= require stripe
14
15
 
15
- Or install it yourself as:
16
+ ### Setup your API keys.
16
17
 
17
- $ gem install stripe-rails
18
+ You will need to configure your application to authenticate with stripe.com
19
+ using [your api key][1]. There are two methods to do this, you can either set the environment
20
+ variable `STRIPE_API_KEY`, or use the rails configuration setting `config.stripe.api_key`.
21
+ In either case, it is recommended that you *not* check in this value into source control.
18
22
 
19
- ## Usage
23
+ Once you can verify that your api is set up and functioning properly by running the following command:
24
+
25
+ rake stripe:verify
26
+
27
+ If you are going to be using stripe.js, then you will also need to set the value of your
28
+ publishiable key. A nice way to do it is to set your test publishable for all environments:
29
+
30
+ # config/application.rb
31
+ # ...
32
+ config.stripe.publishable_key = 'pk_test_XXXYYYZZZ'
33
+
34
+ And then override it to use your live key in production only
35
+
36
+ # config/environments/production.rb
37
+ # ...
38
+ config.stripe.publishable_key = 'pk_live_XXXYYYZZZ'
39
+
40
+ This key will be publicly visible on the internet, so it is ok to put in your source.
41
+
42
+ ### Setup your payment configuration
43
+
44
+ If you're using subscriptions, then you'll need to set up your application's payment plans
45
+ and discounts. `Stripe::Rails` lets you automate the management of these definitions from
46
+ within the application itself. To get started:
47
+
48
+ rails generate stripe:install
49
+
50
+ this will generate the configuration files containing your plan and coupon definitions:
20
51
 
21
- TODO: Write usage instructions here
52
+ create config/stripe/plans.rb
53
+ create config/stripe/coupons.rb
22
54
 
23
- ## Contributing
55
+ ### Configuring your plans
56
+
57
+ Use the plan builder to define as many plans as you want in `config/stripe/plans.rb`
58
+
59
+ Stripe.plan :silver do |plan|
60
+ plan.name = 'ACME Silver'
61
+ plan.amount = 699 # $6.99
62
+ plan.interval = 'month'
63
+ end
64
+
65
+ Stripe.plan :gold do |plan|
66
+ plan.name = 'ACME Gold'
67
+ plan.amount = 999 # $9.99
68
+ plan.interval = 'month'
69
+ end
70
+
71
+ This will define constants for these plans in the Stripe::Plans module so that you
72
+ can refer to them by reference as opposed to an id string.
73
+
74
+ Stripe::Plans::SILVER # => 'silver: ACME Silver'
75
+ Stripe::Plans::GOLD # => 'gold: ACME Gold'
76
+
77
+ To upload these plans onto stripe.com, run:
78
+
79
+ rake stripe:prepare
80
+
81
+ This will create any plans that do not currently exist, and treat as a NOOP any
82
+ plans that do, so you can run this command safely as many times as you wish.
83
+
84
+ NOTE: You must destroy plans manually from your stripe dashboard.
85
+
86
+ ## Usage
24
87
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Added some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
88
+ [1]: https://stripe.com/docs/stripe.js
89
+ [2]: https://manage.stripe.com/#account/apikeys
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
4
+ desc "run minitests"
5
+ task :spec do
6
+ sh "bundle exec ruby -Itest test/*_spec.rb"
7
+ end
8
+
9
+ task :default => :spec
@@ -0,0 +1,10 @@
1
+ module Stripe
2
+ class InstallGenerator < ::Rails::Generators::Base
3
+ source_root File.expand_path("../../templates", __FILE__)
4
+
5
+ desc "copy plans.rb"
6
+ def copy_plans_file
7
+ copy_file "plans.rb", "config/stripe/plans.rb"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ # This file contains descriptions of all your stripe plans
2
+
3
+ # Example
4
+ # Stripe::Plans::PRIMO #=> 'primo'
5
+
6
+ # Stripe.plan :primo do |plan|
7
+ #
8
+ # # plan name as it will appear on credit card statements
9
+ # plan.name = 'Acme as a service PRIMO'
10
+ #
11
+ # # amount in cents. This is 6.99
12
+ # plan.amount = 699
13
+ #
14
+ # # interval must be either 'month' or 'year'
15
+ # plan.interval = 'month'
16
+ #
17
+ # # only bill once every three months (default 1)
18
+ # plan.interval_count = 3
19
+ #
20
+ # # number of days before charging customer's card (default 0)
21
+ # plan.trial_period_days = 30
22
+ # end
23
+
24
+ # Once you have your plans defined, you can run
25
+ #
26
+ # rake stripe:prepare
27
+ #
28
+ # This will export any new plans to stripe.com so that you can
29
+ # begin using them in your API calls.
@@ -0,0 +1,38 @@
1
+ require 'stripe'
2
+
3
+ module Stripe::Rails
4
+ class << self
5
+ attr_accessor :testing
6
+ end
7
+
8
+ class Engine < ::Rails::Engine
9
+
10
+ config.stripe = Struct.new(:api_base, :api_key, :verify_ssl_certs, :publishable_key).new
11
+
12
+ initializer 'stripe.configure.api_key', :before => 'stripe.configure' do |app|
13
+ app.config.stripe.api_key ||= ENV['STRIPE_API_KEY']
14
+ end
15
+
16
+ initializer 'stripe.configure' do |app|
17
+ [:api_base, :api_key, :verify_ssl_certs].each do |key|
18
+ value = app.config.stripe.send(key)
19
+ Stripe.send("#{key}=", value) unless value.nil?
20
+ end
21
+ $stderr.puts <<-MSG unless Stripe.api_key
22
+ No stripe.com API key was configured for environment #{::Rails.env}! this application will be
23
+ unable to interact with stripe.com. You can set your API key with either the environment
24
+ variable `STRIPE_API_KEY` (recommended) or by setting `config.stripe.api_key` in your
25
+ environment file directly.
26
+ MSG
27
+ end
28
+
29
+ initializer 'stripe.plans' do |app|
30
+ path = app.root.join('config/stripe/plans.rb')
31
+ load path if path.exist?
32
+ end
33
+
34
+ rake_tasks do
35
+ load 'stripe-rails/tasks.rake'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,98 @@
1
+ module Stripe
2
+ module Plans
3
+ @plans = {}
4
+
5
+ def self.all
6
+ @plans.values
7
+ end
8
+
9
+ def self.[](key)
10
+ @plans[key.to_s]
11
+ end
12
+
13
+ def self.[]=(key, value)
14
+ @plans[key.to_s] = value
15
+ end
16
+
17
+ def self.put!
18
+ all.each do |plan|
19
+ plan.put!
20
+ end
21
+ end
22
+
23
+ def plan(id)
24
+ config = Configuration.new(id)
25
+ yield config
26
+ config.finalize!
27
+ end
28
+
29
+ class Configuration
30
+ include ActiveModel::Validations
31
+ attr_reader :id, :currency
32
+ attr_accessor :name, :amount, :interval, :interval_count, :trial_period_days
33
+
34
+ validates_presence_of :id, :name, :amount
35
+ validates_inclusion_of :interval, :in => %w(month year), :message => "'%{value}' is not one of 'month' or 'year'"
36
+
37
+ def initialize(id)
38
+ @id = id
39
+ @currency = 'usd'
40
+ @interval_count = 1
41
+ @trial_period_days = 0
42
+ end
43
+
44
+ def finalize!
45
+ validate!
46
+ globalize!
47
+ end
48
+
49
+ def validate!
50
+ fail InvalidPlanError, errors if invalid?
51
+ end
52
+
53
+ def globalize!
54
+ Stripe::Plans[@id.to_s] = self
55
+ Stripe::Plans.const_set(@id.to_s.upcase, self)
56
+ end
57
+
58
+ def put!
59
+ if exists?
60
+ puts "[EXISTS] - #{@id}" unless Stripe::Rails.testing
61
+ else
62
+ plan = Stripe::Plan.create(
63
+ :id => @id,
64
+ :currency => @currency,
65
+ :name => @name,
66
+ :amount => @amount,
67
+ :interval => @interval,
68
+ :interval_count => @interval_count,
69
+ :trial_period_days => @trial_period_days
70
+ )
71
+ puts "[CREATE] - #{plan}" unless Stripe::Rails.testing
72
+ end
73
+ end
74
+
75
+ def to_s
76
+ @id.to_s
77
+ end
78
+
79
+ def exists?
80
+ !!Stripe::Plan.retrieve("#{@id}")
81
+ rescue Stripe::InvalidRequestError
82
+ false
83
+ end
84
+ end
85
+
86
+ class InvalidPlanError < StandardError
87
+ attr_reader :errors
88
+
89
+ def initialize(errors)
90
+ super errors.messages
91
+ @errors = errors
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+ extend Plans
98
+ end
@@ -0,0 +1,20 @@
1
+
2
+ namespace :stripe do
3
+
4
+ desc 'verify your stripe.com authentication configuration'
5
+ task 'verify' => :environment do
6
+ begin
7
+ Stripe::Plan.all
8
+ puts "[OK] - connection to stripe.com is functioning properly"
9
+ rescue Stripe::AuthenticationError => e
10
+ puts "[FAIL] - authentication failed"
11
+ end
12
+ end
13
+
14
+ task 'plans:prepare' => :environment do
15
+ Stripe::Plans.put!
16
+ end
17
+
18
+ desc "create all plans defined in config/stripe/plans.rb"
19
+ task 'prepare' => 'plans:prepare'
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Stripe
2
2
  module Rails
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
data/lib/stripe-rails.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  require "stripe-rails/version"
2
+ require 'stripe-rails/engine'
3
+ require 'stripe-rails/plans'
2
4
 
3
- module Stripe
4
- module Rails
5
- # Your code goes here...
6
- end
7
- end
data/stripe-rails.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
5
5
  gem.authors = ["rubygeek"]
6
6
  gem.email = ["nola@rubygeek.com"]
7
7
  gem.description = "A gem to integrate stripe into your rails app"
8
- gem.summary = "A gem to integrate stripe into your rails app"
8
+ gem.summary = "A gem to integrate stripe into your rails app"
9
9
  gem.homepage = ""
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Stripe::Rails::VERSION
17
17
  gem.add_dependency 'railties', '~> 3.0'
18
18
  gem.add_dependency 'stripe'
19
-
20
- gem.add_development_dependency 'tzinfo'
21
19
 
20
+ gem.add_development_dependency 'tzinfo'
21
+ gem.add_development_dependency 'mocha'
22
22
  end
@@ -1,4 +1,8 @@
1
1
  Dummy::Application.configure do
2
+
3
+ config.stripe.api_base = 'http://localhost:5000'
4
+ config.stripe.verify_ssl_certs = false
5
+
2
6
  # Settings specified here will take precedence over those in config/application.rb
3
7
 
4
8
  # The test environment is used exclusively to run your application's
@@ -0,0 +1,5 @@
1
+ Stripe.plan :gold do |plan|
2
+ plan.name = 'Solid Gold'
3
+ plan.amount = 699
4
+ plan.interval = 'month'
5
+ end
@@ -0,0 +1,71 @@
1
+ require 'minitest/autorun'
2
+ require 'spec_helper'
3
+
4
+ describe 'building plans' do
5
+ describe 'simply' do
6
+ before do
7
+ Stripe.plan :primo do |plan|
8
+ plan.name = 'Acme as a service PRIMO'
9
+ plan.amount = 699
10
+ plan.interval = 'month'
11
+ plan.interval_count = 3
12
+ plan.trial_period_days = 30
13
+ end
14
+ end
15
+ after do
16
+ Stripe::Plans.send(:remove_const, :PRIMO)
17
+ end
18
+
19
+ it 'is accessible via id' do
20
+ Stripe::Plans::PRIMO.wont_be_nil
21
+ end
22
+
23
+ it 'is accessible via collection' do
24
+ Stripe::Plans.all.must_include Stripe::Plans::PRIMO
25
+ end
26
+
27
+ it 'is accessible via hash lookup (symbol/string agnostic)' do
28
+ Stripe::Plans[:primo].must_equal Stripe::Plans::PRIMO
29
+ Stripe::Plans['primo'].must_equal Stripe::Plans::PRIMO
30
+ end
31
+
32
+ describe 'uploading' do
33
+ describe 'when none exists on stripe.com' do
34
+ before do
35
+ Stripe::Plan.stubs(:retrieve).raises(Stripe::InvalidRequestError.new("not found", "id"))
36
+ end
37
+ it 'creates the plan online' do
38
+ Stripe::Plan.expects(:create).with(
39
+ :id => :gold,
40
+ :currency => 'usd',
41
+ :name => 'Solid Gold',
42
+ :amount => 699,
43
+ :interval => 'month',
44
+ :interval_count => 1,
45
+ :trial_period_days => 0
46
+ )
47
+ Stripe::Plans::GOLD.put!
48
+ end
49
+
50
+ end
51
+ describe 'when it is already present on stripe.com' do
52
+ before do
53
+ Stripe::Plan.stubs(:retrieve).returns(Stripe::Plan.construct_from({
54
+ :id => :gold,
55
+ :name => 'Solid Gold'
56
+ }))
57
+ end
58
+ it 'is a no-op' do
59
+ Stripe::Plan.expects(:create).never
60
+ Stripe::Plans::GOLD.put!
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ describe 'with missing mandatory values' do
67
+ it 'raises an exception after configuring it' do
68
+ proc {Stripe.plan(:bad) {}}.must_raise Stripe::Plans::InvalidPlanError
69
+ end
70
+ end
71
+ end
data/test/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # Configure Rails Environment
2
2
  ENV["RAILS_ENV"] = "test"
3
+ ENV['STRIPE_API_KEY'] = 'XYZ'
3
4
 
4
5
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
6
  require "rails/test_help"
@@ -13,3 +14,6 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
13
14
  if ActiveSupport::TestCase.method_defined?(:fixture_path=)
14
15
  ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
15
16
  end
17
+
18
+ Stripe::Rails.testing = true
19
+ require 'mocha/setup'
@@ -1,15 +1,19 @@
1
1
  require 'minitest/autorun'
2
2
  require 'spec_helper'
3
3
 
4
- # Expectations: http://bfts.rubyforge.org/minitest/MiniTest/Expectations.html
5
-
6
- describe "Configuring the stripe" do
7
- it "true should be true" do
8
- @boolean = true
9
- @boolean.must_equal true
4
+ describe "Configuring the stripe engine" do
5
+ it "reads the api key that is set in the environment" do
6
+ Stripe.api_base.must_equal 'http://localhost:5000'
7
+ Stripe.api_key.must_equal 'XYZ'
8
+ Stripe.verify_ssl_certs.must_equal false
10
9
  end
11
-
12
- it "should be a module" do
13
- assert_kind_of Module, Stripe::Rails
10
+ end
11
+
12
+ describe 'initializing plans' do
13
+ require 'rake'
14
+ load 'stripe-rails/tasks.rake'
15
+ it 'creates any plans that do not exist on stripe.com' do
16
+ Stripe::Plans.expects(:put!)
17
+ Rake::Task['stripe:plans:prepare'].invoke
14
18
  end
15
19
  end
@@ -0,0 +1,279 @@
1
+ (function() {
2
+ var _this = this;
3
+
4
+ this.Stripe = (function() {
5
+
6
+ function Stripe() {}
7
+
8
+ Stripe.version = 2;
9
+
10
+ Stripe.endpoint = 'https://api.stripe.com/v1';
11
+
12
+ Stripe.validateCardNumber = function(num) {
13
+ num = (num + '').replace(/\s+|-/g, '');
14
+ return num.length >= 10 && num.length <= 16 && Stripe.luhnCheck(num);
15
+ };
16
+
17
+ Stripe.validateCVC = function(num) {
18
+ num = Stripe.trim(num);
19
+ return /^\d+$/.test(num) && num.length >= 3 && num.length <= 4;
20
+ };
21
+
22
+ Stripe.validateExpiry = function(month, year) {
23
+ var currentTime, expiry;
24
+ month = Stripe.trim(month);
25
+ year = Stripe.trim(year);
26
+ if (!/^\d+$/.test(month)) {
27
+ return false;
28
+ }
29
+ if (!/^\d+$/.test(year)) {
30
+ return false;
31
+ }
32
+ if (!(parseInt(month, 10) <= 12)) {
33
+ return false;
34
+ }
35
+ expiry = new Date(year, month);
36
+ currentTime = new Date;
37
+ expiry.setMonth(expiry.getMonth() - 1);
38
+ expiry.setMonth(expiry.getMonth() + 1, 1);
39
+ return expiry > currentTime;
40
+ };
41
+
42
+ Stripe.cardType = function(num) {
43
+ return Stripe.cardTypes[num.slice(0, 2)] || 'Unknown';
44
+ };
45
+
46
+ Stripe.setPublishableKey = function(key) {
47
+ Stripe.key = key;
48
+ };
49
+
50
+ Stripe.createToken = function(card, params, callback) {
51
+ var amount, key, value;
52
+ if (params == null) {
53
+ params = {};
54
+ }
55
+ if (!card) {
56
+ throw 'card required';
57
+ }
58
+ if (typeof card !== 'object') {
59
+ throw 'card invalid';
60
+ }
61
+ if (typeof params === 'function') {
62
+ callback = params;
63
+ params = {};
64
+ } else if (typeof params !== 'object') {
65
+ amount = parseInt(params, 10);
66
+ params = {};
67
+ if (amount > 0) {
68
+ params.amount = amount;
69
+ }
70
+ }
71
+ for (key in card) {
72
+ value = card[key];
73
+ delete card[key];
74
+ card[Stripe.underscore(key)] = value;
75
+ }
76
+ params.card = card;
77
+ params.key || (params.key = Stripe.key || Stripe.publishableKey);
78
+ Stripe.validateKey(params.key);
79
+ return Stripe.ajaxJSONP({
80
+ url: "" + Stripe.endpoint + "/tokens",
81
+ data: params,
82
+ method: 'POST',
83
+ success: function(body, status) {
84
+ return typeof callback === "function" ? callback(status, body) : void 0;
85
+ },
86
+ complete: Stripe.complete(callback),
87
+ timeout: 40000
88
+ });
89
+ };
90
+
91
+ Stripe.getToken = function(token, callback) {
92
+ if (!token) {
93
+ throw 'token required';
94
+ }
95
+ Stripe.validateKey(Stripe.key);
96
+ return Stripe.ajaxJSONP({
97
+ url: "" + Stripe.endpoint + "/tokens/" + token,
98
+ data: {
99
+ key: Stripe.key
100
+ },
101
+ success: function(body, status) {
102
+ return typeof callback === "function" ? callback(status, body) : void 0;
103
+ },
104
+ complete: Stripe.complete(callback),
105
+ timeout: 40000
106
+ });
107
+ };
108
+
109
+ Stripe.complete = function(callback) {
110
+ return function(type, xhr, options) {
111
+ if (type !== 'success') {
112
+ return typeof callback === "function" ? callback(500, {
113
+ error: {
114
+ code: type,
115
+ type: type,
116
+ message: 'An unexpected error has occured.\nWe have been notified of the problem.'
117
+ }
118
+ }) : void 0;
119
+ }
120
+ };
121
+ };
122
+
123
+ Stripe.validateKey = function(key) {
124
+ if (!key || typeof key !== 'string') {
125
+ throw new Error('You did not set a valid publishable key.\nCall Stripe.setPublishableKey() with your publishable key.\nFor more info, see https://stripe.com/docs/stripe.js');
126
+ }
127
+ if (/^sk_/.test(key)) {
128
+ throw new Error('You are using a secret key with Stripe.js, instead of the publishable one.\nFor more info, see https://stripe.com/docs/stripe.js');
129
+ }
130
+ };
131
+
132
+ return Stripe;
133
+
134
+ }).call(this);
135
+
136
+ if (typeof module !== "undefined" && module !== null) {
137
+ module.exports = this.Stripe;
138
+ }
139
+
140
+ if (typeof define === "function") {
141
+ define('stripe', [], function() {
142
+ return _this.Stripe;
143
+ });
144
+ }
145
+
146
+ }).call(this);
147
+ (function() {
148
+ var e, requestID, serialize,
149
+ __slice = [].slice;
150
+
151
+ e = encodeURIComponent;
152
+
153
+ requestID = new Date().getTime();
154
+
155
+ serialize = function(object, result, scope) {
156
+ var key, value;
157
+ if (result == null) {
158
+ result = [];
159
+ }
160
+ for (key in object) {
161
+ value = object[key];
162
+ if (scope) {
163
+ key = "" + scope + "[" + key + "]";
164
+ }
165
+ if (typeof value === 'object') {
166
+ serialize(value, result, key);
167
+ } else {
168
+ result.push("" + key + "=" + (e(value)));
169
+ }
170
+ }
171
+ return result.join('&').replace(/%20/g, '+');
172
+ };
173
+
174
+ this.Stripe.ajaxJSONP = function(options) {
175
+ var abort, abortTimeout, callbackName, head, script, xhr;
176
+ if (options == null) {
177
+ options = {};
178
+ }
179
+ callbackName = 'sjsonp' + (++requestID);
180
+ script = document.createElement('script');
181
+ abortTimeout = null;
182
+ abort = function() {
183
+ var _ref;
184
+ if ((_ref = script.parentNode) != null) {
185
+ _ref.removeChild(script);
186
+ }
187
+ if (callbackName in window) {
188
+ window[callbackName] = (function() {});
189
+ }
190
+ return typeof options.complete === "function" ? options.complete('abort', xhr, options) : void 0;
191
+ };
192
+ xhr = {
193
+ abort: abort
194
+ };
195
+ script.onerror = function() {
196
+ xhr.abort();
197
+ return typeof options.error === "function" ? options.error(xhr, options) : void 0;
198
+ };
199
+ window[callbackName] = function() {
200
+ var args;
201
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
202
+ clearTimeout(abortTimeout);
203
+ script.parentNode.removeChild(script);
204
+ try {
205
+ delete window[callbackName];
206
+ } catch (e) {
207
+ window[callbackName] = void 0;
208
+ }
209
+ if (typeof options.success === "function") {
210
+ options.success.apply(options, args);
211
+ }
212
+ return typeof options.complete === "function" ? options.complete('success', xhr, options) : void 0;
213
+ };
214
+ options.data || (options.data = {});
215
+ options.data.callback = callbackName;
216
+ if (options.method) {
217
+ options.data._method = options.method;
218
+ }
219
+ script.src = options.url + '?' + serialize(options.data);
220
+ head = document.getElementsByTagName('head')[0];
221
+ head.appendChild(script);
222
+ if (options.timeout > 0) {
223
+ abortTimeout = setTimeout(function() {
224
+ xhr.abort();
225
+ return typeof options.complete === "function" ? options.complete('timeout', xhr, options) : void 0;
226
+ }, options.timeout);
227
+ }
228
+ return xhr;
229
+ };
230
+
231
+ }).call(this);
232
+ (function() {
233
+
234
+ this.Stripe.trim = function(str) {
235
+ return (str + '').replace(/^\s+|\s+$/g, '');
236
+ };
237
+
238
+ this.Stripe.underscore = function(str) {
239
+ return (str + '').replace(/([A-Z])/g, function($1) {
240
+ return "_" + ($1.toLowerCase());
241
+ });
242
+ };
243
+
244
+ this.Stripe.luhnCheck = function(num) {
245
+ var digit, digits, odd, sum, _i, _len;
246
+ odd = true;
247
+ sum = 0;
248
+ digits = (num + '').split('').reverse();
249
+ for (_i = 0, _len = digits.length; _i < _len; _i++) {
250
+ digit = digits[_i];
251
+ digit = parseInt(digit, 10);
252
+ if ((odd = !odd)) {
253
+ digit *= 2;
254
+ }
255
+ if (digit > 9) {
256
+ digit -= 9;
257
+ }
258
+ sum += digit;
259
+ }
260
+ return sum % 10 === 0;
261
+ };
262
+
263
+ this.Stripe.cardTypes = (function() {
264
+ var num, types, _i, _j;
265
+ types = {};
266
+ for (num = _i = 40; _i <= 49; num = ++_i) {
267
+ types[num] = 'Visa';
268
+ }
269
+ for (num = _j = 50; _j <= 59; num = ++_j) {
270
+ types[num] = 'MasterCard';
271
+ }
272
+ types[34] = types[37] = 'American Express';
273
+ types[60] = types[62] = types[64] = types[65] = 'Discover';
274
+ types[35] = 'JCB';
275
+ types[30] = types[36] = types[38] = types[39] = 'Diners Club';
276
+ return types;
277
+ })();
278
+
279
+ }).call(this);
@@ -0,0 +1,3 @@
1
+ //= require stripe-debug
2
+
3
+ Stripe.publishableKey = "<%= Rails.application.config.stripe.publishable_key or fail 'No stripe.com publishable key found. Please set config.stripe.publishable_key in config/application.rb to one of your publishable keys, which can be found here: https://manage.stripe.com/#account/apikeys' %>"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-27 00:00:00.000000000 Z
12
+ date: 2012-11-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mocha
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
62
78
  description: A gem to integrate stripe into your rails app
63
79
  email:
64
80
  - nola@rubygeek.com
@@ -67,11 +83,17 @@ extensions: []
67
83
  extra_rdoc_files: []
68
84
  files:
69
85
  - .gitignore
86
+ - Changelog.md
70
87
  - Gemfile
71
88
  - LICENSE
72
89
  - README.md
73
90
  - Rakefile
91
+ - lib/generators/stripe/install_generator.rb
92
+ - lib/generators/templates/plans.rb
74
93
  - lib/stripe-rails.rb
94
+ - lib/stripe-rails/engine.rb
95
+ - lib/stripe-rails/plans.rb
96
+ - lib/stripe-rails/tasks.rake
75
97
  - lib/stripe-rails/version.rb
76
98
  - stripe-rails.gemspec
77
99
  - test/.DS_Store
@@ -100,6 +122,7 @@ files:
100
122
  - test/dummy/config/initializers/wrap_parameters.rb
101
123
  - test/dummy/config/locales/en.yml
102
124
  - test/dummy/config/routes.rb
125
+ - test/dummy/config/stripe/plans.rb
103
126
  - test/dummy/lib/assets/.gitkeep
104
127
  - test/dummy/log/.gitkeep
105
128
  - test/dummy/log/test.log
@@ -108,8 +131,11 @@ files:
108
131
  - test/dummy/public/500.html
109
132
  - test/dummy/public/favicon.ico
110
133
  - test/dummy/script/rails
134
+ - test/plan_builder_spec.rb
111
135
  - test/spec_helper.rb
112
136
  - test/stripe_rails_spec.rb
137
+ - vendor/assets/javascripts/stripe-debug.js
138
+ - vendor/assets/javascripts/stripe.js.erb
113
139
  homepage: ''
114
140
  licenses: []
115
141
  post_install_message:
@@ -122,18 +148,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
148
  - - ! '>='
123
149
  - !ruby/object:Gem::Version
124
150
  version: '0'
125
- segments:
126
- - 0
127
- hash: -3770056635503761163
128
151
  required_rubygems_version: !ruby/object:Gem::Requirement
129
152
  none: false
130
153
  requirements:
131
154
  - - ! '>='
132
155
  - !ruby/object:Gem::Version
133
156
  version: '0'
134
- segments:
135
- - 0
136
- hash: -3770056635503761163
137
157
  requirements: []
138
158
  rubyforge_project:
139
159
  rubygems_version: 1.8.24
@@ -167,6 +187,7 @@ test_files:
167
187
  - test/dummy/config/initializers/wrap_parameters.rb
168
188
  - test/dummy/config/locales/en.yml
169
189
  - test/dummy/config/routes.rb
190
+ - test/dummy/config/stripe/plans.rb
170
191
  - test/dummy/lib/assets/.gitkeep
171
192
  - test/dummy/log/.gitkeep
172
193
  - test/dummy/log/test.log
@@ -175,5 +196,6 @@ test_files:
175
196
  - test/dummy/public/500.html
176
197
  - test/dummy/public/favicon.ico
177
198
  - test/dummy/script/rails
199
+ - test/plan_builder_spec.rb
178
200
  - test/spec_helper.rb
179
201
  - test/stripe_rails_spec.rb