braintree 2.31.0 → 2.32.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/lib/braintree.rb +12 -0
- data/lib/braintree/client_token.rb +5 -0
- data/lib/braintree/client_token_gateway.rb +2 -1
- data/lib/braintree/configuration.rb +1 -1
- data/lib/braintree/credit_card.rb +1 -1
- data/lib/braintree/credit_card_gateway.rb +3 -3
- data/lib/braintree/customer.rb +18 -4
- data/lib/braintree/customer_gateway.rb +2 -2
- data/lib/braintree/customer_search.rb +1 -0
- data/lib/braintree/error_codes.rb +81 -14
- data/lib/braintree/exceptions.rb +2 -0
- data/lib/braintree/gateway.rb +16 -0
- data/lib/braintree/payment_instrument_type.rb +7 -0
- data/lib/braintree/payment_method.rb +17 -0
- data/lib/braintree/payment_method_gateway.rb +58 -0
- data/lib/braintree/paypal_account.rb +47 -0
- data/lib/braintree/paypal_account_gateway.rb +41 -0
- data/lib/braintree/sepa_bank_account.rb +34 -0
- data/lib/braintree/sepa_bank_account_gateway.rb +16 -0
- data/lib/braintree/successful_result.rb +1 -1
- data/lib/braintree/test/nonce.rb +10 -0
- data/lib/braintree/test_transaction.rb +15 -0
- data/lib/braintree/testing_gateway.rb +35 -0
- data/lib/braintree/transaction.rb +6 -0
- data/lib/braintree/transaction/paypal_details.rb +14 -0
- data/lib/braintree/transaction_gateway.rb +3 -1
- data/lib/braintree/transaction_search.rb +4 -0
- data/lib/braintree/unknown_payment_method.rb +20 -0
- data/lib/braintree/version.rb +2 -2
- data/lib/braintree/webhook_testing_gateway.rb +1 -1
- data/spec/integration/braintree/client_api/client_token_spec.rb +80 -17
- data/spec/integration/braintree/client_api/spec_helper.rb +93 -10
- data/spec/integration/braintree/credit_card_spec.rb +28 -27
- data/spec/integration/braintree/customer_search_spec.rb +23 -0
- data/spec/integration/braintree/customer_spec.rb +83 -1
- data/spec/integration/braintree/payment_method_spec.rb +315 -0
- data/spec/integration/braintree/paypal_account_spec.rb +188 -0
- data/spec/integration/braintree/subscription_spec.rb +50 -20
- data/spec/integration/braintree/test_transaction_spec.rb +104 -0
- data/spec/integration/braintree/transaction_search_spec.rb +60 -0
- data/spec/integration/braintree/transaction_spec.rb +583 -8
- data/spec/integration/spec_helper.rb +22 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/unit/braintree/customer_spec.rb +24 -4
- data/spec/unit/braintree/payment_method_spec.rb +25 -0
- data/spec/unit/braintree/paypal_account_spec.rb +31 -0
- data/spec/unit/braintree/unknown_payment_method_spec.rb +29 -0
- metadata +141 -120
- checksums.yaml +0 -7
- data/spec/httpsd.pid +0 -1
@@ -0,0 +1,17 @@
|
|
1
|
+
module Braintree
|
2
|
+
class PaymentMethod
|
3
|
+
include BaseModule
|
4
|
+
|
5
|
+
def self.create(attributes)
|
6
|
+
Configuration.gateway.payment_method.create(attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find(token)
|
10
|
+
Configuration.gateway.payment_method.find(token)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.delete(token)
|
14
|
+
Configuration.gateway.payment_method.delete(token)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Braintree
|
2
|
+
class PaymentMethodGateway # :nodoc:
|
3
|
+
def initialize(gateway)
|
4
|
+
@gateway = gateway
|
5
|
+
@config = gateway.config
|
6
|
+
end
|
7
|
+
|
8
|
+
def create(attributes)
|
9
|
+
Util.verify_keys(PaymentMethodGateway._create_signature, attributes)
|
10
|
+
_do_create("/payment_methods", :payment_method => attributes)
|
11
|
+
end
|
12
|
+
|
13
|
+
def _do_create(url, params=nil) # :nodoc:
|
14
|
+
response = @config.http.post url, params
|
15
|
+
if response[:credit_card]
|
16
|
+
SuccessfulResult.new(:payment_method => CreditCard._new(@gateway, response[:credit_card]))
|
17
|
+
elsif response[:paypal_account]
|
18
|
+
SuccessfulResult.new(:payment_method => PayPalAccount._new(@gateway, response[:paypal_account]))
|
19
|
+
elsif response[:sepa_bank_account]
|
20
|
+
SuccessfulResult.new(:payment_method => SEPABankAccount._new(@gateway, response[:sepa_bank_account]))
|
21
|
+
elsif response[:api_error_response]
|
22
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
23
|
+
else
|
24
|
+
raise UnexpectedError, "expected :payment_method or :api_error_response"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(token)
|
29
|
+
@config.http.delete("/payment_methods/any/#{token}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def find(token)
|
33
|
+
raise ArgumentError if token.nil? || token.to_s.strip == ""
|
34
|
+
response = @config.http.get "/payment_methods/any/#{token}"
|
35
|
+
if response.has_key?(:credit_card)
|
36
|
+
CreditCard._new(@gateway, response[:credit_card])
|
37
|
+
elsif response.has_key?(:paypal_account)
|
38
|
+
PayPalAccount._new(@gateway, response[:paypal_account])
|
39
|
+
elsif response.has_key?(:sepa_bank_account)
|
40
|
+
SEPABankAccount._new(@gateway, response[:sepa_bank_account])
|
41
|
+
else
|
42
|
+
UnknownPaymentMethod.new(response)
|
43
|
+
end
|
44
|
+
rescue NotFoundError
|
45
|
+
raise NotFoundError, "payment method with token #{token.inspect} not found"
|
46
|
+
end
|
47
|
+
|
48
|
+
def self._create_signature # :nodoc:
|
49
|
+
options = [:make_default]
|
50
|
+
[
|
51
|
+
:customer_id,
|
52
|
+
:payment_method_nonce,
|
53
|
+
:token,
|
54
|
+
{:options => options}
|
55
|
+
]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Braintree
|
2
|
+
class PayPalAccount
|
3
|
+
include BaseModule
|
4
|
+
|
5
|
+
attr_reader :email, :token, :image_url, :created_at, :updated_at
|
6
|
+
|
7
|
+
def initialize(gateway, attributes) # :nodoc:
|
8
|
+
@gateway = gateway
|
9
|
+
set_instance_variables_from_hash(attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
protected :new
|
14
|
+
end
|
15
|
+
|
16
|
+
def self._new(*args)
|
17
|
+
self.new(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find(token)
|
21
|
+
Configuration.gateway.paypal_account.find(token)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.update(token, attributes)
|
25
|
+
Configuration.gateway.paypal_account.update(token, attributes)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.delete(token)
|
29
|
+
Configuration.gateway.paypal_account.delete(token)
|
30
|
+
end
|
31
|
+
|
32
|
+
# See http://www.braintreepayments.com/docs/ruby/transactions/create_from_vault
|
33
|
+
def self.sale(token, transaction_attributes)
|
34
|
+
Configuration.gateway.transaction.sale(transaction_attributes.merge(:payment_method_token => token))
|
35
|
+
end
|
36
|
+
|
37
|
+
# See http://www.braintreepayments.com/docs/ruby/transactions/create_from_vault
|
38
|
+
def self.sale!(token, transaction_attributes)
|
39
|
+
return_object_or_raise(:transaction) { sale(token, transaction_attributes) }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns true if this paypal account is the customer's default payment method.
|
43
|
+
def default?
|
44
|
+
@default
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Braintree
|
2
|
+
class PayPalAccountGateway
|
3
|
+
def initialize(gateway)
|
4
|
+
@gateway = gateway
|
5
|
+
@config = gateway.config
|
6
|
+
end
|
7
|
+
|
8
|
+
def find(token)
|
9
|
+
raise ArgumentError if token.nil? || token.to_s.strip == ""
|
10
|
+
response = @config.http.get "/payment_methods/paypal_account/#{token}"
|
11
|
+
PayPalAccount._new(@gateway, response[:paypal_account])
|
12
|
+
rescue NotFoundError
|
13
|
+
raise NotFoundError, "payment method with token #{token.inspect} not found"
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(token, attributes)
|
17
|
+
Util.verify_keys(PayPalAccountGateway._update_signature, attributes)
|
18
|
+
_do_update(:put, "/payment_methods/paypal_account/#{token}", :paypal_account => attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(token)
|
22
|
+
@config.http.delete("/payment_methods/paypal_account/#{token}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def _do_update(http_verb, url, params) # :nodoc:
|
26
|
+
response = @config.http.send http_verb, url, params
|
27
|
+
if response[:paypal_account]
|
28
|
+
SuccessfulResult.new(:paypal_account => PayPalAccount._new(@gateway, response[:paypal_account]))
|
29
|
+
elsif response[:api_error_response]
|
30
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
31
|
+
else
|
32
|
+
raise UnexpectedError, "expected :paypal_account or :api_error_response"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self._update_signature # :nodoc:
|
37
|
+
options = [:make_default]
|
38
|
+
[:token, {:options => options}]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Braintree
|
2
|
+
class SEPABankAccount
|
3
|
+
include BaseModule
|
4
|
+
|
5
|
+
module MandateType
|
6
|
+
Business = 'business'
|
7
|
+
Consumer = 'consumer'
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :token, :image_url
|
11
|
+
|
12
|
+
def initialize(gateway, attributes) # :nodoc:
|
13
|
+
@gateway = gateway
|
14
|
+
set_instance_variables_from_hash(attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
protected :new
|
19
|
+
end
|
20
|
+
|
21
|
+
def self._new(*args)
|
22
|
+
self.new(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.find(token)
|
26
|
+
Configuration.gateway.sepa_bank_account.find(token)
|
27
|
+
end
|
28
|
+
|
29
|
+
def default?
|
30
|
+
@default
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Braintree
|
2
|
+
class SEPABankAccountGateway
|
3
|
+
def initialize(gateway)
|
4
|
+
@gateway = gateway
|
5
|
+
@config = gateway.config
|
6
|
+
end
|
7
|
+
|
8
|
+
def find(token)
|
9
|
+
raise ArgumentError if token.nil? || token.to_s.strip == ""
|
10
|
+
response = @config.http.get "/payment_methods/sepa_bank_account/#{token}"
|
11
|
+
SEPABankAccount._new(@gateway, response[:sepa_bank_account])
|
12
|
+
rescue NotFoundError
|
13
|
+
raise NotFoundError, "payment method with token #{token.inspect} not found"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -3,7 +3,7 @@ module Braintree
|
|
3
3
|
class SuccessfulResult
|
4
4
|
include BaseModule
|
5
5
|
|
6
|
-
attr_reader :address, :credit_card, :customer, :merchant_account, :settlement_batch_summary, :subscription, :new_transaction, :transaction
|
6
|
+
attr_reader :address, :credit_card, :customer, :merchant_account, :payment_method, :settlement_batch_summary, :subscription, :new_transaction, :transaction
|
7
7
|
|
8
8
|
def initialize(attributes = {}) # :nodoc:
|
9
9
|
@attrs = attributes.keys
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Braintree
|
2
|
+
class TestTransaction < Transaction
|
3
|
+
def self.settle(transaction_id)
|
4
|
+
Configuration.gateway.testing.settle(transaction_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.settlement_confirm(transaction_id)
|
8
|
+
Configuration.gateway.testing.settlement_confirm(transaction_id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.settlement_decline(transaction_id)
|
12
|
+
Configuration.gateway.testing.settlement_decline(transaction_id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Braintree
|
2
|
+
class TestingGateway # :nodoc:
|
3
|
+
|
4
|
+
def initialize(gateway)
|
5
|
+
@gateway = gateway
|
6
|
+
@config = gateway.config
|
7
|
+
@transaction_gateway = TransactionGateway.new(gateway)
|
8
|
+
end
|
9
|
+
|
10
|
+
def settle(transaction_id)
|
11
|
+
check_environment
|
12
|
+
|
13
|
+
response = @config.http.put "/transactions/#{transaction_id}/settle"
|
14
|
+
@transaction_gateway._handle_transaction_response(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def settlement_confirm(transaction_id)
|
18
|
+
check_environment
|
19
|
+
|
20
|
+
response = @config.http.put "/transactions/#{transaction_id}/settlement_confirm"
|
21
|
+
@transaction_gateway._handle_transaction_response(response)
|
22
|
+
end
|
23
|
+
|
24
|
+
def settlement_decline(transaction_id)
|
25
|
+
check_environment
|
26
|
+
|
27
|
+
response = @config.http.put "/transactions/#{transaction_id}/settlement_decline"
|
28
|
+
@transaction_gateway._handle_transaction_response(response)
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_environment
|
32
|
+
raise TestOperationPerformedInProduction if Braintree::Configuration.environment == :production
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -35,6 +35,8 @@ module Braintree
|
|
35
35
|
Failed = 'failed'
|
36
36
|
ProcessorDeclined = 'processor_declined'
|
37
37
|
Settled = 'settled'
|
38
|
+
SettlementConfirmed = 'settlement_confirmed'
|
39
|
+
SettlementDeclined = 'settlement_declined'
|
38
40
|
Settling = 'settling'
|
39
41
|
SubmittedForSettlement = 'submitted_for_settlement'
|
40
42
|
Voided = 'voided'
|
@@ -77,6 +79,7 @@ module Braintree
|
|
77
79
|
attr_reader :order_id
|
78
80
|
attr_reader :channel
|
79
81
|
attr_reader :billing_details, :shipping_details
|
82
|
+
attr_reader :paypal_details
|
80
83
|
attr_reader :plan_id
|
81
84
|
# The authorization code from the processor.
|
82
85
|
attr_reader :processor_authorization_code
|
@@ -99,6 +102,7 @@ module Braintree
|
|
99
102
|
attr_reader :type
|
100
103
|
attr_reader :updated_at
|
101
104
|
attr_reader :add_ons, :discounts
|
105
|
+
attr_reader :payment_instrument_type
|
102
106
|
|
103
107
|
# See http://www.braintreepayments.com/docs/ruby/transactions/create
|
104
108
|
def self.create(attributes)
|
@@ -230,10 +234,12 @@ module Braintree
|
|
230
234
|
@status_history = attributes[:status_history] ? attributes[:status_history].map { |s| StatusDetails.new(s) } : []
|
231
235
|
@tax_amount = Util.to_big_decimal(tax_amount)
|
232
236
|
@descriptor = Descriptor.new(@descriptor)
|
237
|
+
@paypal_details = PayPalDetails.new(@paypal)
|
233
238
|
disputes.map! { |attrs| Dispute._new(attrs) } if disputes
|
234
239
|
@custom_fields = attributes[:custom_fields].is_a?(Hash) ? attributes[:custom_fields] : {}
|
235
240
|
add_ons.map! { |attrs| AddOn._new(attrs) } if add_ons
|
236
241
|
discounts.map! { |attrs| Discount._new(attrs) } if discounts
|
242
|
+
@payment_instrument_type = attributes[:payment_instrument_type]
|
237
243
|
end
|
238
244
|
|
239
245
|
# True if <tt>other</tt> is a Braintree::Transaction with the same id.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Braintree
|
2
|
+
class Transaction
|
3
|
+
class PayPalDetails
|
4
|
+
include BaseModule
|
5
|
+
|
6
|
+
attr_reader :payer_email, :payment_id, :authorization_id, :token,
|
7
|
+
:image_url
|
8
|
+
|
9
|
+
def initialize(attributes)
|
10
|
+
set_instance_variables_from_hash attributes unless attributes.nil?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -108,6 +108,7 @@ module Braintree
|
|
108
108
|
_handle_transaction_response(response)
|
109
109
|
end
|
110
110
|
|
111
|
+
|
111
112
|
def self._clone_signature # :nodoc:
|
112
113
|
[:amount, :channel, {:options => [:submit_for_settlement]}]
|
113
114
|
end
|
@@ -117,7 +118,7 @@ module Braintree
|
|
117
118
|
:amount, :customer_id, :merchant_account_id, :order_id, :channel, :payment_method_token,
|
118
119
|
:purchase_order_number, :recurring, :shipping_address_id, :type, :tax_amount, :tax_exempt,
|
119
120
|
:venmo_sdk_payment_method_code, :device_session_id, :service_fee_amount, :device_data, :fraud_merchant_id,
|
120
|
-
:billing_address_id, :payment_method_nonce,
|
121
|
+
:billing_address_id, :payment_method_nonce, :three_d_secure_token,
|
121
122
|
{:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
|
122
123
|
{:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
|
123
124
|
{
|
@@ -129,6 +130,7 @@ module Braintree
|
|
129
130
|
{:options => [:hold_in_escrow, :store_in_vault, :store_in_vault_on_success, :submit_for_settlement, :add_billing_address_to_payment_method, :store_shipping_address_in_vault, :venmo_sdk_session]},
|
130
131
|
{:custom_fields => :_any_key_},
|
131
132
|
{:descriptor => [:name, :phone]},
|
133
|
+
{:paypal_account => [:email, :token, :paypal_data]},
|
132
134
|
{:industry => [:industry_type, {:data => [:folio_number, :check_in_date, :check_out_date]}]}
|
133
135
|
]
|
134
136
|
end
|
@@ -23,7 +23,11 @@ module Braintree
|
|
23
23
|
:id,
|
24
24
|
:order_id,
|
25
25
|
:payment_method_token,
|
26
|
+
:paypal_payment_id,
|
27
|
+
:paypal_authorization_id,
|
28
|
+
:paypal_payer_email,
|
26
29
|
:processor_authorization_code,
|
30
|
+
:sepa_bank_account_iban,
|
27
31
|
:settlement_batch_id,
|
28
32
|
:shipping_company,
|
29
33
|
:shipping_country_name,
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Braintree
|
2
|
+
class UnknownPaymentMethod
|
3
|
+
include BaseModule
|
4
|
+
|
5
|
+
attr_reader :token
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
nested_attributes = attributes[attributes.keys.first]
|
9
|
+
set_instance_variables_from_hash(nested_attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
def default?
|
13
|
+
@default
|
14
|
+
end
|
15
|
+
|
16
|
+
def image_url
|
17
|
+
"https://assets.braintreegateway.com/payment_method_logo/unknown.png"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/braintree/version.rb
CHANGED
@@ -7,7 +7,7 @@ module Braintree
|
|
7
7
|
|
8
8
|
def sample_notification(kind, id)
|
9
9
|
payload = Base64.encode64(_sample_xml(kind, id))
|
10
|
-
signature_string = "#{
|
10
|
+
signature_string = "#{@config.public_key}|#{Braintree::Digest.hexdigest(@config.private_key, payload)}"
|
11
11
|
|
12
12
|
return signature_string, payload
|
13
13
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
|
3
3
|
|
4
|
-
describe Braintree::ClientToken do
|
5
4
|
|
5
|
+
describe Braintree::ClientToken do
|
6
6
|
describe "self.generate" do
|
7
7
|
it "generates a fingerprint that the gateway accepts" do
|
8
8
|
config = Braintree::Configuration.instantiate
|
9
|
-
|
9
|
+
raw_client_token = Braintree::ClientToken.generate
|
10
|
+
client_token = decode_client_token(raw_client_token)
|
10
11
|
http = ClientApiHttp.new(
|
11
12
|
config,
|
12
|
-
:authorization_fingerprint =>
|
13
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
13
14
|
:shared_customer_identifier => "fake_identifier",
|
14
15
|
:shared_customer_identifier_type => "testing"
|
15
16
|
)
|
16
17
|
|
17
|
-
response = http.
|
18
|
+
response = http.get_payment_methods
|
18
19
|
|
19
20
|
response.code.should == "200"
|
20
21
|
end
|
@@ -25,24 +26,41 @@ describe Braintree::ClientToken do
|
|
25
26
|
end.to raise_error(ArgumentError)
|
26
27
|
end
|
27
28
|
|
29
|
+
describe "version" do
|
30
|
+
it "allows a client token version to be specified" do
|
31
|
+
config = Braintree::Configuration.instantiate
|
32
|
+
client_token_string = Braintree::ClientToken.generate(:version => 1)
|
33
|
+
client_token = JSON.parse(client_token_string)
|
34
|
+
client_token["version"].should == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it "defaults to 2" do
|
38
|
+
config = Braintree::Configuration.instantiate
|
39
|
+
client_token_string = Braintree::ClientToken.generate
|
40
|
+
client_token = decode_client_token(client_token_string)
|
41
|
+
client_token["version"].should == "2"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
28
45
|
it "can pass verify_card" do
|
29
46
|
config = Braintree::Configuration.instantiate
|
30
47
|
result = Braintree::Customer.create
|
31
|
-
|
48
|
+
raw_client_token = Braintree::ClientToken.generate(
|
32
49
|
:customer_id => result.customer.id,
|
33
50
|
:options => {
|
34
51
|
:verify_card => true
|
35
52
|
}
|
36
53
|
)
|
54
|
+
client_token = decode_client_token(raw_client_token)
|
37
55
|
|
38
56
|
http = ClientApiHttp.new(
|
39
57
|
config,
|
40
|
-
:authorization_fingerprint =>
|
58
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
41
59
|
:shared_customer_identifier => "fake_identifier",
|
42
60
|
:shared_customer_identifier_type => "testing"
|
43
61
|
)
|
44
62
|
|
45
|
-
response = http.
|
63
|
+
response = http.add_payment_method(
|
46
64
|
:credit_card => {
|
47
65
|
:number => "4000111111111115",
|
48
66
|
:expiration_month => "11",
|
@@ -57,21 +75,22 @@ describe Braintree::ClientToken do
|
|
57
75
|
config = Braintree::Configuration.instantiate
|
58
76
|
result = Braintree::Customer.create
|
59
77
|
customer_id = result.customer.id
|
60
|
-
|
78
|
+
raw_client_token = Braintree::ClientToken.generate(
|
61
79
|
:customer_id => customer_id,
|
62
80
|
:options => {
|
63
81
|
:make_default => true
|
64
82
|
}
|
65
83
|
)
|
84
|
+
client_token = decode_client_token(raw_client_token)
|
66
85
|
|
67
86
|
http = ClientApiHttp.new(
|
68
87
|
config,
|
69
|
-
:authorization_fingerprint =>
|
88
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
70
89
|
:shared_customer_identifier => "fake_identifier",
|
71
90
|
:shared_customer_identifier_type => "testing"
|
72
91
|
)
|
73
92
|
|
74
|
-
response = http.
|
93
|
+
response = http.add_payment_method(
|
75
94
|
:credit_card => {
|
76
95
|
:number => "4111111111111111",
|
77
96
|
:expiration_month => "11",
|
@@ -81,7 +100,7 @@ describe Braintree::ClientToken do
|
|
81
100
|
|
82
101
|
response.code.should == "201"
|
83
102
|
|
84
|
-
response = http.
|
103
|
+
response = http.add_payment_method(
|
85
104
|
:credit_card => {
|
86
105
|
:number => "4005519200000004",
|
87
106
|
:expiration_month => "11",
|
@@ -99,18 +118,19 @@ describe Braintree::ClientToken do
|
|
99
118
|
config = Braintree::Configuration.instantiate
|
100
119
|
result = Braintree::Customer.create
|
101
120
|
customer_id = result.customer.id
|
102
|
-
|
121
|
+
raw_client_token = Braintree::ClientToken.generate(
|
103
122
|
:customer_id => customer_id
|
104
123
|
)
|
124
|
+
client_token = decode_client_token(raw_client_token)
|
105
125
|
|
106
126
|
http = ClientApiHttp.new(
|
107
127
|
config,
|
108
|
-
:authorization_fingerprint =>
|
128
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
109
129
|
:shared_customer_identifier => "fake_identifier",
|
110
130
|
:shared_customer_identifier_type => "testing"
|
111
131
|
)
|
112
132
|
|
113
|
-
response = http.
|
133
|
+
response = http.add_payment_method(
|
114
134
|
:credit_card => {
|
115
135
|
:number => "4111111111111111",
|
116
136
|
:expiration_month => "11",
|
@@ -120,16 +140,17 @@ describe Braintree::ClientToken do
|
|
120
140
|
|
121
141
|
response.code.should == "201"
|
122
142
|
|
123
|
-
|
143
|
+
second_raw_client_token = Braintree::ClientToken.generate(
|
124
144
|
:customer_id => customer_id,
|
125
145
|
:options => {
|
126
146
|
:fail_on_duplicate_payment_method => true
|
127
147
|
}
|
128
148
|
)
|
149
|
+
second_client_token = decode_client_token(second_raw_client_token)
|
129
150
|
|
130
|
-
http.fingerprint =
|
151
|
+
http.fingerprint = second_client_token["authorizationFingerprint"]
|
131
152
|
|
132
|
-
response = http.
|
153
|
+
response = http.add_payment_method(
|
133
154
|
:credit_card => {
|
134
155
|
:number => "4111111111111111",
|
135
156
|
:expiration_month => "11",
|
@@ -139,5 +160,47 @@ describe Braintree::ClientToken do
|
|
139
160
|
|
140
161
|
response.code.should == "422"
|
141
162
|
end
|
163
|
+
|
164
|
+
it "can pass merchant_account_id" do
|
165
|
+
raw_client_token = Braintree::ClientToken.generate(
|
166
|
+
:merchant_account_id => "my_merchant_account"
|
167
|
+
)
|
168
|
+
client_token = decode_client_token(raw_client_token)
|
169
|
+
|
170
|
+
client_token["merchantAccountId"].should == "my_merchant_account"
|
171
|
+
end
|
172
|
+
|
173
|
+
context "paypal" do
|
174
|
+
it "includes the paypal options for a paypal merchant" do
|
175
|
+
with_altpay_merchant do
|
176
|
+
raw_client_token = Braintree::ClientToken.generate
|
177
|
+
client_token = decode_client_token(raw_client_token)
|
178
|
+
|
179
|
+
client_token["paypal"]["displayName"].should == "merchant who has paypal and sepa enabled"
|
180
|
+
client_token["paypal"]["clientId"].should match(/.+/)
|
181
|
+
client_token["paypal"]["privacyUrl"].should match("http://www.example.com/privacy_policy")
|
182
|
+
client_token["paypal"]["userAgreementUrl"].should match("http://www.example.com/user_agreement")
|
183
|
+
client_token["paypal"]["baseUrl"].should_not be_nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "SEPA" do
|
189
|
+
it "includes the SEPA options for a SEPA merchant" do
|
190
|
+
with_altpay_merchant do
|
191
|
+
result = Braintree::Customer.create
|
192
|
+
customer_id = result.customer.id
|
193
|
+
|
194
|
+
raw_client_token = Braintree::ClientToken.generate(
|
195
|
+
:customer_id => customer_id,
|
196
|
+
:sepa_mandate_acceptance_location => "Hamburg, Germany",
|
197
|
+
:sepa_mandate_type => Braintree::SEPABankAccount::MandateType::Business
|
198
|
+
)
|
199
|
+
client_token = decode_client_token(raw_client_token)
|
200
|
+
|
201
|
+
client_token["authorizationFingerprint"].should include("sepa_mandate_type=business")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
142
205
|
end
|
143
206
|
end
|