braintree 4.35.0 → 4.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/braintree/apple_pay_card.rb +7 -0
- data/lib/braintree/apple_pay_gateway.rb +43 -0
- data/lib/braintree/base_module.rb +9 -0
- data/lib/braintree/credit_card_verification.rb +2 -0
- data/lib/braintree/customer.rb +1 -1
- data/lib/braintree/customer_gateway.rb +2 -0
- data/lib/braintree/error_codes.rb +20 -0
- data/lib/braintree/gateway.rb +4 -0
- data/lib/braintree/graphql/inputs/billing_address_input.rb +34 -0
- data/lib/braintree/graphql/inputs/create_local_payment_context_input.rb +44 -0
- data/lib/braintree/graphql/inputs/payer_info_input.rb +38 -0
- data/lib/braintree/graphql/inputs/shipping_address_input.rb +34 -0
- data/lib/braintree/local_payment_context.rb +108 -0
- data/lib/braintree/local_payment_context_gateway.rb +132 -0
- data/lib/braintree/local_payment_type.rb +6 -0
- data/lib/braintree/merchant_gateway.rb +16 -16
- data/lib/braintree/monetary_amount.rb +24 -0
- data/lib/braintree/successful_result.rb +1 -0
- data/lib/braintree/transaction.rb +2 -0
- data/lib/braintree/transaction_gateway.rb +11 -5
- data/lib/braintree/transaction_search.rb +1 -0
- data/lib/braintree/validation_error_collection.rb +1 -1
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree.rb +20 -3
- data/spec/integration/braintree/customer_spec.rb +550 -0
- data/spec/integration/braintree/http_spec.rb +1 -1
- data/spec/integration/braintree/local_payment_context_spec.rb +168 -0
- data/spec/integration/braintree/merchant_spec.rb +5 -169
- data/spec/integration/braintree/payment_method_spec.rb +174 -1
- data/spec/integration/braintree/transaction_idempotency_spec.rb +320 -0
- data/spec/integration/braintree/transaction_search_spec.rb +3 -2
- data/spec/integration/braintree/transaction_spec.rb +75 -0
- data/spec/integration/braintree/transaction_us_bank_account_spec.rb +2 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/braintree/credit_card_verification_spec.rb +1 -1
- data/spec/unit/braintree/customer_spec.rb +67 -1
- data/spec/unit/braintree/graphql/billing_address_input_spec.rb +68 -0
- data/spec/unit/braintree/graphql/create_local_payment_context_input_spec.rb +63 -0
- data/spec/unit/braintree/graphql/monetary_amount_input_spec.rb +55 -0
- data/spec/unit/braintree/graphql/payer_info_input_spec.rb +92 -0
- data/spec/unit/braintree/local_payment_context_gateway_spec.rb +149 -0
- data/spec/unit/braintree/local_payment_context_spec.rb +141 -0
- data/spec/unit/braintree/monetary_amount_spec.rb +34 -0
- data/spec/unit/braintree/three_d_secure_info_spec.rb +3 -1
- data/spec/unit/braintree/transaction/apple_pay_details_spec.rb +7 -7
- data/spec/unit/braintree/transaction/google_pay_details_spec.rb +7 -7
- data/spec/unit/braintree/transaction/meta_checkout_card_details_spec.rb +6 -6
- data/spec/unit/braintree/transaction/meta_checkout_token_details_spec.rb +6 -6
- data/spec/unit/braintree/transaction/payment_receipt_spec.rb +4 -4
- data/spec/unit/braintree/transaction/visa_checkout_card_details_spec.rb +6 -6
- data/spec/unit/braintree/transaction_gateway_spec.rb +4 -3
- data/spec/unit/braintree/transaction_spec.rb +12 -0
- data/spec/unit/credit_card_details_spec.rb +6 -6
- data/spec/unit/spec_helper.rb +9 -0
- metadata +19 -2
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
|
2
|
+
|
|
3
|
+
describe Braintree::Transaction, "idempotency" do
|
|
4
|
+
describe "sale" do
|
|
5
|
+
it "returns original transaction on duplicate request with same api_request_key" do
|
|
6
|
+
api_request_key = "idempotency-key-#{rand(1000000)}"
|
|
7
|
+
|
|
8
|
+
transaction_params = {
|
|
9
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
10
|
+
:api_request_key => api_request_key,
|
|
11
|
+
:credit_card => {
|
|
12
|
+
:number => "4111111111111111",
|
|
13
|
+
:expiration_date => "05/2035"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
result1 = Braintree::Transaction.sale(transaction_params)
|
|
18
|
+
expect(result1).to be_success
|
|
19
|
+
transaction1 = result1.transaction
|
|
20
|
+
expect(transaction1.id).not_to be_nil
|
|
21
|
+
|
|
22
|
+
result2 = Braintree::Transaction.sale(transaction_params)
|
|
23
|
+
expect(result2).to be_success
|
|
24
|
+
transaction2 = result2.transaction
|
|
25
|
+
|
|
26
|
+
expect(transaction1.status).to eq(transaction2.status)
|
|
27
|
+
expect(transaction1.id).to eq(transaction2.id)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "fails when different request used with same key" do
|
|
31
|
+
api_request_key = "idempotency-key-#{rand(1000000)}"
|
|
32
|
+
|
|
33
|
+
transaction_params1 = {
|
|
34
|
+
:amount => "100.00",
|
|
35
|
+
:api_request_key => api_request_key,
|
|
36
|
+
:credit_card => {
|
|
37
|
+
:number => "4111111111111111",
|
|
38
|
+
:expiration_date => "05/2035"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
result1 = Braintree::Transaction.sale(transaction_params1)
|
|
43
|
+
expect(result1).to be_success
|
|
44
|
+
|
|
45
|
+
transaction_params2 = {
|
|
46
|
+
:amount => "200.00",
|
|
47
|
+
:api_request_key => api_request_key,
|
|
48
|
+
:credit_card => {
|
|
49
|
+
:number => "4111111111111111",
|
|
50
|
+
:expiration_date => "05/2035"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
result2 = Braintree::Transaction.sale(transaction_params2)
|
|
55
|
+
|
|
56
|
+
expect(result2).not_to be_success
|
|
57
|
+
expect(result2.errors).not_to be_nil
|
|
58
|
+
errors = result2.errors.for(:transaction)
|
|
59
|
+
expect(errors.size).to be > 0
|
|
60
|
+
expect(errors.first.code).to eq(Braintree::ErrorCodes::Transaction::ApiRequestKeyCanBeReusedOnlyWithTheSameRequest)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "same sales with different api_request_keys create different transactions" do
|
|
64
|
+
api_request_key1 = "idempotency-key-#{rand(1000000)}"
|
|
65
|
+
|
|
66
|
+
transaction_params1 = {
|
|
67
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
68
|
+
:api_request_key => api_request_key1,
|
|
69
|
+
:credit_card => {
|
|
70
|
+
:number => "4111111111111111",
|
|
71
|
+
:expiration_date => "05/2035"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
result1 = Braintree::Transaction.sale(transaction_params1)
|
|
76
|
+
expect(result1).to be_success
|
|
77
|
+
transaction1 = result1.transaction
|
|
78
|
+
expect(transaction1.id).not_to be_nil
|
|
79
|
+
|
|
80
|
+
api_request_key2 = "idempotency-key-different-#{rand(1000000)}"
|
|
81
|
+
transaction_params2 = {
|
|
82
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
83
|
+
:api_request_key => api_request_key2,
|
|
84
|
+
:credit_card => {
|
|
85
|
+
:number => "4111111111111111",
|
|
86
|
+
:expiration_date => "05/2035"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
result2 = Braintree::Transaction.sale(transaction_params2)
|
|
91
|
+
expect(result2).to be_success
|
|
92
|
+
transaction2 = result2.transaction
|
|
93
|
+
|
|
94
|
+
expect(transaction1.id).not_to eq(transaction2.id)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "fails when api_request_key is too big" do
|
|
98
|
+
transaction_params1 = {
|
|
99
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
100
|
+
:api_request_key => "x" * 255,
|
|
101
|
+
:credit_card => {
|
|
102
|
+
:number => "4111111111111111",
|
|
103
|
+
:expiration_date => "05/2035"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
result1 = Braintree::Transaction.sale(transaction_params1)
|
|
108
|
+
expect(result1).to be_success
|
|
109
|
+
|
|
110
|
+
transaction_params2 = {
|
|
111
|
+
:amount => "200.00",
|
|
112
|
+
:api_request_key => "x" * 256,
|
|
113
|
+
:credit_card => {
|
|
114
|
+
:number => "4111111111111111",
|
|
115
|
+
:expiration_date => "05/2035"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
result2 = Braintree::Transaction.sale(transaction_params2)
|
|
120
|
+
|
|
121
|
+
expect(result2).not_to be_success
|
|
122
|
+
expect(result2.errors).not_to be_nil
|
|
123
|
+
errors = result2.errors.for(:transaction)
|
|
124
|
+
expect(errors.size).to be > 0
|
|
125
|
+
expect(errors.first.code).to eq(Braintree::ErrorCodes::Transaction::ApiRequestKeyTooLong)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
describe "credit" do
|
|
130
|
+
it "returns original on duplicate request with same api_request_key" do
|
|
131
|
+
api_request_key = "credit-idempotency-key-#{rand(1000000)}"
|
|
132
|
+
|
|
133
|
+
transaction_params = {
|
|
134
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
135
|
+
:api_request_key => api_request_key,
|
|
136
|
+
:credit_card => {
|
|
137
|
+
:number => "4111111111111111",
|
|
138
|
+
:expiration_date => "05/2035"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
credit_result1 = Braintree::Transaction.credit(transaction_params)
|
|
143
|
+
expect(credit_result1).to be_success
|
|
144
|
+
credit_transaction1 = credit_result1.transaction
|
|
145
|
+
expect(credit_transaction1.type).to eq(Braintree::Transaction::Type::Credit)
|
|
146
|
+
expect(credit_transaction1.id).not_to be_nil
|
|
147
|
+
|
|
148
|
+
credit_result2 = Braintree::Transaction.credit(transaction_params)
|
|
149
|
+
expect(credit_result2).to be_success
|
|
150
|
+
credit_transaction2 = credit_result2.transaction
|
|
151
|
+
|
|
152
|
+
expect(credit_transaction1.id).to eq(credit_transaction2.id)
|
|
153
|
+
expect(credit_transaction1.type).to eq(credit_transaction2.type)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
describe "submit_for_partial_settlement" do
|
|
158
|
+
it "returns original on duplicate request with same api_request_key" do
|
|
159
|
+
api_request_key = "partial-settlement-idempotency-key-#{rand(1000000)}"
|
|
160
|
+
|
|
161
|
+
sale_request = {
|
|
162
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
163
|
+
:credit_card => {
|
|
164
|
+
:number => "4111111111111111",
|
|
165
|
+
:expiration_date => "05/2035"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
sale_result = Braintree::Transaction.sale(sale_request)
|
|
170
|
+
expect(sale_result).to be_success
|
|
171
|
+
transaction_id = sale_result.transaction.id
|
|
172
|
+
|
|
173
|
+
partial_amount = "50.00"
|
|
174
|
+
partial_settlement_options = {
|
|
175
|
+
:api_request_key => api_request_key
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
partial_settlement_result1 = Braintree::Transaction.submit_for_partial_settlement(
|
|
179
|
+
transaction_id,
|
|
180
|
+
partial_amount,
|
|
181
|
+
partial_settlement_options,
|
|
182
|
+
)
|
|
183
|
+
expect(partial_settlement_result1).to be_success
|
|
184
|
+
partial_settlement_transaction1 = partial_settlement_result1.transaction
|
|
185
|
+
expect(partial_settlement_transaction1.amount).to eq(BigDecimal(partial_amount))
|
|
186
|
+
expect(partial_settlement_transaction1.id).not_to be_nil
|
|
187
|
+
|
|
188
|
+
partial_settlement_result2 = Braintree::Transaction.submit_for_partial_settlement(
|
|
189
|
+
transaction_id,
|
|
190
|
+
partial_amount,
|
|
191
|
+
partial_settlement_options,
|
|
192
|
+
)
|
|
193
|
+
expect(partial_settlement_result2).to be_success
|
|
194
|
+
partial_settlement_transaction2 = partial_settlement_result2.transaction
|
|
195
|
+
|
|
196
|
+
expect(partial_settlement_transaction1.id).to eq(partial_settlement_transaction2.id)
|
|
197
|
+
expect(partial_settlement_transaction1.amount).to eq(partial_settlement_transaction2.amount)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe "submit_for_settlement" do
|
|
202
|
+
it "returns original on duplicate request with same api_request_key" do
|
|
203
|
+
api_request_key = "settlement-idempotency-key-#{rand(1000000)}"
|
|
204
|
+
|
|
205
|
+
sale_request = {
|
|
206
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
207
|
+
:credit_card => {
|
|
208
|
+
:number => "4111111111111111",
|
|
209
|
+
:expiration_date => "05/2035"
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
sale_result = Braintree::Transaction.sale(sale_request)
|
|
214
|
+
expect(sale_result).to be_success
|
|
215
|
+
transaction_id = sale_result.transaction.id
|
|
216
|
+
original_amount = sale_result.transaction.amount
|
|
217
|
+
|
|
218
|
+
settlement_options = {
|
|
219
|
+
:api_request_key => api_request_key
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
settlement_result1 = Braintree::Transaction.submit_for_settlement(
|
|
223
|
+
transaction_id,
|
|
224
|
+
nil,
|
|
225
|
+
settlement_options,
|
|
226
|
+
)
|
|
227
|
+
expect(settlement_result1).to be_success
|
|
228
|
+
settlement_transaction1 = settlement_result1.transaction
|
|
229
|
+
expect(settlement_transaction1.amount).to eq(original_amount)
|
|
230
|
+
expect(settlement_transaction1.id).not_to be_nil
|
|
231
|
+
|
|
232
|
+
settlement_result2 = Braintree::Transaction.submit_for_settlement(
|
|
233
|
+
transaction_id,
|
|
234
|
+
nil,
|
|
235
|
+
settlement_options,
|
|
236
|
+
)
|
|
237
|
+
expect(settlement_result2).to be_success
|
|
238
|
+
settlement_transaction2 = settlement_result2.transaction
|
|
239
|
+
|
|
240
|
+
expect(settlement_transaction1.id).to eq(settlement_transaction2.id)
|
|
241
|
+
expect(settlement_transaction1.amount).to eq(settlement_transaction2.amount)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "void" do
|
|
246
|
+
it "returns original void on duplicate request with same api_request_key" do
|
|
247
|
+
api_request_key = "void-idempotency-key-#{rand(1000000)}"
|
|
248
|
+
|
|
249
|
+
sale_request = {
|
|
250
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
251
|
+
:credit_card => {
|
|
252
|
+
:number => "4111111111111111",
|
|
253
|
+
:expiration_date => "05/2035"
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
sale_result = Braintree::Transaction.sale(sale_request)
|
|
258
|
+
expect(sale_result).to be_success
|
|
259
|
+
transaction_id = sale_result.transaction.id
|
|
260
|
+
|
|
261
|
+
void_options = {
|
|
262
|
+
:api_request_key => api_request_key
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void_result1 = Braintree::Transaction.void(transaction_id, void_options)
|
|
266
|
+
expect(void_result1).to be_success
|
|
267
|
+
voided_transaction1 = void_result1.transaction
|
|
268
|
+
expect(voided_transaction1.status).to eq(Braintree::Transaction::Status::Voided)
|
|
269
|
+
|
|
270
|
+
void_result2 = Braintree::Transaction.void(transaction_id, void_options)
|
|
271
|
+
expect(void_result2).to be_success
|
|
272
|
+
voided_transaction2 = void_result2.transaction
|
|
273
|
+
|
|
274
|
+
expect(voided_transaction1.id).to eq(voided_transaction2.id)
|
|
275
|
+
expect(voided_transaction1.status).to eq(voided_transaction2.status)
|
|
276
|
+
expect(voided_transaction2.status).to eq(Braintree::Transaction::Status::Voided)
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe "refund" do
|
|
281
|
+
it "returns original refund on duplicate request with same api_request_key" do
|
|
282
|
+
api_request_key = "refund-idempotency-key-#{rand(1000000)}"
|
|
283
|
+
|
|
284
|
+
sale_request = {
|
|
285
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
286
|
+
:credit_card => {
|
|
287
|
+
:number => "4111111111111111",
|
|
288
|
+
:expiration_date => "05/2035"
|
|
289
|
+
},
|
|
290
|
+
:options => {
|
|
291
|
+
:submit_for_settlement => true
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
sale_result = Braintree::Transaction.sale(sale_request)
|
|
296
|
+
expect(sale_result).to be_success
|
|
297
|
+
transaction_id = sale_result.transaction.id
|
|
298
|
+
|
|
299
|
+
settled_result = Braintree::TestTransaction.settle(transaction_id)
|
|
300
|
+
expect(settled_result.transaction.status).to eq(Braintree::Transaction::Status::Settled)
|
|
301
|
+
|
|
302
|
+
refund_options = {
|
|
303
|
+
:api_request_key => api_request_key
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
refund_result1 = Braintree::Transaction.refund(transaction_id, refund_options)
|
|
307
|
+
expect(refund_result1).to be_success
|
|
308
|
+
refund_transaction1 = refund_result1.transaction
|
|
309
|
+
expect(refund_transaction1.type).to eq(Braintree::Transaction::Type::Credit)
|
|
310
|
+
expect(refund_transaction1.id).not_to be_nil
|
|
311
|
+
|
|
312
|
+
refund_result2 = Braintree::Transaction.refund(transaction_id, refund_options)
|
|
313
|
+
expect(refund_result2).to be_success
|
|
314
|
+
refund_transaction2 = refund_result2.transaction
|
|
315
|
+
|
|
316
|
+
expect(refund_transaction1.id).to eq(refund_transaction2.id)
|
|
317
|
+
expect(refund_transaction1.type).to eq(refund_transaction2.type)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
@@ -69,6 +69,7 @@ describe Braintree::Transaction, "search" do
|
|
|
69
69
|
credit_card = Braintree::CreditCard.find(token)
|
|
70
70
|
|
|
71
71
|
search_criteria = {
|
|
72
|
+
:acquirer_reference_number => transaction.acquirer_reference_number,
|
|
72
73
|
:billing_company => "Braintree",
|
|
73
74
|
:billing_country_name => "United States of America",
|
|
74
75
|
:billing_extended_address => "Suite 123",
|
|
@@ -207,9 +208,9 @@ describe Braintree::Transaction, "search" do
|
|
|
207
208
|
end
|
|
208
209
|
item = collection.find { |t| t.id == transaction_id }
|
|
209
210
|
expect(item.ach_return_code).to eq("RJCT")
|
|
210
|
-
expect(item.ach_reject_reason).to eq("Bank accounts located outside of the U.S. are not supported
|
|
211
|
+
expect(item.ach_reject_reason).to eq("Bank accounts located outside of the U.S. are not supported")
|
|
211
212
|
expect(item.ach_return_responses.first[:reason_code]).to eq("RJCT")
|
|
212
|
-
expect(item.ach_return_responses.first[:reject_reason]).to eq("Bank accounts located outside of the U.S. are not supported
|
|
213
|
+
expect(item.ach_return_responses.first[:reject_reason]).to eq("Bank accounts located outside of the U.S. are not supported")
|
|
213
214
|
end
|
|
214
215
|
|
|
215
216
|
it "searches on reason_codes" do
|
|
@@ -5324,6 +5324,64 @@ describe Braintree::Transaction do
|
|
|
5324
5324
|
expect(transaction.shipping_details.international_phone[:national_number]).to eq("3121234567")
|
|
5325
5325
|
end
|
|
5326
5326
|
|
|
5327
|
+
it "accepts customer international_phone" do
|
|
5328
|
+
result = Braintree::Transaction.sale(
|
|
5329
|
+
:amount => "100.00",
|
|
5330
|
+
:credit_card => {
|
|
5331
|
+
:number => "5105105105105100",
|
|
5332
|
+
:expiration_date => "05/2011",
|
|
5333
|
+
},
|
|
5334
|
+
:customer => {
|
|
5335
|
+
:first_name => "Dan",
|
|
5336
|
+
:last_name => "Smith",
|
|
5337
|
+
:international_phone => {:country_code => "1", :national_number => "3121234567"},
|
|
5338
|
+
},
|
|
5339
|
+
)
|
|
5340
|
+
|
|
5341
|
+
expect(result.success?).to eq(true)
|
|
5342
|
+
transaction = result.transaction
|
|
5343
|
+
expect(transaction.customer_details.first_name).to eq("Dan")
|
|
5344
|
+
expect(transaction.customer_details.last_name).to eq("Smith")
|
|
5345
|
+
expect(transaction.customer_details.international_phone[:country_code]).to eq("1")
|
|
5346
|
+
expect(transaction.customer_details.international_phone[:national_number]).to eq("3121234567")
|
|
5347
|
+
end
|
|
5348
|
+
|
|
5349
|
+
it "returns validation error for an invalid international_phone country code" do
|
|
5350
|
+
result = Braintree::Transaction.sale(
|
|
5351
|
+
:amount => "100.00",
|
|
5352
|
+
:credit_card => {
|
|
5353
|
+
:number => "5105105105105100",
|
|
5354
|
+
:expiration_date => "05/2011",
|
|
5355
|
+
},
|
|
5356
|
+
:customer => {
|
|
5357
|
+
:first_name => "Dan",
|
|
5358
|
+
:last_name => "Smith",
|
|
5359
|
+
:international_phone => {:country_code => "1111", :national_number => "3121234567"},
|
|
5360
|
+
},
|
|
5361
|
+
)
|
|
5362
|
+
|
|
5363
|
+
expect(result.success?).to eq(false)
|
|
5364
|
+
expect(result.errors.map(&:code)).to include(Braintree::ErrorCodes::Customer::InternationalPhoneCountryCodeIsInvalid)
|
|
5365
|
+
end
|
|
5366
|
+
|
|
5367
|
+
it "returns validation error for an invalid international_phone national number" do
|
|
5368
|
+
result = Braintree::Transaction.sale(
|
|
5369
|
+
:amount => "100.00",
|
|
5370
|
+
:credit_card => {
|
|
5371
|
+
:number => "5105105105105100",
|
|
5372
|
+
:expiration_date => "05/2011",
|
|
5373
|
+
},
|
|
5374
|
+
:customer => {
|
|
5375
|
+
:first_name => "Dan",
|
|
5376
|
+
:last_name => "Smith",
|
|
5377
|
+
:international_phone => {:country_code => "1", :national_number => "31212345611111"},
|
|
5378
|
+
},
|
|
5379
|
+
)
|
|
5380
|
+
|
|
5381
|
+
expect(result.success?).to eq(false)
|
|
5382
|
+
expect(result.errors.map(&:code)).to include(Braintree::ErrorCodes::Customer::InternationalPhoneNationalNumberIsInvalid)
|
|
5383
|
+
end
|
|
5384
|
+
|
|
5327
5385
|
it "accepts processing_merchant_category_code" do
|
|
5328
5386
|
result = Braintree::Transaction.sale(
|
|
5329
5387
|
:amount => "100.00",
|
|
@@ -7901,4 +7959,21 @@ describe Braintree::Transaction do
|
|
|
7901
7959
|
expect(transaction.upcoming_retry_date).to eq(tomorrow.to_s)
|
|
7902
7960
|
end
|
|
7903
7961
|
end
|
|
7962
|
+
|
|
7963
|
+
context "Surcharge Amount" do
|
|
7964
|
+
it "accepts surcharge_amount field" do
|
|
7965
|
+
result = Braintree::Transaction.create(
|
|
7966
|
+
:type => "sale",
|
|
7967
|
+
:amount => "10.00",
|
|
7968
|
+
:surcharge_amount => "1.00",
|
|
7969
|
+
:credit_card => {
|
|
7970
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
|
7971
|
+
:expiration_date => "05/2029"
|
|
7972
|
+
},
|
|
7973
|
+
)
|
|
7974
|
+
|
|
7975
|
+
expect(result.success?).to eq(true)
|
|
7976
|
+
expect(result.transaction.surcharge_amount).to eq(BigDecimal("1.00"))
|
|
7977
|
+
end
|
|
7978
|
+
end
|
|
7904
7979
|
end
|
|
@@ -157,7 +157,8 @@ describe Braintree::Transaction do
|
|
|
157
157
|
},
|
|
158
158
|
)
|
|
159
159
|
expect(result.success?).to eq(true)
|
|
160
|
-
|
|
160
|
+
# if the test is ran before 2pm - it returns 'same_day', otherwise 'standard'
|
|
161
|
+
expect(result.transaction.ach_type).to eq("same_day").or eq("standard")
|
|
161
162
|
expect(result.transaction.requested_ach_type).to eq("same_day")
|
|
162
163
|
end
|
|
163
164
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,6 +3,7 @@ unless defined?(SPEC_HELPER_LOADED)
|
|
|
3
3
|
project_root = File.expand_path(File.dirname(__FILE__) + "/..")
|
|
4
4
|
require "rubygems"
|
|
5
5
|
require "bundler/setup"
|
|
6
|
+
|
|
6
7
|
require "rspec"
|
|
7
8
|
require "rspec/retry"
|
|
8
9
|
require "pry"
|
|
@@ -42,6 +43,7 @@ unless defined?(SPEC_HELPER_LOADED)
|
|
|
42
43
|
HiperBRLMerchantAccountId = "hiper_brl"
|
|
43
44
|
NonDefaultMerchantAccountId = "sandbox_credit_card_non_default"
|
|
44
45
|
PinlessDebitMerchantAccountId = "pinless_debit"
|
|
46
|
+
SuspendedAccount = "suspended_account"
|
|
45
47
|
ThreeDSecureMerchantAccountId = "three_d_secure_merchant_account"
|
|
46
48
|
UsBankMerchantAccountId = "us_bank_merchant_account"
|
|
47
49
|
|
|
@@ -19,7 +19,7 @@ describe Braintree::CreditCardVerification do
|
|
|
19
19
|
:network_response_code => "05",
|
|
20
20
|
:network_response_text => "Do not Honor",
|
|
21
21
|
)
|
|
22
|
-
expect(verification.inspect).to eq(%(#<Braintree::CreditCardVerification amount: "12.45", ani_first_name_response_code: "I", ani_last_name_response_code: "I", avs_error_response_code: "I", avs_postal_code_response_code: "I", avs_street_address_response_code: "I", billing: nil, created_at: nil, credit_card: nil, currency_iso_code: "USD", cvv_response_code: "I", gateway_rejection_reason: nil, id: nil, merchant_account_id: "some_id", network_response_code: "05", network_response_text: "Do not Honor", processor_response_code: "2000", processor_response_text: "Do Not Honor", status: "verified">))
|
|
22
|
+
expect(verification.inspect).to eq(%(#<Braintree::CreditCardVerification amount: "12.45", ani_first_name_response_code: "I", ani_last_name_response_code: "I", apple_pay: nil, avs_error_response_code: "I", avs_postal_code_response_code: "I", avs_street_address_response_code: "I", billing: nil, created_at: nil, credit_card: nil, currency_iso_code: "USD", cvv_response_code: "I", gateway_rejection_reason: nil, id: nil, merchant_account_id: "some_id", network_response_code: "05", network_response_text: "Do not Honor", processor_response_code: "2000", processor_response_text: "Do Not Honor", status: "verified">))
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
it "has a status" do
|
|
@@ -28,7 +28,8 @@ describe Braintree::Customer do
|
|
|
28
28
|
expect(output).to include(%q(first_name: "Patrick"))
|
|
29
29
|
expect(output).to include(%q(last_name: "Smith"))
|
|
30
30
|
expect(output).to include(%q(phone: "802-483-5932"))
|
|
31
|
-
|
|
31
|
+
international_phone_hash = {:country_code => "1", :national_number => "3121234567"}.inspect
|
|
32
|
+
expect(output).to include("international_phone: #{international_phone_hash}")
|
|
32
33
|
expect(output).to include(%q(website: "patrick.smith.com"))
|
|
33
34
|
expect(output).to include(%q(addresses: []))
|
|
34
35
|
expect(output).to include(%q(credit_cards: []))
|
|
@@ -91,6 +92,38 @@ describe Braintree::Customer do
|
|
|
91
92
|
:device_data,
|
|
92
93
|
:payment_method_nonce,
|
|
93
94
|
{:risk_data => [:customer_browser, :customer_ip]},
|
|
95
|
+
{:apple_pay_card => [
|
|
96
|
+
:cardholder_name,
|
|
97
|
+
:cryptogram,
|
|
98
|
+
:eci_indicator,
|
|
99
|
+
:expiration_month,
|
|
100
|
+
:expiration_year,
|
|
101
|
+
:network_transaction_id,
|
|
102
|
+
:number,
|
|
103
|
+
:token,
|
|
104
|
+
{:billing_address => [
|
|
105
|
+
:company,
|
|
106
|
+
:country_code_alpha2,
|
|
107
|
+
:country_code_alpha3,
|
|
108
|
+
:country_code_numeric,
|
|
109
|
+
:country_name,
|
|
110
|
+
:extended_address,
|
|
111
|
+
:first_name,
|
|
112
|
+
{:international_phone=>[:country_code, :national_number]},
|
|
113
|
+
:last_name,
|
|
114
|
+
:locality,
|
|
115
|
+
:phone_number,
|
|
116
|
+
:postal_code,
|
|
117
|
+
:region,
|
|
118
|
+
:street_address
|
|
119
|
+
]},
|
|
120
|
+
{:options => match_array([
|
|
121
|
+
:verification_account_type,
|
|
122
|
+
:verification_amount,
|
|
123
|
+
:verification_merchant_account_id,
|
|
124
|
+
:verify_card
|
|
125
|
+
])},
|
|
126
|
+
]},
|
|
94
127
|
{:credit_card => [
|
|
95
128
|
:billing_address_id,
|
|
96
129
|
:cardholder_name,
|
|
@@ -188,6 +221,39 @@ describe Braintree::Customer do
|
|
|
188
221
|
:device_data,
|
|
189
222
|
:payment_method_nonce,
|
|
190
223
|
:default_payment_method_token,
|
|
224
|
+
{:apple_pay_card => [
|
|
225
|
+
:cardholder_name,
|
|
226
|
+
:cryptogram,
|
|
227
|
+
:eci_indicator,
|
|
228
|
+
:expiration_month,
|
|
229
|
+
:expiration_year,
|
|
230
|
+
:network_transaction_id,
|
|
231
|
+
:number,
|
|
232
|
+
:token,
|
|
233
|
+
{:billing_address => [
|
|
234
|
+
:company,
|
|
235
|
+
:country_code_alpha2,
|
|
236
|
+
:country_code_alpha3,
|
|
237
|
+
:country_code_numeric,
|
|
238
|
+
:country_name,
|
|
239
|
+
:extended_address,
|
|
240
|
+
:first_name,
|
|
241
|
+
{:international_phone=>[:country_code, :national_number]},
|
|
242
|
+
:last_name,
|
|
243
|
+
:locality,
|
|
244
|
+
:phone_number,
|
|
245
|
+
:postal_code,
|
|
246
|
+
:region,
|
|
247
|
+
:street_address
|
|
248
|
+
]},
|
|
249
|
+
{:options => match_array([
|
|
250
|
+
:make_default,
|
|
251
|
+
:verification_account_type,
|
|
252
|
+
:verification_amount,
|
|
253
|
+
:verification_merchant_account_id,
|
|
254
|
+
:verify_card
|
|
255
|
+
])},
|
|
256
|
+
]},
|
|
191
257
|
{:credit_card => [
|
|
192
258
|
:billing_address_id,
|
|
193
259
|
:cardholder_name,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
|
|
2
|
+
|
|
3
|
+
describe Braintree::BillingAddressInput do
|
|
4
|
+
describe "#initialize" do
|
|
5
|
+
it "initializes with all attributes" do
|
|
6
|
+
attributes = {
|
|
7
|
+
street_address: "123 Main St",
|
|
8
|
+
extended_address: "Apt 4B",
|
|
9
|
+
locality: "Mexico City",
|
|
10
|
+
region: "CDMX",
|
|
11
|
+
postal_code: "01000",
|
|
12
|
+
country_code_alpha2: "MX"
|
|
13
|
+
}
|
|
14
|
+
input = Braintree::BillingAddressInput.new(attributes)
|
|
15
|
+
|
|
16
|
+
expect(input.street_address).to eq("123 Main St")
|
|
17
|
+
expect(input.extended_address).to eq("Apt 4B")
|
|
18
|
+
expect(input.locality).to eq("Mexico City")
|
|
19
|
+
expect(input.region).to eq("CDMX")
|
|
20
|
+
expect(input.postal_code).to eq("01000")
|
|
21
|
+
expect(input.country_code_alpha2).to eq("MX")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe "#to_graphql_variables" do
|
|
26
|
+
it "converts to graphql variables with camelCase keys" do
|
|
27
|
+
attributes = {
|
|
28
|
+
street_address: "123 Main St",
|
|
29
|
+
locality: "Mexico City",
|
|
30
|
+
postal_code: "01000",
|
|
31
|
+
country_code_alpha2: "MX"
|
|
32
|
+
}
|
|
33
|
+
input = Braintree::BillingAddressInput.new(attributes)
|
|
34
|
+
expected_variables = {
|
|
35
|
+
"streetAddress" => "123 Main St",
|
|
36
|
+
"locality" => "Mexico City",
|
|
37
|
+
"postalCode" => "01000",
|
|
38
|
+
"countryCode" => "MX"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
expect(input.to_graphql_variables).to eq(expected_variables)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "omits nil values" do
|
|
45
|
+
attributes = {street_address: "123 Main St"}
|
|
46
|
+
input = Braintree::BillingAddressInput.new(attributes)
|
|
47
|
+
expected_variables = {"streetAddress" => "123 Main St"}
|
|
48
|
+
|
|
49
|
+
expect(input.to_graphql_variables).to eq(expected_variables)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#inspect" do
|
|
54
|
+
it "returns formatted string" do
|
|
55
|
+
attributes = {
|
|
56
|
+
street_address: "123 Main St",
|
|
57
|
+
locality: "Mexico City",
|
|
58
|
+
postal_code: "01000"
|
|
59
|
+
}
|
|
60
|
+
input = Braintree::BillingAddressInput.new(attributes)
|
|
61
|
+
result = input.inspect
|
|
62
|
+
|
|
63
|
+
expect(result).to include("BillingAddressInput")
|
|
64
|
+
expect(result).to include("street_address:")
|
|
65
|
+
expect(result).to include("locality:")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
|
|
2
|
+
|
|
3
|
+
describe Braintree::CreateLocalPaymentContextInput do
|
|
4
|
+
let(:input_data) do
|
|
5
|
+
{
|
|
6
|
+
amount: {value: "10.00", currency_code: "EUR"},
|
|
7
|
+
type: Braintree::LocalPaymentType::MBWAY,
|
|
8
|
+
payer_info: {
|
|
9
|
+
given_name: "John",
|
|
10
|
+
surname: "Doe"
|
|
11
|
+
},
|
|
12
|
+
order_id: "order-123"
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "#initialize" do
|
|
17
|
+
it "initializes with attributes" do
|
|
18
|
+
input = Braintree::CreateLocalPaymentContextInput.new(input_data)
|
|
19
|
+
|
|
20
|
+
expect(input.attrs).to eq(input_data.keys)
|
|
21
|
+
expect(input.type).to eq(Braintree::LocalPaymentType::MBWAY)
|
|
22
|
+
expect(input.order_id).to eq("order-123")
|
|
23
|
+
expect(input.amount).to be_a(Braintree::MonetaryAmountInput)
|
|
24
|
+
expect(input.payer_info).to be_a(Braintree::PayerInfoInput)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "handles nil payer_info" do
|
|
28
|
+
attributes = {amount: {value: "10.00", currency_code: "EUR"}, type: "OXXO"}
|
|
29
|
+
input = Braintree::CreateLocalPaymentContextInput.new(attributes)
|
|
30
|
+
expect(input.payer_info).to be_nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#to_graphql_variables" do
|
|
35
|
+
it "converts to graphql variables with camelCase keys" do
|
|
36
|
+
input = Braintree::CreateLocalPaymentContextInput.new(input_data)
|
|
37
|
+
expected_variables = {
|
|
38
|
+
"paymentContext" => {
|
|
39
|
+
"amount" => {"value" => "10.00", "currencyCode" => "EUR"},
|
|
40
|
+
"orderId" => "order-123",
|
|
41
|
+
"payerInfo" => {
|
|
42
|
+
"givenName" => "John",
|
|
43
|
+
"surname" => "Doe"
|
|
44
|
+
},
|
|
45
|
+
"type" => Braintree::LocalPaymentType::MBWAY
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
expect(input.to_graphql_variables).to eq(expected_variables)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe "#inspect" do
|
|
54
|
+
it "returns formatted string" do
|
|
55
|
+
input = Braintree::CreateLocalPaymentContextInput.new(input_data)
|
|
56
|
+
result = input.inspect
|
|
57
|
+
|
|
58
|
+
expect(result).to include("CreateLocalPaymentContextInput")
|
|
59
|
+
expect(result).to include("amount:")
|
|
60
|
+
expect(result).to include("type:")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|