braintree 4.4.0 → 4.5.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/plan.rb +20 -0
- data/lib/braintree/plan_gateway.rb +100 -0
- data/lib/braintree/successful_result.rb +1 -0
- data/lib/braintree/transaction_review.rb +18 -0
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree/webhook_notification.rb +3 -0
- data/lib/braintree/webhook_testing_gateway.rb +15 -0
- data/spec/integration/braintree/plan_spec.rb +82 -0
- data/spec/unit/braintree/webhook_notification_spec.rb +18 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34698c59add2b3613d0c75e58d2d9d8ee5f3aecdd6ef85c79e303211199b4fa8
|
4
|
+
data.tar.gz: 933cf9e7d93aec94ba227fef1f03e4f245b7e0e4512b57ebf96ddd9ffef89cab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d44a8addd727ea6efe503a33c275956bf0a359abe402ee42fff43785b48e30a84a29ecf6e6cbf8aacb080e8562e553f6c9c2424878575815f08cd563647e6762
|
7
|
+
data.tar.gz: 4b631596ff355ee26deceac5c37b61e66b0c5cf5336392120df61802be53b276cf2ebf9d93c6fb64dae3bea06d3dcb925644620aa829afaf7d2382328e7b2152
|
data/lib/braintree/plan.rb
CHANGED
@@ -33,6 +33,26 @@ module Braintree
|
|
33
33
|
|
34
34
|
class << self
|
35
35
|
protected :new
|
36
|
+
|
37
|
+
def create(*args)
|
38
|
+
Configuration.gateway.plan.create(*args)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create!(*args)
|
42
|
+
Configuration.gateway.plan.create!(*args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def find(*args)
|
46
|
+
Configuration.gateway.plan.find(*args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def update(*args)
|
50
|
+
Configuration.gateway.plan.update(*args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def update!(*args)
|
54
|
+
Configuration.gateway.plan.update!(*args)
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
58
|
def self._new(*args)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Braintree
|
2
2
|
class PlanGateway # :nodoc:
|
3
|
+
include BaseModule
|
4
|
+
|
3
5
|
def initialize(gateway)
|
4
6
|
@gateway = gateway
|
5
7
|
@config = gateway.config
|
@@ -13,5 +15,103 @@ module Braintree
|
|
13
15
|
Plan._new(@gateway, attributes)
|
14
16
|
end
|
15
17
|
end
|
18
|
+
|
19
|
+
def create(attributes)
|
20
|
+
Util.verify_keys(PlanGateway._create_signature, attributes)
|
21
|
+
_do_create "/plans", :plan => attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
def create!(*args)
|
25
|
+
return_object_or_raise(:plan) { create(*args) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def find(id)
|
29
|
+
raise ArgumentError if id.nil? || id.to_s.strip == ""
|
30
|
+
response = @config.http.get("#{@config.base_merchant_path}/plans/#{id}")
|
31
|
+
Plan._new(@gateway, response[:plan])
|
32
|
+
rescue NotFoundError
|
33
|
+
raise NotFoundError, "plan with id #{id.inspect} not found"
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(plan_id, attributes)
|
37
|
+
Util.verify_keys(PlanGateway._update_signature, attributes)
|
38
|
+
response = @config.http.put("#{@config.base_merchant_path}/plans/#{plan_id}", :plan => attributes)
|
39
|
+
if response[:plan]
|
40
|
+
SuccessfulResult.new(:plan => Plan._new(@gateway, response[:plan]))
|
41
|
+
elsif response[:api_error_response]
|
42
|
+
ErrorResult.new(@gateway, response[:api_error_response])
|
43
|
+
else
|
44
|
+
raise UnexpectedError, "expected :plan or :api_error_response"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def update!(*args)
|
49
|
+
return_object_or_raise(:plan) { update(*args) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def self._create_signature
|
53
|
+
[
|
54
|
+
:billing_day_of_month,
|
55
|
+
:billing_frequency,
|
56
|
+
:currency_iso_code,
|
57
|
+
:description,
|
58
|
+
:id,
|
59
|
+
:merchant_id,
|
60
|
+
:name,
|
61
|
+
:number_of_billing_cycles,
|
62
|
+
:price,
|
63
|
+
:trial_duration,
|
64
|
+
:trial_duration_unit,
|
65
|
+
:trial_period
|
66
|
+
] + _add_on_discount_signature
|
67
|
+
end
|
68
|
+
|
69
|
+
def self._update_signature
|
70
|
+
[
|
71
|
+
:billing_day_of_month,
|
72
|
+
:billing_frequency,
|
73
|
+
:currency_iso_code,
|
74
|
+
:description,
|
75
|
+
:id,
|
76
|
+
:merchant_id,
|
77
|
+
:name,
|
78
|
+
:number_of_billing_cycles,
|
79
|
+
:price,
|
80
|
+
:trial_duration,
|
81
|
+
:trial_duration_unit,
|
82
|
+
:trial_period
|
83
|
+
] + _add_on_discount_signature
|
84
|
+
end
|
85
|
+
|
86
|
+
def self._add_on_discount_signature
|
87
|
+
[
|
88
|
+
{
|
89
|
+
:add_ons => [
|
90
|
+
{:add => [:amount, :inherited_from_id, :never_expires, :number_of_billing_cycles, :quantity]},
|
91
|
+
{:update => [:amount, :existing_id, :never_expires, :number_of_billing_cycles, :quantity]},
|
92
|
+
{:remove => [:_any_key_]}
|
93
|
+
]
|
94
|
+
},
|
95
|
+
{
|
96
|
+
:discounts => [
|
97
|
+
{:add => [:amount, :inherited_from_id, :never_expires, :number_of_billing_cycles, :quantity]},
|
98
|
+
{:update => [:amount, :existing_id, :never_expires, :number_of_billing_cycles, :quantity]},
|
99
|
+
{:remove => [:_any_key_]}
|
100
|
+
]
|
101
|
+
}
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
def _do_create(path, params) # :nodoc:
|
106
|
+
response = @config.http.post("#{@config.base_merchant_path}#{path}", params)
|
107
|
+
if response[:plan]
|
108
|
+
SuccessfulResult.new(:plan => Plan._new(@gateway, response[:plan]))
|
109
|
+
elsif response[:errors]
|
110
|
+
ErrorResult.new(@gateway, response[:errors])
|
111
|
+
else
|
112
|
+
raise UnexpectedError, "expected :plan or :errors"
|
113
|
+
end
|
114
|
+
end
|
16
115
|
end
|
17
116
|
end
|
117
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Braintree
|
2
|
+
class TransactionReview
|
3
|
+
include BaseModule
|
4
|
+
|
5
|
+
attr_reader :transaction_id, :decision, :reviewer_email, :reviewer_note, :reviewer_time
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
set_instance_variables_from_hash(attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
protected :new
|
13
|
+
def _new(*args) # :nodoc:
|
14
|
+
self.new(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/braintree/version.rb
CHANGED
@@ -54,6 +54,7 @@ module Braintree
|
|
54
54
|
SubMerchantAccountDeclined = "sub_merchant_account_declined"
|
55
55
|
|
56
56
|
TransactionDisbursed = "transaction_disbursed"
|
57
|
+
TransactionReviewed = "transaction_reviewed"
|
57
58
|
TransactionSettlementDeclined = "transaction_settlement_declined"
|
58
59
|
TransactionSettled = "transaction_settled"
|
59
60
|
end
|
@@ -76,6 +77,7 @@ module Braintree
|
|
76
77
|
attr_reader :subscription
|
77
78
|
attr_reader :timestamp
|
78
79
|
attr_reader :transaction
|
80
|
+
attr_reader :transaction_review
|
79
81
|
|
80
82
|
def self.parse(*args)
|
81
83
|
Configuration.gateway.webhook_notification.parse(*args)
|
@@ -94,6 +96,7 @@ module Braintree
|
|
94
96
|
@oauth_access_revocation = OpenStruct.new(@subject[:oauth_application_revocation]) if @subject.has_key?(:oauth_application_revocation)
|
95
97
|
@subscription = Subscription._new(gateway, @subject[:subscription]) if @subject.has_key?(:subscription)
|
96
98
|
@transaction = Transaction._new(gateway, @subject[:transaction]) if @subject.has_key?(:transaction)
|
99
|
+
@transaction_review = OpenStruct.new(@subject[:transaction_review]) if @subject.has_key?(:transaction_review)
|
97
100
|
@disbursement = Disbursement._new(gateway, @subject[:disbursement]) if @subject.has_key?(:disbursement)
|
98
101
|
@dispute = Dispute._new(@subject[:dispute]) if @subject.has_key?(:dispute)
|
99
102
|
@account_updater_daily_report = AccountUpdaterDailyReport._new(@subject[:account_updater_daily_report]) if @subject.has_key?(:account_updater_daily_report)
|
@@ -60,6 +60,8 @@ module Braintree
|
|
60
60
|
_merchant_account_declined_sample_xml(id)
|
61
61
|
when Braintree::WebhookNotification::Kind::TransactionDisbursed
|
62
62
|
_transaction_disbursed_sample_xml(id)
|
63
|
+
when Braintree::WebhookNotification::Kind::TransactionReviewed
|
64
|
+
_transaction_reviewed_sample_xml(id)
|
63
65
|
when Braintree::WebhookNotification::Kind::TransactionSettled
|
64
66
|
_transaction_settled_sample_xml(id)
|
65
67
|
when Braintree::WebhookNotification::Kind::TransactionSettlementDeclined
|
@@ -248,6 +250,19 @@ module Braintree
|
|
248
250
|
XML
|
249
251
|
end
|
250
252
|
|
253
|
+
def _transaction_reviewed_sample_xml(id)
|
254
|
+
|
255
|
+
<<-XML
|
256
|
+
<transaction-review>
|
257
|
+
<transaction-id>my_id</transaction-id>
|
258
|
+
<decision>decision</decision>
|
259
|
+
<reviewer-email>hey@girl.com</reviewer-email>
|
260
|
+
<reviewer-note>i reviewed this</reviewer-note>
|
261
|
+
<reviewed-time type="datetime">2017-06-16T20:44:41Z</reviewed-time>
|
262
|
+
</transaction-review>
|
263
|
+
XML
|
264
|
+
end
|
265
|
+
|
251
266
|
def _transaction_settled_sample_xml(id)
|
252
267
|
<<-XML
|
253
268
|
<transaction>
|
@@ -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::Plan do
|
4
5
|
|
@@ -48,6 +49,87 @@ describe Braintree::Plan do
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
52
|
+
describe "self.create" do
|
53
|
+
let(:attributes) do
|
54
|
+
{
|
55
|
+
:billing_day_of_month => 12,
|
56
|
+
:billing_frequency => 1,
|
57
|
+
:currency_iso_code => "USD",
|
58
|
+
:description => "description on create",
|
59
|
+
:name => "my new plan name",
|
60
|
+
:number_of_billing_cycles => 1,
|
61
|
+
:price => "9.99",
|
62
|
+
:trial_period => false
|
63
|
+
}
|
64
|
+
|
65
|
+
it "is successful with given params" do
|
66
|
+
result = Braintree::Plan.create(attributes)
|
67
|
+
expect(result.success?).to be_truthy
|
68
|
+
expect(result.plan.billing_day_of_month).to eq 12
|
69
|
+
expect(result.plan.description).to eq "description on create"
|
70
|
+
expect(result.plan.name).to eq "my new plan name"
|
71
|
+
expect(result.plan.price).to eq "9.99"
|
72
|
+
expect(result.plan.billing_frequency).to eq 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "self.find" do
|
78
|
+
it "finds a plan" do
|
79
|
+
plan = Braintree::Plan.create(
|
80
|
+
:billing_day_of_month => 12,
|
81
|
+
:billing_frequency => 1,
|
82
|
+
:currency_iso_code => "USD",
|
83
|
+
:description => "description on create",
|
84
|
+
:name => "my new plan name",
|
85
|
+
:number_of_billing_cycles => 1,
|
86
|
+
:price => "9.99",
|
87
|
+
:trial_period => false,
|
88
|
+
).plan
|
89
|
+
|
90
|
+
found_plan = Braintree::Plan.find(plan.id)
|
91
|
+
expect(found_plan.name).to eq plan.name
|
92
|
+
end
|
93
|
+
|
94
|
+
it "raises Braintree::NotFoundError if it cannot find" do
|
95
|
+
expect {
|
96
|
+
Braintree::Plan.find("noSuchPlan")
|
97
|
+
}.to raise_error(Braintree::NotFoundError, 'plan with id "noSuchPlan" not found')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "self.update!" do
|
102
|
+
before(:each) do
|
103
|
+
@plan = Braintree::Plan.create(
|
104
|
+
:billing_day_of_month => 12,
|
105
|
+
:billing_frequency => 1,
|
106
|
+
:currency_iso_code => "USD",
|
107
|
+
:description => "description on create",
|
108
|
+
:name => "my new plan name",
|
109
|
+
:number_of_billing_cycles => 1,
|
110
|
+
:price => "9.99",
|
111
|
+
:trial_period => false,
|
112
|
+
).plan
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns the updated plan if valid" do
|
116
|
+
new_id = rand(36**9).to_s(36)
|
117
|
+
plan = Braintree::Plan.update!(@plan.id,
|
118
|
+
:name => "updated name",
|
119
|
+
:price => 99.88,
|
120
|
+
)
|
121
|
+
|
122
|
+
expect(plan.name).to eq "updated name"
|
123
|
+
expect(plan.price).to eq BigDecimal("99.88")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "raises a ValidationsFailed if invalid" do
|
127
|
+
expect do
|
128
|
+
Braintree::Plan.update!(@plan.id, :number_of_billing_cycles => "number of billing cycles")
|
129
|
+
end.to raise_error(Braintree::ValidationsFailed)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
51
133
|
def create_plan_for_tests(attributes)
|
52
134
|
config = Braintree::Configuration.gateway.config
|
53
135
|
config.http.post("#{config.base_merchant_path}/plans/create_plan_for_tests", :plan => attributes)
|
@@ -317,6 +317,24 @@ describe Braintree::WebhookNotification do
|
|
317
317
|
end
|
318
318
|
end
|
319
319
|
|
320
|
+
context "transaction review" do
|
321
|
+
it " builds a sample notification for a transaction reviewed webhook" do
|
322
|
+
sample_notification = Braintree::WebhookTesting.sample_notification(
|
323
|
+
Braintree::WebhookNotification::Kind::TransactionReviewed,
|
324
|
+
"my_id",
|
325
|
+
)
|
326
|
+
|
327
|
+
notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
|
328
|
+
|
329
|
+
expect(notification.kind).to eq(Braintree::WebhookNotification::Kind::TransactionReviewed)
|
330
|
+
expect(notification.transaction_review.transaction_id).to eq("my_id")
|
331
|
+
expect(notification.transaction_review.decision).to eq("decision")
|
332
|
+
expect(notification.transaction_review.reviewer_email).to eq("hey@girl.com")
|
333
|
+
expect(notification.transaction_review.reviewer_note).to eq("i reviewed this")
|
334
|
+
expect(notification.transaction_review.reviewed_time).to_not be_nil
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
320
338
|
context "us bank account transactions" do
|
321
339
|
it "builds a sample notification for a settlement webhook" do
|
322
340
|
sample_notification = Braintree::WebhookTesting.sample_notification(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: braintree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Braintree
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -176,6 +176,7 @@ files:
|
|
176
176
|
- lib/braintree/transaction_gateway.rb
|
177
177
|
- lib/braintree/transaction_line_item.rb
|
178
178
|
- lib/braintree/transaction_line_item_gateway.rb
|
179
|
+
- lib/braintree/transaction_review.rb
|
179
180
|
- lib/braintree/transaction_search.rb
|
180
181
|
- lib/braintree/unknown_payment_method.rb
|
181
182
|
- lib/braintree/us_bank_account.rb
|
@@ -333,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
333
334
|
- !ruby/object:Gem::Version
|
334
335
|
version: '0'
|
335
336
|
requirements: []
|
336
|
-
rubygems_version: 3.2.
|
337
|
+
rubygems_version: 3.2.31
|
337
338
|
signing_key:
|
338
339
|
specification_version: 4
|
339
340
|
summary: Braintree Ruby Server SDK
|