stripe-ruby/lib/stripe/account.rb

136 lines
4.9 KiB
Ruby

module Stripe
class Account < APIResource
extend Gem::Deprecate
extend Stripe::APIOperations::Create
extend Stripe::APIOperations::List
include Stripe::APIOperations::Delete
include Stripe::APIOperations::Save
OBJECT_NAME = 'account'
save_nested_resource :external_account
# This method is deprecated. Please use `#external_account=` instead.
save_nested_resource :bank_account
deprecate :bank_account=, "#external_account=", 2017, 8
def resource_url
if self['id']
super
else
"/v1/account"
end
end
# @override To make id optional
def self.retrieve(id=ARGUMENT_NOT_PROVIDED, opts={})
id = id.equal?(ARGUMENT_NOT_PROVIDED) ? nil : Util.check_string_argument!(id)
# Account used to be a singleton, where this method's signature was
# `(opts={})`. For the sake of not breaking folks who pass in an OAuth
# key in opts, let's lurkily string match for it.
if opts == {} && id.is_a?(String) && id.start_with?('sk_')
# `super` properly assumes a String opts is the apiKey and normalizes as expected.
opts = id
id = nil
end
super(id, opts)
end
def reject(params={}, opts={})
opts = Util.normalize_opts(opts)
resp, opts = request(:post, resource_url + '/reject', params, opts)
initialize_from(resp.data, opts)
end
# Somewhat unfortunately, we attempt to do a special encoding trick when
# serializing `additional_owners` under an account: when updating a value,
# we actually send the update parameters up as an integer-indexed hash
# rather than an array. So instead of this:
#
# field[]=item1&field[]=item2&field[]=item3
#
# We send this:
#
# field[0]=item1&field[1]=item2&field[2]=item3
#
# There are two major problems with this technique:
#
# * Entities are addressed by array index, which is not stable and can
# easily result in unexpected results between two different requests.
#
# * A replacement of the array's contents is ambiguous with setting a
# subset of the array. Because of this, the only way to shorten an
# array is to unset it completely by making sure it goes into the
# server as an empty string, then setting its contents again.
#
# We're trying to get this overturned on the server side, but for now,
# patch in a special allowance.
def serialize_params(options = {})
serialize_params_account(self, super)
end
def serialize_params_account(obj, update_hash)
if entity = @values[:legal_entity]
if owners = entity[:additional_owners]
entity_update = update_hash[:legal_entity] ||= {}
entity_update[:additional_owners] =
serialize_additional_owners(entity, owners)
end
end
update_hash
end
def self.protected_fields
[:legal_entity]
end
def legal_entity
self['legal_entity']
end
def legal_entity=(_)
raise NoMethodError.new('Overridding legal_entity can cause serious issues. Instead, set the individual fields of legal_entity like blah.legal_entity.first_name = \'Blah\'')
end
def deauthorize(client_id, opts={})
opts = {:api_base => Stripe.connect_base}.merge(Util.normalize_opts(opts))
resp, opts = request(:post, '/oauth/deauthorize', { 'client_id' => client_id, 'stripe_user_id' => self.id }, opts)
opts.delete(:api_base) # the api_base here is a one-off, don't persist it
Util.convert_to_stripe_object(resp.data, opts)
end
ARGUMENT_NOT_PROVIDED = Object.new
private
def serialize_additional_owners(legal_entity, additional_owners)
original_value = legal_entity.instance_variable_get(:@original_values)[:additional_owners]
if original_value && original_value.length > additional_owners.length
# url params provide no mechanism for deleting an item in an array,
# just overwriting the whole array or adding new items. So let's not
# allow deleting without a full overwrite until we have a solution.
raise ArgumentError.new(
"You cannot delete an item from an array, you must instead set a new array"
)
end
update_hash = {}
additional_owners.each_with_index do |v, i|
# We will almost always see a StripeObject except in the case of a Hash
# that's been appended to an array of `additional_owners`. We may be
# able to normalize that ugliness by using an array proxy object with
# StripeObjects that can detect appends and replace a hash with a
# StripeObject.
update = v.is_a?(StripeObject) ? v.serialize_params : v
if update != {} && (!original_value ||
update != legal_entity.serialize_params_value(original_value[i], nil, false, true))
update_hash[i.to_s] = update
end
end
update_hash
end
end
end