Skip to content

Commit c3de633

Browse files
authored
Merge pull request #190 from mollie/GH-187
Add order attributes to Payment API Closes GH-187
2 parents 59a28bc + 0ab3a06 commit c3de633

File tree

5 files changed

+221
-3
lines changed

5 files changed

+221
-3
lines changed

lib/mollie.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ module Mollie
4444
require 'mollie/order/shipment'
4545
require 'mollie/payment/capture'
4646
require 'mollie/payment/chargeback'
47+
require 'mollie/payment/line'
4748
require 'mollie/payment/refund'
4849
require 'mollie/settlement/capture'
4950
require 'mollie/settlement/chargeback'

lib/mollie/payment.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ class Payment < Base
4949
:cancel_url,
5050
:webhook_url
5151

52+
attr_reader :lines,
53+
:billing_address,
54+
:shipping_address
55+
5256
alias links _links
5357

5458
def open?
@@ -185,6 +189,18 @@ def amount_refunded=(amount_refunded)
185189
@amount_refunded = Mollie::Amount.new(amount_refunded)
186190
end
187191

192+
def lines=(lines)
193+
@lines = lines.map { |line| Payment::Line.new(line) }
194+
end
195+
196+
def billing_address=(address)
197+
@billing_address = OpenStruct.new(address) if address.is_a?(Hash)
198+
end
199+
200+
def shipping_address=(address)
201+
@shipping_address = OpenStruct.new(address) if address.is_a?(Hash)
202+
end
203+
188204
def checkout_url
189205
Util.extract_url(links, 'checkout')
190206
end

lib/mollie/payment/line.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module Mollie
2+
class Payment
3+
class Line < Base
4+
attr_accessor :type,
5+
:description,
6+
:quantity,
7+
:quantity_unit,
8+
:vat_rate,
9+
:sku,
10+
:categories,
11+
:image_url,
12+
:product_url
13+
14+
attr_reader :unit_price,
15+
:discount_amount,
16+
:recurring,
17+
:total_amount,
18+
:vat_amount
19+
20+
def discounted?
21+
!@discount_amount.nil?
22+
end
23+
24+
def unit_price=(amount)
25+
@unit_price = Mollie::Amount.new(amount)
26+
end
27+
28+
def discount_amount=(amount)
29+
@discount_amount = Mollie::Amount.new(amount)
30+
end
31+
32+
def recurring=(object)
33+
return if object.nil?
34+
35+
@recurring = OpenStruct.new(object).tap do |r|
36+
r.amount = Mollie::Amount.new(r.amount) if r.amount
37+
r.start_date = Date.parse(r.start_date) if r.start_date
38+
end
39+
end
40+
41+
def total_amount=(amount)
42+
@total_amount = Mollie::Amount.new(amount)
43+
end
44+
45+
def vat_amount=(amount)
46+
@vat_amount = Mollie::Amount.new(amount)
47+
end
48+
end
49+
end
50+
end

lib/mollie/util.rb

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,31 @@ def nested_underscore_keys(obj)
1414
end
1515
end
1616

17-
def camelize_keys(hash)
18-
hash.each_with_object({}) do |(key, value), camelized|
19-
camelized[camelize(key)] = value
17+
CAMELIZE_NESTED = [
18+
:lines,
19+
"lines",
20+
:recurring,
21+
"recurring",
22+
:billing_address,
23+
"billing_address",
24+
:shipping_address,
25+
"shipping_address"
26+
].freeze
27+
28+
def camelize_keys(object)
29+
case object
30+
when Hash
31+
object.each_with_object({}) do |(key, value), camelized|
32+
camelized[camelize(key)] = if CAMELIZE_NESTED.include?(key)
33+
camelize_keys(value)
34+
else
35+
value
36+
end
37+
end
38+
when Array
39+
object.map { |value| camelize_keys(value) }
40+
else
41+
object
2042
end
2143
end
2244

test/mollie/payment_test.rb

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,135 @@ def test_refunded?
124124
assert_false Payment.new([]).refunded?
125125
end
126126

127+
def test_payment_lines_attributes
128+
attributes = {
129+
resource: "payment",
130+
id: "tr_7UhSN1zuXS",
131+
lines: [{
132+
type: "physical",
133+
description: "LEGO 4440 Forest Police Station",
134+
quantity: 1,
135+
quantity_unit: "pcs",
136+
unit_price: { value: "89.00", currency: "EUR" },
137+
discount_amount: { value: "10.00", currency: "EUR" },
138+
recurring: {
139+
description: "A description of the recurring item.",
140+
interval: "3 months",
141+
amount: { value: "29.00", currency: "EUR" },
142+
times: 4,
143+
start_date: "2025-05-04"
144+
},
145+
total_amount: { value: "95.59", currency: "EUR" },
146+
vat_rate: "21.00",
147+
vat_amount: { value: "16.59", currency: "EUR" },
148+
sku: "SKU-12345",
149+
categories: ["eco", "meal", "gift", "sport_culture"],
150+
image_url: "https://example.org/lego-4440-forest-police-station.jpg",
151+
product_url: "https://example.org/lego-4440-forest-police-station"
152+
}]
153+
}
154+
155+
payment = Payment.new(attributes)
156+
line = payment.lines.first
157+
158+
assert_equal Payment::Line, line.class
159+
assert_equal "physical", line.type
160+
assert_equal "LEGO 4440 Forest Police Station", line.description
161+
assert_equal 1, line.quantity
162+
assert_equal "pcs", line.quantity_unit
163+
assert_equal 89.00, line.unit_price.value
164+
assert_equal "EUR", line.unit_price.currency
165+
assert_equal 10.00, line.discount_amount.value
166+
assert_equal "EUR", line.discount_amount.currency
167+
assert_equal 95.59, line.total_amount.value
168+
assert_equal "EUR", line.total_amount.currency
169+
assert_equal "21.00", line.vat_rate
170+
assert_equal 16.59, line.vat_amount.value
171+
assert_equal "EUR", line.vat_amount.currency
172+
assert_equal "SKU-12345", line.sku
173+
assert_equal ["eco", "meal", "gift", "sport_culture"], line.categories
174+
assert_equal "https://example.org/lego-4440-forest-police-station.jpg", line.image_url
175+
assert_equal "https://example.org/lego-4440-forest-police-station", line.product_url
176+
177+
# Recurring object
178+
assert_equal "A description of the recurring item.", line.recurring.description
179+
assert_equal "3 months", line.recurring.interval
180+
assert_equal 29.00, line.recurring.amount.value
181+
assert_equal "EUR", line.recurring.amount.currency
182+
assert_equal 4, line.recurring.times
183+
assert_equal Date.parse("2025-05-04"), line.recurring.start_date
184+
end
185+
186+
def test_billing_address
187+
attributes = {
188+
resource: "payment",
189+
id: "tr_7UhSN1zuXS",
190+
billing_address: {
191+
title: "Dhr",
192+
given_name: "Piet",
193+
family_name: "Mondriaan",
194+
organization_name: "Mollie B.V.",
195+
street_and_number: "Keizersgracht 313",
196+
street_additional: "apt",
197+
postal_code: "1234AB",
198+
email: "piet@mondriaan.com",
199+
phone: "+31208202070",
200+
city: "Amsterdam",
201+
region: "Noord-Holland",
202+
country: "NL"
203+
}
204+
}
205+
206+
payment = Payment.new(attributes)
207+
assert_equal "Dhr", payment.billing_address.title
208+
assert_equal "Piet", payment.billing_address.given_name
209+
assert_equal "Mondriaan", payment.billing_address.family_name
210+
assert_equal "Mollie B.V.", payment.billing_address.organization_name
211+
assert_equal "Keizersgracht 313", payment.billing_address.street_and_number
212+
assert_equal "apt", payment.billing_address.street_additional
213+
assert_equal "1234AB", payment.billing_address.postal_code
214+
assert_equal "piet@mondriaan.com", payment.billing_address.email
215+
assert_equal "+31208202070", payment.billing_address.phone
216+
assert_equal "Amsterdam", payment.billing_address.city
217+
assert_equal "Noord-Holland", payment.billing_address.region
218+
assert_equal "NL", payment.billing_address.country
219+
end
220+
221+
def test_shipping_address
222+
attributes = {
223+
resource: "payment",
224+
id: "tr_7UhSN1zuXS",
225+
shipping_address: {
226+
title: "Dhr",
227+
given_name: "Piet",
228+
family_name: "Mondriaan",
229+
organization_name: "Mollie B.V.",
230+
street_and_number: "Keizersgracht 313",
231+
street_additional: "apt",
232+
postal_code: "1234AB",
233+
email: "piet@mondriaan.com",
234+
phone: "+31208202070",
235+
city: "Amsterdam",
236+
region: "Noord-Holland",
237+
country: "NL"
238+
}
239+
}
240+
241+
payment = Payment.new(attributes)
242+
assert_equal "Dhr", payment.shipping_address.title
243+
assert_equal "Piet", payment.shipping_address.given_name
244+
assert_equal "Mondriaan", payment.shipping_address.family_name
245+
assert_equal "Mollie B.V.", payment.shipping_address.organization_name
246+
assert_equal "Keizersgracht 313", payment.shipping_address.street_and_number
247+
assert_equal "apt", payment.shipping_address.street_additional
248+
assert_equal "1234AB", payment.shipping_address.postal_code
249+
assert_equal "piet@mondriaan.com", payment.shipping_address.email
250+
assert_equal "+31208202070", payment.shipping_address.phone
251+
assert_equal "Amsterdam", payment.shipping_address.city
252+
assert_equal "Noord-Holland", payment.shipping_address.region
253+
assert_equal "NL", payment.shipping_address.country
254+
end
255+
127256
def test_create_payment
128257
stub_request(:post, 'https://api.mollie.com/v2/payments')
129258
.with(body: %({"amount":{"value":1.95,"currency":"EUR"}}))

0 commit comments

Comments
 (0)