stripe 1.16.0 → 1.16.1

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,11 +1,15 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
4
  - 1.8.7
4
5
  - 1.9.2
5
6
  - 1.9.3
6
7
  - 2.0.0
7
- - 2.1.0
8
+ - 2.1
9
+
8
10
  gemfile:
9
11
  - gemfiles/default-with-activesupport.gemfile
10
12
  - gemfiles/json.gemfile
11
13
  - gemfiles/yajl.gemfile
14
+
15
+ sudo: false
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ === 1.16.1 2014-12-19
2
+
3
+ * 2 minor enhancements:
4
+ * Ability to send idempotent requests
5
+ * Ability to specify stripe account as a header.
6
+
1
7
  === 1.16.0 2014-10-08
2
8
 
3
9
  * 1 minor enhacement:
data/README.rdoc CHANGED
@@ -14,7 +14,13 @@ If you want to build the gem from source:
14
14
  == Requirements
15
15
 
16
16
  * Ruby 1.8.7 or above. (Ruby 1.8.6 may work if you load
17
- ActiveSupport.)
17
+ ActiveSupport.) For Ruby versions before 1.9.2, you'll need to add this to your Gemfile:
18
+
19
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('1.9.2')
20
+ gem 'rest-client', '~> 1.6.8'
21
+ end
22
+
23
+
18
24
  * rest-client, json
19
25
 
20
26
  == Mirrors
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.16.0
1
+ 1.16.1
@@ -2,8 +2,9 @@ module Stripe
2
2
  module APIOperations
3
3
  module Create
4
4
  module ClassMethods
5
- def create(params={}, api_key=nil)
6
- response, api_key = Stripe.request(:post, self.url, api_key, params)
5
+ def create(params={}, opts={})
6
+ api_key, headers = Util.parse_opts(opts)
7
+ response, api_key = Stripe.request(:post, self.url, api_key, params, headers)
7
8
  Util.convert_to_stripe_object(response, api_key)
8
9
  end
9
10
  end
@@ -1,10 +1,10 @@
1
1
  module Stripe
2
2
  module APIOperations
3
3
  module Delete
4
- def delete(params = {})
5
- response, api_key = Stripe.request(:delete, url, @api_key, params)
4
+ def delete(params = {}, opts={})
5
+ api_key, headers = Util.parse_opts(opts)
6
+ response, api_key = Stripe.request(:delete, url, api_key, params, headers)
6
7
  refresh_from(response, api_key)
7
- self
8
8
  end
9
9
  end
10
10
  end
@@ -2,8 +2,9 @@ module Stripe
2
2
  module APIOperations
3
3
  module List
4
4
  module ClassMethods
5
- def all(filters={}, api_key=nil)
6
- response, api_key = Stripe.request(:get, url, api_key, filters)
5
+ def all(filters={}, opts={})
6
+ api_key, headers = Util.parse_opts(opts)
7
+ response, api_key = Stripe.request(:get, url, api_key, filters, headers)
7
8
  Util.convert_to_stripe_object(response, api_key)
8
9
  end
9
10
  end
@@ -4,7 +4,7 @@ module Stripe
4
4
  self.name.split('::')[-1]
5
5
  end
6
6
 
7
- def self.url()
7
+ def self.url
8
8
  if self == APIResource
9
9
  raise NotImplementedError.new('APIResource is an abstract class. You should perform actions on its subclasses (Charge, Customer, etc.)')
10
10
  end
@@ -21,7 +21,6 @@ module Stripe
21
21
  def refresh
22
22
  response, api_key = Stripe.request(:get, url, @api_key, @retrieve_options)
23
23
  refresh_from(response, api_key)
24
- self
25
24
  end
26
25
 
27
26
  def self.retrieve(id, api_key=nil)
@@ -6,10 +6,10 @@ module Stripe
6
6
  '/v1/application_fees'
7
7
  end
8
8
 
9
- def refund(params={})
10
- response, api_key = Stripe.request(:post, refund_url, @api_key, params)
9
+ def refund(params={}, opts={})
10
+ api_key, headers = Util.parse_opts(opts)
11
+ response, api_key = Stripe.request(:post, refund_url, api_key, params, headers)
11
12
  refresh_from(response, api_key)
12
- self
13
13
  end
14
14
 
15
15
  private
data/lib/stripe/charge.rb CHANGED
@@ -4,28 +4,49 @@ module Stripe
4
4
  include Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Update
6
6
 
7
- def refund(params={})
8
- response, api_key = Stripe.request(:post, refund_url, @api_key, params)
7
+ def refund(params={}, opts={})
8
+ api_key, headers = Util.parse_opts(opts)
9
+ response, api_key = Stripe.request(
10
+ :post, refund_url, api_key || @api_key, params, headers)
9
11
  refresh_from(response, api_key)
10
- self
11
12
  end
12
13
 
13
- def capture(params={})
14
- response, api_key = Stripe.request(:post, capture_url, @api_key, params)
14
+ def capture(params={}, opts={})
15
+ api_key, headers = Util.parse_opts(opts)
16
+ response, api_key = Stripe.request(
17
+ :post, capture_url, api_key || @api_key, params, headers)
15
18
  refresh_from(response, api_key)
16
- self
17
19
  end
18
20
 
19
- def update_dispute(params)
20
- response, api_key = Stripe.request(:post, dispute_url, @api_key, params)
21
+ def update_dispute(params={}, opts={})
22
+ api_key, headers = Util.parse_opts(opts)
23
+ response, api_key = Stripe.request(
24
+ :post, dispute_url, api_key || @api_key, params, headers)
21
25
  refresh_from({ :dispute => response }, api_key, true)
22
26
  dispute
23
27
  end
24
28
 
25
- def close_dispute
26
- response, api_key = Stripe.request(:post, close_dispute_url, @api_key)
29
+ def close_dispute(params={}, opts={})
30
+ api_key, headers = Util.parse_opts(opts)
31
+ response, api_key = Stripe.request(
32
+ :post, close_dispute_url, api_key || @api_key, params, headers)
33
+ refresh_from(response, api_key)
34
+ end
35
+
36
+ def mark_as_fraudulent
37
+ params = {
38
+ :fraud_details => { :user_report => 'fraudulent' }
39
+ }
40
+ response, api_key = Stripe.request(:post, url, @api_key, params)
41
+ refresh_from(response, api_key)
42
+ end
43
+
44
+ def mark_as_safe
45
+ params = {
46
+ :fraud_details => { :user_report => 'safe' }
47
+ }
48
+ response, api_key = Stripe.request(:post, url, @api_key, params)
27
49
  refresh_from(response, api_key)
28
- self
29
50
  end
30
51
 
31
52
  private
@@ -5,8 +5,9 @@ module Stripe
5
5
  include Stripe::APIOperations::Update
6
6
  include Stripe::APIOperations::List
7
7
 
8
- def add_invoice_item(params)
9
- InvoiceItem.create(params.merge(:customer => id), @api_key)
8
+ def add_invoice_item(params, opts={})
9
+ opts[:api_key] = @api_key
10
+ InvoiceItem.create(params.merge(:customer => id), opts)
10
11
  end
11
12
 
12
13
  def invoices
@@ -25,24 +26,31 @@ module Stripe
25
26
  Charge.all({ :customer => id }, @api_key)
26
27
  end
27
28
 
28
- def create_upcoming_invoice(params={})
29
- Invoice.create(params.merge(:customer => id), @api_key)
29
+ def create_upcoming_invoice(params={}, opts={})
30
+ opts[:api_key] = @api_key
31
+ Invoice.create(params.merge(:customer => id), opts)
30
32
  end
31
33
 
32
- def cancel_subscription(params={})
33
- response, api_key = Stripe.request(:delete, subscription_url, @api_key, params)
34
+ def cancel_subscription(params={}, opts={})
35
+ api_key, headers = Util.parse_opts(opts)
36
+ response, api_key = Stripe.request(
37
+ :delete, subscription_url, api_key || @api_key, params, headers)
34
38
  refresh_from({ :subscription => response }, api_key, true)
35
39
  subscription
36
40
  end
37
41
 
38
- def update_subscription(params)
39
- response, api_key = Stripe.request(:post, subscription_url, @api_key, params)
42
+ def update_subscription(params={}, opts={})
43
+ api_key, headers = Util.parse_opts(opts)
44
+ response, api_key = Stripe.request(
45
+ :post, subscription_url, api_key || @api_key, params, headers)
40
46
  refresh_from({ :subscription => response }, api_key, true)
41
47
  subscription
42
48
  end
43
49
 
44
- def create_subscription(params)
45
- response, api_key = Stripe.request(:post, subscriptions_url, @api_key, params)
50
+ def create_subscription(params={}, opts={})
51
+ api_key, headers = Util.parse_opts(opts)
52
+ response, api_key = Stripe.request(
53
+ :post, subscriptions_url, api_key || @api_key, params, headers)
46
54
  refresh_from({ :subscription => response }, api_key, true)
47
55
  subscription
48
56
  end
@@ -12,7 +12,6 @@ module Stripe
12
12
  def pay
13
13
  response, api_key = Stripe.request(:post, pay_url, @api_key)
14
14
  refresh_from(response, api_key)
15
- self
16
15
  end
17
16
 
18
17
  private
@@ -20,15 +20,17 @@ module Stripe
20
20
  Util.convert_to_stripe_object(response, api_key)
21
21
  end
22
22
 
23
- def create(params={}, api_key=nil)
23
+ def create(params={}, opts={})
24
+ api_key, headers = Util.parse_opts(opts)
24
25
  api_key ||= @api_key
25
- response, api_key = Stripe.request(:post, url, api_key, params)
26
+ response, api_key = Stripe.request(:post, url, api_key, params, headers)
26
27
  Util.convert_to_stripe_object(response, api_key)
27
28
  end
28
29
 
29
- def all(params={}, api_key=nil)
30
+ def all(params={}, opts={})
31
+ api_key, headers = Util.parse_opts(opts)
30
32
  api_key ||= @api_key
31
- response, api_key = Stripe.request(:get, url, api_key, params)
33
+ response, api_key = Stripe.request(:get, url, api_key, params, headers)
32
34
  Util.convert_to_stripe_object(response, api_key)
33
35
  end
34
36
  end
@@ -1,6 +1,6 @@
1
1
  module Stripe
2
2
  class SingletonAPIResource < APIResource
3
- def self.url()
3
+ def self.url
4
4
  if self == SingletonAPIResource
5
5
  raise NotImplementedError.new('SingletonAPIResource is an abstract class. You should perform actions on its subclasses (Account, etc.)')
6
6
  end
@@ -30,16 +30,14 @@ module Stripe
30
30
  end
31
31
 
32
32
  def self.construct_from(values, api_key=nil)
33
- obj = self.new(values[:id], api_key)
34
- obj.refresh_from(values, api_key)
35
- obj
33
+ self.new(values[:id], api_key).refresh_from(values, api_key)
36
34
  end
37
35
 
38
36
  def to_s(*args)
39
37
  JSON.pretty_generate(@values)
40
38
  end
41
39
 
42
- def inspect()
40
+ def inspect
43
41
  id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
44
42
  "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
45
43
  end
@@ -68,6 +66,8 @@ module Stripe
68
66
  @transient_values.delete(k)
69
67
  @unsaved_values.delete(k)
70
68
  end
69
+
70
+ return self
71
71
  end
72
72
 
73
73
  def [](k)
@@ -7,7 +7,6 @@ module Stripe
7
7
  def cancel
8
8
  response, api_key = Stripe.request(:post, cancel_url, @api_key)
9
9
  refresh_from(response, api_key)
10
- self
11
10
  end
12
11
 
13
12
  def cancel_url
data/lib/stripe/util.rb CHANGED
@@ -17,23 +17,26 @@ module Stripe
17
17
 
18
18
  def self.object_classes
19
19
  @object_classes ||= {
20
+ # data structures
21
+ 'list' => ListObject,
22
+
23
+ # business objects
24
+ 'application_fee' => ApplicationFee,
20
25
  'balance' => Balance,
21
26
  'balance_transaction' => BalanceTransaction,
27
+ 'card' => Card,
22
28
  'charge' => Charge,
29
+ 'coupon' => Coupon,
23
30
  'customer' => Customer,
31
+ 'event' => Event,
32
+ 'fee_refund' => ApplicationFeeRefund,
24
33
  'invoiceitem' => InvoiceItem,
25
34
  'invoice' => Invoice,
26
35
  'plan' => Plan,
27
- 'coupon' => Coupon,
28
- 'event' => Event,
29
- 'transfer' => Transfer,
30
36
  'recipient' => Recipient,
31
- 'card' => Card,
32
- 'subscription' => Subscription,
33
- 'list' => ListObject,
34
37
  'refund' => Refund,
35
- 'application_fee' => ApplicationFee,
36
- 'fee_refund' => ApplicationFeeRefund
38
+ 'subscription' => Subscription,
39
+ 'transfer' => Transfer
37
40
  }
38
41
  end
39
42
 
@@ -65,12 +68,12 @@ module Stripe
65
68
  def self.symbolize_names(object)
66
69
  case object
67
70
  when Hash
68
- new = {}
71
+ new_hash = {}
69
72
  object.each do |key, value|
70
73
  key = (key.to_sym rescue key) || key
71
- new[key] = symbolize_names(value)
74
+ new_hash[key] = symbolize_names(value)
72
75
  end
73
- new
76
+ new_hash
74
77
  when Array
75
78
  object.map { |value| symbolize_names(value) }
76
79
  else
@@ -110,5 +113,27 @@ module Stripe
110
113
  end
111
114
  result
112
115
  end
116
+
117
+ # The secondary opts argument can either be a string or hash
118
+ # Turn this value into an api_key and a set of headers
119
+ def self.parse_opts(opts)
120
+ case opts
121
+ when NilClass
122
+ return nil, {}
123
+ when String
124
+ return opts, {}
125
+ when Hash
126
+ headers = {}
127
+ if opts[:idempotency_key]
128
+ headers[:idempotency_key] = opts[:idempotency_key]
129
+ end
130
+ if opts[:stripe_account]
131
+ headers[:stripe_account] = opts[:stripe_account]
132
+ end
133
+ return opts[:api_key], headers
134
+ else
135
+ raise TypeError.new("parse_opts expects a string or a hash")
136
+ end
137
+ end
113
138
  end
114
139
  end
@@ -1,3 +1,3 @@
1
1
  module Stripe
2
- VERSION = '1.16.0'
2
+ VERSION = '1.16.1'
3
3
  end
@@ -63,10 +63,29 @@ module Stripe
63
63
  assert_equal(401, e.http_status)
64
64
  assert_equal(true, !!e.http_body)
65
65
  assert_equal(true, !!e.json_body[:error][:message])
66
- assert_equal(test_invalid_api_key_error['error']['message'], e.json_body[:error][:message])
66
+ assert_equal(test_invalid_api_key_error[:error][:message], e.json_body[:error][:message])
67
67
  end
68
68
  end
69
69
 
70
+ should "send stripe account as header when set" do
71
+ stripe_account = "acct_0000"
72
+ Stripe.expects(:execute_request).with do |opts|
73
+ opts[:headers][:stripe_account] == stripe_account
74
+ end.returns(test_response(test_charge))
75
+
76
+ Stripe::Charge.create({:card => {:number => '4242424242424242'}},
77
+ {:stripe_account => stripe_account, :api_key => 'sk_test_local'})
78
+ end
79
+
80
+ should "not send stripe account as header when not set" do
81
+ Stripe.expects(:execute_request).with do |opts|
82
+ opts[:headers][:stripe_account].nil?
83
+ end.returns(test_response(test_charge))
84
+
85
+ Stripe::Charge.create({:card => {:number => '4242424242424242'}},
86
+ 'sk_test_local')
87
+ end
88
+
70
89
  context "when specifying per-object credentials" do
71
90
  context "with no global API key set" do
72
91
  should "use the per-object credential when creating" do
@@ -114,6 +133,17 @@ module Stripe
114
133
  end
115
134
 
116
135
  context "with valid credentials" do
136
+ should "send along the idempotency-key header" do
137
+ Stripe.expects(:execute_request).with do |opts|
138
+ opts[:headers][:idempotency_key] == 'bar'
139
+ end.returns(test_response(test_charge))
140
+
141
+ Stripe::Charge.create({:card => {:number => '4242424242424242'}}, {
142
+ :idempotency_key => 'bar',
143
+ :api_key => 'local',
144
+ })
145
+ end
146
+
117
147
  should "urlencode values in GET params" do
118
148
  response = test_response(test_charge_array)
119
149
  @mock.expects(:get).with("#{Stripe.api_base}/v1/charges?customer=test%20customer", nil, nil).returns(response)