payson_api 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -42,7 +42,7 @@ You can configure the following default values by overriding these values using
42
42
  )
43
43
 
44
44
  sender = PaysonAPI::Sender.new(
45
- email = 'mycustomer@mydomain.com,
45
+ email = 'mycustomer@mydomain.com',
46
46
  first_name = 'My',
47
47
  last_name = 'Customer'
48
48
  )
@@ -56,7 +56,7 @@ You can configure the following default values by overriding these values using
56
56
  sku = 'MY-ITEM-1'
57
57
  )
58
58
 
59
- pay_data = PaysonAPI::PayData.new(
59
+ payment = PaysonAPI::Request::Payment.new(
60
60
  return_url,
61
61
  cancel_url,
62
62
  ipn_url,
@@ -64,9 +64,9 @@ You can configure the following default values by overriding these values using
64
64
  sender,
65
65
  receivers
66
66
  )
67
- pay_data.order_items = order_items
67
+ payment.order_items = order_items
68
68
 
69
- response = PaysonAPI::Client.pay(pay_data)
69
+ response = PaysonAPI::Client.initiate_payment(payment)
70
70
 
71
71
  if response.success?
72
72
  # Redirect to response.forward_url
@@ -75,12 +75,67 @@ You can configure the following default values by overriding these values using
75
75
  end
76
76
 
77
77
 
78
+ === Requesting payment details
79
+
80
+ token = 'token-received-from-payment-request'
81
+
82
+ payment_details = PaysonAPI::Request::PaymentDetails.new(token)
83
+
84
+ response = PaysonAPI::Client.get_payment_details(payment_details)
85
+
86
+ if response.success?
87
+ # Do stuff with response object
88
+ else
89
+ puts response.errors
90
+ end
91
+
92
+
93
+ === Updating a payment
94
+
95
+ token = 'token-received-from-payment-request'
96
+ action = 'CANCELORDER'
97
+
98
+ payment_update = PaysonAPI::Request::PaymentUpdate.new(token, action)
99
+
100
+ response = PaysonAPI::Client.update_payment(payment_update)
101
+
102
+ if response.success?
103
+ # Do stuff with response object
104
+ else
105
+ puts response.errors
106
+ end
107
+
108
+
109
+ === Validating an IPN response
110
+
111
+ This example assumes the use of the Rails web framework.
112
+
113
+ class Payson < ApplicationController
114
+ def ipn_responder
115
+ request_body = request.body.read
116
+ ipn_response = PaysonAPI::Response::IPN.new(request_body)
117
+
118
+ # Do business stuff, e.g. update the corresponding order:
119
+ # order = Order.find_by_payson_token(ipn.token)
120
+ # order.payson_status = ipn.status
121
+ # order.save!
122
+
123
+ # Create a new IPN request object containing the raw response from above
124
+ ipn_request = PaysonAPI::Request::IPN.new(ipn_response.raw)
125
+
126
+ validate = PaysonAPI::Client.validate_ipn(ipn_request)
127
+
128
+ unless validate.verified?
129
+ raise "Something went terribly wrong."
130
+ end
131
+ end
132
+ end
133
+
134
+
78
135
  == Todo
79
136
 
80
137
  Implement the following requests:
81
138
 
82
- * PaymentDetails - Get details on a payment.
83
- * PaymentUpdate - Update a payment.
84
139
  * Validate - Validate an IPN (Instant Payment Notification).
85
140
 
86
141
 
@@ -1,37 +1,82 @@
1
1
  require 'net/https'
2
2
 
3
3
  module PaysonAPI
4
- class Client
5
- def self.pay(pay_data)
6
- action = '/%s/%s/' % [PAYSON_API_VERSION, PAYSON_API_PAY_ACTION]
7
- response = post(PAYSON_API_ENDPOINT + action, pay_data.to_hash)
8
- Response.new(response.body)
9
- end
4
+ class Client
5
+ def self.initiate_payment(payment_data)
6
+ response = payson_request(
7
+ PAYSON_API_PAY_ACTION,
8
+ payment_data.to_hash
9
+ )
10
+ response_hash = params_to_hash(response.body)
11
+ PaysonAPI::Response::Payment.new(response_hash)
12
+ end
13
+
14
+ def self.get_payment_details(payment_details_data)
15
+ response = payson_request(
16
+ PAYSON_API_PAYMENT_DETAILS_ACTION,
17
+ payment_details_data.to_hash
18
+ )
19
+ response_hash = params_to_hash(response.body)
20
+ PaysonAPI::Response::PaymentDetails.new(response_hash)
21
+ end
22
+
23
+ def self.update_payment(payment_update_data)
24
+ response = payson_request(
25
+ PAYSON_API_PAYMENT_DETAILS_ACTION,
26
+ payment_update_data.to_hash
27
+ )
28
+ response_hash = params_to_hash(response.body)
29
+ PaysonAPI::Response::PaymentUpdate.new(response_hash)
30
+ end
31
+
32
+ def self.validate_ipn(ipn_data)
33
+ response = payson_request(
34
+ PAYSON_API_PAYMENT_VALIDATE_ACTION,
35
+ ipn_data.to_s
36
+ )
37
+ PaysonAPI::Response::Validate.new(response.body)
38
+ end
10
39
 
11
- private
12
-
13
- def self.post(url, data)
14
- headers = {
15
- 'PAYSON-SECURITY-USERID' => PaysonAPI.config.api_user_id,
16
- 'PAYSON-SECURITY-PASSWORD' => PaysonAPI.config.api_password,
17
- 'Content-Type' => 'application/x-www-form-urlencoded'
18
- }
19
- uri = URI.parse(url)
20
- http = Net::HTTP.new(uri.host, uri.port)
21
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
22
- http.use_ssl = uri.scheme == 'https'
23
- req = Net::HTTP::Post.new(uri.path)
24
- req.body = hash_to_params(data)
25
- headers.each do |name, value|
26
- req[name] = value
40
+ def self.hash_to_params(hash)
41
+ out = ""
42
+ hash.each { |k, v| out << "#{k}=#{v}&" }
43
+ out.chop
44
+ end
45
+
46
+ def self.params_to_hash(params)
47
+ {}.tap do |hash|
48
+ parts = params.split(/&/)
49
+ parts.each do |part|
50
+ key, val = part.split(/=/)
51
+ hash[key] = val
27
52
  end
28
- http.request(req)
29
53
  end
54
+ end
55
+
56
+ private
30
57
 
31
- def self.hash_to_params(hash)
32
- out = ""
33
- hash.each { |k, v| out << "#{k}=#{v}&" }
34
- out.chop
58
+ def self.payson_request(action, data)
59
+ action = '/%s/%s/' % [PAYSON_API_VERSION, action]
60
+ url = PAYSON_API_ENDPOINT + action
61
+ headers = {
62
+ 'PAYSON-SECURITY-USERID' => PaysonAPI.config.api_user_id,
63
+ 'PAYSON-SECURITY-PASSWORD' => PaysonAPI.config.api_password,
64
+ 'Content-Type' => 'application/x-www-form-urlencoded'
65
+ }
66
+ post(url, data, headers)
67
+ end
68
+
69
+ def self.post(url, data, headers)
70
+ uri = URI.parse(url)
71
+ http = Net::HTTP.new(uri.host, uri.port)
72
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
73
+ http.use_ssl = uri.scheme == 'https'
74
+ req = Net::HTTP::Post.new(uri.path)
75
+ req.body = data.is_a?(Hash) ? hash_to_params(data) : data
76
+ headers.each do |name, value|
77
+ req[name] = value
35
78
  end
79
+ http.request(req)
36
80
  end
37
81
  end
82
+ end
@@ -14,10 +14,6 @@ module PaysonAPI
14
14
  LOCALES = %w[SV FI EN]
15
15
  CURRENCIES = %w[SEK EUR]
16
16
 
17
- # Configures global settings for Payson
18
- # PaysonAPI.configure do |config|
19
- # config.api_user = 12345
20
- # end
21
17
  def configure(&block)
22
18
  yield @config ||= Configuration.new
23
19
  end
@@ -34,5 +30,4 @@ module PaysonAPI
34
30
  config.api_user_id = 'XXXX'
35
31
  config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
36
32
  end
37
-
38
33
  end
@@ -0,0 +1,21 @@
1
+ require 'cgi'
2
+
3
+ module PaysonAPI
4
+ class Envelope
5
+ attr_accessor :ack, :timestamp, :correlation_id
6
+ FORMAT_STRING = "responseEnvelope.%s"
7
+
8
+ def initialize(ack, timestamp, correlation_id)
9
+ @ack = ack
10
+ @timestamp = timestamp
11
+ @correlation_id = correlation_id
12
+ end
13
+
14
+ def self.parse(data)
15
+ ack = data[FORMAT_STRING % 'ack']
16
+ timestamp = DateTime.parse(CGI.unescape(data[FORMAT_STRING % 'timestamp']))
17
+ correlation_id = data[FORMAT_STRING % 'correlationId']
18
+ self.new(ack, timestamp, correlation_id)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module PaysonAPI
2
+ class Funding
3
+ FORMAT_STRING = "fundingList.fundingConstraint(%d).%s"
4
+ attr_accessor :constraint
5
+
6
+ def initialize(constraint)
7
+ @constraint = constraint
8
+ end
9
+
10
+ def self.to_hash(fundings)
11
+ {}.tap do |hash|
12
+ fundings.each_with_index do |funding, index|
13
+ hash.merge!({
14
+ FORMAT_STRING % [index, 'email'] => funding.constraint
15
+ })
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.parse(data)
21
+ [].tap do |fundings|
22
+ i = 0
23
+ while data[FORMAT_STRING % [i, 'constraint']]
24
+ constraint = data[FORMAT_STRING % [i, 'constraint']]
25
+ fundings << self.new(constraint)
26
+ i += 1
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,7 +1,9 @@
1
+ require 'cgi'
2
+
1
3
  module PaysonAPI
2
4
  class OrderItem
3
- FORMAT_STRING = "orderItemList.orderItem(%d).%s"
4
5
  attr_accessor :description, :quantity, :unit_price, :sku, :tax
6
+ FORMAT_STRING = "orderItemList.orderItem(%d).%s"
5
7
 
6
8
  def initialize(description, unit_price, quantity, tax, sku)
7
9
  @description = description
@@ -14,7 +16,6 @@ class OrderItem
14
16
  def self.to_hash(order_items)
15
17
  {}.tap do |hash|
16
18
  order_items.each_with_index do |item, index|
17
- raise "Invalid order item" unless item.instance_of?(self)
18
19
  hash.merge!({
19
20
  FORMAT_STRING % [index, 'description'] => item.description,
20
21
  FORMAT_STRING % [index, 'unitPrice'] => item.unit_price,
@@ -26,21 +27,26 @@ class OrderItem
26
27
  end
27
28
  end
28
29
 
29
- def self.parse_order_items(data)
30
- i = 0
30
+ def self.parse(data)
31
31
  [].tap do |order_items|
32
+ i = 0
32
33
  while data[FORMAT_STRING % [i, 'description']]
33
- description = data[FORMAT_STRING % [i, 'description']]
34
+ description = CGI.unescape(data[FORMAT_STRING % [i, 'description']])
34
35
  unit_price = data[FORMAT_STRING % [i, 'unitPrice']]
35
36
  quantity = data[FORMAT_STRING % [i, 'quantity']]
36
37
  tax = data[FORMAT_STRING % [i, 'taxPercentage']]
37
38
  sku = data[FORMAT_STRING % [i, 'sku']]
38
39
 
39
- order_items << OrderItem.new(description, unit_price, quantity, tax, sku)
40
+ order_items << OrderItem.new(
41
+ description,
42
+ unit_price,
43
+ quantity,
44
+ tax,
45
+ sku
46
+ )
40
47
  i += 1
41
48
  end
42
49
  end
43
50
  end
44
-
45
51
  end
46
52
  end
@@ -1,3 +1,5 @@
1
+ require 'cgi'
2
+
1
3
  module PaysonAPI
2
4
  class Receiver
3
5
  FORMAT_STRING = "receiverList.receiver(%d).%s"
@@ -20,13 +22,13 @@ class Receiver
20
22
  end
21
23
  end
22
24
 
23
- def self.parse_receivers(data)
24
- i = 0
25
+ def self.parse(data)
25
26
  [].tap do |receivers|
27
+ i = 0
26
28
  while data[FORMAT_STRING % [i, 'email']]
27
- email = data[FORMAT_STRING % [i, 'email']]
29
+ email = CGI.unescape(data[FORMAT_STRING % [i, 'email']])
28
30
  amount = data[FORMAT_STRING % [i, 'amount']]
29
- receivers << Receiver.new(email, amount)
31
+ receivers << self.new(email, amount)
30
32
  i += 1
31
33
  end
32
34
  end
@@ -0,0 +1,31 @@
1
+ require 'cgi'
2
+
3
+ module PaysonAPI
4
+ class RemoteError
5
+ attr_accessor :id, :message, :parameter
6
+ FORMAT_STRING = "errorList.error(%d).%s"
7
+
8
+ def initialize(id, message, parameter)
9
+ @id = id
10
+ @message = message
11
+ @parameter = parameter
12
+ end
13
+
14
+ def self.parse(data)
15
+ [].tap do |errors|
16
+ i = 0
17
+ while data[FORMAT_STRING % [i, 'errorId']]
18
+ id = data[FORMAT_STRING % [i, 'errorId']]
19
+ message = CGI.unescape(data[FORMAT_STRING % [i, 'message']])
20
+ parameter = CGI.unescape(data[FORMAT_STRING % [i, 'parameter']])
21
+ errors << self.new(id, message, parameter)
22
+ i += 1
23
+ end
24
+ end
25
+ end
26
+
27
+ def to_s
28
+ "ID: #{@id}, Message: #{@message}, Parameter: #{@parameter}"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ module PaysonAPI
2
+ module Request
3
+ class IPN
4
+ attr_accessor :data
5
+
6
+ def initialize(data)
7
+ @data = data
8
+ end
9
+
10
+ def to_s
11
+ @data
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,6 @@
1
1
  module PaysonAPI
2
- class PayData
2
+ module Request
3
+ class Payment
3
4
  attr_accessor :return_url, :cancel_url, :ipn_url, :memo, :sender, :receivers,
4
5
  :locale, :currency, :tracking_id, :invoice_fee, :order_items
5
6
 
@@ -29,9 +30,6 @@ class PayData
29
30
  hash['trackingId'] = @tracking_id if @tracking_id
30
31
  end
31
32
  end
32
-
33
- def to_s
34
- to_hash.to_s
35
- end
33
+ end
36
34
  end
37
35
  end
@@ -0,0 +1,15 @@
1
+ module PaysonAPI
2
+ module Request
3
+ class PaymentDetails
4
+ attr_accessor :token
5
+
6
+ def initialize(token)
7
+ @token = token
8
+ end
9
+
10
+ def to_hash
11
+ { 'token' => @token }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module PaysonAPI
2
+ module Request
3
+ class PaymentUpdate
4
+ attr_accessor :token, :action
5
+
6
+ def initialize(token, action)
7
+ @token = token
8
+ @action = action
9
+ end
10
+
11
+ def to_hash
12
+ {}.tap do |hash|
13
+ hash['token'] = @token
14
+ hash['action'] = @action
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module PaysonAPI
2
+ module Response
3
+ class IPN
4
+ attr_accessor :purchase_id, :sender_email, :status,
5
+ :payment_type, :guarantee_status, :guarantee_deadline_at,
6
+ :invoice_status, :custom, :tracking_id, :receivers, :currency,
7
+ :order_items, :fundings, :token, :shipping_address, :raw, :hash
8
+
9
+ def initialize(raw_data)
10
+ @raw = raw_data
11
+ data_hash = PaysonAPI::Client.params_to_hash(raw_data)
12
+ @purchase_id = data_hash['purchaseId']
13
+ @payment_type = data_hash['type']
14
+ @comment = data_hash['custom']
15
+ @tracking_id = data_hash['trackingId']
16
+ @currency = data_hash['currencyCode']
17
+ @sender_email = data_hash['senderEmail']
18
+ @status = data_hash['status']
19
+ @token = data_hash['token']
20
+ @fundings = Funding.parse(data_hash)
21
+ @receivers = Receiver.parse(data_hash)
22
+ @order_items = OrderItem.parse(data_hash)
23
+ @hash = data_hash['HASH']
24
+
25
+ case @payment_type
26
+ when 'GUARANTEE'
27
+ @guarantee_status = data_hash['guaranteeStatus']
28
+ @guarantee_deadline_at = Time.at(data_hash['guaranteeDeadlineTimestamp'])
29
+ when 'INVOICE'
30
+ @invoice_status = data_hash['invoiceStatus']
31
+ @shipping_address = ShippingAddress.parse(data_hash)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module PaysonAPI
2
+ module Response
3
+ class Payment
4
+ attr_accessor :envelope, :token, :errors
5
+
6
+ def initialize(data)
7
+ @envelope = Envelope.parse(data)
8
+ @token = data['TOKEN']
9
+ @errors = RemoteError.parse(data)
10
+ end
11
+
12
+ def success?
13
+ @envelope.ack == 'SUCCESS'
14
+ end
15
+
16
+ def forward_url
17
+ PAYSON_WWW_HOST + PAYSON_WWW_PAY_FORWARD_URL % @token
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module PaysonAPI
2
+ module Response
3
+ class PaymentDetails
4
+ attr_accessor :envelope, :purchase_id, :sender_email, :status,
5
+ :payment_type, :guarantee_status, :guarantee_deadline_at,
6
+ :invoice_status, :custom, :tracking_id, :receivers, :currency,
7
+ :order_items, :errors, :fundings, :token, :shipping_address
8
+
9
+ def initialize(data)
10
+ @envelope = Envelope.parse(data)
11
+ @purchase_id = data['purchaseId']
12
+ @payment_type = data['type']
13
+ @comment = data['custom']
14
+ @tracking_id = data['trackingId']
15
+ @currency = data['currencyCode']
16
+ @sender_email = data['senderEmail']
17
+ @status = data['status']
18
+ @token = data['token']
19
+ @fundings = Funding.parse(data)
20
+ @receivers = Receiver.parse(data)
21
+ @order_items = OrderItem.parse(data)
22
+ @errors = RemoteError.parse(data)
23
+
24
+ case @payment_type
25
+ when 'GUARANTEE'
26
+ @guarantee_status = data['guaranteeStatus']
27
+ @guarantee_deadline_at = Time.at(data['guaranteeDeadlineTimestamp'])
28
+ when 'INVOICE'
29
+ @invoice_status = data['invoiceStatus']
30
+ @shipping_address = ShippingAddress.parse(data)
31
+ end
32
+ end
33
+
34
+ def success?
35
+ @envelope.ack == 'SUCCESS'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ module PaysonAPI
2
+ module Response
3
+ class PaymentUpdate
4
+ attr_accessor :envelope, :errors
5
+
6
+ def initialize(data)
7
+ @envelope = Envelope.parse(data)
8
+ @errors = RemoteError.parse(data)
9
+ end
10
+
11
+ def success?
12
+ @envelope.ack == 'SUCCESS'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module PaysonAPI
2
+ module Response
3
+ class Validate
4
+ attr_accessor :data
5
+
6
+ def initialize(data)
7
+ @data = data
8
+ end
9
+
10
+ def verified?
11
+ @data == 'VERIFIED'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,8 @@
1
+ require 'cgi'
2
+
1
3
  module PaysonAPI
2
4
  class Sender
5
+ FORMAT_STRING = "sender%s"
3
6
  attr_accessor :email, :first_name, :last_name
4
7
 
5
8
  def initialize(email, first_name, last_name)
@@ -10,10 +13,17 @@ class Sender
10
13
 
11
14
  def to_hash
12
15
  {}.tap do |hash|
13
- hash['senderEmail'] = @email
14
- hash['senderFirstName'] = @first_name
15
- hash['senderLastName'] = @last_name
16
+ hash[FORMAT_STRING % 'Email'] = @email
17
+ hash[FORMAT_STRING % 'FirstName'] = @first_name
18
+ hash[FORMAT_STRING % 'LastName'] = @last_name
16
19
  end
17
20
  end
21
+
22
+ def self.parse(data)
23
+ email = data[FORMAT_STRING % 'email']
24
+ first_name = CGI.unescape(data[FORMAT_STRING % 'FirstName'])
25
+ last_name = CGI.unescape(data[FORMAT_STRING % 'LastName'])
26
+ self.new(email, first_name, last_name)
27
+ end
18
28
  end
19
29
  end
@@ -0,0 +1,36 @@
1
+ require 'cgi'
2
+
3
+ module PaysonAPI
4
+ class ShippingAddress
5
+ FORMAT_STRING = "shippingAddress.%s"
6
+ attr_accessor :name, :street_address, :postal_code, :city, :country
7
+
8
+ def initialize(name, street_address, postal_code, city, country)
9
+ @name = name
10
+ @street_address = street_address
11
+ @postal_code = postal_code
12
+ @city = city
13
+ @country = country
14
+ end
15
+
16
+ def to_hash
17
+ {}.tap do |hash|
18
+ hash[FORMAT_STRING % 'name'] = @name
19
+ hash[FORMAT_STRING % 'streetAddress'] = @street_address
20
+ hash[FORMAT_STRING % 'postalCode'] = @postal_code
21
+ hash[FORMAT_STRING % 'city'] = @city
22
+ hash[FORMAT_STRING % 'country'] = @country
23
+ end
24
+ end
25
+
26
+ def self.parse(data)
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'])
33
+ self.new(name, street_address, postal_code, city, country)
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module PaysonAPI
2
- VERSION = "0.0.6"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/payson_api.rb CHANGED
@@ -1,10 +1,26 @@
1
- require 'payson_api/config'
2
- require 'payson_api/client'
3
- require 'payson_api/errors/payson_api_error'
4
- require 'payson_api/errors/remote_error'
5
- require 'payson_api/order_item'
6
- require 'payson_api/pay_data'
7
- require 'payson_api/receiver'
8
- require 'payson_api/response'
9
- require 'payson_api/sender'
10
- require 'payson_api/version'
1
+ required_files = [
2
+ 'config',
3
+ 'error_codes',
4
+ 'client',
5
+ 'envelope',
6
+ 'funding',
7
+ 'order_item',
8
+ 'receiver',
9
+ 'remote_error',
10
+ 'request/ipn',
11
+ 'request/payment_details',
12
+ 'request/payment_update',
13
+ 'request/payment',
14
+ 'response/ipn',
15
+ 'response/payment_details',
16
+ 'response/payment_update',
17
+ 'response/payment',
18
+ 'response/validate',
19
+ 'sender',
20
+ 'shipping_address',
21
+ 'version'
22
+ ]
23
+
24
+ required_files.each do |file|
25
+ require "payson_api/#{file}"
26
+ end
@@ -1,2 +1,5 @@
1
- :api_user_id: XXXX
2
- :api_password: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
1
+ #:api_user_id: XXXX
2
+ #:api_password: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
3
+
4
+ :api_user_id: 13671
5
+ :api_password: 305390e8-f866-41e5-a543-dc8747f545f8
File without changes
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'test_helper'
5
+ require 'payson_api'
6
+
7
+ class PaymentDetailsTest < Test::Unit::TestCase
8
+ include TestHelper
9
+
10
+ def test_generated_hash_from_payment_details
11
+ #token = acquire_token
12
+ #token = 'b28c31bb-1499-4988-9fc6-fa915c287e90'
13
+ token = '4d7328b0-9883-44e3-a19d-b25cef65a3b8'
14
+
15
+ if !token
16
+ puts "Token was not received, please look into your test config"
17
+ return
18
+ end
19
+
20
+ payment_details = PaysonAPI::Request::PaymentDetails.new(token)
21
+ response = PaysonAPI::Client.get_payment_details(payment_details)
22
+
23
+
24
+
25
+ p response
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'test_helper'
5
+ require 'payson_api'
6
+
7
+ class PaymentTest < Test::Unit::TestCase
8
+ include TestHelper
9
+
10
+ def test_generated_hash_from_payment_data
11
+ setup_payment_hash(include_order_items = true)
12
+
13
+ assert_equal PAYMENT_DATA[:return_url], @payment_hash['returnUrl']
14
+ assert_equal PAYMENT_DATA[:cancel_url], @payment_hash['cancelUrl']
15
+ assert_equal PAYMENT_DATA[:ipn_url], @payment_hash['ipnNotificationUrl']
16
+ assert_equal PAYMENT_DATA[:memo], @payment_hash['memo']
17
+
18
+ # Ensure expected format of receiver list
19
+ receiver_format = PaysonAPI::Receiver::FORMAT_STRING
20
+ @receivers.each_with_index do |receiver, index|
21
+ email = @payment_hash[receiver_format % [index, 'email']]
22
+ amount = @payment_hash[receiver_format % [index, 'amount']]
23
+
24
+ assert_equal receiver.email, email
25
+ assert_equal receiver.amount, amount
26
+ end
27
+
28
+ # Do same test for order items
29
+ order_item_format = PaysonAPI::OrderItem::FORMAT_STRING
30
+ @order_items.each_with_index do |order_item, index|
31
+ description = @payment_hash[order_item_format % [index, 'description']]
32
+ unit_price = @payment_hash[order_item_format % [index, 'unitPrice']]
33
+ quantity = @payment_hash[order_item_format % [index, 'quantity']]
34
+ tax = @payment_hash[order_item_format % [index, 'taxPercentage']]
35
+ sku = @payment_hash[order_item_format % [index, 'sku']]
36
+
37
+ assert_equal order_item.description, description
38
+ assert_equal order_item.unit_price, unit_price
39
+ assert_equal order_item.quantity, quantity
40
+ assert_equal order_item.tax, tax
41
+ assert_equal order_item.sku, sku
42
+ end
43
+ end
44
+
45
+ def test_payment_initiation_request
46
+ token = acquire_token
47
+
48
+ if !token
49
+ puts "Token was not received, please look into your test config"
50
+ return
51
+ end
52
+ end
53
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,7 @@ require 'yaml'
2
2
 
3
3
  module TestHelper
4
4
  CONFIG = YAML.load_file('test/fixtures/config.yml')
5
+ PAYMENT_DATA = YAML.load_file('test/fixtures/payment_data.yml')
5
6
 
6
7
  def setup
7
8
  PaysonAPI.configure do |config|
@@ -10,6 +11,56 @@ module TestHelper
10
11
  end
11
12
  end
12
13
 
14
+ def setup_payment_hash(include_order_items = false)
15
+ @sender = PaysonAPI::Sender.new(
16
+ PAYMENT_DATA[:sender][:email],
17
+ PAYMENT_DATA[:sender][:first_name],
18
+ PAYMENT_DATA[:sender][:last_name]
19
+ )
20
+
21
+ @receivers = []
22
+ PAYMENT_DATA[:receivers].each do |receiver|
23
+ @receivers << PaysonAPI::Receiver.new(
24
+ receiver[:email],
25
+ receiver[:amount]
26
+ )
27
+ end
28
+
29
+ @payment = PaysonAPI::Request::Payment.new(
30
+ PAYMENT_DATA[:return_url],
31
+ PAYMENT_DATA[:cancel_url],
32
+ PAYMENT_DATA[:ipn_url],
33
+ PAYMENT_DATA[:memo],
34
+ @sender,
35
+ @receivers
36
+ )
37
+
38
+ @order_items = []
39
+ PAYMENT_DATA[:order_items].each do |order_item|
40
+ @order_items << PaysonAPI::OrderItem.new(
41
+ order_item[:description],
42
+ order_item[:unit_price],
43
+ order_item[:quantity],
44
+ order_item[:tax],
45
+ order_item[:sku]
46
+ )
47
+ end
48
+
49
+ @payment.order_items = @order_items if include_order_items
50
+ @payment_hash = @payment.to_hash
51
+ end
52
+
53
+ # Note that for this method to succeed you must configure the tests
54
+ # with your personal details:
55
+ # * The api_user_id/api_password must be valid (in config.yml)
56
+ # * The receiver email must be valid for the supplied credentials
57
+ # (in payment_data.yml)
58
+ def acquire_token
59
+ setup_payment_hash
60
+ response = PaysonAPI::Client.initiate_payment(@payment_hash)
61
+ response.token
62
+ end
63
+
13
64
  def teardown
14
65
  end
15
66
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 6
9
- version: 0.0.6
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Christopher Svensson
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-07-25 00:00:00 +02:00
17
+ date: 2012-07-27 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -61,20 +61,29 @@ files:
61
61
  - lib/payson_api.rb
62
62
  - lib/payson_api/client.rb
63
63
  - lib/payson_api/config.rb
64
- - lib/payson_api/errors/payson_api_error.rb
65
- - lib/payson_api/errors/remote_error.rb
64
+ - lib/payson_api/envelope.rb
65
+ - lib/payson_api/funding.rb
66
66
  - lib/payson_api/order_item.rb
67
- - lib/payson_api/pay_data.rb
68
67
  - lib/payson_api/receiver.rb
69
- - lib/payson_api/response.rb
68
+ - lib/payson_api/remote_error.rb
69
+ - lib/payson_api/request/ipn.rb
70
+ - lib/payson_api/request/payment.rb
71
+ - lib/payson_api/request/payment_details.rb
72
+ - lib/payson_api/request/payment_update.rb
73
+ - lib/payson_api/response/ipn.rb
74
+ - lib/payson_api/response/payment.rb
75
+ - lib/payson_api/response/payment_details.rb
76
+ - lib/payson_api/response/payment_update.rb
77
+ - lib/payson_api/response/validate.rb
70
78
  - lib/payson_api/sender.rb
79
+ - lib/payson_api/shipping_address.rb
71
80
  - lib/payson_api/version.rb
72
81
  - payson_api.gemspec
73
82
  - test/fixtures/config.yml
74
- - test/fixtures/order.yml
83
+ - test/fixtures/payment_data.yml
75
84
  - test/integration/config_test.rb
76
- - test/integration/pay_data_test.rb
77
- - test/integration/request_test.rb
85
+ - test/integration/payment_details_test.rb
86
+ - test/integration/payment_test.rb
78
87
  - test/test_helper.rb
79
88
  has_rdoc: true
80
89
  homepage: https://github.com/stoffus/payson_api
@@ -108,8 +117,8 @@ specification_version: 3
108
117
  summary: Client for Payson API
109
118
  test_files:
110
119
  - test/fixtures/config.yml
111
- - test/fixtures/order.yml
120
+ - test/fixtures/payment_data.yml
112
121
  - test/integration/config_test.rb
113
- - test/integration/pay_data_test.rb
114
- - test/integration/request_test.rb
122
+ - test/integration/payment_details_test.rb
123
+ - test/integration/payment_test.rb
115
124
  - test/test_helper.rb
@@ -1,7 +0,0 @@
1
- module PaysonAPI
2
- module Errors
3
- class PaysonAPIError < StandardError
4
- # Base error.
5
- end
6
- end
7
- end
@@ -1,55 +0,0 @@
1
- module PaysonAPI
2
- module Errors
3
- class RemoteError < PaysonAPIError
4
- ERROR_CODES = {
5
- '500000' => "System error.",
6
- '520002' => "Internal error.",
7
- '520003' => "Authentication failed; Credentials were not valid.",
8
- '520004' => "The merchant account is restricted.",
9
- '520005' => "The merchant account is locked.",
10
- '520006' => "The requested API endpoint is unknown.",
11
- '529038' => "Error while executing payment.",
12
- '539041' => "An email account is not receive enabled.",
13
- '539043' => "An email account is not send enabled.",
14
- '559044' => "A receiver's preferences denied the payment.",
15
- '560027' => "Unrecognized fees payer type.",
16
- '579007' => "Payment request number of receivers exceeds the maximum.",
17
- '579008' => "Number of primary receivers exceeds 1.",
18
- '579017' => "Primary receiver amount for chained payment must not be less than sum of other receiver amounts.",
19
- '579033' => "Sender and each receiver must all have different accounts.",
20
- '579040' => "Two receivers belong to the same Payson user account.",
21
- '579042' => "The tracking ID already exists and cannot be duplicated.",
22
- '579045' => "This request would exceed the receiving limit for an account.",
23
- '579047' => "This request would exceed the purse limit for an account.",
24
- '579048' => "This request would exceed the sending limit for an account.",
25
- '579049' => "The payment request you are looking for was not found in our system.",
26
- '580001' => "Invalid request - the request did not pass our basic validation.",
27
- '580021' => "Invalid parameter - too long.",
28
- '580022' => "Your request was invalid. Check the parameter of the error to see which is invalid.",
29
- '580023' => "A receiver was given more than once in the request.",
30
- '580027' => "Unsupported currency code.",
31
- '580028' => "A URL supplied with the request is malformed.",
32
- '580029' => "A required parameter was not provided. Check the error parameter list.",
33
- '589018' => "Invalid pay key.",
34
- '589052' => "The transaction ID was not found in our system.",
35
- '589053' => "All payment methods have been disabled for this combination of funding constraint, merchant and receiver.",
36
- '590001' => "The total amount specified for receivers does not match the total amount specified by the order items.",
37
- '590005' => "Not all related order item parameters where specified. All or none of unitPrice, quantity, taxPercentage and sku must be set.",
38
- '590006' => "Invoice requires one reciever.",
39
- '590007' => "Invoice requires fee on reciever.",
40
- '590008' => "Invoice requires that order items are specified.",
41
- '590009' => "Invoice payments are not available to this merchant.",
42
- '590010' => "The requested action is not possible in the current state of the payment.",
43
- '590011' => "The amount on the invoice is below the minimum limit.",
44
- '590012' => "Invoice does not support the selected currency.",
45
- '590013' => "The invoice fee out of the valid range (0-30 SEK).",
46
- '590014' => "The invoice fee can only be specified for invoices.",
47
- '590015' => "The receiver is not allowed to receive invoices.",
48
- '590016' => "The sender and reciever is the same user.",
49
- '590017' => "Invoice is frozen and cannot be updated.",
50
- '590018' => "The requested action is not possible for the current type of payment.",
51
- '590021' => "The funding constraint INVOICE cannot be combined with other funding constraints."
52
- }
53
- end
54
- end
55
- end
@@ -1,35 +0,0 @@
1
- module PaysonAPI
2
- class Response
3
- attr_accessor :envelope, :token, :errors
4
-
5
- def initialize(response)
6
- @errors = {}
7
- @envelope = {}
8
- @token = nil
9
- parse_response(response)
10
- end
11
-
12
- def parse_response(response)
13
- response.split(/&/).each do |item|
14
- if item =~ /TOKEN/
15
- @token = item.split(/=/)[1]
16
- elsif item =~ /errorId/
17
- code = item.split(/=/)[1]
18
- @errors[code] = Errors::RemoteError::ERROR_CODES[code]
19
- elsif item =~ /responseEnvelope/
20
- name, value = item.split(/=/)
21
- name = name.split(/\./)[1]
22
- @envelope[name] = value
23
- end
24
- end
25
- end
26
-
27
- def success?
28
- @envelope['ack'] == 'SUCCESS'
29
- end
30
-
31
- def forward_url
32
- url = PAYSON_WWW_HOST + PAYSON_WWW_PAY_FORWARD_URL % @token
33
- end
34
- end
35
- end
@@ -1,80 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'test/unit'
4
- require 'test_helper'
5
- require 'payson_api'
6
-
7
- class PayDataTest < Test::Unit::TestCase
8
- include TestHelper
9
- ORDER = YAML.load_file('test/fixtures/order.yml')
10
-
11
- def test_generated_hash_from_pay_data
12
- sender = PaysonAPI::Sender.new(
13
- ORDER[:sender][:email],
14
- ORDER[:sender][:first_name],
15
- ORDER[:sender][:last_name]
16
- )
17
-
18
- receivers = []
19
- ORDER[:receivers].each do |receiver|
20
- receivers << PaysonAPI::Receiver.new(
21
- receiver[:email],
22
- receiver[:amount]
23
- )
24
- end
25
-
26
- pay_data = PaysonAPI::PayData.new(
27
- ORDER[:return_url],
28
- ORDER[:cancel_url],
29
- ORDER[:ipn_url],
30
- ORDER[:memo],
31
- sender,
32
- receivers
33
- )
34
-
35
- order_items = []
36
- ORDER[:order_items].each do |order_item|
37
- order_items << PaysonAPI::OrderItem.new(
38
- order_item[:description],
39
- order_item[:unit_price],
40
- order_item[:quantity],
41
- order_item[:tax],
42
- order_item[:sku]
43
- )
44
- end
45
-
46
- pay_data.order_items = order_items
47
- pay_data_hash = pay_data.to_hash
48
-
49
- assert_equal ORDER[:return_url], pay_data_hash['returnUrl']
50
- assert_equal ORDER[:cancel_url], pay_data_hash['cancelUrl']
51
- assert_equal ORDER[:ipn_url], pay_data_hash['ipnNotificationUrl']
52
- assert_equal ORDER[:memo], pay_data_hash['memo']
53
-
54
- # Ensure expected format of receiver list
55
- receiver_format = PaysonAPI::Receiver::FORMAT_STRING
56
- receivers.each_with_index do |receiver, index|
57
- email = pay_data_hash[receiver_format % [index, 'email']]
58
- amount = pay_data_hash[receiver_format % [index, 'amount']]
59
-
60
- assert_equal receiver.email, email
61
- assert_equal receiver.amount, amount
62
- end
63
-
64
- # Do same test for order items
65
- order_item_format = PaysonAPI::OrderItem::FORMAT_STRING
66
- order_items.each_with_index do |order_item, index|
67
- description = pay_data_hash[order_item_format % [index, 'description']]
68
- unit_price = pay_data_hash[order_item_format % [index, 'unitPrice']]
69
- quantity = pay_data_hash[order_item_format % [index, 'quantity']]
70
- tax = pay_data_hash[order_item_format % [index, 'taxPercentage']]
71
- sku = pay_data_hash[order_item_format % [index, 'sku']]
72
-
73
- assert_equal order_item.description, description
74
- assert_equal order_item.unit_price, unit_price
75
- assert_equal order_item.quantity, quantity
76
- assert_equal order_item.tax, tax
77
- assert_equal order_item.sku, sku
78
- end
79
- end
80
- end
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'test/unit'
4
- require 'test_helper'
5
- require 'payson_api'
6
-
7
- class PayDataTest < Test::Unit::TestCase
8
- include TestHelper
9
- ORDER = YAML.load_file('test/fixtures/order.yml')
10
-
11
- def test_request_and_fail_gracefully
12
- sender = PaysonAPI::Sender.new(
13
- ORDER[:sender][:email],
14
- ORDER[:sender][:first_name],
15
- ORDER[:sender][:last_name]
16
- )
17
-
18
- receivers = []
19
- ORDER[:receivers].each do |receiver|
20
- receivers << PaysonAPI::Receiver.new(
21
- receiver[:email],
22
- receiver[:amount]
23
- )
24
- end
25
-
26
- pay_data = PaysonAPI::PayData.new(
27
- ORDER[:return_url],
28
- ORDER[:cancel_url],
29
- ORDER[:ipn_url],
30
- ORDER[:memo],
31
- sender,
32
- receivers
33
- )
34
-
35
- response = PaysonAPI::Client.pay(pay_data)
36
-
37
- # This should fail due to bad credentials
38
- assert_equal 'FAILURE', response.envelope['ack']
39
- end
40
- end