stripe 1.18.0 → 1.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -1
  4. data/History.txt +98 -0
  5. data/README.rdoc +19 -10
  6. data/VERSION +1 -1
  7. data/lib/stripe/account.rb +46 -4
  8. data/lib/stripe/api_operations/create.rb +3 -10
  9. data/lib/stripe/api_operations/delete.rb +4 -4
  10. data/lib/stripe/api_operations/list.rb +17 -9
  11. data/lib/stripe/api_operations/request.rb +41 -0
  12. data/lib/stripe/api_operations/update.rb +41 -40
  13. data/lib/stripe/api_resource.rb +7 -4
  14. data/lib/stripe/application_fee.rb +3 -4
  15. data/lib/stripe/application_fee_refund.rb +1 -1
  16. data/lib/stripe/balance_transaction.rb +1 -1
  17. data/lib/stripe/bank_account.rb +19 -0
  18. data/lib/stripe/bitcoin_receiver.rb +12 -2
  19. data/lib/stripe/bitcoin_transaction.rb +5 -0
  20. data/lib/stripe/card.rb +6 -4
  21. data/lib/stripe/charge.rb +14 -22
  22. data/lib/stripe/coupon.rb +2 -2
  23. data/lib/stripe/customer.rb +24 -26
  24. data/lib/stripe/dispute.rb +16 -0
  25. data/lib/stripe/errors/card_error.rb +3 -2
  26. data/lib/stripe/errors/invalid_request_error.rb +3 -2
  27. data/lib/stripe/errors/rate_limit_error.rb +4 -0
  28. data/lib/stripe/errors/stripe_error.rb +8 -2
  29. data/lib/stripe/event.rb +1 -1
  30. data/lib/stripe/file_upload.rb +12 -22
  31. data/lib/stripe/invoice.rb +8 -8
  32. data/lib/stripe/invoice_item.rb +2 -2
  33. data/lib/stripe/list_object.rb +77 -13
  34. data/lib/stripe/order.rb +19 -0
  35. data/lib/stripe/plan.rb +2 -2
  36. data/lib/stripe/product.rb +16 -0
  37. data/lib/stripe/recipient.rb +2 -2
  38. data/lib/stripe/refund.rb +2 -9
  39. data/lib/stripe/reversal.rb +14 -0
  40. data/lib/stripe/singleton_api_resource.rb +2 -2
  41. data/lib/stripe/sku.rb +8 -0
  42. data/lib/stripe/stripe_object.rb +232 -46
  43. data/lib/stripe/subscription.rb +3 -3
  44. data/lib/stripe/token.rb +1 -1
  45. data/lib/stripe/transfer.rb +3 -3
  46. data/lib/stripe/util.rb +64 -21
  47. data/lib/stripe/version.rb +1 -1
  48. data/lib/stripe.rb +102 -67
  49. data/stripe.gemspec +0 -2
  50. data/test/stripe/account_test.rb +135 -6
  51. data/test/stripe/api_resource_test.rb +326 -42
  52. data/test/stripe/application_fee_refund_test.rb +6 -6
  53. data/test/stripe/application_fee_test.rb +3 -3
  54. data/test/stripe/balance_test.rb +11 -0
  55. data/test/stripe/bitcoin_receiver_test.rb +30 -7
  56. data/test/stripe/bitcoin_transaction_test.rb +29 -0
  57. data/test/stripe/charge_refund_test.rb +55 -0
  58. data/test/stripe/charge_test.rb +32 -13
  59. data/test/stripe/coupon_test.rb +3 -3
  60. data/test/stripe/customer_card_test.rb +20 -14
  61. data/test/stripe/customer_test.rb +15 -15
  62. data/test/stripe/dispute_test.rb +45 -0
  63. data/test/stripe/file_upload_test.rb +17 -6
  64. data/test/stripe/invoice_test.rb +18 -4
  65. data/test/stripe/list_object_test.rb +126 -2
  66. data/test/stripe/metadata_test.rb +28 -13
  67. data/test/stripe/order_test.rb +52 -0
  68. data/test/stripe/product_test.rb +41 -0
  69. data/test/stripe/recipient_card_test.rb +9 -9
  70. data/test/stripe/refund_test.rb +23 -15
  71. data/test/stripe/reversal_test.rb +47 -0
  72. data/test/stripe/sku_test.rb +24 -0
  73. data/test/stripe/stripe_object_test.rb +67 -6
  74. data/test/stripe/subscription_test.rb +13 -13
  75. data/test/stripe/transfer_test.rb +4 -4
  76. data/test/stripe/util_test.rb +45 -29
  77. data/test/stripe_test.rb +16 -0
  78. data/test/test_data.rb +273 -66
  79. metadata +47 -76
  80. data/lib/stripe/certificate_blacklist.rb +0 -55
  81. data/test/stripe/certificate_blacklist_test.rb +0 -18
data/lib/stripe/charge.rb CHANGED
@@ -1,52 +1,44 @@
1
1
  module Stripe
2
2
  class Charge < APIResource
3
- include Stripe::APIOperations::List
4
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Update
6
6
 
7
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)
11
- refresh_from(response, api_key)
8
+ response, opts = request(:post, refund_url, params, opts)
9
+ initialize_from(response, opts)
12
10
  end
13
11
 
14
12
  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)
18
- refresh_from(response, api_key)
13
+ response, opts = request(:post, capture_url, params, opts)
14
+ initialize_from(response, opts)
19
15
  end
20
16
 
21
17
  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)
25
- refresh_from({ :dispute => response }, api_key, true)
18
+ response, opts = request(:post, dispute_url, params, opts)
19
+ initialize_from({ :dispute => response }, opts, true)
26
20
  dispute
27
21
  end
28
22
 
29
23
  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)
24
+ response, opts = request(:post, close_dispute_url, params, opts)
25
+ initialize_from(response, opts)
34
26
  end
35
27
 
36
28
  def mark_as_fraudulent
37
29
  params = {
38
30
  :fraud_details => { :user_report => 'fraudulent' }
39
31
  }
40
- response, api_key = Stripe.request(:post, url, @api_key, params)
41
- refresh_from(response, api_key)
32
+ response, opts = request(:post, url, params)
33
+ initialize_from(response, opts)
42
34
  end
43
35
 
44
36
  def mark_as_safe
45
37
  params = {
46
38
  :fraud_details => { :user_report => 'safe' }
47
39
  }
48
- response, api_key = Stripe.request(:post, url, @api_key, params)
49
- refresh_from(response, api_key)
40
+ response, opts = request(:post, url, params)
41
+ initialize_from(response, opts)
50
42
  end
51
43
 
52
44
  private
data/lib/stripe/coupon.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Stripe
2
2
  class Coupon < APIResource
3
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::Create
4
4
  include Stripe::APIOperations::Update
5
5
  include Stripe::APIOperations::Delete
6
- include Stripe::APIOperations::List
6
+ extend Stripe::APIOperations::List
7
7
  end
8
8
  end
@@ -1,63 +1,61 @@
1
1
  module Stripe
2
2
  class Customer < APIResource
3
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::Create
4
4
  include Stripe::APIOperations::Delete
5
5
  include Stripe::APIOperations::Update
6
- include Stripe::APIOperations::List
6
+ extend Stripe::APIOperations::List
7
7
 
8
8
  def add_invoice_item(params, opts={})
9
- opts[:api_key] = @api_key
9
+ opts = @opts.merge(Util.normalize_opts(opts))
10
10
  InvoiceItem.create(params.merge(:customer => id), opts)
11
11
  end
12
12
 
13
- def invoices
14
- Invoice.all({ :customer => id }, @api_key)
13
+ def invoices(params={}, opts={})
14
+ opts = @opts.merge(Util.normalize_opts(opts))
15
+ Invoice.all(params.merge(:customer => id), opts)
15
16
  end
16
17
 
17
- def invoice_items
18
- InvoiceItem.all({ :customer => id }, @api_key)
18
+ def invoice_items(params={}, opts={})
19
+ opts = @opts.merge(Util.normalize_opts(opts))
20
+ InvoiceItem.all(params.merge(:customer => id), opts)
19
21
  end
20
22
 
21
- def upcoming_invoice
22
- Invoice.upcoming({ :customer => id }, @api_key)
23
+ def upcoming_invoice(params={}, opts={})
24
+ opts = @opts.merge(Util.normalize_opts(opts))
25
+ Invoice.upcoming(params.merge(:customer => id), opts)
23
26
  end
24
27
 
25
- def charges
26
- Charge.all({ :customer => id }, @api_key)
28
+ def charges(params={}, opts={})
29
+ opts = @opts.merge(Util.normalize_opts(opts))
30
+ Charge.all(params.merge(:customer => id), opts)
27
31
  end
28
32
 
29
33
  def create_upcoming_invoice(params={}, opts={})
30
- opts[:api_key] = @api_key
34
+ opts = @opts.merge(Util.normalize_opts(opts))
31
35
  Invoice.create(params.merge(:customer => id), opts)
32
36
  end
33
37
 
34
38
  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)
38
- refresh_from({ :subscription => response }, api_key, true)
39
+ response, opts = request(:delete, subscription_url, params, opts)
40
+ initialize_from({ :subscription => response }, opts, true)
39
41
  subscription
40
42
  end
41
43
 
42
44
  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)
46
- refresh_from({ :subscription => response }, api_key, true)
45
+ response, opts = request(:post, subscription_url, params, opts)
46
+ initialize_from({ :subscription => response }, opts, true)
47
47
  subscription
48
48
  end
49
49
 
50
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)
54
- refresh_from({ :subscription => response }, api_key, true)
51
+ response, opts = request(:post, subscriptions_url, params, opts)
52
+ initialize_from({ :subscription => response }, opts, true)
55
53
  subscription
56
54
  end
57
55
 
58
56
  def delete_discount
59
- Stripe.request(:delete, discount_url, @api_key)
60
- refresh_from({ :discount => nil }, api_key, true)
57
+ _, opts = request(:delete, discount_url)
58
+ initialize_from({ :discount => nil }, opts, true)
61
59
  end
62
60
 
63
61
  private
@@ -0,0 +1,16 @@
1
+ module Stripe
2
+ class Dispute < APIResource
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
+ include Stripe::APIOperations::Update
6
+
7
+ def close(params={}, opts={})
8
+ response, opts = request(:post, close_url, params, opts)
9
+ initialize_from(response, opts)
10
+ end
11
+
12
+ def close_url
13
+ url + '/close'
14
+ end
15
+ end
16
+ end
@@ -2,8 +2,9 @@ module Stripe
2
2
  class CardError < StripeError
3
3
  attr_reader :param, :code
4
4
 
5
- def initialize(message, param, code, http_status=nil, http_body=nil, json_body=nil)
6
- super(message, http_status, http_body, json_body)
5
+ def initialize(message, param, code, http_status=nil, http_body=nil, json_body=nil,
6
+ http_headers=nil)
7
+ super(message, http_status, http_body, json_body, http_headers)
7
8
  @param = param
8
9
  @code = code
9
10
  end
@@ -2,8 +2,9 @@ module Stripe
2
2
  class InvalidRequestError < StripeError
3
3
  attr_accessor :param
4
4
 
5
- def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
6
- super(message, http_status, http_body, json_body)
5
+ def initialize(message, param, http_status=nil, http_body=nil, json_body=nil,
6
+ http_headers=nil)
7
+ super(message, http_status, http_body, json_body, http_headers)
7
8
  @param = param
8
9
  end
9
10
  end
@@ -0,0 +1,4 @@
1
+ module Stripe
2
+ class RateLimitError < StripeError
3
+ end
4
+ end
@@ -3,18 +3,24 @@ module Stripe
3
3
  attr_reader :message
4
4
  attr_reader :http_status
5
5
  attr_reader :http_body
6
+ attr_reader :http_headers
7
+ attr_reader :request_id
6
8
  attr_reader :json_body
7
9
 
8
- def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
10
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil,
11
+ http_headers=nil)
9
12
  @message = message
10
13
  @http_status = http_status
11
14
  @http_body = http_body
15
+ @http_headers = http_headers || {}
12
16
  @json_body = json_body
17
+ @request_id = @http_headers[:request_id]
13
18
  end
14
19
 
15
20
  def to_s
16
21
  status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
17
- "#{status_string}#{@message}"
22
+ id_string = @request_id.nil? ? "" : "(Request #{@request_id}) "
23
+ "#{status_string}#{id_string}#{@message}"
18
24
  end
19
25
  end
20
26
  end
data/lib/stripe/event.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Stripe
2
2
  class Event < APIResource
3
- include Stripe::APIOperations::List
3
+ extend Stripe::APIOperations::List
4
4
  end
5
5
  end
@@ -1,34 +1,24 @@
1
1
  module Stripe
2
2
  class FileUpload < APIResource
3
- UPLOADS_API_BASE = "https://uploads.stripe.com"
3
+ extend Stripe::APIOperations::Create
4
+ extend Stripe::APIOperations::List
4
5
 
5
6
  def self.url
6
7
  "/v1/files"
7
8
  end
8
9
 
9
- def self.request_headers
10
- {
11
- :content_type => 'multipart/form-data',
12
- }
13
- end
14
-
15
- def self.create(params={}, api_key=nil)
16
- response, api_key = Stripe.request(
17
- :post, self.url, api_key, params, self.request_headers, UPLOADS_API_BASE)
18
- Util.convert_to_stripe_object(response, api_key)
10
+ def self.request(method, url, params={}, opts={})
11
+ opts = {
12
+ :api_base => Stripe::uploads_base
13
+ }.merge(Util.normalize_opts(opts))
14
+ super
19
15
  end
20
16
 
21
- def self.all(filters={}, opts={})
22
- api_key, headers = Util.parse_opts(opts)
23
- response, api_key = Stripe.request(
24
- :get, self.url, api_key, filters, headers, UPLOADS_API_BASE)
25
- Util.convert_to_stripe_object(response, api_key)
26
- end
27
-
28
- def refresh
29
- response, api_key = Stripe.request(
30
- :get, url, @api_key, @retrieve_options, self.class.request_headers, UPLOADS_API_BASE)
31
- refresh_from(response, api_key)
17
+ def self.create(params={}, opts={})
18
+ opts = {
19
+ :content_type => 'multipart/form-data',
20
+ }.merge(Util.normalize_opts(opts))
21
+ super
32
22
  end
33
23
  end
34
24
  end
@@ -1,17 +1,17 @@
1
1
  module Stripe
2
2
  class Invoice < APIResource
3
- include Stripe::APIOperations::List
3
+ extend Stripe::APIOperations::List
4
4
  include Stripe::APIOperations::Update
5
- include Stripe::APIOperations::Create
5
+ extend Stripe::APIOperations::Create
6
6
 
7
- def self.upcoming(params, api_key = nil)
8
- response, api_key = Stripe.request(:get, upcoming_url, api_key, params)
9
- Util.convert_to_stripe_object(response, api_key)
7
+ def self.upcoming(params, opts={})
8
+ response, opts = request(:get, upcoming_url, params, opts)
9
+ Util.convert_to_stripe_object(response, opts)
10
10
  end
11
11
 
12
- def pay
13
- response, api_key = Stripe.request(:post, pay_url, @api_key)
14
- refresh_from(response, api_key)
12
+ def pay(opts={})
13
+ response, opts = request(:post, pay_url, {}, opts)
14
+ initialize_from(response, opts)
15
15
  end
16
16
 
17
17
  private
@@ -1,7 +1,7 @@
1
1
  module Stripe
2
2
  class InvoiceItem < APIResource
3
- include Stripe::APIOperations::List
4
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
5
  include Stripe::APIOperations::Delete
6
6
  include Stripe::APIOperations::Update
7
7
  end
@@ -1,5 +1,20 @@
1
1
  module Stripe
2
2
  class ListObject < StripeObject
3
+ include Enumerable
4
+ include Stripe::APIOperations::List
5
+ include Stripe::APIOperations::Request
6
+
7
+ # This accessor allows a `ListObject` to inherit a limit that was given to
8
+ # a predecessor. This allows consistent limits as a user pages through
9
+ # resources.
10
+ attr_accessor :limit
11
+
12
+ # An empty list object. This is returned from +next+ when we know that
13
+ # there isn't a next page in order to replicate the behavior of the API
14
+ # when it attempts to return a page beyond the last.
15
+ def self.empty_list(opts={})
16
+ ListObject.construct_from({ :data => [] }, opts)
17
+ end
3
18
 
4
19
  def [](k)
5
20
  case k
@@ -10,28 +25,77 @@ module Stripe
10
25
  end
11
26
  end
12
27
 
28
+ # Iterates through each resource in the page represented by the current
29
+ # `ListObject`.
30
+ #
31
+ # Note that this method makes no effort to fetch a new page when it gets to
32
+ # the end of the current page's resources. See also +auto_paging_each+.
13
33
  def each(&blk)
14
34
  self.data.each(&blk)
15
35
  end
16
36
 
17
- def retrieve(id, api_key=nil)
18
- api_key ||= @api_key
19
- response, api_key = Stripe.request(:get,"#{url}/#{CGI.escape(id)}", api_key)
20
- Util.convert_to_stripe_object(response, api_key)
37
+ # Iterates through each resource in all pages, making additional fetches to
38
+ # the API as necessary.
39
+ #
40
+ # Note that this method will make as many API calls as necessary to fetch
41
+ # all resources. For more granular control, please see +each+ and
42
+ # +next_page+.
43
+ def auto_paging_each(&blk)
44
+ return enum_for(:auto_paging_each) unless block_given?
45
+
46
+ page = self
47
+ loop do
48
+ page.each(&blk)
49
+ page = page.next_page
50
+ break if page.empty?
51
+ end
52
+ end
53
+
54
+ # Returns true if the page object contains no elements.
55
+ def empty?
56
+ self.data.empty?
57
+ end
58
+
59
+ def retrieve(id, opts={})
60
+ id, retrieve_params = Util.normalize_id(id)
61
+ response, opts = request(:get,"#{url}/#{CGI.escape(id)}", retrieve_params, opts)
62
+ Util.convert_to_stripe_object(response, opts)
21
63
  end
22
64
 
23
65
  def create(params={}, opts={})
24
- api_key, headers = Util.parse_opts(opts)
25
- api_key ||= @api_key
26
- response, api_key = Stripe.request(:post, url, api_key, params, headers)
27
- Util.convert_to_stripe_object(response, api_key)
66
+ response, opts = request(:post, url, params, opts)
67
+ Util.convert_to_stripe_object(response, opts)
28
68
  end
29
69
 
30
- def all(params={}, opts={})
31
- api_key, headers = Util.parse_opts(opts)
32
- api_key ||= @api_key
33
- response, api_key = Stripe.request(:get, url, api_key, params, headers)
34
- Util.convert_to_stripe_object(response, api_key)
70
+ # Fetches the next page in the resource list (if there is one).
71
+ #
72
+ # This method will try to respect the limit of the current page. If none
73
+ # was given, the default limit will be fetched again.
74
+ def next_page(params={}, opts={})
75
+ return self.class.empty_list(opts) if !has_more
76
+ last_id = data.last.id
77
+
78
+ params = {
79
+ :limit => limit, # may be nil
80
+ :starting_after => last_id,
81
+ }.merge(params)
82
+
83
+ list(params, opts)
84
+ end
85
+
86
+ # Fetches the previous page in the resource list (if there is one).
87
+ #
88
+ # This method will try to respect the limit of the current page. If none
89
+ # was given, the default limit will be fetched again.
90
+ def previous_page(params={}, opts={})
91
+ first_id = data.first.id
92
+
93
+ params = {
94
+ :ending_before => first_id,
95
+ :limit => limit, # may be nil
96
+ }.merge(params)
97
+
98
+ list(params, opts)
35
99
  end
36
100
  end
37
101
  end
@@ -0,0 +1,19 @@
1
+ module Stripe
2
+ class Order < APIResource
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
+ include Stripe::APIOperations::Update
6
+
7
+ def pay(params, opts={})
8
+ response, opts = request(:post, pay_url, params, opts)
9
+ initialize_from(response, opts)
10
+ end
11
+
12
+ private
13
+
14
+ def pay_url
15
+ url + "/pay"
16
+ end
17
+
18
+ end
19
+ end
data/lib/stripe/plan.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Stripe
2
2
  class Plan < APIResource
3
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::Create
4
4
  include Stripe::APIOperations::Delete
5
- include Stripe::APIOperations::List
5
+ extend Stripe::APIOperations::List
6
6
  include Stripe::APIOperations::Update
7
7
  end
8
8
  end
@@ -0,0 +1,16 @@
1
+ module Stripe
2
+ class Product < APIResource
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
+ include Stripe::APIOperations::Update
6
+
7
+ # Keep APIResource#url as `api_url` to avoid letting the external URL
8
+ # replace the Stripe URL.
9
+ alias_method :api_url, :url
10
+
11
+ # Override Stripe::APIOperations::Update#save to explicitly pass URL.
12
+ def save
13
+ super(:req_url => api_url)
14
+ end
15
+ end
16
+ end
@@ -1,9 +1,9 @@
1
1
  module Stripe
2
2
  class Recipient < APIResource
3
- include Stripe::APIOperations::Create
3
+ extend Stripe::APIOperations::Create
4
4
  include Stripe::APIOperations::Delete
5
5
  include Stripe::APIOperations::Update
6
- include Stripe::APIOperations::List
6
+ extend Stripe::APIOperations::List
7
7
 
8
8
  def transfers
9
9
  Transfer.all({ :recipient => id }, @api_key)
data/lib/stripe/refund.rb CHANGED
@@ -1,14 +1,7 @@
1
1
  module Stripe
2
2
  class Refund < APIResource
3
+ extend Stripe::APIOperations::Create
4
+ extend Stripe::APIOperations::List
3
5
  include Stripe::APIOperations::Update
4
- include Stripe::APIOperations::List
5
-
6
- def url
7
- "#{Charge.url}/#{CGI.escape(charge)}/refunds/#{CGI.escape(id)}"
8
- end
9
-
10
- def self.retrieve(id, api_key=nil)
11
- raise NotImplementedError.new("Refunds cannot be retrieved without a charge ID. Retrieve a refund using charge.refunds.retrieve('refund_id')")
12
- end
13
6
  end
14
7
  end
@@ -0,0 +1,14 @@
1
+ module Stripe
2
+ class Reversal < APIResource
3
+ include Stripe::APIOperations::Update
4
+ extend Stripe::APIOperations::List
5
+
6
+ def url
7
+ "#{Transfer.url}/#{CGI.escape(transfer)}/reversals/#{CGI.escape(id)}"
8
+ end
9
+
10
+ def self.retrieve(id, opts={})
11
+ raise NotImplementedError.new("Reversals cannot be retrieved without a transfer ID. Retrieve a reversal using transfer.reversals.retrieve('reversal_id')")
12
+ end
13
+ end
14
+ end
@@ -11,8 +11,8 @@ module Stripe
11
11
  self.class.url
12
12
  end
13
13
 
14
- def self.retrieve(api_key=nil)
15
- instance = self.new(nil, api_key)
14
+ def self.retrieve(opts={})
15
+ instance = self.new(nil, Util.normalize_opts(opts))
16
16
  instance.refresh
17
17
  instance
18
18
  end
data/lib/stripe/sku.rb ADDED
@@ -0,0 +1,8 @@
1
+ module Stripe
2
+ class SKU < APIResource
3
+ extend Stripe::APIOperations::List
4
+ extend Stripe::APIOperations::Create
5
+ include Stripe::APIOperations::Update
6
+
7
+ end
8
+ end