affirm-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ module Affirm
2
+ module Objects
3
+ class Address
4
+ include Virtus.model
5
+
6
+ attribute :line1, String
7
+ attribute :line2, String
8
+ attribute :city, String
9
+ attribute :state, String
10
+ attribute :zipcode, String
11
+ attribute :country, String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Affirm
2
+ module Objects
3
+ class Billing
4
+ include Virtus.model
5
+
6
+ attribute :name, Contact
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Affirm
2
+ module Objects
3
+ class Contact
4
+ include Virtus.model
5
+
6
+ attribute :full, String
7
+ attribute :first, String
8
+ attribute :last, String
9
+ attribute :middle, String
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Affirm
2
+ module Objects
3
+ class Discount
4
+ include Virtus.model
5
+
6
+ attribute :discount_display_name, String
7
+ attribute :discount_amount, Integer
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module Affirm
2
+ module Objects
3
+ class Event
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :transaction_id, String
8
+ attribute :currency, String
9
+ attribute :amount, Integer
10
+ attribute :type, String
11
+ attribute :created, DateTime
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module Affirm
2
+ module Objects
3
+ class Item
4
+ include Virtus.model
5
+
6
+ attribute :sku, String
7
+ attribute :display_name, String
8
+ attribute :unit_price, Integer
9
+ attribute :qty, Integer
10
+ attribute :item_type, String
11
+ attribute :item_url, String
12
+ attribute :item_image_url, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Affirm
2
+ module Objects
3
+ class Order
4
+ include Virtus.model
5
+
6
+ attribute :currency, Integer
7
+ attribute :tax_amount, Integer
8
+ attribute :shipping_amount, Integer
9
+ attribute :total, Integer
10
+ attribute :discounts, Hash[String => Discount]
11
+ attribute :items, Hash[String => Item]
12
+ attribute :billing, Billing
13
+ attribute :shipping, Shipping
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Affirm
2
+ module Objects
3
+ class Shipping
4
+ include Virtus.model
5
+
6
+ attribute :name, Contact
7
+ attribute :address, Address
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Affirm
2
+ module Responses
3
+ class Auth
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :status, String
8
+ attribute :user_id, String
9
+ attribute :currency, String
10
+ attribute :amount, Integer
11
+ attribute :auth_hold, Integer
12
+ attribute :payable, Integer
13
+ attribute :pending, Boolean
14
+ attribute :void, Boolean
15
+ attribute :under_dispute, Boolean
16
+ attribute :events, Array[Objects::Event]
17
+ attribute :details, Objects::Order
18
+ attribute :created, DateTime
19
+ attribute :expires, DateTime
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Affirm
2
+ module Responses
3
+ class Capture
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :transaction_id, String
8
+ attribute :currency, String
9
+ attribute :amount, Integer
10
+ attribute :fee, Integer
11
+ attribute :created, DateTime
12
+ attribute :type, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Affirm
2
+ module Responses
3
+ class Error
4
+ include Virtus.model
5
+
6
+ attribute :status_code, Integer
7
+ attribute :type, String
8
+ attribute :code, String
9
+ attribute :message, String
10
+ attribute :field, String
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Affirm
2
+ module Responses
3
+ class Refund
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :transaction_id, String
8
+ attribute :amount, Integer
9
+ attribute :fee_refunded, Integer
10
+ attribute :created, DateTime
11
+ attribute :type, String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Affirm
2
+ module Responses
3
+ class Update
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :order_id, String
8
+ attribute :shipping_carrier, String
9
+ attribute :shipping_confirmation, String
10
+ attribute :created, DateTime
11
+ attribute :type, String
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ module Affirm
2
+ module Responses
3
+ class Void
4
+ include Virtus.model
5
+
6
+ attribute :id, String
7
+ attribute :transaction_id, String
8
+ attribute :created, DateTime
9
+ attribute :type, String
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ module Affirm
2
+ class SuccessResult
3
+ attr_reader :object
4
+ private :object
5
+
6
+ def initialize(object)
7
+ @object = object
8
+ end
9
+
10
+ def success?
11
+ true
12
+ end
13
+
14
+ def method_missing(method_name, *arguments, &block)
15
+ if object.respond_to?(method_name)
16
+ object.send(method_name, *arguments, &block)
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def respond_to_missing?(method_name, include_private = false)
23
+ object.respond_to?(method_name) || super
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Affirm
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,131 @@
1
+ RSpec.shared_examples "a charge object interface" do
2
+ %w(
3
+ id
4
+ status
5
+ user_id
6
+ currency
7
+ amount
8
+ auth_hold
9
+ payable
10
+ pending
11
+ void
12
+ under_dispute
13
+ ).each do |method|
14
+ it method do
15
+ expect(subject.public_send(method)).to eq(body[method])
16
+ end
17
+ end
18
+
19
+ it "created" do
20
+ expect(
21
+ to_seconds(subject.created)
22
+ ).to eq(to_seconds(body["created"]))
23
+ end
24
+
25
+ it "expires" do
26
+ expect(
27
+ to_seconds(subject.expires)
28
+ ).to eq(to_seconds(body["expires"]))
29
+ end
30
+
31
+ %w(
32
+ id
33
+ transaction_id
34
+ currency
35
+ amount
36
+ type
37
+ ).each do |method|
38
+ it "events.#{method}" do
39
+ expect(
40
+ subject.events.first.public_send(method)
41
+ ).to eq(body["events"].first[method])
42
+ end
43
+ end
44
+
45
+ it "events.created" do
46
+ expect(
47
+ to_seconds(subject.events.first.created)
48
+ ).to eq(to_seconds(body["events"].first["created"]))
49
+ end
50
+
51
+ %w(
52
+ currency
53
+ tax_amount
54
+ shipping_amount
55
+ total
56
+ ).each do |method|
57
+ it "details.#{method}" do
58
+ expect(
59
+ subject.details.public_send(method)
60
+ ).to eq(body["details"][method])
61
+ end
62
+ end
63
+
64
+ %w(
65
+ discount_display_name
66
+ discount_amount
67
+ ).each do |method|
68
+ it "details.discounts.#{method}" do
69
+ expect(
70
+ subject.details.discounts["discount_name"].public_send(method)
71
+ ).to eq(body["details"]["discounts"]["discount_name"][method])
72
+ end
73
+ end
74
+
75
+ %w(
76
+ sku
77
+ display_name
78
+ unit_price
79
+ qty
80
+ item_type
81
+ item_url
82
+ item_image_url
83
+ ).each do |method|
84
+ it "details.items.#{method}" do
85
+ expect(
86
+ subject.details.items["ABC-123"].public_send(method)
87
+ ).to eq(body["details"]["items"]["ABC-123"][method])
88
+ end
89
+ end
90
+
91
+ %w(
92
+ full
93
+ first
94
+ last
95
+ middle
96
+ ).each do |method|
97
+ it "details.billing.name.#{method}" do
98
+ expect(
99
+ subject.details.billing.name.public_send(method)
100
+ ).to eq(body["details"]["billing"]["name"][method])
101
+ end
102
+ end
103
+
104
+ %w(
105
+ full
106
+ first
107
+ last
108
+ middle
109
+ ).each do |method|
110
+ it "details.shipping.name.#{method}" do
111
+ expect(
112
+ subject.details.shipping.name.public_send(method)
113
+ ).to eq(body["details"]["shipping"]["name"][method])
114
+ end
115
+ end
116
+
117
+ %w(
118
+ line1
119
+ line2
120
+ city
121
+ state
122
+ zipcode
123
+ country
124
+ ).each do |method|
125
+ it "details.shipping.address.#{method}" do
126
+ expect(
127
+ subject.details.shipping.address.public_send(method)
128
+ ).to eq(body["details"]["shipping"]["address"][method])
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,337 @@
1
+ require "helper"
2
+ require_relative "charge_object_interface"
3
+
4
+ RSpec.describe Affirm::Charge do
5
+ let(:failed_response) { double(:response, success?: false, body: Hash.new) }
6
+
7
+ context "authorize" do
8
+ context "with failed response" do
9
+ subject { described_class }
10
+
11
+ before do
12
+ expect(Affirm::Client).to receive(:request)
13
+ .with(:post, "charges", checkout_token: "ABC")
14
+ .and_return(failed_response)
15
+ end
16
+
17
+ it "returns failure object" do
18
+ expect(
19
+ subject.authorize("ABC")
20
+ ).to be_an_instance_of(Affirm::FailureResult)
21
+ end
22
+ end
23
+
24
+ context "with successful response" do
25
+ subject { described_class.authorize("ABC") }
26
+
27
+ let(:body) do
28
+ JSON.load(
29
+ File.read(File.expand_path("../fixtures/auth.json", __FILE__))
30
+ )
31
+ end
32
+
33
+ let(:successful_response) do
34
+ double(:response, success?: true, body: body)
35
+ end
36
+
37
+ before do
38
+ expect(Affirm::Client).to receive(:request)
39
+ .with(:post, "charges", checkout_token: "ABC")
40
+ .and_return(successful_response)
41
+ end
42
+
43
+ it_behaves_like "a charge object interface"
44
+ end
45
+ end
46
+
47
+ context "find" do
48
+ context "with failed response" do
49
+ subject { described_class }
50
+
51
+ before do
52
+ expect(Affirm::Client).to receive(:request)
53
+ .with(:get, "charges/1")
54
+ .and_return(failed_response)
55
+ end
56
+
57
+ it "returns failure object" do
58
+ expect(
59
+ subject.find(1)
60
+ ).to be_an_instance_of(Affirm::FailureResult)
61
+ end
62
+ end
63
+
64
+ context "with successful response" do
65
+ subject { described_class.find("ABC") }
66
+
67
+ let(:body) do
68
+ JSON.load(
69
+ File.read(File.expand_path("../fixtures/auth.json", __FILE__))
70
+ )
71
+ end
72
+
73
+ let(:successful_response) do
74
+ double(:response, success?: true, body: body)
75
+ end
76
+
77
+ before do
78
+ expect(Affirm::Client).to receive(:request)
79
+ .with(:get, "charges/ABC")
80
+ .and_return(successful_response)
81
+ end
82
+
83
+ it_behaves_like "a charge object interface"
84
+ end
85
+ end
86
+
87
+ context "capture" do
88
+ context "with failed response" do
89
+ subject { described_class }
90
+
91
+ before do
92
+ expect(Affirm::Client).to receive(:request)
93
+ .with(:post, "charges/1/capture")
94
+ .and_return(failed_response)
95
+ end
96
+
97
+ it "returns failure object" do
98
+ expect(
99
+ subject.capture(1)
100
+ ).to be_an_instance_of(Affirm::FailureResult)
101
+ end
102
+ end
103
+
104
+ context "with successful response" do
105
+ subject { described_class.capture(1) }
106
+
107
+ let(:body) do
108
+ {
109
+ "id" => "ABC-111",
110
+ "transaction_id" => "XYZ-999",
111
+ "currency" => "USD",
112
+ "amount" => 100,
113
+ "fee" => 10,
114
+ "created" => Time.local(2015, 1, 1),
115
+ "type" => "capture"
116
+ }
117
+ end
118
+
119
+ let(:successful_response) do
120
+ double(:response, success?: true, body: body)
121
+ end
122
+
123
+ before do
124
+ expect(Affirm::Client).to receive(:request)
125
+ .with(:post, "charges/1/capture")
126
+ .and_return(successful_response)
127
+ end
128
+
129
+ %w(
130
+ id
131
+ transaction_id
132
+ currency
133
+ amount
134
+ fee
135
+ type
136
+ ).each do |method|
137
+ it method do
138
+ expect(subject.public_send(method)).to eq(body[method])
139
+ end
140
+ end
141
+
142
+ it "created" do
143
+ expect(to_seconds(subject.created)).to eq(to_seconds(body["created"]))
144
+ end
145
+ end
146
+ end
147
+
148
+ context "void" do
149
+ context "with failed response" do
150
+ subject { described_class }
151
+
152
+ before do
153
+ expect(Affirm::Client).to receive(:request)
154
+ .with(:post, "charges/1/void")
155
+ .and_return(failed_response)
156
+ end
157
+
158
+ it "returns failure object" do
159
+ expect(
160
+ subject.void(1)
161
+ ).to be_an_instance_of(Affirm::FailureResult)
162
+ end
163
+ end
164
+
165
+ context "with successful response" do
166
+ subject { described_class.void(1) }
167
+
168
+ let(:body) do
169
+ {
170
+ "id" => "ABC-111",
171
+ "transaction_id" => "XYZ-999",
172
+ "created" => Time.local(2015, 1, 1),
173
+ "type" => "void"
174
+ }
175
+ end
176
+
177
+ let(:successful_response) do
178
+ double(:response, success?: true, body: body)
179
+ end
180
+
181
+ before do
182
+ expect(Affirm::Client).to receive(:request)
183
+ .with(:post, "charges/1/void")
184
+ .and_return(successful_response)
185
+ end
186
+
187
+ %w(
188
+ id
189
+ transaction_id
190
+ type
191
+ ).each do |method|
192
+ it method do
193
+ expect(subject.public_send(method)).to eq(body[method])
194
+ end
195
+ end
196
+
197
+ it "created" do
198
+ expect(to_seconds(subject.created)).to eq(to_seconds(body["created"]))
199
+ end
200
+ end
201
+ end
202
+
203
+ context "refund" do
204
+ context "with failed response" do
205
+ subject { described_class }
206
+
207
+ before do
208
+ expect(Affirm::Client).to receive(:request)
209
+ .with(:post, "charges/1/refund", amount: 50)
210
+ .and_return(failed_response)
211
+ end
212
+
213
+ it "returns failure object" do
214
+ expect(
215
+ subject.refund(1, amount: 50)
216
+ ).to be_an_instance_of(Affirm::FailureResult)
217
+ end
218
+ end
219
+
220
+ context "with successful response" do
221
+ subject { described_class.refund(1, amount: 50) }
222
+
223
+ let(:body) do
224
+ {
225
+ "id" => "ABC-111",
226
+ "transaction_id" => "XYZ-999",
227
+ "amount" => 50,
228
+ "fee_refunded" => 0,
229
+ "created" => Time.local(2015, 1, 1),
230
+ "type" => "refund"
231
+ }
232
+ end
233
+
234
+ let(:successful_response) do
235
+ double(:response, success?: true, body: body)
236
+ end
237
+
238
+ before do
239
+ expect(Affirm::Client).to receive(:request)
240
+ .with(:post, "charges/1/refund", amount: 50)
241
+ .and_return(successful_response)
242
+ end
243
+
244
+ %w(
245
+ id
246
+ transaction_id
247
+ amount
248
+ fee_refunded
249
+ type
250
+ ).each do |method|
251
+ it method do
252
+ expect(subject.public_send(method)).to eq(body[method])
253
+ end
254
+ end
255
+
256
+ it "created" do
257
+ expect(to_seconds(subject.created)).to eq(to_seconds(body["created"]))
258
+ end
259
+ end
260
+ end
261
+
262
+ context "update" do
263
+ context "with failed response" do
264
+ subject { described_class }
265
+
266
+ before do
267
+ expect(Affirm::Client).to receive(:request)
268
+ .with(:post, "charges/1/update",
269
+ order_id: "XYZ-007",
270
+ shipping_carrier: "FedEx",
271
+ shipping_confirmation: "1ZX007")
272
+ .and_return(failed_response)
273
+ end
274
+
275
+ it "returns failure object" do
276
+ expect(
277
+ subject.update(1,
278
+ order_id: "XYZ-007",
279
+ shipping_carrier: "FedEx",
280
+ shipping_confirmation: "1ZX007"
281
+ )
282
+ ).to be_an_instance_of(Affirm::FailureResult)
283
+ end
284
+ end
285
+
286
+ context "with successful response" do
287
+ subject do
288
+ described_class.update(1,
289
+ order_id: "XYZ-007",
290
+ shipping_carrier: "FedEx",
291
+ shipping_confirmation: "1ZX007"
292
+ )
293
+ end
294
+
295
+ let(:body) do
296
+ {
297
+ "id" => "ABC-007",
298
+ "order_id" => "XYZ-007",
299
+ "shipping_carrier" => "FedEx",
300
+ "shipping_confirmation" => "1ZX007",
301
+ "created" => Time.local(2015, 1, 1),
302
+ "type" => "update"
303
+ }
304
+ end
305
+
306
+ let(:successful_response) do
307
+ double(:response, success?: true, body: body)
308
+ end
309
+
310
+ before do
311
+ expect(Affirm::Client).to receive(:request)
312
+ .with(:post, "charges/1/update",
313
+ order_id: "XYZ-007",
314
+ shipping_carrier: "FedEx",
315
+ shipping_confirmation: "1ZX007"
316
+ )
317
+ .and_return(successful_response)
318
+ end
319
+
320
+ %w(
321
+ id
322
+ order_id
323
+ shipping_carrier
324
+ shipping_confirmation
325
+ type
326
+ ).each do |method|
327
+ it method do
328
+ expect(subject.public_send(method)).to eq(body[method])
329
+ end
330
+ end
331
+
332
+ it "created" do
333
+ expect(to_seconds(subject.created)).to eq(to_seconds(body["created"]))
334
+ end
335
+ end
336
+ end
337
+ end