braintree 2.4.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +4 -0
- data/lib/braintree.rb +43 -32
- data/lib/braintree/add_on.rb +4 -0
- data/lib/braintree/address.rb +18 -72
- data/lib/braintree/address_gateway.rb +76 -0
- data/lib/braintree/advanced_search.rb +31 -13
- data/lib/braintree/base_module.rb +6 -0
- data/lib/braintree/configuration.rb +57 -39
- data/lib/braintree/credit_card.rb +75 -129
- data/lib/braintree/credit_card_gateway.rb +133 -0
- data/lib/braintree/credit_card_verification.rb +8 -0
- data/lib/braintree/customer.rb +70 -123
- data/lib/braintree/customer_gateway.rb +121 -0
- data/lib/braintree/digest.rb +2 -2
- data/lib/braintree/discount.rb +4 -0
- data/lib/braintree/error_codes.rb +50 -5
- data/lib/braintree/error_result.rb +4 -18
- data/lib/braintree/errors.rb +1 -2
- data/lib/braintree/exceptions.rb +11 -16
- data/lib/braintree/gateway.rb +39 -0
- data/lib/braintree/http.rb +30 -26
- data/lib/braintree/modification.rb +23 -0
- data/lib/braintree/resource_collection.rb +1 -1
- data/lib/braintree/subscription.rb +29 -129
- data/lib/braintree/subscription_gateway.rb +122 -0
- data/lib/braintree/subscription_search.rb +6 -7
- data/lib/braintree/successful_result.rb +1 -12
- data/lib/braintree/test/credit_card_numbers.rb +4 -2
- data/lib/braintree/test/transaction_amounts.rb +3 -0
- data/lib/braintree/transaction.rb +83 -243
- data/lib/braintree/transaction/credit_card_details.rb +4 -4
- data/lib/braintree/transaction_gateway.rb +124 -0
- data/lib/braintree/transaction_search.rb +5 -3
- data/lib/braintree/transparent_redirect.rb +19 -112
- data/lib/braintree/transparent_redirect_gateway.rb +105 -0
- data/lib/braintree/util.rb +4 -0
- data/lib/braintree/validation_error.rb +1 -0
- data/lib/braintree/validation_error_collection.rb +5 -23
- data/lib/braintree/version.rb +2 -2
- data/lib/braintree/xml/parser.rb +1 -1
- data/lib/braintree/xml/rexml.rb +2 -2
- data/spec/integration/braintree/advanced_search_spec.rb +532 -0
- data/spec/integration/braintree/credit_card_spec.rb +5 -8
- data/spec/integration/braintree/http_spec.rb +53 -39
- data/spec/integration/braintree/subscription_spec.rb +678 -213
- data/spec/integration/braintree/transaction_search_spec.rb +318 -43
- data/spec/integration/braintree/transaction_spec.rb +134 -3
- data/spec/integration/braintree/transparent_redirect_spec.rb +1 -1
- data/spec/spec_helper.rb +55 -4
- data/spec/unit/braintree/address_spec.rb +8 -8
- data/spec/unit/braintree/base_module_spec.rb +1 -1
- data/spec/unit/braintree/configuration_spec.rb +34 -29
- data/spec/unit/braintree/credit_card_spec.rb +14 -12
- data/spec/unit/braintree/credit_card_verification_spec.rb +16 -0
- data/spec/unit/braintree/customer_spec.rb +10 -8
- data/spec/unit/braintree/digest_spec.rb +8 -17
- data/spec/unit/braintree/error_result_spec.rb +12 -2
- data/spec/unit/braintree/http_spec.rb +2 -2
- data/spec/unit/braintree/subscription_search_spec.rb +77 -0
- data/spec/unit/braintree/subscription_spec.rb +16 -8
- data/spec/unit/braintree/transaction_spec.rb +17 -12
- data/spec/unit/braintree/transparent_redirect_spec.rb +12 -12
- data/spec/unit/braintree/util_spec.rb +24 -0
- data/spec/unit/braintree/xml/parser_spec.rb +1 -1
- data/spec/unit/braintree_spec.rb +1 -1
- metadata +16 -5
@@ -10,6 +10,10 @@ module Braintree
|
|
10
10
|
set_instance_variables_from_hash attributes unless attributes.nil?
|
11
11
|
end
|
12
12
|
|
13
|
+
def expiration_date
|
14
|
+
"#{expiration_month}/#{expiration_year}"
|
15
|
+
end
|
16
|
+
|
13
17
|
def inspect
|
14
18
|
attr_order = [:token, :bin, :last_4, :card_type, :expiration_date, :cardholder_name, :customer_location]
|
15
19
|
formatted_attrs = attr_order.map do |attr|
|
@@ -18,10 +22,6 @@ module Braintree
|
|
18
22
|
"#<#{formatted_attrs.join(", ")}>"
|
19
23
|
end
|
20
24
|
|
21
|
-
def expiration_date
|
22
|
-
"#{expiration_month}/#{expiration_year}"
|
23
|
-
end
|
24
|
-
|
25
25
|
def masked_number
|
26
26
|
"#{bin}******#{last_4}"
|
27
27
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Braintree
|
2
|
+
class TransactionGateway # :nodoc:
|
3
|
+
def initialize(gateway)
|
4
|
+
@gateway = gateway
|
5
|
+
@config = gateway.config
|
6
|
+
end
|
7
|
+
|
8
|
+
def create(attributes)
|
9
|
+
Util.verify_keys(TransactionGateway._create_signature, attributes)
|
10
|
+
_do_create "/transactions", :transaction => attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
# Deprecated
|
14
|
+
def create_from_transparent_redirect(query_string)
|
15
|
+
params = @gateway.transparent_redirect.parse_and_validate_query_string query_string
|
16
|
+
_do_create("/transactions/all/confirm_transparent_redirect_request", :id => params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_transaction_url
|
20
|
+
warn "[DEPRECATED] Transaction.create_transaction_url is deprecated. Please use TransparentRedirect.url"
|
21
|
+
"#{@config.base_merchant_url}/transactions/all/create_via_transparent_redirect_request"
|
22
|
+
end
|
23
|
+
|
24
|
+
def credit(attributes)
|
25
|
+
create(attributes.merge(:type => 'credit'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def find(id)
|
29
|
+
response = @config.http.get "/transactions/#{id}"
|
30
|
+
Transaction._new(@gateway, response[:transaction])
|
31
|
+
rescue NotFoundError
|
32
|
+
raise NotFoundError, "transaction with id #{id.inspect} not found"
|
33
|
+
end
|
34
|
+
|
35
|
+
def refund(transaction_id, amount = nil)
|
36
|
+
response = @config.http.post "/transactions/#{transaction_id}/refund", :transaction => {:amount => amount}
|
37
|
+
if response[:transaction]
|
38
|
+
SuccessfulResult.new(:transaction => Transaction._new(@gateway, response[:transaction]))
|
39
|
+
elsif response[:api_error_response]
|
40
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
41
|
+
else
|
42
|
+
raise UnexpectedError, "expected :transaction or :api_error_response"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def retry_subscription_charge(subscription_id, amount=nil)
|
47
|
+
attributes = {
|
48
|
+
:amount => amount,
|
49
|
+
:subscription_id => subscription_id,
|
50
|
+
:type => Transaction::Type::Sale
|
51
|
+
}
|
52
|
+
_do_create "/transactions", :transaction => attributes
|
53
|
+
end
|
54
|
+
|
55
|
+
def sale(attributes)
|
56
|
+
create(attributes.merge(:type => 'sale'))
|
57
|
+
end
|
58
|
+
|
59
|
+
def search(&block)
|
60
|
+
search = TransactionSearch.new
|
61
|
+
block.call(search) if block
|
62
|
+
|
63
|
+
response = @config.http.post "/transactions/advanced_search_ids", {:search => search.to_hash}
|
64
|
+
ResourceCollection.new(response) { |ids| _fetch_transactions(search, ids) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def submit_for_settlement(transaction_id, amount = nil)
|
68
|
+
raise ArgumentError, "transaction_id is invalid" unless transaction_id =~ /\A[0-9a-z]+\z/
|
69
|
+
response = @config.http.put "/transactions/#{transaction_id}/submit_for_settlement", :transaction => {:amount => amount}
|
70
|
+
if response[:transaction]
|
71
|
+
SuccessfulResult.new(:transaction => Transaction._new(@gateway, response[:transaction]))
|
72
|
+
elsif response[:api_error_response]
|
73
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
74
|
+
else
|
75
|
+
raise UnexpectedError, "expected :transaction or :response"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def void(transaction_id)
|
80
|
+
response = @config.http.put "/transactions/#{transaction_id}/void"
|
81
|
+
if response[:transaction]
|
82
|
+
SuccessfulResult.new(:transaction => Transaction._new(@gateway, response[:transaction]))
|
83
|
+
elsif response[:api_error_response]
|
84
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
85
|
+
else
|
86
|
+
raise UnexpectedError, "expected :transaction or :api_error_response"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def self._create_signature # :nodoc:
|
91
|
+
[
|
92
|
+
:amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token, :type,
|
93
|
+
{:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
|
94
|
+
{:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
|
95
|
+
{
|
96
|
+
:billing => AddressGateway._shared_signature
|
97
|
+
},
|
98
|
+
{
|
99
|
+
:shipping => AddressGateway._shared_signature
|
100
|
+
},
|
101
|
+
{:options => [:store_in_vault, :submit_for_settlement, :add_billing_address_to_payment_method, :store_shipping_address_in_vault]},
|
102
|
+
{:custom_fields => :_any_key_}
|
103
|
+
]
|
104
|
+
end
|
105
|
+
|
106
|
+
def _do_create(url, params=nil) # :nodoc:
|
107
|
+
response = @config.http.post url, params
|
108
|
+
if response[:transaction]
|
109
|
+
SuccessfulResult.new(:transaction => Transaction._new(@gateway, response[:transaction]))
|
110
|
+
elsif response[:api_error_response]
|
111
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
112
|
+
else
|
113
|
+
raise UnexpectedError, "expected :transaction or :api_error_response"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def _fetch_transactions(search, ids) # :nodoc:
|
118
|
+
search.ids.in ids
|
119
|
+
response = @config.http.post "/transactions/advanced_search", {:search => search.to_hash}
|
120
|
+
attributes = response[:credit_card_transactions]
|
121
|
+
Util.extract_attribute_as_array(attributes, :transaction).map { |attrs| Transaction._new(@gateway, attrs) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Braintree
|
2
|
-
class TransactionSearch < AdvancedSearch
|
3
|
-
|
2
|
+
class TransactionSearch < AdvancedSearch # :nodoc:
|
3
|
+
text_fields(
|
4
4
|
:billing_company,
|
5
5
|
:billing_country_name,
|
6
6
|
:billing_extended_address,
|
@@ -24,6 +24,7 @@ module Braintree
|
|
24
24
|
:order_id,
|
25
25
|
:payment_method_token,
|
26
26
|
:processor_authorization_code,
|
27
|
+
:settlement_batch_id,
|
27
28
|
:shipping_company,
|
28
29
|
:shipping_country_name,
|
29
30
|
:shipping_extended_address,
|
@@ -59,6 +60,7 @@ module Braintree
|
|
59
60
|
|
60
61
|
key_value_fields :refund
|
61
62
|
|
62
|
-
range_fields :amount, :created_at
|
63
|
+
range_fields :amount, :created_at, :authorized_at, :failed_at, :gateway_rejected_at, :processor_declined_at,
|
64
|
+
:settled_at, :submitted_for_settlement_at, :voided_at
|
63
65
|
end
|
64
66
|
end
|
@@ -1,32 +1,12 @@
|
|
1
1
|
module Braintree
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# tr_data = Braintree::TransparentRedirect.create_customer_data(
|
10
|
-
# :redirect_url => "http://example.com/redirect_back_to_merchant_site
|
11
|
-
# )
|
12
|
-
#
|
13
|
-
# In addition to the redirect_url, any data that needs to be protected from user tampering
|
14
|
-
# should be included in the tr_data. For example, to prevent the user from tampering with the transaction
|
15
|
-
# amount, include the amount in the tr_data.
|
16
|
-
#
|
17
|
-
# tr_data = Braintree::TransparentRedirect.transaction_data(
|
18
|
-
# :redirect_url => "http://example.com/complete_transaction",
|
19
|
-
# :transaction => {:amount => "100.00"}
|
20
|
-
# )
|
2
|
+
# See:
|
3
|
+
# * http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_tr
|
4
|
+
# * http://www.braintreepaymentsolutions.com/docs/ruby/customers/create_tr
|
5
|
+
# * http://www.braintreepaymentsolutions.com/docs/ruby/customers/update_tr
|
6
|
+
# * http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create_tr
|
7
|
+
# * http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update_tr
|
21
8
|
module TransparentRedirect
|
22
|
-
|
23
|
-
CreateCustomerSignature = TransparentRedirectKeys + [{:customer => Customer._create_signature}] # :nodoc:
|
24
|
-
UpdateCustomerSignature = TransparentRedirectKeys + [:customer_id, {:customer => Customer._update_signature}] # :nodoc:
|
25
|
-
TransactionSignature = TransparentRedirectKeys + [{:transaction => Transaction._create_signature}] # :nodoc:
|
26
|
-
CreateCreditCardSignature = TransparentRedirectKeys + [{:credit_card => CreditCard._create_signature}] # :nodoc:
|
27
|
-
UpdateCreditCardSignature = TransparentRedirectKeys + [:payment_method_token, {:credit_card => CreditCard._update_signature}] # :nodoc:
|
28
|
-
|
29
|
-
module Kind
|
9
|
+
module Kind # :nodoc:
|
30
10
|
CreateCustomer = "create_customer"
|
31
11
|
UpdateCustomer = "update_customer"
|
32
12
|
CreatePaymentMethod = "create_payment_method"
|
@@ -35,110 +15,37 @@ module Braintree
|
|
35
15
|
end
|
36
16
|
|
37
17
|
def self.confirm(query_string)
|
38
|
-
|
39
|
-
confirmation_klass = {
|
40
|
-
Kind::CreateCustomer => Braintree::Customer,
|
41
|
-
Kind::UpdateCustomer => Braintree::Customer,
|
42
|
-
Kind::CreatePaymentMethod => Braintree::CreditCard,
|
43
|
-
Kind::UpdatePaymentMethod => Braintree::CreditCard,
|
44
|
-
Kind::CreateTransaction => Braintree::Transaction
|
45
|
-
}[params[:kind]]
|
46
|
-
|
47
|
-
confirmation_klass._do_create("/transparent_redirect_requests/#{params[:id]}/confirm")
|
18
|
+
Configuration.gateway.transparent_redirect.confirm(query_string)
|
48
19
|
end
|
49
20
|
|
50
|
-
#
|
21
|
+
# See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/create_tr
|
51
22
|
def self.create_credit_card_data(params)
|
52
|
-
|
53
|
-
params[:kind] = Kind::CreatePaymentMethod
|
54
|
-
_data(params)
|
23
|
+
Configuration.gateway.transparent_redirect.create_credit_card_data(params)
|
55
24
|
end
|
56
25
|
|
57
|
-
#
|
26
|
+
# See http://www.braintreepaymentsolutions.com/docs/ruby/customers/create_tr
|
58
27
|
def self.create_customer_data(params)
|
59
|
-
|
60
|
-
params[:kind] = Kind::CreateCustomer
|
61
|
-
_data(params)
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.parse_and_validate_query_string(query_string) # :nodoc:
|
65
|
-
params = Util.symbolize_keys(Util.parse_query_string(query_string))
|
66
|
-
query_string_without_hash = query_string[/(.*)&hash=.*/, 1]
|
67
|
-
|
68
|
-
if params[:http_status] == nil
|
69
|
-
raise UnexpectedError, "expected query string to have an http_status param"
|
70
|
-
elsif params[:http_status] != '200'
|
71
|
-
Util.raise_exception_for_status_code(params[:http_status], params[:bt_message])
|
72
|
-
end
|
73
|
-
|
74
|
-
if _hash(query_string_without_hash) == params[:hash]
|
75
|
-
params
|
76
|
-
else
|
77
|
-
raise ForgedQueryString
|
78
|
-
end
|
28
|
+
Configuration.gateway.transparent_redirect.create_customer_data(params)
|
79
29
|
end
|
80
30
|
|
81
|
-
#
|
31
|
+
# See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/create_tr
|
82
32
|
def self.transaction_data(params)
|
83
|
-
|
84
|
-
params[:kind] = Kind::CreateTransaction
|
85
|
-
transaction_type = params[:transaction] && params[:transaction][:type]
|
86
|
-
unless %w[sale credit].include?(transaction_type)
|
87
|
-
raise ArgumentError, "expected transaction[type] of sale or credit, was: #{transaction_type.inspect}"
|
88
|
-
end
|
89
|
-
_data(params)
|
33
|
+
Configuration.gateway.transparent_redirect.transaction_data(params)
|
90
34
|
end
|
91
35
|
|
92
|
-
#
|
93
|
-
# The payment_method_token of the credit card to update is required.
|
94
|
-
#
|
95
|
-
# tr_data = Braintree::TransparentRedirect.update_credit_card_data(
|
96
|
-
# :redirect_url => "http://example.com/redirect_here",
|
97
|
-
# :payment_method_token => "token123"
|
98
|
-
# )
|
36
|
+
# See http://www.braintreepaymentsolutions.com/docs/ruby/credit_cards/update_tr
|
99
37
|
def self.update_credit_card_data(params)
|
100
|
-
|
101
|
-
unless params[:payment_method_token]
|
102
|
-
raise ArgumentError, "expected params to contain :payment_method_token of payment method to update"
|
103
|
-
end
|
104
|
-
params[:kind] = Kind::UpdatePaymentMethod
|
105
|
-
_data(params)
|
38
|
+
Configuration.gateway.transparent_redirect.update_credit_card_data(params)
|
106
39
|
end
|
107
40
|
|
108
|
-
#
|
109
|
-
# The customer_id of the customer to update is required.
|
110
|
-
#
|
111
|
-
# tr_data = Braintree::TransparentRedirect.update_customer_data(
|
112
|
-
# :redirect_url => "http://example.com/redirect_here",
|
113
|
-
# :customer_id => "customer123"
|
114
|
-
# )
|
41
|
+
# See http://www.braintreepaymentsolutions.com/docs/ruby/customers/update_tr
|
115
42
|
def self.update_customer_data(params)
|
116
|
-
|
117
|
-
unless params[:customer_id]
|
118
|
-
raise ArgumentError, "expected params to contain :customer_id of customer to update"
|
119
|
-
end
|
120
|
-
params[:kind] = Kind::UpdateCustomer
|
121
|
-
_data(params)
|
43
|
+
Configuration.gateway.transparent_redirect.update_customer_data(params)
|
122
44
|
end
|
123
45
|
|
124
46
|
# Returns the URL to which Transparent Redirect Requests should be posted
|
125
47
|
def self.url
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
def self._data(params) # :nodoc:
|
130
|
-
raise ArgumentError, "expected params to contain :redirect_url" unless params[:redirect_url]
|
131
|
-
tr_data_segment = Util.hash_to_query_string(params.merge(
|
132
|
-
:api_version => Configuration::API_VERSION,
|
133
|
-
:time => Time.now.utc.strftime("%Y%m%d%H%M%S"),
|
134
|
-
:public_key => Configuration.public_key
|
135
|
-
))
|
136
|
-
tr_data_hash = _hash(tr_data_segment)
|
137
|
-
"#{tr_data_hash}|#{tr_data_segment}"
|
138
|
-
end
|
139
|
-
|
140
|
-
def self._hash(string) # :nodoc:
|
141
|
-
::Braintree::Digest.hexdigest(string)
|
48
|
+
Configuration.gateway.transparent_redirect.url
|
142
49
|
end
|
143
50
|
end
|
144
51
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Braintree
|
2
|
+
class TransparentRedirectGateway # :nodoc
|
3
|
+
TransparentRedirectKeys = [:redirect_url] # :nodoc:
|
4
|
+
CreateCustomerSignature = TransparentRedirectKeys + [{:customer => CustomerGateway._create_signature}] # :nodoc:
|
5
|
+
UpdateCustomerSignature = TransparentRedirectKeys + [:customer_id, {:customer => CustomerGateway._update_signature}] # :nodoc:
|
6
|
+
TransactionSignature = TransparentRedirectKeys + [{:transaction => TransactionGateway._create_signature}] # :nodoc:
|
7
|
+
CreateCreditCardSignature = TransparentRedirectKeys + [{:credit_card => CreditCardGateway._create_signature}] # :nodoc:
|
8
|
+
UpdateCreditCardSignature = TransparentRedirectKeys + [:payment_method_token, {:credit_card => CreditCardGateway._update_signature}] # :nodoc:
|
9
|
+
|
10
|
+
def initialize(gateway)
|
11
|
+
@gateway = gateway
|
12
|
+
@config = gateway.config
|
13
|
+
end
|
14
|
+
|
15
|
+
def confirm(query_string)
|
16
|
+
params = @gateway.transparent_redirect.parse_and_validate_query_string query_string
|
17
|
+
confirmation_gateway = {
|
18
|
+
TransparentRedirect::Kind::CreateCustomer => :customer,
|
19
|
+
TransparentRedirect::Kind::UpdateCustomer => :customer,
|
20
|
+
TransparentRedirect::Kind::CreatePaymentMethod => :credit_card,
|
21
|
+
TransparentRedirect::Kind::UpdatePaymentMethod => :credit_card,
|
22
|
+
TransparentRedirect::Kind::CreateTransaction => :transaction
|
23
|
+
}[params[:kind]]
|
24
|
+
|
25
|
+
@gateway.send(confirmation_gateway)._do_create("/transparent_redirect_requests/#{params[:id]}/confirm")
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_credit_card_data(params)
|
29
|
+
Util.verify_keys(CreateCreditCardSignature, params)
|
30
|
+
params[:kind] = TransparentRedirect::Kind::CreatePaymentMethod
|
31
|
+
_data(params)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_customer_data(params)
|
35
|
+
Util.verify_keys(CreateCustomerSignature, params)
|
36
|
+
params[:kind] = TransparentRedirect::Kind::CreateCustomer
|
37
|
+
_data(params)
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_and_validate_query_string(query_string) # :nodoc:
|
41
|
+
params = Util.symbolize_keys(Util.parse_query_string(query_string))
|
42
|
+
query_string_without_hash = query_string[/(.*)&hash=.*/, 1]
|
43
|
+
|
44
|
+
if params[:http_status] == nil
|
45
|
+
raise UnexpectedError, "expected query string to have an http_status param"
|
46
|
+
elsif params[:http_status] != '200'
|
47
|
+
Util.raise_exception_for_status_code(params[:http_status], params[:bt_message])
|
48
|
+
end
|
49
|
+
|
50
|
+
if _hash(query_string_without_hash) == params[:hash]
|
51
|
+
params
|
52
|
+
else
|
53
|
+
raise ForgedQueryString
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def transaction_data(params)
|
58
|
+
Util.verify_keys(TransactionSignature, params)
|
59
|
+
params[:kind] = TransparentRedirect::Kind::CreateTransaction
|
60
|
+
transaction_type = params[:transaction] && params[:transaction][:type]
|
61
|
+
unless %w[sale credit].include?(transaction_type)
|
62
|
+
raise ArgumentError, "expected transaction[type] of sale or credit, was: #{transaction_type.inspect}"
|
63
|
+
end
|
64
|
+
_data(params)
|
65
|
+
end
|
66
|
+
|
67
|
+
def update_credit_card_data(params)
|
68
|
+
Util.verify_keys(UpdateCreditCardSignature, params)
|
69
|
+
unless params[:payment_method_token]
|
70
|
+
raise ArgumentError, "expected params to contain :payment_method_token of payment method to update"
|
71
|
+
end
|
72
|
+
params[:kind] = TransparentRedirect::Kind::UpdatePaymentMethod
|
73
|
+
_data(params)
|
74
|
+
end
|
75
|
+
|
76
|
+
def update_customer_data(params)
|
77
|
+
Util.verify_keys(UpdateCustomerSignature, params)
|
78
|
+
unless params[:customer_id]
|
79
|
+
raise ArgumentError, "expected params to contain :customer_id of customer to update"
|
80
|
+
end
|
81
|
+
params[:kind] = TransparentRedirect::Kind::UpdateCustomer
|
82
|
+
_data(params)
|
83
|
+
end
|
84
|
+
|
85
|
+
def url
|
86
|
+
"#{@config.base_merchant_url}/transparent_redirect_requests"
|
87
|
+
end
|
88
|
+
|
89
|
+
def _data(params) # :nodoc:
|
90
|
+
raise ArgumentError, "expected params to contain :redirect_url" unless params[:redirect_url]
|
91
|
+
tr_data_segment = Util.hash_to_query_string(params.merge(
|
92
|
+
:api_version => @config.api_version,
|
93
|
+
:time => Time.now.utc.strftime("%Y%m%d%H%M%S"),
|
94
|
+
:public_key => @config.public_key
|
95
|
+
))
|
96
|
+
tr_data_hash = _hash(tr_data_segment)
|
97
|
+
"#{tr_data_hash}|#{tr_data_segment}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def _hash(string) # :nodoc:
|
101
|
+
::Braintree::Digest.hexdigest(@config.private_key, string)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
data/lib/braintree/util.rb
CHANGED
@@ -104,6 +104,10 @@ module Braintree
|
|
104
104
|
full_key = (namespace ? "#{namespace}[#{key}]" : key.to_s)
|
105
105
|
if value.is_a?(Hash)
|
106
106
|
result += _flatten_hash_keys(value, full_key)
|
107
|
+
elsif value.is_a?(Array)
|
108
|
+
value.each do |item|
|
109
|
+
result += _flatten_hash_keys(item, full_key)
|
110
|
+
end
|
107
111
|
else
|
108
112
|
result << full_key
|
109
113
|
end
|