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
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OTA5MmJiMDRiODYwMTMyMzJkYTUxMmJlYWRmZDk1Njg0ODBhYTU5MQ==
5
- data.tar.gz: !binary |-
6
- Y2I4YTQ0ZDBjYzUwZDRhYzZiNmMyODU2ZDEwMTFlNjI3YmQ4NWZlZA==
2
+ SHA256:
3
+ metadata.gz: 4542d9a26a029687326f4a3f7f8fbc196b1c7f1c1c176407aea8f45cf1621346
4
+ data.tar.gz: 2d0b654fea59184a93827c87e6f57dde0d6194ae8dd81b3d6e7e541415349f6f
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NzYwOThkMmExNjI1NzVmNGQ5YmRmZGQ5MWU0ZmQ1ZmRlYjJiYTQyY2ViZjlm
10
- ODA1M2YzMmI1MGIyZmU3NDZlYjU1NjQzZTNmMjhlMDE0MjczOTc1OTkwZThl
11
- YzRlMjg4OTAwYmM3MzY2NzFiNmM4NDIwMjRhMzBjYjUzZjQ2ZGI=
12
- data.tar.gz: !binary |-
13
- NzgzZmY5MDlkM2RlM2RlYTU5MDZmNWJiMjc5NGNmNWIyMDkyMjFiZWRmY2Vi
14
- NTUwMGQxN2FhMDAzZWU5NmEzYWRkZTExNWE5YmUzYzcwNjFiNWNmZDQ1ZjBk
15
- NTBkNjgyM2YwNmM2ZDFiMmYzZmVhOWFiZWVjMmYxZjFlZGQyYWQ=
6
+ metadata.gz: 741d52cce371302839ce8ff2f68dd4b92c9312724563c22091fed701f5f06f3110ce0596464df6982121d5eaa1daac50ed71e6a4c8b1e0907275ee5a10558746
7
+ data.tar.gz: ce5ff56b813dbdb555845072de35b872328613ebddc1e5c84204b6999a96cff20c154aa368f53bc464123370c7dcdab61a891c736f94ebd0dfa8bcf88c4578ba
data/MIT-LICENSE CHANGED
@@ -1,20 +1,19 @@
1
- Copyright (c) 2012 Christopher Svensson
1
+ Copyright (c) 2021 Christopher Svensson
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
10
9
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
13
12
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,230 @@
1
+ # Payson API
2
+
3
+ A zero dependency, pure Ruby utility to handle requests against the Payson payment gateway API.
4
+
5
+ ## Supported Ruby versions
6
+
7
+ * 2.6
8
+ * 2.7
9
+ * 3.0
10
+
11
+ ## Installation
12
+
13
+ Put this line in your Gemfile:
14
+
15
+ gem 'payson_api'
16
+
17
+ Then bundle:
18
+
19
+ $ bundle
20
+
21
+ ## Usage (v2)
22
+
23
+ This explains how to use this gem with the [Payson Checkout v2 API](https://tech.payson.se/paysoncheckout2).
24
+
25
+ ### General configuration options
26
+
27
+ You need to configure the gem with your own Payson credentials through the `PaysonAPI::V2.configure` method:
28
+
29
+ ```ruby
30
+ PaysonAPI::V2.configure do |config|
31
+ config.api_user_id = 'XXXX'
32
+ config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
33
+ end
34
+ ```
35
+
36
+ Please note that if `config.api_user_id` is set to 4, the client will go into test mode. Valid test access credentials could be found in their [documentation](https://tech.payson.se/#Testing/sandbox).
37
+
38
+ For more detailed testing you may create your own test agent for use in the test environment. Use `config.test_mode = true`
39
+
40
+ ### Showing account info
41
+
42
+ ```ruby
43
+ account = PaysonAPI::V2::Client.get_account
44
+ ```
45
+
46
+ ### Creating a checkout
47
+
48
+ ```ruby
49
+ request = PaysonAPI::V2::Requests::CreateCheckout.new
50
+ request.merchant.checkout_uri = 'http://localhost/checkout'
51
+ request.merchant.confirmation_uri = 'http://localhost/confirmation'
52
+ request.merchant.notification_uri = 'http://localhost/notification'
53
+ request.merchant.terms_uri = 'http://localhost/terms'
54
+ request.order.currency = 'sek'
55
+ request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item|
56
+ item.name = 'My product name'
57
+ item.unit_price = 1000
58
+ item.quantity = 3
59
+ item.reference = 'product-1'
60
+ end
61
+
62
+ checkout = PaysonAPI::V2::Client.create_checkout(request)
63
+
64
+ # Continue by rendering the HTML from checkout.snippet.
65
+ ```
66
+
67
+ ### Updating a checkout
68
+
69
+ ```ruby
70
+ checkout = PaysonAPI::V2::Client.get_checkout(checkout_id)
71
+
72
+ request = PaysonAPI::V2::Requests::UpdateCheckout.new
73
+ request.id = checkout.id
74
+ request.status = checkout.status
75
+ request.merchant.checkout_uri = checkout.merchant.checkout_uri
76
+ request.merchant.confirmation_uri = checkout.merchant.confirmation_uri
77
+ request.merchant.notification_uri = checkout.merchant.notification_uri
78
+ request.merchant.terms_uri = checkout.merchant.terms_uri
79
+ request.order.currency = 'eur'
80
+ request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item|
81
+ item.name = 'My product name'
82
+ item.unit_price = 200
83
+ item.quantity = 3
84
+ item.reference = 'product-1'
85
+ end
86
+ request.order.items << PaysonAPI::V2::Requests::OrderItem.new.tap do |item|
87
+ item.name = 'Another product name'
88
+ item.unit_price = 600
89
+ item.quantity = 1
90
+ item.reference = 'product-2'
91
+ end
92
+
93
+ checkout = PaysonAPI::V2::Client.update_checkout(request)
94
+ ```
95
+
96
+ ## Usage (v1)
97
+
98
+ This explains how to use the [Payson 1.0 API](https://tech.payson.se/paysoncheckout1).
99
+
100
+ ### General configuration options
101
+
102
+ You need to configure the gem with your own Payson credentials through the `PaysonAPI::V1.configure` method:
103
+
104
+ ```ruby
105
+ PaysonAPI::V1.configure do |config|
106
+ config.api_user_id = 'XXXX'
107
+ config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
108
+ end
109
+ ```
110
+
111
+ Please note that if `config.api_user_id` is set to 4, the client will go into test mode. Valid test access credentials could be found in {documentation}[https://tech.payson.se/#Testing/sandbox].
112
+
113
+ For more detailed testing you may create your own test agent for use in the test environment. Use `config.test_mode = true`
114
+
115
+ ### Initiating a payment
116
+
117
+ ```ruby
118
+ payment = PaysonAPI::V1::Requests::Payment.new
119
+ payment.return_url = 'http://localhost/payson/success'
120
+ payment.cancel_url = 'http://localhost/payson/cancel'
121
+ payment.ipn_url = 'http://localhost/payson/ipn'
122
+ payment.memo = 'Sample order description'
123
+ payment.sender = PaysonAPI::V1::Sender.new.tap do |s|
124
+ s.email = 'mycustomer@mydomain.com'
125
+ s.first_name = 'My'
126
+ s.last_name = 'Customer'
127
+ end
128
+
129
+ payment.receivers = []
130
+ payment.receivers << PaysonAPI::V1::Receiver.new.tap do |r|
131
+ r.email = 'me@mydomain.com'
132
+ r.amount = 100
133
+ r.first_name = 'Me'
134
+ r.last_name = 'Just me'
135
+ r.primary = true
136
+ end
137
+
138
+ payment.order_items = []
139
+ payment.order_items << PaysonAPI::V1::OrderItem.new.tap do |i|
140
+ i.description = 'Order item description'
141
+ i.unit_price = 100
142
+ i.quantity = 1
143
+ i.tax = 0
144
+ i.sku = 'MY-ITEM-1'
145
+ end
146
+
147
+ response = PaysonAPI::V1::Client.initiate_payment(payment)
148
+
149
+ if response.success?
150
+ # Redirect to response.forward_url
151
+ else
152
+ puts response.errors
153
+ end
154
+ ```
155
+
156
+ ### Requesting payment details
157
+
158
+ ```ruby
159
+ token = 'token-received-from-payment-request'
160
+
161
+ payment_details = PaysonAPI::V1::Requests::PaymentDetails.new(token)
162
+
163
+ response = PaysonAPI::V1::Client.get_payment_details(payment_details)
164
+
165
+ if response.success?
166
+ # Do stuff with response object
167
+ else
168
+ puts response.errors
169
+ end
170
+ ```
171
+
172
+ ### Updating a payment
173
+
174
+ ```ruby
175
+ token = 'token-received-from-payment-request'
176
+ action = 'CANCELORDER'
177
+
178
+ payment_update = PaysonAPI::V1::Requests::PaymentUpdate.new(token, action)
179
+
180
+ response = PaysonAPI::V1::Client.update_payment(payment_update)
181
+
182
+ if response.success?
183
+ # Do stuff with response object
184
+ else
185
+ puts response.errors
186
+ end
187
+ ```
188
+
189
+ ### Validating an IPN response
190
+
191
+ This example assumes the use of the Rails web framework.
192
+
193
+ ```ruby
194
+ class Payson < ApplicationController
195
+ def ipn_responder
196
+ request_body = request.body.read
197
+ ipn_response = PaysonAPI::V1::Responses::IPN.new(request_body)
198
+
199
+ # Create a new IPN request object containing the raw response from above
200
+ ipn_request = PaysonAPI::V1::Requests::IPN.new(ipn_response.raw)
201
+
202
+ validation = PaysonAPI::V1::Client.validate_ipn(ipn_request)
203
+
204
+ unless validation.verified?
205
+ raise "Something went terribly wrong"
206
+ end
207
+
208
+ # Do business transactions, e.g. update the corresponding order:
209
+ # order = Order.find_by_payson_token(ipn_response.token)
210
+ # order.payson_status = ipn_response.status
211
+ # order.save!
212
+ end
213
+ end
214
+ ```
215
+
216
+ ## Todo
217
+
218
+ Nothing at the moment.
219
+
220
+ ## Project Status
221
+
222
+ [![Build Status](https://travis-ci.org/stoffus/payson_api.svg?branch=master)](https://travis-ci.org/stoffus/payson_api) [![Gem Version](https://badge.fury.io/rb/payson_api.svg)](https://badge.fury.io/rb/payson_api)
223
+
224
+ ## Questions, Feedback
225
+
226
+ Feel free to message me on [GitHub](https://github.com/stoffus).
227
+
228
+ ## Copyright
229
+
230
+ Copyright (c) 2021 Christopher Svensson.
data/lib/payson_api.rb CHANGED
@@ -1,25 +1,58 @@
1
- required_files = [
2
- 'config',
3
- 'client',
4
- 'envelope',
5
- 'funding',
6
- 'order_item',
7
- 'receiver',
8
- 'remote_error',
9
- 'request/ipn',
10
- 'request/payment_details',
11
- 'request/payment_update',
12
- 'request/payment',
13
- 'response/ipn',
14
- 'response/payment_details',
15
- 'response/payment_update',
16
- 'response/payment',
17
- 'response/validate',
18
- 'sender',
19
- 'shipping_address',
20
- 'version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'payson_api/version'
4
+
5
+ required_files_v1 = %w[
6
+ config
7
+ client
8
+ envelope
9
+ errors/unknown_currency_error
10
+ errors/unknown_fees_payer_error
11
+ errors/unknown_funding_constraint_error
12
+ errors/unknown_guarantee_offering_error
13
+ errors/unknown_locale_error
14
+ errors/unknown_payment_action_error
15
+ funding
16
+ order_item
17
+ receiver
18
+ remote_error
19
+ requests/ipn
20
+ requests/payment_details
21
+ requests/payment_update
22
+ requests/payment
23
+ responses/ipn
24
+ responses/payment_details
25
+ responses/payment_update
26
+ responses/payment
27
+ responses/validate
28
+ sender
29
+ shipping_address
30
+ ]
31
+
32
+ required_files_v2 = %w[
33
+ config
34
+ client
35
+ errors/validation_error
36
+ errors/unauthorized_error
37
+ models/account
38
+ models/checkout
39
+ models/customer
40
+ models/merchant
41
+ models/order_item
42
+ models/order
43
+ requests/order_item
44
+ requests/customer
45
+ requests/merchant
46
+ requests/order
47
+ requests/create_checkout
48
+ requests/update_checkout
49
+ requests/list_checkouts
21
50
  ]
22
51
 
23
- required_files.each do |file|
24
- require "payson_api/#{file}"
52
+ required_files_v1.each do |file|
53
+ require_relative "payson_api/v1/#{file}"
54
+ end
55
+
56
+ required_files_v2.each do |file|
57
+ require_relative "payson_api/v2/#{file}"
25
58
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/https'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class Client
8
+ def self.initiate_payment(payment_data)
9
+ response = payson_request(
10
+ PAYSON_API_PAY_ACTION,
11
+ payment_data.to_hash
12
+ )
13
+ response_hash = params_to_hash(response.body)
14
+ PaysonAPI::V1::Responses::Payment.new(response_hash)
15
+ end
16
+
17
+ def self.get_payment_details(payment_details_data)
18
+ response = payson_request(
19
+ PAYSON_API_PAYMENT_DETAILS_ACTION,
20
+ payment_details_data.to_hash
21
+ )
22
+ response_hash = params_to_hash(response.body)
23
+ PaysonAPI::V1::Responses::PaymentDetails.new(response_hash)
24
+ end
25
+
26
+ def self.update_payment(payment_update_data)
27
+ response = payson_request(
28
+ PAYSON_API_PAYMENT_DETAILS_ACTION,
29
+ payment_update_data.to_hash
30
+ )
31
+ response_hash = params_to_hash(response.body)
32
+ PaysonAPI::V1::Responses::PaymentUpdate.new(response_hash)
33
+ end
34
+
35
+ def self.validate_ipn(ipn_data)
36
+ response = payson_request(
37
+ PAYSON_API_PAYMENT_VALIDATE_ACTION,
38
+ ipn_data.to_s
39
+ )
40
+ PaysonAPI::V1::Responses::Validate.new(response.body)
41
+ end
42
+
43
+ def self.hash_to_params(hash)
44
+ hash.map { |k, v| "#{k}=#{URI.encode_www_form_component(v.to_s)}" }.join('&')
45
+ end
46
+
47
+ def self.params_to_hash(params)
48
+ {}.tap do |hash|
49
+ params.split('&').each do |param|
50
+ key, val = param.split('=')
51
+ hash[key] = URI.decode_www_form_component(val)
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.payson_request(action, data)
57
+ path = format('/%<api_version>s/%<action>s/', api_version: PAYSON_API_VERSION, action: action)
58
+ url = PaysonAPI::V1.api_base_url + path
59
+ headers = {
60
+ 'PAYSON-SECURITY-USERID' => PaysonAPI::V1.config.api_user_id,
61
+ 'PAYSON-SECURITY-PASSWORD' => PaysonAPI::V1.config.api_password,
62
+ 'Content-Type' => 'application/x-www-form-urlencoded'
63
+ }
64
+ post(url, data, headers)
65
+ end
66
+
67
+ def self.post(url, data, headers)
68
+ uri = URI.parse(url)
69
+ http = Net::HTTP.new(uri.host, uri.port)
70
+ http.use_ssl = uri.scheme == 'https'
71
+ req = Net::HTTP::Post.new(uri.request_uri)
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
80
+ end