payson_api 0.1.0 → 0.2.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.
- data/Guardfile +1 -1
- data/README.rdoc +7 -7
- data/lib/payson_api/config.rb +13 -1
- data/lib/payson_api/envelope.rb +1 -1
- data/lib/payson_api/funding.rb +4 -1
- data/lib/payson_api/order_item.rb +1 -1
- data/lib/payson_api/receiver.rb +14 -5
- data/lib/payson_api/request/payment.rb +38 -7
- data/lib/payson_api/request/payment_update.rb +3 -0
- data/lib/payson_api/response/payment_details.rb +3 -1
- data/lib/payson_api/sender.rb +2 -2
- data/lib/payson_api/shipping_address.rb +5 -5
- data/lib/payson_api/version.rb +1 -1
- data/test/fixtures/payment_data.yml +16 -2
- data/test/integration/payment_details_test.rb +1 -4
- data/test/integration/payment_test.rb +14 -0
- data/test/test_helper.rb +16 -1
- metadata +2 -2
data/Guardfile
CHANGED
data/README.rdoc
CHANGED
@@ -38,7 +38,10 @@ You can configure the following default values by overriding these values using
|
|
38
38
|
receivers = []
|
39
39
|
receivers << PaysonAPI::Receiver.new(
|
40
40
|
email = 'me@mydomain.com',
|
41
|
-
amount = 100
|
41
|
+
amount = 100,
|
42
|
+
first_name = 'Me',
|
43
|
+
last_name = 'Just me',
|
44
|
+
primary = true
|
42
45
|
)
|
43
46
|
|
44
47
|
sender = PaysonAPI::Sender.new(
|
@@ -116,8 +119,8 @@ This example assumes the use of the Rails web framework.
|
|
116
119
|
ipn_response = PaysonAPI::Response::IPN.new(request_body)
|
117
120
|
|
118
121
|
# Do business stuff, e.g. update the corresponding order:
|
119
|
-
# order = Order.find_by_payson_token(
|
120
|
-
# order.payson_status =
|
122
|
+
# order = Order.find_by_payson_token(ipn_response.token)
|
123
|
+
# order.payson_status = ipn_response.status
|
121
124
|
# order.save!
|
122
125
|
|
123
126
|
# Create a new IPN request object containing the raw response from above
|
@@ -134,10 +137,7 @@ This example assumes the use of the Rails web framework.
|
|
134
137
|
|
135
138
|
== Todo
|
136
139
|
|
137
|
-
|
138
|
-
|
139
|
-
* Validate - Validate an IPN (Instant Payment Notification).
|
140
|
-
|
140
|
+
Nothing at the moment. Will focus on writing more thourough test cases and look over the code all in all.
|
141
141
|
|
142
142
|
|
143
143
|
== Build Status {<img src="https://secure.travis-ci.org/stoffus/payson_api.png"/>}[http://travis-ci.org/stoffus/payson_api]
|
data/lib/payson_api/config.rb
CHANGED
@@ -11,8 +11,20 @@ module PaysonAPI
|
|
11
11
|
PAYSON_API_PAYMENT_UPDATE_ACTION = "PaymentUpdate"
|
12
12
|
PAYSON_API_PAYMENT_VALIDATE_ACTION = "Validate"
|
13
13
|
|
14
|
-
LOCALES = %w[SV FI
|
14
|
+
LOCALES = %w[SV EN FI]
|
15
15
|
CURRENCIES = %w[SEK EUR]
|
16
|
+
FEES_PAYERS = %w[EACHRECEIVER SENDER PRIMARYRECEIVER SECONDARYONLY]
|
17
|
+
FUNDING_CONSTRAINTS = %w[CREDITCARD BANK INVOICE]
|
18
|
+
GUARANTEE_OFFERINGS = %w[OPTIONAL REQUIRED NO]
|
19
|
+
PAYMENT_STATUSES = %w[CREATED PENDING PROCESSING COMPLETED CREDITED
|
20
|
+
INCOMPLETE ERROR EXPIRED REVERSALERROR ABORTED]
|
21
|
+
PAYMENT_TYPES = %w[TRANSFER GUARANTEE INVOICE]
|
22
|
+
GUARANTEE_STATUSES = %w[WAITINGFORSEND WAITINGFORACCEPTANCE WAITINGFORRETURN
|
23
|
+
WAITINGFORRETURNACCEPTANCE RETURNNOTACCEPTED NOTRECEIVED RETURNNOTRECEIVED
|
24
|
+
MONEYRETURNEDTOSENDER RETURNACCEPTED
|
25
|
+
]
|
26
|
+
INVOICE_STATUSES = %w[PENDING ORDERCREATED CANCELED SHIPPED DONE CREDITED]
|
27
|
+
PAYMENT_ACTIONS = %w[CANCELORDER SHIPORDER CREDITORDER REFUND]
|
16
28
|
|
17
29
|
def configure(&block)
|
18
30
|
yield @config ||= Configuration.new
|
data/lib/payson_api/envelope.rb
CHANGED
@@ -13,7 +13,7 @@ class Envelope
|
|
13
13
|
|
14
14
|
def self.parse(data)
|
15
15
|
ack = data[FORMAT_STRING % 'ack']
|
16
|
-
timestamp = DateTime.parse(CGI.unescape(data[FORMAT_STRING % 'timestamp']))
|
16
|
+
timestamp = DateTime.parse(CGI.unescape(data[FORMAT_STRING % 'timestamp'].to_s))
|
17
17
|
correlation_id = data[FORMAT_STRING % 'correlationId']
|
18
18
|
self.new(ack, timestamp, correlation_id)
|
19
19
|
end
|
data/lib/payson_api/funding.rb
CHANGED
@@ -4,6 +4,9 @@ class Funding
|
|
4
4
|
attr_accessor :constraint
|
5
5
|
|
6
6
|
def initialize(constraint)
|
7
|
+
if !FUNDING_CONSTRAINTS.include?(constraint)
|
8
|
+
raise "Unknown funding constraint: #{constraint}"
|
9
|
+
end
|
7
10
|
@constraint = constraint
|
8
11
|
end
|
9
12
|
|
@@ -11,7 +14,7 @@ class Funding
|
|
11
14
|
{}.tap do |hash|
|
12
15
|
fundings.each_with_index do |funding, index|
|
13
16
|
hash.merge!({
|
14
|
-
FORMAT_STRING % [index, '
|
17
|
+
FORMAT_STRING % [index, 'constraint'] => funding.constraint
|
15
18
|
})
|
16
19
|
end
|
17
20
|
end
|
@@ -31,7 +31,7 @@ class OrderItem
|
|
31
31
|
[].tap do |order_items|
|
32
32
|
i = 0
|
33
33
|
while data[FORMAT_STRING % [i, 'description']]
|
34
|
-
description = CGI.unescape(data[FORMAT_STRING % [i, 'description']])
|
34
|
+
description = CGI.unescape(data[FORMAT_STRING % [i, 'description']].to_s)
|
35
35
|
unit_price = data[FORMAT_STRING % [i, 'unitPrice']]
|
36
36
|
quantity = data[FORMAT_STRING % [i, 'quantity']]
|
37
37
|
tax = data[FORMAT_STRING % [i, 'taxPercentage']]
|
data/lib/payson_api/receiver.rb
CHANGED
@@ -3,11 +3,14 @@ require 'cgi'
|
|
3
3
|
module PaysonAPI
|
4
4
|
class Receiver
|
5
5
|
FORMAT_STRING = "receiverList.receiver(%d).%s"
|
6
|
-
attr_accessor :email, :amount
|
6
|
+
attr_accessor :email, :amount, :first_name, :last_name, :primary
|
7
7
|
|
8
|
-
def initialize(email, amount)
|
8
|
+
def initialize(email, amount, first_name, last_name, primary = true)
|
9
9
|
@email = email
|
10
10
|
@amount = amount
|
11
|
+
@first_name = first_name
|
12
|
+
@last_name = last_name
|
13
|
+
@primary = primary
|
11
14
|
end
|
12
15
|
|
13
16
|
def self.to_hash(receivers)
|
@@ -16,7 +19,10 @@ class Receiver
|
|
16
19
|
raise "Invalid receiver" unless receiver.instance_of?(self)
|
17
20
|
hash.merge!({
|
18
21
|
FORMAT_STRING % [index, 'email'] => receiver.email,
|
19
|
-
FORMAT_STRING % [index, 'amount'] => receiver.amount
|
22
|
+
FORMAT_STRING % [index, 'amount'] => receiver.amount,
|
23
|
+
FORMAT_STRING % [index, 'firstName'] => receiver.first_name,
|
24
|
+
FORMAT_STRING % [index, 'lastName'] => receiver.last_name,
|
25
|
+
FORMAT_STRING % [index, 'primary'] => receiver.primary
|
20
26
|
})
|
21
27
|
end
|
22
28
|
end
|
@@ -26,9 +32,12 @@ class Receiver
|
|
26
32
|
[].tap do |receivers|
|
27
33
|
i = 0
|
28
34
|
while data[FORMAT_STRING % [i, 'email']]
|
29
|
-
email = CGI.unescape(data[FORMAT_STRING % [i, 'email']])
|
35
|
+
email = CGI.unescape(data[FORMAT_STRING % [i, 'email']].to_s)
|
30
36
|
amount = data[FORMAT_STRING % [i, 'amount']]
|
31
|
-
|
37
|
+
first_name = CGI.unescape(data[FORMAT_STRING % [i, 'firstName']].to_s)
|
38
|
+
last_name = CGI.unescape(data[FORMAT_STRING % [i, 'lastName']].to_s)
|
39
|
+
primary = data[FORMAT_STRING % [i, 'primary']]
|
40
|
+
receivers << self.new(email, amount, first_name, last_name, primary)
|
32
41
|
i += 1
|
33
42
|
end
|
34
43
|
end
|
@@ -2,7 +2,8 @@ module PaysonAPI
|
|
2
2
|
module Request
|
3
3
|
class Payment
|
4
4
|
attr_accessor :return_url, :cancel_url, :ipn_url, :memo, :sender, :receivers,
|
5
|
-
:locale, :currency, :tracking_id, :invoice_fee, :order_items
|
5
|
+
:locale, :currency, :tracking_id, :invoice_fee, :order_items, :fundings,
|
6
|
+
:fees_payer, :guarantee_offered
|
6
7
|
|
7
8
|
def initialize(return_url, cancel_url, ipn_url, memo, sender, receivers)
|
8
9
|
@return_url = return_url
|
@@ -15,21 +16,51 @@ class Payment
|
|
15
16
|
|
16
17
|
def to_hash
|
17
18
|
{}.tap do |hash|
|
19
|
+
# Append mandatory params
|
18
20
|
hash['returnUrl'] = @return_url
|
19
21
|
hash['cancelUrl'] = @cancel_url
|
20
|
-
if @ipn_url && !@ipn_url.empty?
|
21
|
-
hash['ipnNotificationUrl'] = @ipn_url
|
22
|
-
end
|
23
22
|
hash['memo'] = @memo
|
24
|
-
hash['localeCode'] = LOCALES[@locale] if @locale
|
25
|
-
hash['currencyCode'] = CURRENCIES[@currency] if @currency
|
26
|
-
hash.merge!(Receiver.to_hash(@receivers))
|
27
23
|
hash.merge!(@sender.to_hash)
|
24
|
+
hash.merge!(Receiver.to_hash(@receivers))
|
25
|
+
|
26
|
+
# Append optional params
|
27
|
+
append_locale(hash, @locale) if @locale
|
28
|
+
append_currency(hash, @currency) if @currency
|
29
|
+
append_fees_payer(hash, @fees_payer) if @fees_payer
|
30
|
+
append_guarantee(hash, @guarantee_offered) if @guarantee_offered
|
28
31
|
hash.merge!(OrderItem.to_hash(@order_items)) if @order_items
|
32
|
+
hash.merge!(Funding.to_hash(@fundings)) if @fundings
|
33
|
+
hash['ipnNotificationUrl'] = @ipn_url if @ipn_url
|
29
34
|
hash['invoiceFee'] = @invoice_fee if @invoice_fee
|
30
35
|
hash['trackingId'] = @tracking_id if @tracking_id
|
31
36
|
end
|
32
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def append_locale(hash, locale)
|
42
|
+
raise "Unknown locale: #{locale}" if !LOCALES.include?(locale)
|
43
|
+
hash['localeCode'] = locale
|
44
|
+
end
|
45
|
+
|
46
|
+
def append_currency(hash, currency)
|
47
|
+
raise "Unknown currency: #{currency}" if !CURRENCIES.include?(currency)
|
48
|
+
hash['currencyCode'] = currency
|
49
|
+
end
|
50
|
+
|
51
|
+
def append_guarantee(hash, guarantee_offered)
|
52
|
+
if !GUARANTEE_OFFERINGS.include?(guarantee_offered)
|
53
|
+
raise "Unknown guarantee offering: #{guarantee_offered}"
|
54
|
+
end
|
55
|
+
hash['guaranteeOffered'] = guarantee_offered
|
56
|
+
end
|
57
|
+
|
58
|
+
def append_fees_payer(hash, fees_payer)
|
59
|
+
if !FEES_PAYERS.include?(fees_payer)
|
60
|
+
raise "Unknown fees payer: #{fees_payer}"
|
61
|
+
end
|
62
|
+
hash['feesPayer'] = fees_payer if fees_payer
|
63
|
+
end
|
33
64
|
end
|
34
65
|
end
|
35
66
|
end
|
@@ -27,7 +27,9 @@ class PaymentDetails
|
|
27
27
|
@guarantee_deadline_at = Time.at(data['guaranteeDeadlineTimestamp'])
|
28
28
|
when 'INVOICE'
|
29
29
|
@invoice_status = data['invoiceStatus']
|
30
|
-
|
30
|
+
if %w[ORDERCREATED SHIPPED DONE CREDITED].include?(@invoice_status)
|
31
|
+
@shipping_address = ShippingAddress.parse(data)
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
data/lib/payson_api/sender.rb
CHANGED
@@ -21,8 +21,8 @@ class Sender
|
|
21
21
|
|
22
22
|
def self.parse(data)
|
23
23
|
email = data[FORMAT_STRING % 'email']
|
24
|
-
first_name = CGI.unescape(data[FORMAT_STRING % 'FirstName'])
|
25
|
-
last_name = CGI.unescape(data[FORMAT_STRING % 'LastName'])
|
24
|
+
first_name = CGI.unescape(data[FORMAT_STRING % 'FirstName'].to_s)
|
25
|
+
last_name = CGI.unescape(data[FORMAT_STRING % 'LastName'].to_s)
|
26
26
|
self.new(email, first_name, last_name)
|
27
27
|
end
|
28
28
|
end
|
@@ -25,11 +25,11 @@ class ShippingAddress
|
|
25
25
|
|
26
26
|
def self.parse(data)
|
27
27
|
return unless data[FORMAT_STRING % 'name']
|
28
|
-
name = CGI.unescape(data[FORMAT_STRING % 'name'])
|
29
|
-
street_address = CGI.unescape(data[FORMAT_STRING % 'streetAddress'])
|
30
|
-
postal_code = CGI.unescape(data[FORMAT_STRING % 'postalCode'])
|
31
|
-
city = CGI.unescape(data[FORMAT_STRING % 'city'])
|
32
|
-
country = CGI.unescape(data[FORMAT_STRING % 'country'])
|
28
|
+
name = CGI.unescape(data[FORMAT_STRING % 'name'].to_s)
|
29
|
+
street_address = CGI.unescape(data[FORMAT_STRING % 'streetAddress'].to_s)
|
30
|
+
postal_code = CGI.unescape(data[FORMAT_STRING % 'postalCode'].to_s)
|
31
|
+
city = CGI.unescape(data[FORMAT_STRING % 'city'].to_s)
|
32
|
+
country = CGI.unescape(data[FORMAT_STRING % 'country'].to_s)
|
33
33
|
self.new(name, street_address, postal_code, city, country)
|
34
34
|
end
|
35
35
|
end
|
data/lib/payson_api/version.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
1
|
:return_url: http://localhost/return
|
2
2
|
:cancel_url: http://localhost/cancel
|
3
|
-
:ipn_url:
|
3
|
+
:ipn_url: http://localhost/ipn
|
4
4
|
:memo: Test
|
5
5
|
:receivers:
|
6
6
|
-
|
7
7
|
:email: mytest@domain.com
|
8
8
|
:amount: 123
|
9
|
+
:first_name: Test
|
10
|
+
:last_name: Person 1
|
11
|
+
:primary: true
|
9
12
|
-
|
10
13
|
:email: mytest2@domain2.com
|
11
14
|
:amount: 234
|
15
|
+
:first_name: Test
|
16
|
+
:last_name: Person 2
|
17
|
+
:primary: false
|
12
18
|
:sender:
|
13
19
|
:email: test_person@anotherdomain.com
|
14
20
|
:first_name: Test
|
15
|
-
:last_name:
|
21
|
+
:last_name: Receiver
|
16
22
|
:order_items:
|
17
23
|
-
|
18
24
|
:description: 'My order item description'
|
@@ -26,3 +32,11 @@
|
|
26
32
|
:quantity: 2
|
27
33
|
:tax: 10
|
28
34
|
:sku: 'MY-ITEM-2'
|
35
|
+
:fundings:
|
36
|
+
-
|
37
|
+
:constraint: CREDITCARD
|
38
|
+
-
|
39
|
+
:constraint: BANK
|
40
|
+
:fees_payer: EACHRECEIVER
|
41
|
+
:guarantee_offered: NO
|
42
|
+
:locale: SV
|
@@ -14,15 +14,22 @@ class PaymentTest < Test::Unit::TestCase
|
|
14
14
|
assert_equal PAYMENT_DATA[:cancel_url], @payment_hash['cancelUrl']
|
15
15
|
assert_equal PAYMENT_DATA[:ipn_url], @payment_hash['ipnNotificationUrl']
|
16
16
|
assert_equal PAYMENT_DATA[:memo], @payment_hash['memo']
|
17
|
+
assert_equal PAYMENT_DATA[:locale], @payment_hash['localeCode']
|
17
18
|
|
18
19
|
# Ensure expected format of receiver list
|
19
20
|
receiver_format = PaysonAPI::Receiver::FORMAT_STRING
|
20
21
|
@receivers.each_with_index do |receiver, index|
|
21
22
|
email = @payment_hash[receiver_format % [index, 'email']]
|
22
23
|
amount = @payment_hash[receiver_format % [index, 'amount']]
|
24
|
+
first_name = @payment_hash[receiver_format % [index, 'firstName']]
|
25
|
+
last_name = @payment_hash[receiver_format % [index, 'lastName']]
|
26
|
+
primary = @payment_hash[receiver_format % [index, 'primary']]
|
23
27
|
|
24
28
|
assert_equal receiver.email, email
|
25
29
|
assert_equal receiver.amount, amount
|
30
|
+
assert_equal receiver.first_name, first_name
|
31
|
+
assert_equal receiver.last_name, last_name
|
32
|
+
assert_equal receiver.primary, primary
|
26
33
|
end
|
27
34
|
|
28
35
|
# Do same test for order items
|
@@ -40,6 +47,13 @@ class PaymentTest < Test::Unit::TestCase
|
|
40
47
|
assert_equal order_item.tax, tax
|
41
48
|
assert_equal order_item.sku, sku
|
42
49
|
end
|
50
|
+
|
51
|
+
# Ensure expected format of fundings list
|
52
|
+
funding_format = PaysonAPI::Funding::FORMAT_STRING
|
53
|
+
@fundings.each_with_index do |funding, index|
|
54
|
+
constraint = @payment_hash[funding_format % [index, 'constraint']]
|
55
|
+
assert_equal funding.constraint, constraint
|
56
|
+
end
|
43
57
|
end
|
44
58
|
|
45
59
|
def test_payment_initiation_request
|
data/test/test_helper.rb
CHANGED
@@ -22,7 +22,10 @@ module TestHelper
|
|
22
22
|
PAYMENT_DATA[:receivers].each do |receiver|
|
23
23
|
@receivers << PaysonAPI::Receiver.new(
|
24
24
|
receiver[:email],
|
25
|
-
receiver[:amount]
|
25
|
+
receiver[:amount],
|
26
|
+
receiver[:first_name],
|
27
|
+
receiver[:last_name],
|
28
|
+
receiver[:primary]
|
26
29
|
)
|
27
30
|
end
|
28
31
|
|
@@ -46,7 +49,19 @@ module TestHelper
|
|
46
49
|
)
|
47
50
|
end
|
48
51
|
|
52
|
+
@fundings = []
|
53
|
+
PAYMENT_DATA[:fundings].each do |funding|
|
54
|
+
@fundings << PaysonAPI::Funding.new(
|
55
|
+
funding[:constraint]
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
49
59
|
@payment.order_items = @order_items if include_order_items
|
60
|
+
@payment.fundings = @fundings
|
61
|
+
@payment.fees_payer = PAYMENT_DATA[:fees_payer]
|
62
|
+
@payment.locale = PAYMENT_DATA[:locale]
|
63
|
+
@payment.guarantee_offered = PAYMENT_DATA[:guarantee_offered]
|
64
|
+
|
50
65
|
@payment_hash = @payment.to_hash
|
51
66
|
end
|
52
67
|
|