braintree 2.99.0 → 2.104.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/braintree/address_gateway.rb +2 -2
- data/lib/braintree/amex_express_checkout_card.rb +2 -0
- data/lib/braintree/android_pay_card.rb +5 -0
- data/lib/braintree/base_module.rb +4 -0
- data/lib/braintree/credit_card.rb +5 -1
- data/lib/braintree/credit_card_gateway.rb +14 -0
- data/lib/braintree/credit_card_verification.rb +2 -0
- data/lib/braintree/customer.rb +5 -2
- data/lib/braintree/dispute.rb +1 -0
- data/lib/braintree/dispute/transaction.rb +2 -0
- data/lib/braintree/error_codes.rb +76 -33
- data/lib/braintree/graphql_client.rb +7 -1
- data/lib/braintree/masterpass_card.rb +2 -0
- data/lib/braintree/payment_instrument_type.rb +2 -1
- data/lib/braintree/payment_method_gateway.rb +14 -0
- data/lib/braintree/payment_method_nonce.rb +2 -0
- data/lib/braintree/payment_method_nonce_gateway.rb +13 -2
- data/lib/braintree/payment_method_parser.rb +1 -0
- data/lib/braintree/risk_data.rb +4 -1
- data/lib/braintree/test/authentication_id.rb +21 -0
- data/lib/braintree/test/credit_card.rb +1 -0
- data/lib/braintree/test/nonce.rb +18 -0
- data/lib/braintree/three_d_secure_info.rb +2 -0
- data/lib/braintree/transaction.rb +15 -1
- data/lib/braintree/transaction/address_details.rb +11 -0
- data/lib/braintree/transaction/android_pay_details.rb +5 -0
- data/lib/braintree/transaction/apple_pay_details.rb +1 -0
- data/lib/braintree/transaction/masterpass_card_details.rb +2 -0
- data/lib/braintree/transaction/paypal_details.rb +2 -0
- data/lib/braintree/transaction_gateway.rb +12 -3
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree/webhook_notification.rb +3 -0
- data/lib/braintree/webhook_testing_gateway.rb +243 -0
- data/spec/integration/braintree/client_api/spec_helper.rb +98 -46
- data/spec/integration/braintree/credit_card_spec.rb +135 -2
- data/spec/integration/braintree/credit_card_verification_spec.rb +2 -0
- data/spec/integration/braintree/customer_spec.rb +116 -0
- data/spec/integration/braintree/dispute_search_spec.rb +1 -1
- data/spec/integration/braintree/dispute_spec.rb +1 -0
- data/spec/integration/braintree/document_upload_spec.rb +12 -0
- data/spec/integration/braintree/merchant_spec.rb +2 -2
- data/spec/integration/braintree/payment_method_nonce_spec.rb +83 -2
- data/spec/integration/braintree/payment_method_spec.rb +113 -18
- data/spec/integration/braintree/paypal_account_spec.rb +1 -1
- data/spec/integration/braintree/transaction_spec.rb +437 -45
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/braintree/credit_card_spec.rb +51 -3
- data/spec/unit/braintree/credit_card_verification_spec.rb +7 -0
- data/spec/unit/braintree/customer_spec.rb +28 -2
- data/spec/unit/braintree/dispute_spec.rb +3 -0
- data/spec/unit/braintree/three_d_secure_info_spec.rb +3 -1
- data/spec/unit/braintree/transaction/paypal_details_spec.rb +57 -0
- data/spec/unit/braintree/transaction_spec.rb +16 -2
- data/spec/unit/braintree/webhook_notification_spec.rb +48 -0
- metadata +5 -3
@@ -186,6 +186,7 @@ describe Braintree::Dispute do
|
|
186
186
|
dispute.amount_disputed.should == 31.0
|
187
187
|
dispute.amount_won.should == 0.0
|
188
188
|
dispute.id.should == "open_dispute"
|
189
|
+
dispute.graphql_id.should_not be_nil
|
189
190
|
dispute.status.should == Braintree::Dispute::Status::Open
|
190
191
|
dispute.transaction.amount.should == 31.0
|
191
192
|
dispute.transaction.id.should == "open_disputed_transaction"
|
@@ -46,6 +46,18 @@ describe Braintree::DocumentUploadGateway do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
it "returns file is empty error with empty file" do
|
50
|
+
filename = "#{File.dirname(__FILE__)}/../../fixtures/files/empty_file.png"
|
51
|
+
begin
|
52
|
+
File.open(filename, "w+") {}
|
53
|
+
file = File.new(filename, "r")
|
54
|
+
response = Braintree::DocumentUpload.create({:kind => Braintree::DocumentUpload::Kind::EvidenceDocument, :file => file})
|
55
|
+
response.errors.for(:document_upload).first.code.should == Braintree::ErrorCodes::DocumentUpload::FileIsEmpty
|
56
|
+
ensure
|
57
|
+
File.delete(filename)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
49
61
|
it "returns file too long error with file over 50 pages" do
|
50
62
|
filename = "#{File.dirname(__FILE__)}/../../fixtures/files/too_long.pdf"
|
51
63
|
file = File.new(filename, "r")
|
@@ -305,7 +305,7 @@ describe Braintree::MerchantGateway do
|
|
305
305
|
it "succeeds" do
|
306
306
|
result = Braintree::Merchant.provision_raw_apple_pay
|
307
307
|
result.should be_success
|
308
|
-
result.supported_networks.should == ["visa", "mastercard", "amex", "discover"]
|
308
|
+
result.supported_networks.should == ["visa", "mastercard", "amex", "discover", "maestro"]
|
309
309
|
end
|
310
310
|
|
311
311
|
it "is repeatable" do
|
@@ -313,7 +313,7 @@ describe Braintree::MerchantGateway do
|
|
313
313
|
result.should be_success
|
314
314
|
result = Braintree::Merchant.provision_raw_apple_pay
|
315
315
|
result.should be_success
|
316
|
-
result.supported_networks.should == ["visa", "mastercard", "amex", "discover"]
|
316
|
+
result.supported_networks.should == ["visa", "mastercard", "amex", "discover", "maestro"]
|
317
317
|
end
|
318
318
|
end
|
319
319
|
|
@@ -84,10 +84,14 @@ describe Braintree::PaymentMethodNonce do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it "return paypal details if details exist" do
|
87
|
-
result = Braintree::PaymentMethodNonce.find("fake-
|
88
|
-
|
87
|
+
result = Braintree::PaymentMethodNonce.find("fake-paypal-one-time-nonce")
|
89
88
|
nonce = result.payment_method_nonce
|
90
89
|
|
90
|
+
nonce.details.fetch(:cobranded_card_label).should_not be_nil
|
91
|
+
nonce.details.fetch(:shipping_option_id).should_not be_nil
|
92
|
+
nonce.details.fetch(:billing_address).fetch(:recipient_name).should_not be_nil
|
93
|
+
nonce.details.fetch(:shipping_address).fetch(:recipient_name).should_not be_nil
|
94
|
+
|
91
95
|
nonce.details.fetch(:payer_info).fetch(:first_name).should_not be_nil
|
92
96
|
nonce.details.fetch(:payer_info).fetch(:last_name).should_not be_nil
|
93
97
|
nonce.details.fetch(:payer_info).fetch(:email).should_not be_nil
|
@@ -235,5 +239,82 @@ describe Braintree::PaymentMethodNonce do
|
|
235
239
|
Braintree::PaymentMethodNonce.find("not_a_nonce")
|
236
240
|
end.to raise_error(Braintree::NotFoundError)
|
237
241
|
end
|
242
|
+
|
243
|
+
context "authentication insights" do
|
244
|
+
let(:indian_payment_token) { "india_visa_credit" }
|
245
|
+
let(:european_payment_token) { "european_visa_credit" }
|
246
|
+
let(:indian_merchant_token) { "india_three_d_secure_merchant_account" }
|
247
|
+
let(:european_merchant_token) { "european_three_d_secure_merchant_account" }
|
248
|
+
|
249
|
+
describe "self.create" do
|
250
|
+
it "raises an exception if hash includes an invalid key" do
|
251
|
+
expect do
|
252
|
+
Braintree::PaymentMethodNonce.create("european_visa_credit", :invalid_key => "foo")
|
253
|
+
end.to raise_error(ArgumentError, "invalid keys: invalid_key")
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context "regulation environments" do
|
258
|
+
it "can get unregulated" do
|
259
|
+
expect(
|
260
|
+
request_authentication_insights(european_merchant_token, indian_payment_token)[:regulation_environment]
|
261
|
+
).to eq "unregulated"
|
262
|
+
end
|
263
|
+
|
264
|
+
it "can get psd2" do
|
265
|
+
expect(
|
266
|
+
request_authentication_insights(european_merchant_token, european_payment_token)[:regulation_environment]
|
267
|
+
).to eq "psd2"
|
268
|
+
end
|
269
|
+
|
270
|
+
it "can get rbi" do
|
271
|
+
expect(
|
272
|
+
request_authentication_insights(indian_merchant_token, indian_payment_token)[:regulation_environment]
|
273
|
+
).to eq "rbi"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context "sca_indicator" do
|
278
|
+
it "can get unavailable" do
|
279
|
+
expect(
|
280
|
+
request_authentication_insights(indian_merchant_token, indian_payment_token)[:sca_indicator]
|
281
|
+
).to eq "unavailable"
|
282
|
+
end
|
283
|
+
|
284
|
+
it "can get sca_required" do
|
285
|
+
expect(
|
286
|
+
request_authentication_insights(indian_merchant_token, indian_payment_token, {amount: 2001})[:sca_indicator]
|
287
|
+
).to eq "sca_required"
|
288
|
+
end
|
289
|
+
|
290
|
+
it "can get sca_optional" do
|
291
|
+
expect(
|
292
|
+
request_authentication_insights(indian_merchant_token, indian_payment_token, {amount: 2000, recurring_customer_consent: true, recurring_max_amount: 2000})[:sca_indicator]
|
293
|
+
|
294
|
+
).to eq "sca_optional"
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def request_authentication_insights(merchant_token, payment_method_token, options = {})
|
299
|
+
authentication_insight_options = {
|
300
|
+
amount: options[:amount],
|
301
|
+
recurring_customer_consent: options[:recurring_customer_consent],
|
302
|
+
recurring_max_amount: options[:recurring_max_amount],
|
303
|
+
}
|
304
|
+
nonce_request = {
|
305
|
+
merchant_account_id: merchant_token,
|
306
|
+
authentication_insight: true,
|
307
|
+
authentication_insight_options: authentication_insight_options,
|
308
|
+
}
|
309
|
+
|
310
|
+
result = Braintree::PaymentMethodNonce.create(
|
311
|
+
payment_method_token,
|
312
|
+
payment_method_nonce: nonce_request
|
313
|
+
)
|
314
|
+
result.should be_success
|
315
|
+
|
316
|
+
return result.payment_method_nonce.authentication_insight
|
317
|
+
end
|
318
|
+
end
|
238
319
|
end
|
239
320
|
end
|
@@ -121,6 +121,7 @@ describe Braintree::PaymentMethod do
|
|
121
121
|
android_pay_card.expiration_year.to_i.should > 0
|
122
122
|
android_pay_card.default.should == true
|
123
123
|
android_pay_card.image_url.should =~ /android_pay/
|
124
|
+
android_pay_card.is_network_tokenized?.should == false
|
124
125
|
android_pay_card.source_card_type.should == Braintree::CreditCard::CardType::Discover
|
125
126
|
android_pay_card.source_card_last_4.should == "1111"
|
126
127
|
android_pay_card.google_transaction_id.should == "google_transaction_id"
|
@@ -148,6 +149,7 @@ describe Braintree::PaymentMethod do
|
|
148
149
|
android_pay_card.expiration_year.to_i.should > 0
|
149
150
|
android_pay_card.default.should == true
|
150
151
|
android_pay_card.image_url.should =~ /android_pay/
|
152
|
+
android_pay_card.is_network_tokenized?.should == true
|
151
153
|
android_pay_card.source_card_type.should == Braintree::CreditCard::CardType::MasterCard
|
152
154
|
android_pay_card.source_card_last_4.should == "4444"
|
153
155
|
android_pay_card.google_transaction_id.should == "google_transaction_id"
|
@@ -298,6 +300,50 @@ describe Braintree::PaymentMethod do
|
|
298
300
|
result.credit_card_verification.amount.should == BigDecimal("100.00")
|
299
301
|
end
|
300
302
|
|
303
|
+
it "validates presence of three_d_secure_version in 3ds pass thru params" do
|
304
|
+
customer = Braintree::Customer.create!
|
305
|
+
result = Braintree::PaymentMethod.create(
|
306
|
+
:customer_id => customer.id,
|
307
|
+
:payment_method_nonce => Braintree::Test::Nonce::Transactable,
|
308
|
+
:three_d_secure_pass_thru => {
|
309
|
+
:eci_flag => '02',
|
310
|
+
:cavv => 'some_cavv',
|
311
|
+
:xid => 'some_xid',
|
312
|
+
:three_d_secure_version => 'xx',
|
313
|
+
:authentication_response => 'Y',
|
314
|
+
:directory_response => 'Y',
|
315
|
+
:cavv_algorithm => '2',
|
316
|
+
:ds_transaction_id => 'some_ds_transaction_id',
|
317
|
+
},
|
318
|
+
:options => {:verify_card => true}
|
319
|
+
)
|
320
|
+
expect(result).not_to be_success
|
321
|
+
error = result.errors.for(:verification).first
|
322
|
+
expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsInvalid)
|
323
|
+
expect(error.message).to eq("The version of 3D Secure authentication must be composed only of digits and separated by periods (e.g. `1.0.2`).")
|
324
|
+
end
|
325
|
+
|
326
|
+
it "accepts three_d_secure pass thru params in the request" do
|
327
|
+
customer = Braintree::Customer.create!
|
328
|
+
result = Braintree::PaymentMethod.create(
|
329
|
+
:customer_id => customer.id,
|
330
|
+
:payment_method_nonce => Braintree::Test::Nonce::Transactable,
|
331
|
+
:three_d_secure_pass_thru => {
|
332
|
+
:eci_flag => '02',
|
333
|
+
:cavv => 'some_cavv',
|
334
|
+
:xid => 'some_xid',
|
335
|
+
:three_d_secure_version => '1.0.2',
|
336
|
+
:authentication_response => 'Y',
|
337
|
+
:directory_response => 'Y',
|
338
|
+
:cavv_algorithm => '2',
|
339
|
+
:ds_transaction_id => 'some_ds_transaction_id',
|
340
|
+
},
|
341
|
+
:options => {:verify_card => true}
|
342
|
+
)
|
343
|
+
|
344
|
+
expect(result).to be_success
|
345
|
+
end
|
346
|
+
|
301
347
|
it "returns 3DS info on cc verification" do
|
302
348
|
customer = Braintree::Customer.create.customer
|
303
349
|
result = Braintree::PaymentMethod.create(
|
@@ -727,24 +773,6 @@ describe Braintree::PaymentMethod do
|
|
727
773
|
found_paypal_account.payer_id.should_not be_nil
|
728
774
|
end
|
729
775
|
|
730
|
-
it "creates a billing agreement payment method from a refresh token without upgrading" do
|
731
|
-
customer = Braintree::Customer.create.customer
|
732
|
-
result = Braintree::PaymentMethod.create(
|
733
|
-
:customer_id => customer.id,
|
734
|
-
:paypal_refresh_token => "some_future_payment_token",
|
735
|
-
:paypal_vault_without_upgrade => true,
|
736
|
-
)
|
737
|
-
|
738
|
-
result.should be_success
|
739
|
-
result.payment_method.should be_a(Braintree::PayPalAccount)
|
740
|
-
result.payment_method.billing_agreement_id.should be_nil
|
741
|
-
token = result.payment_method.token
|
742
|
-
|
743
|
-
found_paypal_account = Braintree::PayPalAccount.find(token)
|
744
|
-
found_paypal_account.should_not be_nil
|
745
|
-
found_paypal_account.billing_agreement_id.should be_nil
|
746
|
-
end
|
747
|
-
|
748
776
|
it "does not create a payment method from an unvalidated onetime paypal account nonce" do
|
749
777
|
customer = Braintree::Customer.create.customer
|
750
778
|
nonce = nonce_for_paypal_account(:access_token => "PAYPAL_ACCESS_TOKEN")
|
@@ -1017,6 +1045,7 @@ describe Braintree::PaymentMethod do
|
|
1017
1045
|
android_pay_card.expiration_year.to_i.should > 0
|
1018
1046
|
android_pay_card.default.should == true
|
1019
1047
|
android_pay_card.image_url.should =~ /android_pay/
|
1048
|
+
android_pay_card.is_network_tokenized?.should == false
|
1020
1049
|
android_pay_card.source_card_type.should == Braintree::CreditCard::CardType::Discover
|
1021
1050
|
android_pay_card.source_card_last_4.should == "1111"
|
1022
1051
|
android_pay_card.google_transaction_id.should == "google_transaction_id"
|
@@ -1044,6 +1073,7 @@ describe Braintree::PaymentMethod do
|
|
1044
1073
|
android_pay_card.expiration_year.to_i.should > 0
|
1045
1074
|
android_pay_card.default.should == true
|
1046
1075
|
android_pay_card.image_url.should =~ /android_pay/
|
1076
|
+
android_pay_card.is_network_tokenized?.should == true
|
1047
1077
|
android_pay_card.source_card_type.should == Braintree::CreditCard::CardType::MasterCard
|
1048
1078
|
android_pay_card.source_card_last_4.should == "4444"
|
1049
1079
|
android_pay_card.google_transaction_id.should == "google_transaction_id"
|
@@ -1183,6 +1213,71 @@ describe Braintree::PaymentMethod do
|
|
1183
1213
|
|
1184
1214
|
describe "self.update" do
|
1185
1215
|
context "credit cards" do
|
1216
|
+
it "throws validation error when passing invalid pass thru params" do
|
1217
|
+
customer = Braintree::Customer.create!
|
1218
|
+
credit_card = Braintree::CreditCard.create!(
|
1219
|
+
:customer_id => customer.id,
|
1220
|
+
:payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
|
1221
|
+
:options => {:verify_card => true},
|
1222
|
+
)
|
1223
|
+
|
1224
|
+
update_result = Braintree::PaymentMethod.update(credit_card.token,
|
1225
|
+
:cardholder_name => "New Holder",
|
1226
|
+
:cvv => "456",
|
1227
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
1228
|
+
:expiration_date => "06/2013",
|
1229
|
+
:three_d_secure_pass_thru => {
|
1230
|
+
:eci_flag => '02',
|
1231
|
+
:cavv => 'some_cavv',
|
1232
|
+
:xid => 'some_xid',
|
1233
|
+
:three_d_secure_version => 'xx',
|
1234
|
+
:authentication_response => 'Y',
|
1235
|
+
:directory_response => 'Y',
|
1236
|
+
:cavv_algorithm => '2',
|
1237
|
+
:ds_transaction_id => 'some_ds_transaction_id',
|
1238
|
+
},
|
1239
|
+
:options => {:verify_card => true},
|
1240
|
+
)
|
1241
|
+
expect(update_result).to_not be_success
|
1242
|
+
error = update_result.errors.for(:verification).first
|
1243
|
+
expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsInvalid)
|
1244
|
+
expect(error.message).to eq("The version of 3D Secure authentication must be composed only of digits and separated by periods (e.g. `1.0.2`).")
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
it "updates the credit card with three_d_secure pass thru params" do
|
1248
|
+
customer = Braintree::Customer.create!
|
1249
|
+
credit_card = Braintree::CreditCard.create!(
|
1250
|
+
:customer_id => customer.id,
|
1251
|
+
:payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
|
1252
|
+
:options => {:verify_card => true},
|
1253
|
+
)
|
1254
|
+
|
1255
|
+
update_result = Braintree::PaymentMethod.update(credit_card.token,
|
1256
|
+
:cardholder_name => "New Holder",
|
1257
|
+
:cvv => "456",
|
1258
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
1259
|
+
:expiration_date => "06/2013",
|
1260
|
+
:three_d_secure_pass_thru => {
|
1261
|
+
:eci_flag => '02',
|
1262
|
+
:cavv => 'some_cavv',
|
1263
|
+
:xid => 'some_xid',
|
1264
|
+
:three_d_secure_version => '1.0.2',
|
1265
|
+
:authentication_response => 'Y',
|
1266
|
+
:directory_response => 'Y',
|
1267
|
+
:cavv_algorithm => '2',
|
1268
|
+
:ds_transaction_id => 'some_ds_transaction_id',
|
1269
|
+
},
|
1270
|
+
:options => {:verify_card => true},
|
1271
|
+
)
|
1272
|
+
update_result.success?.should == true
|
1273
|
+
update_result.payment_method.should == credit_card
|
1274
|
+
updated_credit_card = update_result.payment_method
|
1275
|
+
updated_credit_card.cardholder_name.should == "New Holder"
|
1276
|
+
updated_credit_card.bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
|
1277
|
+
updated_credit_card.last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
|
1278
|
+
updated_credit_card.expiration_date.should == "06/2013"
|
1279
|
+
end
|
1280
|
+
|
1186
1281
|
it "updates the credit card" do
|
1187
1282
|
customer = Braintree::Customer.create!
|
1188
1283
|
credit_card = Braintree::CreditCard.create!(
|
@@ -140,6 +140,31 @@ describe Braintree::Transaction do
|
|
140
140
|
result.transaction.risk_data.should respond_to(:fraud_service_provider)
|
141
141
|
end
|
142
142
|
end
|
143
|
+
|
144
|
+
it "handles validation errors for invalid risk data attributes" do
|
145
|
+
with_advanced_fraud_integration_merchant do
|
146
|
+
result = Braintree::Transaction.create(
|
147
|
+
:type => "sale",
|
148
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
149
|
+
:credit_card => {
|
150
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
151
|
+
:expiration_date => "05/2009"
|
152
|
+
},
|
153
|
+
:risk_data => {
|
154
|
+
:customer_browser => "#{"1" * 300}",
|
155
|
+
:customer_device_id => "customer_device_id_0#{"1" * 300}",
|
156
|
+
:customer_ip => "192.168.0.1",
|
157
|
+
:customer_location_zip => "not-a-$#phone",
|
158
|
+
:customer_tenure => "20#{"0" * 500}"
|
159
|
+
}
|
160
|
+
)
|
161
|
+
result.success?.should == false
|
162
|
+
result.errors.for(:transaction).for(:risk_data).on(:customer_browser).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerBrowserIsTooLong
|
163
|
+
result.errors.for(:transaction).for(:risk_data).on(:customer_device_id).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerDeviceIdIsTooLong
|
164
|
+
result.errors.for(:transaction).for(:risk_data).on(:customer_location_zip).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerLocationZipInvalidCharacters
|
165
|
+
result.errors.for(:transaction).for(:risk_data).on(:customer_tenure).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerTenureIsTooLong
|
166
|
+
end
|
167
|
+
end
|
143
168
|
end
|
144
169
|
|
145
170
|
describe "card type indicators" do
|
@@ -419,6 +444,7 @@ describe Braintree::Transaction do
|
|
419
444
|
result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
|
420
445
|
result.transaction.credit_card_details.expiration_date.should == "05/2009"
|
421
446
|
result.transaction.credit_card_details.customer_location.should == "US"
|
447
|
+
result.transaction.retrieval_reference_number.should_not be_nil
|
422
448
|
end
|
423
449
|
|
424
450
|
it "returns a successful network response code if successful" do
|
@@ -498,7 +524,7 @@ describe Braintree::Transaction do
|
|
498
524
|
result.success?.should == true
|
499
525
|
end
|
500
526
|
|
501
|
-
it "accepts additional security parameters: risk data
|
527
|
+
it "accepts additional security parameters: risk data" do
|
502
528
|
result = Braintree::Transaction.create(
|
503
529
|
:type => "sale",
|
504
530
|
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
@@ -508,7 +534,10 @@ describe Braintree::Transaction do
|
|
508
534
|
},
|
509
535
|
:risk_data => {
|
510
536
|
:customer_browser => "IE6",
|
511
|
-
:
|
537
|
+
:customer_device_id => "customer_device_id_012",
|
538
|
+
:customer_ip => "192.168.0.1",
|
539
|
+
:customer_location_zip => "91244",
|
540
|
+
:customer_tenure => "20",
|
512
541
|
}
|
513
542
|
)
|
514
543
|
|
@@ -687,6 +716,68 @@ describe Braintree::Transaction do
|
|
687
716
|
codes.should include(Braintree::ErrorCodes::Address::CountryCodeNumericIsNotAccepted)
|
688
717
|
end
|
689
718
|
|
719
|
+
it "returns an error if provided product sku is invalid" do
|
720
|
+
result = Braintree::Transaction.sale(
|
721
|
+
:amount => "100",
|
722
|
+
:credit_card => {
|
723
|
+
:number => "5105105105105100",
|
724
|
+
:expiration_date => "05/2012"
|
725
|
+
},
|
726
|
+
:product_sku => "product$ku!",
|
727
|
+
)
|
728
|
+
|
729
|
+
result.success?.should == false
|
730
|
+
result.errors.for(:transaction).on(:product_sku).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ProductSkuIsInvalid)
|
731
|
+
end
|
732
|
+
|
733
|
+
it "returns an error if provided shipping phone number is invalid" do
|
734
|
+
result = Braintree::Transaction.sale(
|
735
|
+
:amount => "100",
|
736
|
+
:credit_card => {
|
737
|
+
:number => "5105105105105100",
|
738
|
+
:expiration_date => "05/2012"
|
739
|
+
},
|
740
|
+
:shipping => {
|
741
|
+
:phone_number => "123-234-3456=098765"
|
742
|
+
}
|
743
|
+
)
|
744
|
+
|
745
|
+
result.success?.should == false
|
746
|
+
result.errors.for(:transaction).for(:shipping).on(:phone_number).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ShippingPhoneNumberIsInvalid)
|
747
|
+
end
|
748
|
+
|
749
|
+
it "returns an error if provided shipping method is invalid" do
|
750
|
+
result = Braintree::Transaction.sale(
|
751
|
+
:amount => "100",
|
752
|
+
:credit_card => {
|
753
|
+
:number => "5105105105105100",
|
754
|
+
:expiration_date => "05/2012"
|
755
|
+
},
|
756
|
+
:shipping => {
|
757
|
+
:shipping_method => "urgent"
|
758
|
+
}
|
759
|
+
)
|
760
|
+
|
761
|
+
result.success?.should == false
|
762
|
+
result.errors.for(:transaction).for(:shipping).on(:shipping_method).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ShippingMethodIsInvalid)
|
763
|
+
end
|
764
|
+
|
765
|
+
it "returns an error if provided billing phone number is invalid" do
|
766
|
+
result = Braintree::Transaction.sale(
|
767
|
+
:amount => "100",
|
768
|
+
:credit_card => {
|
769
|
+
:number => "5105105105105100",
|
770
|
+
:expiration_date => "05/2012"
|
771
|
+
},
|
772
|
+
:billing => {
|
773
|
+
:phone_number => "123-234-3456=098765"
|
774
|
+
}
|
775
|
+
)
|
776
|
+
|
777
|
+
result.success?.should == false
|
778
|
+
result.errors.for(:transaction).for(:billing).on(:phone_number).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::BillingPhoneNumberIsInvalid)
|
779
|
+
end
|
780
|
+
|
690
781
|
context "gateway rejection reason" do
|
691
782
|
it "exposes the cvv gateway rejection reason" do
|
692
783
|
old_merchant = Braintree::Configuration.merchant_id
|
@@ -804,16 +895,44 @@ describe Braintree::Transaction do
|
|
804
895
|
end
|
805
896
|
|
806
897
|
it "exposes the fraud gateway rejection reason" do
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
:
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
898
|
+
with_advanced_fraud_integration_merchant do
|
899
|
+
result = Braintree::Transaction.sale(
|
900
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
901
|
+
:credit_card => {
|
902
|
+
:number => Braintree::Test::CreditCardNumbers::Fraud,
|
903
|
+
:expiration_date => "05/2017",
|
904
|
+
:cvv => "333"
|
905
|
+
}
|
906
|
+
)
|
907
|
+
result.success?.should == false
|
908
|
+
result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::Fraud
|
909
|
+
end
|
910
|
+
end
|
911
|
+
|
912
|
+
it "exposes the risk_threshold gateway rejection reason (via test cc num)" do
|
913
|
+
with_advanced_fraud_integration_merchant do
|
914
|
+
result = Braintree::Transaction.sale(
|
915
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
916
|
+
:credit_card => {
|
917
|
+
:number => Braintree::Test::CreditCardNumbers::RiskThreshold,
|
918
|
+
:expiration_date => "05/2017",
|
919
|
+
:cvv => "333"
|
920
|
+
}
|
921
|
+
)
|
922
|
+
result.success?.should == false
|
923
|
+
result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::RiskThreshold
|
924
|
+
end
|
925
|
+
end
|
926
|
+
|
927
|
+
it "exposes the risk_threshold gateway rejection reason (via test test nonce)" do
|
928
|
+
with_advanced_fraud_integration_merchant do
|
929
|
+
result = Braintree::Transaction.sale(
|
930
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
931
|
+
:payment_method_nonce => Braintree::Test::Nonce::GatewayRejectedRiskThresholds,
|
932
|
+
)
|
933
|
+
result.success?.should == false
|
934
|
+
result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::RiskThreshold
|
935
|
+
end
|
817
936
|
end
|
818
937
|
|
819
938
|
it "exposes the token issuance gateway rejection reason" do
|
@@ -1645,6 +1764,7 @@ describe Braintree::Transaction do
|
|
1645
1764
|
result.transaction.should_not be_nil
|
1646
1765
|
apple_pay_details = result.transaction.apple_pay_details
|
1647
1766
|
apple_pay_details.should_not be_nil
|
1767
|
+
apple_pay_details.bin.should_not be_nil
|
1648
1768
|
apple_pay_details.card_type.should == Braintree::ApplePayCard::CardType::Visa
|
1649
1769
|
apple_pay_details.payment_instrument_name.should == "Visa 8886"
|
1650
1770
|
apple_pay_details.source_description.should == "Visa 8886"
|
@@ -1695,6 +1815,7 @@ describe Braintree::Transaction do
|
|
1695
1815
|
result.transaction.should_not be_nil
|
1696
1816
|
android_pay_details = result.transaction.android_pay_details
|
1697
1817
|
android_pay_details.should_not be_nil
|
1818
|
+
android_pay_details.bin.should_not be_nil
|
1698
1819
|
android_pay_details.card_type.should == Braintree::CreditCard::CardType::Discover
|
1699
1820
|
android_pay_details.virtual_card_type.should == Braintree::CreditCard::CardType::Discover
|
1700
1821
|
android_pay_details.last_4.should == "1117"
|
@@ -1704,6 +1825,7 @@ describe Braintree::Transaction do
|
|
1704
1825
|
android_pay_details.expiration_year.to_i.should > 0
|
1705
1826
|
android_pay_details.google_transaction_id.should == "google_transaction_id"
|
1706
1827
|
android_pay_details.image_url.should_not be_nil
|
1828
|
+
android_pay_details.is_network_tokenized?.should == false
|
1707
1829
|
android_pay_details.token.should be_nil
|
1708
1830
|
android_pay_details.prepaid.should_not be_nil
|
1709
1831
|
android_pay_details.healthcare.should_not be_nil
|
@@ -1735,6 +1857,7 @@ describe Braintree::Transaction do
|
|
1735
1857
|
android_pay_details.expiration_year.to_i.should > 0
|
1736
1858
|
android_pay_details.google_transaction_id.should == "google_transaction_id"
|
1737
1859
|
android_pay_details.image_url.should_not be_nil
|
1860
|
+
android_pay_details.is_network_tokenized?.should == false
|
1738
1861
|
android_pay_details.token.should_not be_nil
|
1739
1862
|
end
|
1740
1863
|
|
@@ -1757,6 +1880,7 @@ describe Braintree::Transaction do
|
|
1757
1880
|
android_pay_details.expiration_month.to_i.should > 0
|
1758
1881
|
android_pay_details.expiration_year.to_i.should > 0
|
1759
1882
|
android_pay_details.google_transaction_id.should == "google_transaction_id"
|
1883
|
+
android_pay_details.is_network_tokenized?.should == true
|
1760
1884
|
end
|
1761
1885
|
|
1762
1886
|
it "can create a transaction with a fake amex express checkout card nonce" do
|
@@ -2083,6 +2207,7 @@ describe Braintree::Transaction do
|
|
2083
2207
|
|
2084
2208
|
result = Braintree::Transaction.create(
|
2085
2209
|
:type => "sale",
|
2210
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2086
2211
|
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2087
2212
|
:credit_card => {
|
2088
2213
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
@@ -2119,7 +2244,8 @@ describe Braintree::Transaction do
|
|
2119
2244
|
result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::ThreeDSecure
|
2120
2245
|
end
|
2121
2246
|
|
2122
|
-
|
2247
|
+
|
2248
|
+
it "can create a transaction without a three_d_secure_authentication_id" do
|
2123
2249
|
result = Braintree::Transaction.create(
|
2124
2250
|
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2125
2251
|
:type => "sale",
|
@@ -2132,41 +2258,174 @@ describe Braintree::Transaction do
|
|
2132
2258
|
result.success?.should == true
|
2133
2259
|
end
|
2134
2260
|
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2140
|
-
:credit_card => {
|
2261
|
+
context "with three_d_secure_authentication_id" do
|
2262
|
+
it "can create a transaction with a three_d_secure_authentication_id" do
|
2263
|
+
three_d_secure_authentication_id = SpecHelper.create_3ds_verification(
|
2264
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2141
2265
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2142
|
-
:
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2266
|
+
:expiration_month => "12",
|
2267
|
+
:expiration_year => "2022"
|
2268
|
+
)
|
2269
|
+
|
2270
|
+
result = Braintree::Transaction.create(
|
2271
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2272
|
+
:type => "sale",
|
2273
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2274
|
+
:credit_card => {
|
2275
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2276
|
+
:expiration_date => "12/22",
|
2277
|
+
},
|
2278
|
+
:three_d_secure_authentication_id => three_d_secure_authentication_id
|
2279
|
+
)
|
2280
|
+
|
2281
|
+
result.success?.should == true
|
2282
|
+
end
|
2283
|
+
it "returns an error if sent a nil three_d_secure_authentication_id" do
|
2284
|
+
result = Braintree::Transaction.create(
|
2285
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2286
|
+
:type => "sale",
|
2287
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2288
|
+
:credit_card => {
|
2289
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2290
|
+
:expiration_date => "12/12",
|
2291
|
+
},
|
2292
|
+
:three_d_secure_authentication_id => nil
|
2293
|
+
)
|
2294
|
+
result.success?.should == false
|
2295
|
+
result.errors.for(:transaction).on(:three_d_secure_authentication_id)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureAuthenticationIdIsInvalid
|
2296
|
+
end
|
2297
|
+
it "returns an error if merchant_account in the payment_method does not match with 3ds data" do
|
2298
|
+
three_d_secure_authentication_id = SpecHelper.create_3ds_verification(
|
2299
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2300
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2301
|
+
:expiration_month => "12",
|
2302
|
+
:expiration_year => "2012"
|
2303
|
+
)
|
2304
|
+
|
2305
|
+
result = Braintree::Transaction.create(
|
2306
|
+
:type => "sale",
|
2307
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2308
|
+
:credit_card => {
|
2309
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
2310
|
+
:expiration_date => "12/12",
|
2311
|
+
},
|
2312
|
+
:three_d_secure_authentication_id => three_d_secure_authentication_id
|
2313
|
+
)
|
2314
|
+
result.success?.should == false
|
2315
|
+
result.errors.for(:transaction).on(:three_d_secure_authentication_id)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTransactionPaymentMethodDoesntMatchThreeDSecureAuthenticationPaymentMethod
|
2316
|
+
end
|
2317
|
+
it "returns an error if 3ds lookup data does not match txn data" do
|
2318
|
+
three_d_secure_authentication_id = SpecHelper.create_3ds_verification(
|
2319
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2320
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2321
|
+
:expiration_month => "12",
|
2322
|
+
:expiration_year => "2012"
|
2323
|
+
)
|
2324
|
+
|
2325
|
+
result = Braintree::Transaction.create(
|
2326
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2327
|
+
:type => "sale",
|
2328
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2329
|
+
:credit_card => {
|
2330
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
2331
|
+
:expiration_date => "12/12",
|
2332
|
+
},
|
2333
|
+
:three_d_secure_authentication_id => three_d_secure_authentication_id
|
2334
|
+
)
|
2335
|
+
result.success?.should == false
|
2336
|
+
result.errors.for(:transaction).on(:three_d_secure_authentication_id)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTransactionPaymentMethodDoesntMatchThreeDSecureAuthenticationPaymentMethod
|
2337
|
+
end
|
2338
|
+
it "returns an error if three_d_secure_authentication_id is supplied with three_d_secure_pass_thru" do
|
2339
|
+
three_d_secure_authentication_id = SpecHelper.create_3ds_verification(
|
2340
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2341
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2342
|
+
:expiration_month => "12",
|
2343
|
+
:expiration_year => "2012"
|
2344
|
+
)
|
2345
|
+
result = Braintree::Transaction.create(
|
2346
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2347
|
+
:type => "sale",
|
2348
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2349
|
+
:credit_card => {
|
2350
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2351
|
+
:expiration_date => "12/12",
|
2352
|
+
},
|
2353
|
+
:three_d_secure_authentication_id => three_d_secure_authentication_id,
|
2354
|
+
:three_d_secure_pass_thru => {
|
2355
|
+
:eci_flag => "02",
|
2356
|
+
:cavv => "some_cavv",
|
2357
|
+
:xid => "some_xid",
|
2358
|
+
:three_d_secure_version => "1.0.2",
|
2359
|
+
:authentication_response => "Y",
|
2360
|
+
:directory_response => "Y",
|
2361
|
+
:cavv_algorithm => "2",
|
2362
|
+
:ds_transaction_id => "some_ds_id",
|
2363
|
+
}
|
2364
|
+
)
|
2365
|
+
result.success?.should == false
|
2366
|
+
result.errors.for(:transaction).on(:three_d_secure_authentication_id)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureAuthenticationIdWithThreeDSecurePassThruIsInvalid
|
2367
|
+
end
|
2148
2368
|
end
|
2149
2369
|
|
2150
|
-
|
2151
|
-
|
2152
|
-
SpecHelper
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2370
|
+
context "with three_d_secure_token" do
|
2371
|
+
it "can create a transaction with a three_d_secure token" do
|
2372
|
+
three_d_secure_token = SpecHelper.create_3ds_verification(
|
2373
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2374
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2375
|
+
:expiration_month => "12",
|
2376
|
+
:expiration_year => "2012"
|
2377
|
+
)
|
2157
2378
|
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
|
2379
|
+
result = Braintree::Transaction.create(
|
2380
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2381
|
+
:type => "sale",
|
2382
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2383
|
+
:credit_card => {
|
2384
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2385
|
+
:expiration_date => "12/12",
|
2386
|
+
},
|
2387
|
+
:three_d_secure_token => three_d_secure_token
|
2388
|
+
)
|
2389
|
+
|
2390
|
+
result.success?.should == true
|
2391
|
+
end
|
2392
|
+
|
2393
|
+
it "returns an error if sent a nil three_d_secure token" do
|
2394
|
+
result = Braintree::Transaction.create(
|
2395
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2396
|
+
:type => "sale",
|
2397
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2398
|
+
:credit_card => {
|
2399
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2400
|
+
:expiration_date => "12/12",
|
2401
|
+
},
|
2402
|
+
:three_d_secure_token => nil
|
2403
|
+
)
|
2404
|
+
result.success?.should == false
|
2405
|
+
result.errors.for(:transaction).on(:three_d_secure_token)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTokenIsInvalid
|
2406
|
+
end
|
2407
|
+
|
2408
|
+
it "returns an error if 3ds lookup data does not match txn data" do
|
2409
|
+
three_d_secure_token = SpecHelper.create_3ds_verification(
|
2410
|
+
SpecHelper::ThreeDSecureMerchantAccountId,
|
2411
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
2412
|
+
:expiration_month => "12",
|
2413
|
+
:expiration_year => "2012"
|
2414
|
+
)
|
2415
|
+
|
2416
|
+
result = Braintree::Transaction.create(
|
2417
|
+
:merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
|
2418
|
+
:type => "sale",
|
2419
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
2420
|
+
:credit_card => {
|
2421
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
2422
|
+
:expiration_date => "12/12",
|
2423
|
+
},
|
2424
|
+
:three_d_secure_token => three_d_secure_token
|
2425
|
+
)
|
2426
|
+
result.success?.should == false
|
2427
|
+
result.errors.for(:transaction).on(:three_d_secure_token)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTransactionDataDoesntMatchVerify
|
2428
|
+
end
|
2170
2429
|
end
|
2171
2430
|
|
2172
2431
|
it "can create a transaction with a three_d_secure_pass_thru" do
|
@@ -2630,6 +2889,36 @@ describe Braintree::Transaction do
|
|
2630
2889
|
result.success?.should == false
|
2631
2890
|
result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::CannotRefundUnlessSettled
|
2632
2891
|
end
|
2892
|
+
|
2893
|
+
it "handles soft declined refund authorizations" do
|
2894
|
+
transaction = Braintree::Transaction.sale!(
|
2895
|
+
:amount => "9000.00",
|
2896
|
+
:payment_method_nonce => Braintree::Test::Nonce::Transactable,
|
2897
|
+
:options => {
|
2898
|
+
:submit_for_settlement => true
|
2899
|
+
}
|
2900
|
+
)
|
2901
|
+
config = Braintree::Configuration.instantiate
|
2902
|
+
response = config.http.put("#{config.base_merchant_path}/transactions/#{transaction.id}/settle")
|
2903
|
+
result = Braintree::Transaction.refund(transaction.id, :amount => "2046.00")
|
2904
|
+
result.success?.should == false
|
2905
|
+
result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::RefundAuthSoftDeclined
|
2906
|
+
end
|
2907
|
+
|
2908
|
+
it "handles hard declined refund authorizations" do
|
2909
|
+
transaction = Braintree::Transaction.sale!(
|
2910
|
+
:amount => "9000.00",
|
2911
|
+
:payment_method_nonce => Braintree::Test::Nonce::Transactable,
|
2912
|
+
:options => {
|
2913
|
+
:submit_for_settlement => true
|
2914
|
+
}
|
2915
|
+
)
|
2916
|
+
config = Braintree::Configuration.instantiate
|
2917
|
+
response = config.http.put("#{config.base_merchant_path}/transactions/#{transaction.id}/settle")
|
2918
|
+
result = Braintree::Transaction.refund(transaction.id, :amount => "2009.00")
|
2919
|
+
result.success?.should == false
|
2920
|
+
result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::RefundAuthHardDeclined
|
2921
|
+
end
|
2633
2922
|
end
|
2634
2923
|
|
2635
2924
|
context "handling errors" do
|
@@ -4365,6 +4654,7 @@ describe Braintree::Transaction do
|
|
4365
4654
|
result = Braintree::Transaction.sale(
|
4366
4655
|
:amount => "100.00",
|
4367
4656
|
:order_id => "123",
|
4657
|
+
:product_sku => "productsku01",
|
4368
4658
|
:channel => "MyShoppingCartProvider",
|
4369
4659
|
:credit_card => {
|
4370
4660
|
:cardholder_name => "The Cardholder",
|
@@ -4389,6 +4679,7 @@ describe Braintree::Transaction do
|
|
4389
4679
|
:extended_address => "Suite 403",
|
4390
4680
|
:locality => "Chicago",
|
4391
4681
|
:region => "IL",
|
4682
|
+
:phone_number => "122-555-1237",
|
4392
4683
|
:postal_code => "60622",
|
4393
4684
|
:country_name => "United States of America"
|
4394
4685
|
},
|
@@ -4400,8 +4691,10 @@ describe Braintree::Transaction do
|
|
4400
4691
|
:extended_address => "Apt 2F",
|
4401
4692
|
:locality => "Bartlett",
|
4402
4693
|
:region => "IL",
|
4694
|
+
:phone_number => "122-555-1236",
|
4403
4695
|
:postal_code => "60103",
|
4404
|
-
:country_name => "United States of America"
|
4696
|
+
:country_name => "United States of America",
|
4697
|
+
:shipping_method => Braintree::Transaction::AddressDetails::ShippingMethod::Electronic
|
4405
4698
|
}
|
4406
4699
|
)
|
4407
4700
|
result.success?.should == true
|
@@ -5086,6 +5379,71 @@ describe Braintree::Transaction do
|
|
5086
5379
|
result.errors.for(:transaction).on(:amount)[0].code.should == Braintree::ErrorCodes::Transaction::SettlementAmountIsLessThanServiceFeeAmount
|
5087
5380
|
end
|
5088
5381
|
end
|
5382
|
+
|
5383
|
+
it "succeeds when level 2 data is provided" do
|
5384
|
+
result = Braintree::Transaction.sale(
|
5385
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
5386
|
+
:merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
|
5387
|
+
:credit_card => {
|
5388
|
+
:number => Braintree::Test::CreditCardNumbers::AmexPayWithPoints::Success,
|
5389
|
+
:expiration_date => "05/2009"
|
5390
|
+
},
|
5391
|
+
:options => {
|
5392
|
+
:amex_rewards => {
|
5393
|
+
:request_id => "ABC123",
|
5394
|
+
:points => "1000",
|
5395
|
+
:currency_amount => "10.00",
|
5396
|
+
:currency_iso_code => "USD"
|
5397
|
+
}
|
5398
|
+
}
|
5399
|
+
)
|
5400
|
+
result.success?.should == true
|
5401
|
+
|
5402
|
+
result = Braintree::Transaction.submit_for_settlement(result.transaction.id, nil, :tax_amount => "2.00", :tax_exempt => false, :purchase_order_number => "0Rd3r#")
|
5403
|
+
result.success?.should == true
|
5404
|
+
result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
|
5405
|
+
end
|
5406
|
+
|
5407
|
+
it "succeeds when level 3 data is provided" do
|
5408
|
+
result = Braintree::Transaction.sale(
|
5409
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
5410
|
+
:merchant_account_id => SpecHelper::FakeAmexDirectMerchantAccountId,
|
5411
|
+
:credit_card => {
|
5412
|
+
:number => Braintree::Test::CreditCardNumbers::AmexPayWithPoints::Success,
|
5413
|
+
:expiration_date => "05/2009"
|
5414
|
+
},
|
5415
|
+
:options => {
|
5416
|
+
:amex_rewards => {
|
5417
|
+
:request_id => "ABC123",
|
5418
|
+
:points => "1000",
|
5419
|
+
:currency_amount => "10.00",
|
5420
|
+
:currency_iso_code => "USD"
|
5421
|
+
}
|
5422
|
+
}
|
5423
|
+
)
|
5424
|
+
result.success?.should == true
|
5425
|
+
|
5426
|
+
result = Braintree::Transaction.submit_for_settlement(
|
5427
|
+
result.transaction.id,
|
5428
|
+
nil,
|
5429
|
+
:discount_amount => "2.00",
|
5430
|
+
:shipping_amount => "1.23",
|
5431
|
+
:ships_from_postal_code => "90210",
|
5432
|
+
:line_items => [
|
5433
|
+
{
|
5434
|
+
:quantity => 1,
|
5435
|
+
:unit_amount => 1,
|
5436
|
+
:name => "New line item",
|
5437
|
+
:kind => "debit",
|
5438
|
+
:total_amount => "18.00",
|
5439
|
+
:discount_amount => "12.00",
|
5440
|
+
:tax_amount => "0",
|
5441
|
+
},
|
5442
|
+
]
|
5443
|
+
)
|
5444
|
+
result.success?.should == true
|
5445
|
+
result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
|
5446
|
+
end
|
5089
5447
|
end
|
5090
5448
|
|
5091
5449
|
describe "self.submit_for_settlement!" do
|
@@ -5882,6 +6240,7 @@ describe Braintree::Transaction do
|
|
5882
6240
|
created_transaction = result.transaction
|
5883
6241
|
found_transaction = Braintree::Transaction.find(created_transaction.id)
|
5884
6242
|
found_transaction.should == created_transaction
|
6243
|
+
found_transaction.graphql_id.should_not be_nil
|
5885
6244
|
end
|
5886
6245
|
|
5887
6246
|
it "finds the vaulted transaction with the given id" do
|
@@ -6802,4 +7161,37 @@ describe Braintree::Transaction do
|
|
6802
7161
|
details.refund_id.should_not be_nil
|
6803
7162
|
end
|
6804
7163
|
end
|
7164
|
+
|
7165
|
+
describe "card on file network tokenization" do
|
7166
|
+
it "creates a transaction with a vaulted, tokenized credit card" do
|
7167
|
+
result = Braintree::Transaction.sale(
|
7168
|
+
:amount => "112.44",
|
7169
|
+
:payment_method_token => "network_tokenized_credit_card",
|
7170
|
+
)
|
7171
|
+
result.success?.should == true
|
7172
|
+
transaction = result.transaction
|
7173
|
+
|
7174
|
+
transaction.amount.should == BigDecimal("112.44")
|
7175
|
+
transaction.processed_with_network_token?.should == true
|
7176
|
+
end
|
7177
|
+
|
7178
|
+
it "creates a transaction with a vaulted, non-tokenized credit card" do
|
7179
|
+
customer = Braintree::Customer.create!
|
7180
|
+
result = Braintree::PaymentMethod.create(
|
7181
|
+
:payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
|
7182
|
+
:customer_id => customer.id
|
7183
|
+
)
|
7184
|
+
payment_method_token = result.payment_method.token
|
7185
|
+
|
7186
|
+
result = Braintree::Transaction.sale(
|
7187
|
+
:amount => "112.44",
|
7188
|
+
:payment_method_token => payment_method_token,
|
7189
|
+
)
|
7190
|
+
result.success?.should == true
|
7191
|
+
transaction = result.transaction
|
7192
|
+
|
7193
|
+
transaction.amount.should == BigDecimal("112.44")
|
7194
|
+
transaction.processed_with_network_token?.should == false
|
7195
|
+
end
|
7196
|
+
end
|
6805
7197
|
end
|