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 CHANGED
@@ -5,5 +5,5 @@ guard 'test' do
5
5
  watch(%r{^test/unit/.+_test\.rb$}) { "test" }
6
6
  watch(%r{^test/fixtures/(.+)\.yml$}) { "test" }
7
7
  watch(%r{^test/integration/.+_test\.rb$}) { "test" }
8
- watch('test/.+.rb') { "test" }
8
+ watch('test/.+\.rb') { "test" }
9
9
  end
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(ipn.token)
120
- # order.payson_status = ipn.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
- Implement the following requests:
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]
@@ -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 EN]
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
@@ -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
@@ -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, 'email'] => funding.constraint
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']]
@@ -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
- receivers << self.new(email, amount)
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
@@ -5,6 +5,9 @@ class PaymentUpdate
5
5
 
6
6
  def initialize(token, action)
7
7
  @token = token
8
+ if !PAYMENT_ACTIONS.include?(action)
9
+ raise "Unknown payment update action: #{action}"
10
+ end
8
11
  @action = action
9
12
  end
10
13
 
@@ -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
- @shipping_address = ShippingAddress.parse(data)
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
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module PaysonAPI
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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: Person
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
@@ -19,9 +19,6 @@ class PaymentDetailsTest < Test::Unit::TestCase
19
19
 
20
20
  payment_details = PaysonAPI::Request::PaymentDetails.new(token)
21
21
  response = PaysonAPI::Client.get_payment_details(payment_details)
22
-
23
-
24
-
25
- p response
22
+ #p response
26
23
  end
27
24
  end
@@ -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
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Christopher Svensson