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
@@ -1,22 +1,58 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
|
-
def
|
3
|
+
def decode_client_token(raw_client_token)
|
4
|
+
decoded_client_token_string = Base64.decode64(raw_client_token)
|
5
|
+
JSON.parse(decoded_client_token_string)
|
6
|
+
end
|
7
|
+
|
8
|
+
def nonce_for_new_payment_method(options)
|
9
|
+
client = _initialize_client(options)
|
10
|
+
response = client.add_payment_method(options)
|
11
|
+
|
12
|
+
_nonce_from_response(response)
|
13
|
+
end
|
14
|
+
|
15
|
+
def _initialize_client(options)
|
4
16
|
client_token_options = options.delete(:client_token_options) || {}
|
5
|
-
|
6
|
-
|
7
|
-
|
17
|
+
raw_client_token = Braintree::ClientToken.generate(client_token_options)
|
18
|
+
client_token = decode_client_token(raw_client_token)
|
19
|
+
|
20
|
+
ClientApiHttp.new(Braintree::Configuration.instantiate,
|
21
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
8
22
|
:shared_customer_identifier => "fake_identifier",
|
9
23
|
:shared_customer_identifier_type => "testing"
|
10
24
|
)
|
25
|
+
end
|
11
26
|
|
12
|
-
|
27
|
+
def _nonce_from_response(response)
|
13
28
|
body = JSON.parse(response.body)
|
14
29
|
|
15
30
|
if body["errors"] != nil
|
16
31
|
raise body["errors"].inspect
|
17
32
|
end
|
18
33
|
|
19
|
-
body
|
34
|
+
if body.has_key?("paypalAccounts")
|
35
|
+
body["paypalAccounts"][0]["nonce"]
|
36
|
+
else
|
37
|
+
body["creditCards"][0]["nonce"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def nonce_for_paypal_account(paypal_account_details)
|
42
|
+
raw_client_token = Braintree::ClientToken.generate
|
43
|
+
client_token = decode_client_token(raw_client_token)
|
44
|
+
client = ClientApiHttp.new(Braintree::Configuration.instantiate,
|
45
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"]
|
46
|
+
)
|
47
|
+
|
48
|
+
response = client.create_paypal_account(paypal_account_details)
|
49
|
+
body = JSON.parse(response.body)
|
50
|
+
|
51
|
+
if body["errors"] != nil
|
52
|
+
raise body["errors"].inspect
|
53
|
+
end
|
54
|
+
|
55
|
+
body["paypalAccounts"][0]["nonce"]
|
20
56
|
end
|
21
57
|
|
22
58
|
class ClientApiHttp
|
@@ -35,6 +71,10 @@ class ClientApiHttp
|
|
35
71
|
_http_do(Net::HTTP::Post, path, params.to_json)
|
36
72
|
end
|
37
73
|
|
74
|
+
def put(path, params)
|
75
|
+
_http_do(Net::HTTP::Put, path, params.to_json)
|
76
|
+
end
|
77
|
+
|
38
78
|
def fingerprint=(fingerprint)
|
39
79
|
@options[:authorization_fingerprint] = fingerprint
|
40
80
|
end
|
@@ -59,9 +99,9 @@ class ClientApiHttp
|
|
59
99
|
raise Braintree::SSLCertificateError
|
60
100
|
end
|
61
101
|
|
62
|
-
def
|
102
|
+
def get_payment_methods
|
63
103
|
encoded_fingerprint = Braintree::Util.url_encode(@options[:authorization_fingerprint])
|
64
|
-
url = "/merchants/#{@config.merchant_id}/client_api/
|
104
|
+
url = "/merchants/#{@config.merchant_id}/client_api/v1/payment_methods?"
|
65
105
|
url += "authorizationFingerprint=#{encoded_fingerprint}"
|
66
106
|
url += "&sharedCustomerIdentifier=#{@options[:shared_customer_identifier]}"
|
67
107
|
url += "&sharedCustomerIdentifierType=#{@options[:shared_customer_identifier_type]}"
|
@@ -69,12 +109,55 @@ class ClientApiHttp
|
|
69
109
|
get(url)
|
70
110
|
end
|
71
111
|
|
72
|
-
def
|
112
|
+
def add_payment_method(params)
|
73
113
|
fingerprint = @options[:authorization_fingerprint]
|
74
114
|
params[:authorizationFingerprint] = fingerprint
|
75
115
|
params[:sharedCustomerIdentifier] = @options[:shared_customer_identifier]
|
76
116
|
params[:sharedCustomerIdentifierType] = @options[:shared_customer_identifier_type]
|
77
117
|
|
78
|
-
|
118
|
+
payment_method_type = nil
|
119
|
+
if params.has_key?(:paypal_account)
|
120
|
+
payment_method_type = "paypal_accounts"
|
121
|
+
else
|
122
|
+
payment_method_type = "credit_cards"
|
123
|
+
end
|
124
|
+
|
125
|
+
post("/merchants/#{@config.merchant_id}/client_api/v1/payment_methods/#{payment_method_type}", params)
|
126
|
+
end
|
127
|
+
|
128
|
+
def create_credit_card(params)
|
129
|
+
params = {:credit_card => params}
|
130
|
+
params.merge!(
|
131
|
+
:authorization_fingerprint => @options[:authorization_fingerprint],
|
132
|
+
:shared_customer_identifier => "fake_identifier",
|
133
|
+
:shared_customer_identifier_type => "testing"
|
134
|
+
)
|
135
|
+
|
136
|
+
post("/merchants/#{config.merchant_id}/client_api/v1/payment_methods/credit_cards", params)
|
137
|
+
end
|
138
|
+
|
139
|
+
def create_paypal_account(params)
|
140
|
+
params = {:paypal_account => params}
|
141
|
+
params.merge!(
|
142
|
+
:authorization_fingerprint => @options[:authorization_fingerprint]
|
143
|
+
)
|
144
|
+
|
145
|
+
post("/merchants/#{config.merchant_id}/client_api/v1/payment_methods/paypal_accounts", params)
|
146
|
+
end
|
147
|
+
|
148
|
+
def create_sepa_bank_account_nonce(params)
|
149
|
+
foo = {
|
150
|
+
:authorization_fingerprint => @options[:authorization_fingerprint],
|
151
|
+
:shared_customer_identifier => "fake_identifier",
|
152
|
+
:shared_customer_identifier_type => "testing",
|
153
|
+
|
154
|
+
:sepa_mandate => params
|
155
|
+
}
|
156
|
+
|
157
|
+
response = post("/merchants/#{config.merchant_id}/client_api/v1/sepa_mandates", foo)
|
158
|
+
|
159
|
+
mrn = JSON.parse(response.body)['sepaMandates'][0]['mandateReferenceNumber']
|
160
|
+
accept_response = put("/merchants/#{config.merchant_id}/client_api/v1/sepa_mandates/#{mrn}/accept.json",foo)
|
161
|
+
JSON.parse(accept_response.body)['sepaBankAccounts'][0]['nonce']
|
79
162
|
end
|
80
163
|
end
|
@@ -456,7 +456,7 @@ describe Braintree::CreditCard do
|
|
456
456
|
|
457
457
|
context "client API" do
|
458
458
|
it "adds credit card to an existing customer using a payment method nonce" do
|
459
|
-
nonce =
|
459
|
+
nonce = nonce_for_new_payment_method(
|
460
460
|
:credit_card => {
|
461
461
|
:number => "4111111111111111",
|
462
462
|
:expiration_month => "11",
|
@@ -1050,24 +1050,6 @@ describe Braintree::CreditCard do
|
|
1050
1050
|
end
|
1051
1051
|
end
|
1052
1052
|
|
1053
|
-
describe "delete" do
|
1054
|
-
it "deletes the credit card" do
|
1055
|
-
customer = Braintree::Customer.create.customer
|
1056
|
-
result = Braintree::CreditCard.create(
|
1057
|
-
:customer_id => customer.id,
|
1058
|
-
:number => Braintree::Test::CreditCardNumbers::Visa,
|
1059
|
-
:expiration_date => "05/2012"
|
1060
|
-
)
|
1061
|
-
|
1062
|
-
result.success?.should == true
|
1063
|
-
credit_card = result.credit_card
|
1064
|
-
credit_card.delete.should == true
|
1065
|
-
expect do
|
1066
|
-
Braintree::CreditCard.find(credit_card.token)
|
1067
|
-
end.to raise_error(Braintree::NotFoundError)
|
1068
|
-
end
|
1069
|
-
end
|
1070
|
-
|
1071
1053
|
describe "self.expired" do
|
1072
1054
|
it "can iterate over all items, and make sure they are all expired" do
|
1073
1055
|
customer = Braintree::Customer.all.first
|
@@ -1161,12 +1143,30 @@ describe Braintree::CreditCard do
|
|
1161
1143
|
Braintree::CreditCard.find("invalid-token")
|
1162
1144
|
end.to raise_error(Braintree::NotFoundError, 'payment method with token "invalid-token" not found')
|
1163
1145
|
end
|
1146
|
+
|
1147
|
+
it "raises a NotFoundError exception if searching for a PayPalAccount token" do
|
1148
|
+
customer = Braintree::Customer.create!
|
1149
|
+
paypal_account_token = "PAYPAL_ACCOUNT_TOKEN_#{rand(36**3).to_s(36)}"
|
1150
|
+
paypal_nonce = nonce_for_paypal_account({
|
1151
|
+
:consent_code => "PAYPAL_CONSENT_CODE",
|
1152
|
+
:token => paypal_account_token
|
1153
|
+
})
|
1154
|
+
|
1155
|
+
Braintree::PaymentMethod.create({
|
1156
|
+
:payment_method_nonce => paypal_nonce,
|
1157
|
+
:customer_id => customer.id
|
1158
|
+
})
|
1159
|
+
|
1160
|
+
expect do
|
1161
|
+
Braintree::CreditCard.find(paypal_account_token)
|
1162
|
+
end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{paypal_account_token}\" not found")
|
1163
|
+
end
|
1164
1164
|
end
|
1165
1165
|
|
1166
1166
|
describe "self.from_nonce" do
|
1167
1167
|
it "finds the payment method with the given nonce" do
|
1168
1168
|
customer = Braintree::Customer.create!
|
1169
|
-
nonce =
|
1169
|
+
nonce = nonce_for_new_payment_method(
|
1170
1170
|
:credit_card => {
|
1171
1171
|
:number => "4111111111111111",
|
1172
1172
|
:expiration_month => "11",
|
@@ -1181,7 +1181,7 @@ describe Braintree::CreditCard do
|
|
1181
1181
|
end
|
1182
1182
|
|
1183
1183
|
it "does not find a payment method for an unlocked nonce that points to a shared credit card" do
|
1184
|
-
nonce =
|
1184
|
+
nonce = nonce_for_new_payment_method(
|
1185
1185
|
:credit_card => {
|
1186
1186
|
:number => "4111111111111111",
|
1187
1187
|
:expiration_month => "11",
|
@@ -1194,14 +1194,15 @@ describe Braintree::CreditCard do
|
|
1194
1194
|
end
|
1195
1195
|
|
1196
1196
|
it "does not find the payment method for a locked nonce" do
|
1197
|
-
|
1197
|
+
raw_client_token = Braintree::ClientToken.generate
|
1198
|
+
client_token = decode_client_token(raw_client_token)
|
1198
1199
|
client = ClientApiHttp.new(Braintree::Configuration.instantiate,
|
1199
|
-
:authorization_fingerprint =>
|
1200
|
+
:authorization_fingerprint => client_token["authorizationFingerprint"],
|
1200
1201
|
:shared_customer_identifier => "fake_identifier",
|
1201
1202
|
:shared_customer_identifier_type => "testing"
|
1202
1203
|
)
|
1203
1204
|
|
1204
|
-
client.
|
1205
|
+
client.add_payment_method(
|
1205
1206
|
:credit_card => {
|
1206
1207
|
:number => "4111111111111111",
|
1207
1208
|
:expiration_month => "11",
|
@@ -1210,9 +1211,9 @@ describe Braintree::CreditCard do
|
|
1210
1211
|
:share => true
|
1211
1212
|
)
|
1212
1213
|
|
1213
|
-
response = client.
|
1214
|
+
response = client.get_payment_methods
|
1214
1215
|
body = JSON.parse(response.body)
|
1215
|
-
nonce = body["
|
1216
|
+
nonce = body["paymentMethods"].first["nonce"]
|
1216
1217
|
|
1217
1218
|
expect do
|
1218
1219
|
Braintree::CreditCard.from_nonce(nonce)
|
@@ -1221,7 +1222,7 @@ describe Braintree::CreditCard do
|
|
1221
1222
|
|
1222
1223
|
it "does not find the payment method for a consumednonce" do
|
1223
1224
|
customer = Braintree::Customer.create!
|
1224
|
-
nonce =
|
1225
|
+
nonce = nonce_for_new_payment_method(
|
1225
1226
|
:credit_card => {
|
1226
1227
|
:number => "4111111111111111",
|
1227
1228
|
:expiration_month => "11",
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
|
2
3
|
|
3
4
|
describe Braintree::Transaction, "search" do
|
4
5
|
context "advanced" do
|
@@ -169,4 +170,26 @@ describe Braintree::Transaction, "search" do
|
|
169
170
|
collection.first.company.should == customer.company
|
170
171
|
end
|
171
172
|
end
|
173
|
+
|
174
|
+
it "can search by paypal_account_email" do
|
175
|
+
paypal_token = rand(36**3).to_s(36)
|
176
|
+
nonce = nonce_for_paypal_account(
|
177
|
+
:consent_code => "PAYPAL_CONSENT_CODE",
|
178
|
+
:token => paypal_token
|
179
|
+
)
|
180
|
+
|
181
|
+
customer_id = "UNIQUE_CUSTOMER_ID_" + rand(36**3).to_s(36)
|
182
|
+
customer = Braintree::Customer.create!(
|
183
|
+
:payment_method_nonce => nonce,
|
184
|
+
:id => customer_id
|
185
|
+
)
|
186
|
+
|
187
|
+
collection = Braintree::Customer.search do |search|
|
188
|
+
search.paypal_account_email.is "jane.doe@example.com"
|
189
|
+
search.id.is customer_id
|
190
|
+
end
|
191
|
+
|
192
|
+
collection.maximum_size.should == 1
|
193
|
+
collection.first.should == customer
|
194
|
+
end
|
172
195
|
end
|
@@ -383,7 +383,7 @@ describe Braintree::Customer do
|
|
383
383
|
|
384
384
|
context "client API" do
|
385
385
|
it "can create a customer with a payment method nonce" do
|
386
|
-
nonce =
|
386
|
+
nonce = nonce_for_new_payment_method(
|
387
387
|
:credit_card => {
|
388
388
|
:number => "4111111111111111",
|
389
389
|
:expiration_month => "11",
|
@@ -1135,4 +1135,86 @@ describe Braintree::Customer do
|
|
1135
1135
|
customer.default_credit_card.should == default_credit_card
|
1136
1136
|
end
|
1137
1137
|
end
|
1138
|
+
|
1139
|
+
describe "paypal" do
|
1140
|
+
context "future" do
|
1141
|
+
it "creates a customer with a future paypal account" do
|
1142
|
+
result = Braintree::Customer.create(
|
1143
|
+
:payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
|
1144
|
+
)
|
1145
|
+
|
1146
|
+
result.should be_success
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
it "updates a customer with a future paypal account" do
|
1150
|
+
customer = Braintree::Customer.create!(
|
1151
|
+
:credit_card => {
|
1152
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
1153
|
+
:expiration_date => "12/2015",
|
1154
|
+
:options => {
|
1155
|
+
:make_default => true
|
1156
|
+
}
|
1157
|
+
}
|
1158
|
+
)
|
1159
|
+
|
1160
|
+
paypal_account_token = "PAYPAL_ACCOUNT_TOKEN_#{rand(36**3).to_s(36)}"
|
1161
|
+
nonce = nonce_for_paypal_account(
|
1162
|
+
:consent_code => "PAYPAL_CONSENT_CODE",
|
1163
|
+
:token => paypal_account_token,
|
1164
|
+
:options => {
|
1165
|
+
:make_default => true
|
1166
|
+
}
|
1167
|
+
)
|
1168
|
+
|
1169
|
+
result = Braintree::Customer.update(
|
1170
|
+
customer.id,
|
1171
|
+
:payment_method_nonce => nonce
|
1172
|
+
)
|
1173
|
+
|
1174
|
+
result.should be_success
|
1175
|
+
result.customer.default_payment_method.token.should == paypal_account_token
|
1176
|
+
end
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
context "onetime" do
|
1180
|
+
it "does not create a customer with a onetime paypal account" do
|
1181
|
+
result = Braintree::Customer.create(
|
1182
|
+
:payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment
|
1183
|
+
)
|
1184
|
+
|
1185
|
+
result.should_not be_success
|
1186
|
+
end
|
1187
|
+
|
1188
|
+
it "does not update a customer with a onetime paypal account" do
|
1189
|
+
credit_card_token = rand(36**3).to_s(36)
|
1190
|
+
customer = Braintree::Customer.create!(
|
1191
|
+
:credit_card => {
|
1192
|
+
:token => credit_card_token,
|
1193
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
1194
|
+
:expiration_date => "12/2015",
|
1195
|
+
:options => {
|
1196
|
+
:make_default => true
|
1197
|
+
}
|
1198
|
+
}
|
1199
|
+
)
|
1200
|
+
|
1201
|
+
paypal_account_token = "PAYPAL_ACCOUNT_TOKEN_#{rand(36**3).to_s(36)}"
|
1202
|
+
nonce = nonce_for_paypal_account(
|
1203
|
+
:access_token => "PAYPAL_ACCESS_TOKEN",
|
1204
|
+
:token => paypal_account_token,
|
1205
|
+
:options => {
|
1206
|
+
:make_default => true
|
1207
|
+
}
|
1208
|
+
)
|
1209
|
+
|
1210
|
+
result = Braintree::Customer.update(
|
1211
|
+
customer.id,
|
1212
|
+
:payment_method_nonce => nonce
|
1213
|
+
)
|
1214
|
+
|
1215
|
+
result.should_not be_success
|
1216
|
+
customer.default_payment_method.token.should == credit_card_token
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
end
|
1138
1220
|
end
|
@@ -0,0 +1,315 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
|
3
|
+
|
4
|
+
describe Braintree::PaymentMethod do
|
5
|
+
describe "self.create" do
|
6
|
+
it "creates a payment method from a vaulted credit card nonce" do
|
7
|
+
config = Braintree::Configuration.instantiate
|
8
|
+
customer = Braintree::Customer.create.customer
|
9
|
+
raw_client_token = Braintree::ClientToken.generate(:customer_id => customer.id)
|
10
|
+
client_token = decode_client_token(raw_client_token)
|
11
|
+
authorization_fingerprint = client_token["authorizationFingerprint"]
|
12
|
+
http = ClientApiHttp.new(
|
13
|
+
config,
|
14
|
+
:authorization_fingerprint => authorization_fingerprint,
|
15
|
+
:shared_customer_identifier => "fake_identifier",
|
16
|
+
:shared_customer_identifier_type => "testing"
|
17
|
+
)
|
18
|
+
|
19
|
+
response = http.create_credit_card(
|
20
|
+
:number => 4111111111111111,
|
21
|
+
:expirationMonth => 12,
|
22
|
+
:expirationYear => 2020
|
23
|
+
)
|
24
|
+
response.code.should == "201"
|
25
|
+
|
26
|
+
nonce = JSON.parse(response.body)["creditCards"].first["nonce"]
|
27
|
+
result = Braintree::PaymentMethod.create(
|
28
|
+
:payment_method_nonce => nonce,
|
29
|
+
:customer_id => customer.id
|
30
|
+
)
|
31
|
+
|
32
|
+
result.should be_success
|
33
|
+
result.payment_method.should be_a(Braintree::CreditCard)
|
34
|
+
token = result.payment_method.token
|
35
|
+
|
36
|
+
found_credit_card = Braintree::CreditCard.find(token)
|
37
|
+
found_credit_card.should_not be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "creates a payment method from an unvalidated credit card nonce" do
|
41
|
+
config = Braintree::Configuration.instantiate
|
42
|
+
customer = Braintree::Customer.create.customer
|
43
|
+
raw_client_token = Braintree::ClientToken.generate(:customer_id => customer.id)
|
44
|
+
client_token = decode_client_token(raw_client_token)
|
45
|
+
authorization_fingerprint = client_token["authorizationFingerprint"]
|
46
|
+
http = ClientApiHttp.new(
|
47
|
+
config,
|
48
|
+
:authorization_fingerprint => authorization_fingerprint,
|
49
|
+
:shared_customer_identifier => "fake_identifier",
|
50
|
+
:shared_customer_identifier_type => "testing"
|
51
|
+
)
|
52
|
+
|
53
|
+
response = http.create_credit_card(
|
54
|
+
:number => "4111111111111111",
|
55
|
+
:expirationMonth => "12",
|
56
|
+
:expirationYear => "2020",
|
57
|
+
:options => {:validate => false}
|
58
|
+
)
|
59
|
+
response.code.should == "202"
|
60
|
+
|
61
|
+
nonce = JSON.parse(response.body)["creditCards"].first["nonce"]
|
62
|
+
result = Braintree::PaymentMethod.create(
|
63
|
+
:payment_method_nonce => nonce,
|
64
|
+
:customer_id => customer.id
|
65
|
+
)
|
66
|
+
|
67
|
+
result.should be_success
|
68
|
+
result.payment_method.should be_a(Braintree::CreditCard)
|
69
|
+
token = result.payment_method.token
|
70
|
+
|
71
|
+
found_credit_card = Braintree::CreditCard.find(token)
|
72
|
+
found_credit_card.should_not be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
it "allows passing the make_default option alongside the nonce" do
|
76
|
+
customer = Braintree::Customer.create!
|
77
|
+
result = Braintree::CreditCard.create(
|
78
|
+
:customer_id => customer.id,
|
79
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
80
|
+
:expiration_date => "05/2009",
|
81
|
+
:cvv => "100"
|
82
|
+
)
|
83
|
+
result.success?.should == true
|
84
|
+
original_payment_method = result.credit_card
|
85
|
+
original_payment_method.should be_default
|
86
|
+
|
87
|
+
nonce = nonce_for_paypal_account(:consent_code => "PAYPAL_CONSENT_CODE")
|
88
|
+
result = Braintree::PaymentMethod.create(
|
89
|
+
:payment_method_nonce => nonce,
|
90
|
+
:customer_id => customer.id,
|
91
|
+
:options => {:make_default => true}
|
92
|
+
)
|
93
|
+
|
94
|
+
result.should be_success
|
95
|
+
new_payment_method = result.payment_method
|
96
|
+
new_payment_method.should be_default
|
97
|
+
end
|
98
|
+
|
99
|
+
it "overrides the token in the nonce" do
|
100
|
+
customer = Braintree::Customer.create!
|
101
|
+
|
102
|
+
first_token = "FIRST_TOKEN_#{rand(36**3).to_s(36)}"
|
103
|
+
second_token = "SECOND_TOKEN_#{rand(36**3).to_s(36)}"
|
104
|
+
nonce = nonce_for_paypal_account(
|
105
|
+
:consent_code => "PAYPAL_CONSENT_CODE",
|
106
|
+
:token => first_token
|
107
|
+
)
|
108
|
+
result = Braintree::PaymentMethod.create(
|
109
|
+
:payment_method_nonce => nonce,
|
110
|
+
:customer_id => customer.id,
|
111
|
+
:token => second_token
|
112
|
+
)
|
113
|
+
|
114
|
+
result.should be_success
|
115
|
+
payment_method = result.payment_method
|
116
|
+
payment_method.token.should == second_token
|
117
|
+
end
|
118
|
+
|
119
|
+
context "paypal" do
|
120
|
+
it "creates a payment method from an unvalidated future paypal account nonce" do
|
121
|
+
nonce = nonce_for_paypal_account(:consent_code => "PAYPAL_CONSENT_CODE")
|
122
|
+
customer = Braintree::Customer.create.customer
|
123
|
+
result = Braintree::PaymentMethod.create(
|
124
|
+
:payment_method_nonce => nonce,
|
125
|
+
:customer_id => customer.id
|
126
|
+
)
|
127
|
+
|
128
|
+
result.should be_success
|
129
|
+
result.payment_method.should be_a(Braintree::PayPalAccount)
|
130
|
+
result.payment_method.image_url.should_not be_nil
|
131
|
+
token = result.payment_method.token
|
132
|
+
|
133
|
+
found_paypal_account = Braintree::PayPalAccount.find(token)
|
134
|
+
found_paypal_account.should_not be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
it "does not create a payment method from an unvalidated onetime paypal account nonce" do
|
138
|
+
customer = Braintree::Customer.create.customer
|
139
|
+
nonce = nonce_for_paypal_account(:access_token => "PAYPAL_ACCESS_TOKEN")
|
140
|
+
result = Braintree::PaymentMethod.create(
|
141
|
+
:payment_method_nonce => nonce,
|
142
|
+
:customer_id => customer.id
|
143
|
+
)
|
144
|
+
|
145
|
+
result.should_not be_success
|
146
|
+
result.errors.first.code.should == "82902"
|
147
|
+
end
|
148
|
+
|
149
|
+
it "returns appropriate validation errors" do
|
150
|
+
customer = Braintree::Customer.create.customer
|
151
|
+
nonce = nonce_for_paypal_account(:token => "PAYPAL_TOKEN")
|
152
|
+
result = Braintree::PaymentMethod.create(
|
153
|
+
:payment_method_nonce => nonce,
|
154
|
+
:customer_id => customer.id
|
155
|
+
)
|
156
|
+
|
157
|
+
result.should_not be_success
|
158
|
+
errors = result.errors.map(&:code)
|
159
|
+
errors.should include("82901")
|
160
|
+
errors.should include("82902")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "SEPA" do
|
165
|
+
it "returns the SEPA bank account behind the nonce" do
|
166
|
+
config = Braintree::Configuration.instantiate
|
167
|
+
customer = Braintree::Customer.create.customer
|
168
|
+
raw_client_token = Braintree::ClientToken.generate(:customer_id => customer.id, :sepa_mandate_type => Braintree::SEPABankAccount::MandateType::Business)
|
169
|
+
client_token = decode_client_token(raw_client_token)
|
170
|
+
authorization_fingerprint = client_token["authorizationFingerprint"]
|
171
|
+
http = ClientApiHttp.new(
|
172
|
+
config,
|
173
|
+
:authorization_fingerprint => authorization_fingerprint
|
174
|
+
)
|
175
|
+
|
176
|
+
nonce = http.create_sepa_bank_account_nonce(
|
177
|
+
:accountHolderName => "Bob Holder",
|
178
|
+
:iban => "DE89370400440532013000",
|
179
|
+
:bic => "DEUTDEFF",
|
180
|
+
:locale => "en-US",
|
181
|
+
:billingAddress => {
|
182
|
+
:region => "Hesse",
|
183
|
+
:country_name => "Germany"
|
184
|
+
}
|
185
|
+
)
|
186
|
+
nonce.should_not == nil
|
187
|
+
result = Braintree::PaymentMethod.create(
|
188
|
+
:payment_method_nonce => nonce,
|
189
|
+
:customer_id => customer.id
|
190
|
+
)
|
191
|
+
|
192
|
+
result.should be_success
|
193
|
+
result.payment_method.token.should_not == nil
|
194
|
+
result.payment_method.image_url.should_not be_nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "self.find" do
|
200
|
+
context "credit cards" do
|
201
|
+
it "finds the payment method with the given token" do
|
202
|
+
customer = Braintree::Customer.create.customer
|
203
|
+
result = Braintree::CreditCard.create(
|
204
|
+
:customer_id => customer.id,
|
205
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
206
|
+
:expiration_date => "05/2012"
|
207
|
+
)
|
208
|
+
result.success?.should == true
|
209
|
+
|
210
|
+
credit_card = Braintree::PaymentMethod.find(result.credit_card.token)
|
211
|
+
credit_card.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
|
212
|
+
credit_card.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
|
213
|
+
credit_card.token.should == result.credit_card.token
|
214
|
+
credit_card.expiration_date.should == "05/2012"
|
215
|
+
end
|
216
|
+
|
217
|
+
it "returns associated subscriptions with the credit card" do
|
218
|
+
customer = Braintree::Customer.create.customer
|
219
|
+
credit_card = Braintree::CreditCard.create(
|
220
|
+
:customer_id => customer.id,
|
221
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
222
|
+
:expiration_date => "05/2012"
|
223
|
+
).credit_card
|
224
|
+
|
225
|
+
subscription = Braintree::Subscription.create(
|
226
|
+
:payment_method_token => credit_card.token,
|
227
|
+
:plan_id => "integration_trialless_plan",
|
228
|
+
:price => "1.00"
|
229
|
+
).subscription
|
230
|
+
|
231
|
+
found_card = Braintree::PaymentMethod.find(credit_card.token)
|
232
|
+
found_card.subscriptions.first.id.should == subscription.id
|
233
|
+
found_card.subscriptions.first.plan_id.should == "integration_trialless_plan"
|
234
|
+
found_card.subscriptions.first.payment_method_token.should == credit_card.token
|
235
|
+
found_card.subscriptions.first.price.should == BigDecimal.new("1.00")
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "paypal accounts" do
|
240
|
+
it "finds the payment method with the given token" do
|
241
|
+
customer = Braintree::Customer.create!
|
242
|
+
payment_method_token = "PAYMENT_METHOD_TOKEN_#{rand(36**3).to_s(36)}"
|
243
|
+
nonce = nonce_for_paypal_account(
|
244
|
+
:consent_code => "consent-code",
|
245
|
+
:token => payment_method_token
|
246
|
+
)
|
247
|
+
result = Braintree::PaymentMethod.create(
|
248
|
+
:payment_method_nonce => nonce,
|
249
|
+
:customer_id => customer.id
|
250
|
+
)
|
251
|
+
result.should be_success
|
252
|
+
|
253
|
+
paypal_account = Braintree::PaymentMethod.find(payment_method_token)
|
254
|
+
paypal_account.should be_a(Braintree::PayPalAccount)
|
255
|
+
paypal_account.token.should == payment_method_token
|
256
|
+
paypal_account.email.should == "jane.doe@example.com"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
it "raises a NotFoundError exception if payment method cannot be found" do
|
261
|
+
expect do
|
262
|
+
Braintree::PaymentMethod.find("invalid-token")
|
263
|
+
end.to raise_error(Braintree::NotFoundError, 'payment method with token "invalid-token" not found')
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "self.delete" do
|
268
|
+
it "deletes a paypal account" do
|
269
|
+
customer = Braintree::Customer.create!
|
270
|
+
paypal_account_token = "PAYPAL_ACCOUNT_TOKEN_#{rand(36**3).to_s(36)}"
|
271
|
+
nonce = nonce_for_paypal_account(
|
272
|
+
:consent_code => "PAYPAL_CONSENT_CODE",
|
273
|
+
:token => paypal_account_token
|
274
|
+
)
|
275
|
+
Braintree::PaymentMethod.create(
|
276
|
+
:payment_method_nonce => nonce,
|
277
|
+
:customer_id => customer.id
|
278
|
+
)
|
279
|
+
|
280
|
+
paypal_account = Braintree::PaymentMethod.find(paypal_account_token)
|
281
|
+
paypal_account.should be_a(Braintree::PayPalAccount)
|
282
|
+
|
283
|
+
result = Braintree::PaymentMethod.delete(paypal_account_token)
|
284
|
+
|
285
|
+
expect do
|
286
|
+
Braintree::PaymentMethod.find(paypal_account_token)
|
287
|
+
end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{paypal_account_token}\" not found")
|
288
|
+
end
|
289
|
+
|
290
|
+
it "deletes a credit card" do
|
291
|
+
token = "CREDIT_CARD_#{rand(36**3).to_s(36)}"
|
292
|
+
customer = Braintree::Customer.create!
|
293
|
+
nonce = nonce_for_new_payment_method({
|
294
|
+
:credit_card => {
|
295
|
+
:number => "4111111111111111",
|
296
|
+
:expiration_month => "11",
|
297
|
+
:expiration_year => "2099",
|
298
|
+
:token => token
|
299
|
+
},
|
300
|
+
:client_token_options => {:customer_id => customer.id}
|
301
|
+
})
|
302
|
+
|
303
|
+
Braintree::PaymentMethod.create(
|
304
|
+
:payment_method_nonce => nonce,
|
305
|
+
:customer_id => customer.id
|
306
|
+
)
|
307
|
+
|
308
|
+
Braintree::PaymentMethod.delete(token)
|
309
|
+
|
310
|
+
expect do
|
311
|
+
Braintree::PaymentMethod.find(token)
|
312
|
+
end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{token}\" not found")
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|