payson_api 0.3.3 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +5 -13
  2. data/MIT-LICENSE +16 -17
  3. data/README.md +230 -0
  4. data/lib/payson_api.rb +55 -22
  5. data/lib/payson_api/v1/client.rb +80 -0
  6. data/lib/payson_api/v1/config.rb +63 -0
  7. data/lib/payson_api/v1/envelope.rb +27 -0
  8. data/lib/payson_api/v1/errors/unknown_currency_error.rb +13 -0
  9. data/lib/payson_api/v1/errors/unknown_fees_payer_error.rb +13 -0
  10. data/lib/payson_api/v1/errors/unknown_funding_constraint_error.rb +13 -0
  11. data/lib/payson_api/v1/errors/unknown_guarantee_offering_error.rb +13 -0
  12. data/lib/payson_api/v1/errors/unknown_locale_error.rb +13 -0
  13. data/lib/payson_api/v1/errors/unknown_payment_action_error.rb +13 -0
  14. data/lib/payson_api/v1/funding.rb +38 -0
  15. data/lib/payson_api/v1/order_item.rb +43 -0
  16. data/lib/payson_api/v1/receiver.rb +46 -0
  17. data/lib/payson_api/v1/remote_error.rb +36 -0
  18. data/lib/payson_api/v1/requests/ipn.rb +19 -0
  19. data/lib/payson_api/v1/requests/payment.rb +68 -0
  20. data/lib/payson_api/v1/requests/payment_details.rb +19 -0
  21. data/lib/payson_api/v1/requests/payment_update.rb +27 -0
  22. data/lib/payson_api/v1/responses/ipn.rb +43 -0
  23. data/lib/payson_api/v1/responses/payment.rb +25 -0
  24. data/lib/payson_api/v1/responses/payment_details.rb +50 -0
  25. data/lib/payson_api/v1/responses/payment_update.rb +20 -0
  26. data/lib/payson_api/v1/responses/validate.rb +19 -0
  27. data/lib/payson_api/v1/sender.rb +28 -0
  28. data/lib/payson_api/v1/shipping_address.rb +34 -0
  29. data/lib/payson_api/v2/client.rb +69 -0
  30. data/lib/payson_api/v2/config.rb +51 -0
  31. data/lib/payson_api/v2/errors/unauthorized_error.rb +10 -0
  32. data/lib/payson_api/v2/errors/validation_error.rb +16 -0
  33. data/lib/payson_api/v2/models/account.rb +23 -0
  34. data/lib/payson_api/v2/models/checkout.rb +28 -0
  35. data/lib/payson_api/v2/models/customer.rb +27 -0
  36. data/lib/payson_api/v2/models/merchant.rb +24 -0
  37. data/lib/payson_api/v2/models/order.rb +32 -0
  38. data/lib/payson_api/v2/models/order_item.rb +33 -0
  39. data/lib/payson_api/v2/requests/create_checkout.rb +26 -0
  40. data/lib/payson_api/v2/requests/customer.rb +23 -0
  41. data/lib/payson_api/v2/requests/list_checkouts.rb +23 -0
  42. data/lib/payson_api/v2/requests/merchant.rb +25 -0
  43. data/lib/payson_api/v2/requests/order.rb +22 -0
  44. data/lib/payson_api/v2/requests/order_item.rb +27 -0
  45. data/lib/payson_api/v2/requests/update_checkout.rb +25 -0
  46. data/lib/payson_api/version.rb +3 -1
  47. metadata +76 -59
  48. data/.gitignore +0 -7
  49. data/.travis.yml +0 -6
  50. data/Gemfile +0 -11
  51. data/Guardfile +0 -9
  52. data/README.rdoc +0 -155
  53. data/Rakefile +0 -24
  54. data/lib/payson_api/client.rb +0 -79
  55. data/lib/payson_api/config.rb +0 -50
  56. data/lib/payson_api/envelope.rb +0 -21
  57. data/lib/payson_api/funding.rb +0 -34
  58. data/lib/payson_api/order_item.rb +0 -52
  59. data/lib/payson_api/receiver.rb +0 -52
  60. data/lib/payson_api/remote_error.rb +0 -31
  61. data/lib/payson_api/request/ipn.rb +0 -15
  62. data/lib/payson_api/request/payment.rb +0 -66
  63. data/lib/payson_api/request/payment_details.rb +0 -15
  64. data/lib/payson_api/request/payment_update.rb +0 -22
  65. data/lib/payson_api/response/ipn.rb +0 -36
  66. data/lib/payson_api/response/payment.rb +0 -22
  67. data/lib/payson_api/response/payment_details.rb +0 -43
  68. data/lib/payson_api/response/payment_update.rb +0 -16
  69. data/lib/payson_api/response/validate.rb +0 -15
  70. data/lib/payson_api/sender.rb +0 -29
  71. data/lib/payson_api/shipping_address.rb +0 -36
  72. data/payson_api.gemspec +0 -23
  73. data/test/fixtures/config.yml +0 -2
  74. data/test/fixtures/payment_data.yml +0 -37
  75. data/test/integration/config_test.rb +0 -15
  76. data/test/integration/payment_details_test.rb +0 -21
  77. data/test/integration/payment_test.rb +0 -65
  78. data/test/test_helper.rb +0 -76
data/.gitignore DELETED
@@ -1,7 +0,0 @@
1
- .DS_Store
2
- *.gem
3
- .bundle
4
- Gemfile.lock
5
- pkg/*.gem
6
- .rvmrc
7
- doc
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 1.9.2
5
- - 1.8.7
6
- - 2.0.0
data/Gemfile DELETED
@@ -1,11 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- group :test, :development do
6
- gem 'guard-test'
7
- gem 'rake'
8
- platforms :ruby do
9
- gem 'rb-readline'
10
- end
11
- end
data/Guardfile DELETED
@@ -1,9 +0,0 @@
1
- guard 'test' do
2
- watch(%r{^lib/(.+)\.rb$}) { "test" }
3
- watch(%r{^lib/payson_api/(.+)\.rb$}) { "test" }
4
-
5
- watch(%r{^test/unit/.+_test\.rb$}) { "test" }
6
- watch(%r{^test/fixtures/(.+)\.yml$}) { "test" }
7
- watch(%r{^test/integration/.+_test\.rb$}) { "test" }
8
- watch(%r{^test/.+_helper\.rb$}) { "test" }
9
- end
data/README.rdoc DELETED
@@ -1,155 +0,0 @@
1
- = Payson API
2
-
3
- A simple utility to handle requests against the Payson payment gateway API.
4
-
5
-
6
- == Supported versions
7
-
8
- * Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0
9
-
10
-
11
- == Install
12
-
13
- Put this line in your Gemfile:
14
- gem 'payson_api'
15
-
16
- Then bundle:
17
- $ bundle
18
-
19
-
20
- == Usage
21
-
22
- === General configuration options
23
-
24
- You need to configure the gem with your own Payson credentials through the <tt>PaysonAPI.configure</tt> method:
25
-
26
- PaysonAPI.configure do |config|
27
- config.api_user_id = 'XXXX'
28
- config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
29
- end
30
-
31
- Please note that if <tt>config.api_user_id</tt> is set to 4, the client will go into test mode. Valid test access credentials could be found in {documentation}[https://api.payson.se/#Testing/sandbox].
32
-
33
- === Initiating a payment
34
-
35
- return_url = 'http://localhost/payson/success'
36
- cancel_url = 'http://localhost/payson/cancel'
37
- ipn_url = 'http://localhost/payson/ipn'
38
- memo = 'Sample order description'
39
-
40
- receivers = []
41
- receivers << PaysonAPI::Receiver.new(
42
- email = 'me@mydomain.com',
43
- amount = 100,
44
- first_name = 'Me',
45
- last_name = 'Just me',
46
- primary = true
47
- )
48
-
49
- sender = PaysonAPI::Sender.new(
50
- email = 'mycustomer@mydomain.com',
51
- first_name = 'My',
52
- last_name = 'Customer'
53
- )
54
-
55
- order_items = []
56
- order_items << PaysonAPI::OrderItem.new(
57
- description = 'Order item description',
58
- unit_price = 100,
59
- quantity = 1,
60
- tax = 0,
61
- sku = 'MY-ITEM-1'
62
- )
63
-
64
- payment = PaysonAPI::Request::Payment.new(
65
- return_url,
66
- cancel_url,
67
- ipn_url,
68
- memo,
69
- sender,
70
- receivers
71
- )
72
- payment.order_items = order_items
73
-
74
- response = PaysonAPI::Client.initiate_payment(payment)
75
-
76
- if response.success?
77
- # Redirect to response.forward_url
78
- else
79
- puts response.errors
80
- end
81
-
82
-
83
- === Requesting payment details
84
-
85
- token = 'token-received-from-payment-request'
86
-
87
- payment_details = PaysonAPI::Request::PaymentDetails.new(token)
88
-
89
- response = PaysonAPI::Client.get_payment_details(payment_details)
90
-
91
- if response.success?
92
- # Do stuff with response object
93
- else
94
- puts response.errors
95
- end
96
-
97
-
98
- === Updating a payment
99
-
100
- token = 'token-received-from-payment-request'
101
- action = 'CANCELORDER'
102
-
103
- payment_update = PaysonAPI::Request::PaymentUpdate.new(token, action)
104
-
105
- response = PaysonAPI::Client.update_payment(payment_update)
106
-
107
- if response.success?
108
- # Do stuff with response object
109
- else
110
- puts response.errors
111
- end
112
-
113
-
114
- === Validating an IPN response
115
-
116
- This example assumes the use of the Rails web framework.
117
-
118
- class Payson < ApplicationController
119
- def ipn_responder
120
- request_body = request.body.read
121
- ipn_response = PaysonAPI::Response::IPN.new(request_body)
122
-
123
- # Do business stuff, e.g. update the corresponding order:
124
- # order = Order.find_by_payson_token(ipn_response.token)
125
- # order.payson_status = ipn_response.status
126
- # order.save!
127
-
128
- # Create a new IPN request object containing the raw response from above
129
- ipn_request = PaysonAPI::Request::IPN.new(ipn_response.raw)
130
-
131
- validate = PaysonAPI::Client.validate_ipn(ipn_request)
132
-
133
- unless validate.verified?
134
- raise "Something went terribly wrong."
135
- end
136
- end
137
- end
138
-
139
-
140
- == Todo
141
-
142
- Nothing at the moment. Will focus on writing more thourough test cases and look over the code all in all.
143
-
144
-
145
- == Build Status {<img src="https://secure.travis-ci.org/stoffus/payson_api.png"/>}[http://travis-ci.org/stoffus/payson_api]
146
-
147
-
148
- == Questions, Feedback
149
-
150
- Feel free to message me on Github (stoffus).
151
-
152
-
153
- == Copyright
154
-
155
- Copyright (c) 2013 Christopher Svensson.
data/Rakefile DELETED
@@ -1,24 +0,0 @@
1
- require 'bundler/gem_tasks'
2
-
3
- task :default => ["test"]
4
-
5
- task :test do
6
- Rake::Task['test:unit'].execute
7
- Rake::Task['test:integration'].execute
8
- end
9
-
10
- namespace :test do
11
- desc "Run unit tests"
12
- task :unit do
13
- Dir["test/unit/*_test.rb"].each do |path|
14
- system "ruby -Ilib -Itest #{path}"
15
- end
16
- end
17
-
18
- desc "Run integration tests"
19
- task :integration do
20
- Dir["test/integration/*_test.rb"].each do |path|
21
- system "ruby -Ilib -Itest #{path}"
22
- end
23
- end
24
- end
@@ -1,79 +0,0 @@
1
- require 'net/https'
2
-
3
- module PaysonAPI
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
39
-
40
- def self.hash_to_params(hash)
41
- hash.map { |k, v| "#{k}=#{v}" }.join('&')
42
- end
43
-
44
- def self.params_to_hash(params)
45
- {}.tap do |hash|
46
- params.split('&').each do |param|
47
- key, val = param.split('=')
48
- hash[key] = val
49
- end
50
- end
51
- end
52
-
53
- private
54
-
55
- def self.payson_request(action, data)
56
- action = '/%s/%s/' % [PAYSON_API_VERSION, action]
57
- url = PAYSON_API_ENDPOINT % (PaysonAPI.test? ? 'test-api' : 'api') + action
58
- headers = {
59
- 'PAYSON-SECURITY-USERID' => PaysonAPI.config.api_user_id,
60
- 'PAYSON-SECURITY-PASSWORD' => PaysonAPI.config.api_password,
61
- 'Content-Type' => 'application/x-www-form-urlencoded'
62
- }
63
- post(url, data, headers)
64
- end
65
-
66
- def self.post(url, data, headers)
67
- uri = URI.parse(url)
68
- http = Net::HTTP.new(uri.host, uri.port)
69
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
- http.use_ssl = uri.scheme == 'https'
71
- req = Net::HTTP::Post.new(uri.path)
72
- req.body = data.is_a?(Hash) ? hash_to_params(data) : data
73
- headers.each do |name, value|
74
- req[name] = value
75
- end
76
- http.request(req)
77
- end
78
- end
79
- end
@@ -1,50 +0,0 @@
1
- module PaysonAPI
2
- extend self
3
-
4
- PAYSON_WWW_HOST = "https://%s.payson.se"
5
- PAYSON_WWW_PAY_FORWARD_URL = "/paysecure/?token=%s"
6
-
7
- PAYSON_API_ENDPOINT = "https://%s.payson.se"
8
- PAYSON_API_VERSION = "1.0"
9
- PAYSON_API_PAY_ACTION = "Pay"
10
- PAYSON_API_PAYMENT_DETAILS_ACTION = "PaymentDetails"
11
- PAYSON_API_PAYMENT_UPDATE_ACTION = "PaymentUpdate"
12
- PAYSON_API_PAYMENT_VALIDATE_ACTION = "Validate"
13
-
14
- LOCALES = %w[SV EN FI]
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]
28
-
29
- def configure(&block)
30
- yield @config ||= Configuration.new
31
- end
32
-
33
- def config
34
- @config
35
- end
36
-
37
- class Configuration
38
- attr_accessor :api_user_id, :api_password
39
- end
40
-
41
- configure do |config|
42
- config.api_user_id = 'XXXX'
43
- config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
44
- end
45
-
46
- def test?
47
- @config.api_user_id == '4'
48
- end
49
-
50
- end
@@ -1,21 +0,0 @@
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'].to_s))
17
- correlation_id = data[FORMAT_STRING % 'correlationId']
18
- self.new(ack, timestamp, correlation_id)
19
- end
20
- end
21
- end
@@ -1,34 +0,0 @@
1
- module PaysonAPI
2
- class Funding
3
- FORMAT_STRING = "fundingList.fundingConstraint(%d).%s"
4
- attr_accessor :constraint
5
-
6
- def initialize(constraint)
7
- if !FUNDING_CONSTRAINTS.include?(constraint)
8
- raise "Unknown funding constraint: #{constraint}"
9
- end
10
- @constraint = constraint
11
- end
12
-
13
- def self.to_hash(fundings)
14
- {}.tap do |hash|
15
- fundings.each_with_index do |funding, index|
16
- hash.merge!({
17
- FORMAT_STRING % [index, 'constraint'] => funding.constraint
18
- })
19
- end
20
- end
21
- end
22
-
23
- def self.parse(data)
24
- [].tap do |fundings|
25
- i = 0
26
- while data[FORMAT_STRING % [i, 'constraint']]
27
- constraint = data[FORMAT_STRING % [i, 'constraint']]
28
- fundings << self.new(constraint)
29
- i += 1
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,52 +0,0 @@
1
- require 'cgi'
2
-
3
- module PaysonAPI
4
- class OrderItem
5
- attr_accessor :description, :quantity, :unit_price, :sku, :tax
6
- FORMAT_STRING = "orderItemList.orderItem(%d).%s"
7
-
8
- def initialize(description, unit_price, quantity, tax, sku)
9
- @description = description
10
- @unit_price = unit_price
11
- @quantity = quantity
12
- @tax = tax
13
- @sku = sku
14
- end
15
-
16
- def self.to_hash(order_items)
17
- {}.tap do |hash|
18
- order_items.each_with_index do |item, index|
19
- hash.merge!({
20
- FORMAT_STRING % [index, 'description'] => item.description,
21
- FORMAT_STRING % [index, 'unitPrice'] => item.unit_price,
22
- FORMAT_STRING % [index, 'quantity'] => item.quantity,
23
- FORMAT_STRING % [index, 'taxPercentage'] => item.tax,
24
- FORMAT_STRING % [index, 'sku'] => item.sku
25
- })
26
- end
27
- end
28
- end
29
-
30
- def self.parse(data)
31
- [].tap do |order_items|
32
- i = 0
33
- while data[FORMAT_STRING % [i, 'description']]
34
- description = CGI.unescape(data[FORMAT_STRING % [i, 'description']].to_s)
35
- unit_price = data[FORMAT_STRING % [i, 'unitPrice']]
36
- quantity = data[FORMAT_STRING % [i, 'quantity']]
37
- tax = data[FORMAT_STRING % [i, 'taxPercentage']]
38
- sku = data[FORMAT_STRING % [i, 'sku']]
39
-
40
- order_items << OrderItem.new(
41
- description,
42
- unit_price,
43
- quantity,
44
- tax,
45
- sku
46
- )
47
- i += 1
48
- end
49
- end
50
- end
51
- end
52
- end