affirm-ruby 0.0.1

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.
@@ -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