payson_api 0.4.2 → 1.0.1

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.
Files changed (78) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +16 -17
  3. data/README.md +228 -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 +67 -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 +70 -53
  48. data/.gitignore +0 -7
  49. data/.travis.yml +0 -5
  50. data/Gemfile +0 -2
  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 -68
  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
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Responses
6
+ class Payment
7
+ attr_accessor :envelope, :token, :errors
8
+
9
+ def initialize(data)
10
+ @envelope = PaysonAPI::V1::Envelope.parse(data)
11
+ @token = data['TOKEN']
12
+ @errors = PaysonAPI::V1::RemoteError.parse(data)
13
+ end
14
+
15
+ def success?
16
+ @envelope.ack == 'SUCCESS'
17
+ end
18
+
19
+ def forward_url
20
+ PaysonAPI::V1.forward_url(@token)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ module Responses
8
+ class PaymentDetails
9
+ attr_accessor :envelope, :purchase_id, :sender_email, :status,
10
+ :payment_type, :guarantee_status, :guarantee_deadline_at,
11
+ :invoice_status, :custom, :tracking_id, :receivers, :currency,
12
+ :order_items, :errors, :fundings, :token, :shipping_address
13
+
14
+ def initialize(data)
15
+ @envelope = PaysonAPI::V1::Envelope.parse(data)
16
+ @purchase_id = data['purchaseId']
17
+ @payment_type = data['type']
18
+ @comment = data['custom']
19
+ @tracking_id = data['trackingId']
20
+ @currency = data['currencyCode']
21
+ @sender_email = data['senderEmail']
22
+ @status = data['status']
23
+ @token = data['token']
24
+ @fundings = PaysonAPI::V1::Funding.parse(data)
25
+ @receivers = PaysonAPI::V1::Receiver.parse(data)
26
+ @order_items = PaysonAPI::V1::OrderItem.parse(data)
27
+ @errors = PaysonAPI::V1::RemoteError.parse(data)
28
+ append_payment_type_conditionals
29
+ end
30
+
31
+ def append_payment_type_conditionals
32
+ case @payment_type
33
+ when 'GUARANTEE'
34
+ @guarantee_status = data['guaranteeStatus']
35
+ @guarantee_deadline_at = Time.parse(CGI.unescape(data['guaranteeDeadlineTimestamp']))
36
+ when 'INVOICE'
37
+ @invoice_status = data['invoiceStatus']
38
+ if %w[ORDERCREATED SHIPPED DONE CREDITED].include?(@invoice_status)
39
+ @shipping_address = PaysonAPI::V1::ShippingAddress.parse(data)
40
+ end
41
+ end
42
+ end
43
+
44
+ def success?
45
+ @envelope.ack == 'SUCCESS'
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Responses
6
+ class PaymentUpdate
7
+ attr_accessor :envelope, :errors
8
+
9
+ def initialize(data)
10
+ @envelope = PaysonAPI::V1::Envelope.parse(data)
11
+ @errors = PaysonAPI::V1::RemoteError.parse(data)
12
+ end
13
+
14
+ def success?
15
+ @envelope.ack == 'SUCCESS'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Responses
6
+ class Validate
7
+ attr_accessor :data
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def verified?
14
+ @data == 'VERIFIED'
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class Sender
8
+ FORMAT_STRING = 'sender%s'
9
+ attr_accessor :email, :first_name, :last_name
10
+
11
+ def to_hash
12
+ {}.tap do |hash|
13
+ hash[FORMAT_STRING % 'Email'] = @email
14
+ hash[FORMAT_STRING % 'FirstName'] = @first_name
15
+ hash[FORMAT_STRING % 'LastName'] = @last_name
16
+ end
17
+ end
18
+
19
+ def self.parse(data)
20
+ new.tap do |s|
21
+ s.email = data[FORMAT_STRING % 'email']
22
+ s.first_name = CGI.unescape(data[FORMAT_STRING % 'FirstName'].to_s)
23
+ s.last_name = CGI.unescape(data[FORMAT_STRING % 'LastName'].to_s)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class ShippingAddress
8
+ FORMAT_STRING = 'shippingAddress.%s'
9
+ attr_accessor :name, :street_address, :postal_code, :city, :country
10
+
11
+ def to_hash
12
+ {}.tap do |hash|
13
+ hash[FORMAT_STRING % 'name'] = @name
14
+ hash[FORMAT_STRING % 'streetAddress'] = @street_address
15
+ hash[FORMAT_STRING % 'postalCode'] = @postal_code
16
+ hash[FORMAT_STRING % 'city'] = @city
17
+ hash[FORMAT_STRING % 'country'] = @country
18
+ end
19
+ end
20
+
21
+ def self.parse(data)
22
+ return unless data[FORMAT_STRING % 'name']
23
+
24
+ new.tap do |s|
25
+ s.name = CGI.unescape(data[FORMAT_STRING % 'name'].to_s)
26
+ s.street_address = CGI.unescape(data[FORMAT_STRING % 'streetAddress'].to_s)
27
+ s.postal_code = CGI.unescape(data[FORMAT_STRING % 'postalCode'].to_s)
28
+ s.city = CGI.unescape(data[FORMAT_STRING % 'city'].to_s)
29
+ s.country = CGI.unescape(data[FORMAT_STRING % 'country'].to_s)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/https'
4
+ require 'json'
5
+
6
+ module PaysonAPI
7
+ module V2
8
+ class Client
9
+ def self.account_info
10
+ response = payson_request(Net::HTTP::Get, PAYSON_API_RESOURCES[:accounts][:get])
11
+ PaysonAPI::V2::Models::Account.from_hash(JSON.parse(response.body))
12
+ end
13
+
14
+ def self.get_checkout(id)
15
+ response = payson_request(Net::HTTP::Get, PAYSON_API_RESOURCES[:checkouts][:get] % id)
16
+ PaysonAPI::V2::Models::Checkout.from_hash(JSON.parse(response.body))
17
+ end
18
+
19
+ def self.create_checkout(request)
20
+ response = payson_request(Net::HTTP::Post, PAYSON_API_RESOURCES[:checkouts][:create], request)
21
+ handle_validation_error(response)
22
+ PaysonAPI::V2::Models::Checkout.from_hash(JSON.parse(response.body))
23
+ end
24
+
25
+ def self.update_checkout(request)
26
+ response = payson_request(Net::HTTP::Put, PAYSON_API_RESOURCES[:checkouts][:update] % request.id, request)
27
+ handle_validation_error(response)
28
+ PaysonAPI::V2::Models::Checkout.from_hash(JSON.parse(response.body))
29
+ end
30
+
31
+ def self.list_checkouts(request)
32
+ path = [PAYSON_API_RESOURCES[:checkouts][:list], hash_to_params(request.to_hash)].join('?')
33
+ response = payson_request(Net::HTTP::Get, path)
34
+ [].tap do |checkouts|
35
+ JSON.parse(response.body)['data'].each do |json|
36
+ checkouts << PaysonAPI::V2::Models::Checkout.from_hash(json)
37
+ end
38
+ end
39
+ end
40
+
41
+ def self.handle_validation_error(response)
42
+ if response.code == '400' || response.code == '500' # rubocop:disable Style/GuardClause
43
+ raise PaysonAPI::V2::Errors::ValidationError, errors: JSON.parse(response.body)['errors']
44
+ end
45
+ end
46
+
47
+ def self.hash_to_params(hash)
48
+ hash.map { |k, v| "#{k}=#{URI.encode_www_form_component(v.to_s)}" }.join('&')
49
+ end
50
+
51
+ def self.payson_request(method, resource, request = nil)
52
+ url = [PaysonAPI::V2.api_base_url, PAYSON_API_VERSION, resource].join('/')
53
+ uri = URI.parse(url)
54
+ http = Net::HTTP.new(uri.host, uri.port)
55
+ http.use_ssl = uri.scheme == 'https'
56
+ req = method.new(uri.request_uri)
57
+ req.basic_auth PaysonAPI::V2.config.api_user_id, PaysonAPI::V2.config.api_password
58
+ req.body = JSON.generate(request.to_hash) unless request.nil?
59
+ req['Content-Type'] = 'application/json'
60
+ response = http.request(req)
61
+ raise PaysonAPI::V2::Errors::UnauthorizedError if response.code == '401'
62
+
63
+ response
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module_function
6
+
7
+ PAYSON_API_ENDPOINT = 'https://%s.payson.se'
8
+ PAYSON_API_VERSION = '2.0'
9
+ PAYSON_API_RESOURCES = {
10
+ checkouts: {
11
+ create: 'Checkouts',
12
+ update: 'Checkouts/%s',
13
+ get: 'Checkouts/%s',
14
+ list: 'Checkouts'
15
+ },
16
+ accounts: {
17
+ get: 'Accounts'
18
+ }
19
+ }.freeze
20
+
21
+ PAYSON_API_TEST_ENDPOINT = 'https://test-api.payson.se'
22
+
23
+ LOCALES = %w[SV EN FI].freeze
24
+ CURRENCIES = %w[sek eur].freeze
25
+
26
+ def configure
27
+ yield @config ||= Configuration.new # rubocop:disable Naming/MemoizedInstanceVariableName
28
+ end
29
+
30
+ def config
31
+ @config
32
+ end
33
+
34
+ class Configuration
35
+ attr_accessor :api_user_id, :api_password, :test_mode
36
+ end
37
+
38
+ configure do |config|
39
+ config.api_user_id = 'XXXX'
40
+ config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
41
+ end
42
+
43
+ def test?
44
+ @config.test_mode || @config.api_user_id == '4'
45
+ end
46
+
47
+ def api_base_url
48
+ test? ? PAYSON_API_TEST_ENDPOINT : PAYSON_API_ENDPOINT
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Errors
6
+ class UnauthorizedError < StandardError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Errors
6
+ class ValidationError < StandardError
7
+ attr_reader :errors
8
+
9
+ def initialize(msg = 'Validation failed', errors: [])
10
+ @errors = errors
11
+ super(msg)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Models
6
+ class Account
7
+ attr_accessor :account_email, :status, :merchant_id, :enabled_for_invoice,
8
+ :enabled_for_payment_plan, :enabled_for_recurring_payments
9
+
10
+ def self.from_hash(hash)
11
+ new.tap do |account|
12
+ account.account_email = hash['accountEmail']
13
+ account.status = hash['status']
14
+ account.merchant_id = hash['merchantId']
15
+ account.enabled_for_invoice = hash['enabledForInvoice']
16
+ account.enabled_for_payment_plan = hash['enabledForpaymentPlan']
17
+ account.enabled_for_recurring_payments = hash['enabledForRecurringPayments']
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Models
6
+ class Checkout
7
+ attr_accessor :id, :status, :expiration_time, :description, :snippet,
8
+ :customer, :order, :merchant
9
+
10
+ def self.from_hash(hash)
11
+ new.tap do |checkout|
12
+ checkout.id = hash['id']
13
+ checkout.status = hash['status']
14
+ checkout.expiration_time = hash['expirationTime']
15
+ checkout.description = hash['description']
16
+ checkout.snippet = hash['snippet']
17
+
18
+ checkout.customer = PaysonAPI::V2::Models::Customer.from_hash(hash['customer']) if hash['customer']
19
+
20
+ checkout.merchant = PaysonAPI::V2::Models::Merchant.from_hash(hash['merchant']) if hash['merchant']
21
+
22
+ checkout.order = PaysonAPI::V2::Models::Order.from_hash(hash['order'])
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Models
6
+ class Customer
7
+ attr_accessor :city, :country_code, :identity_number, :email, :first_name,
8
+ :last_name, :phone, :postal_code, :street, :type
9
+
10
+ def self.from_hash(hash)
11
+ new.tap do |customer|
12
+ customer.city = hash['city']
13
+ customer.country_code = hash['countryCode']
14
+ customer.first_name = hash['firstName']
15
+ customer.last_name = hash['lastName']
16
+ customer.identity_number = hash['identityNumber']
17
+ customer.email = hash['email']
18
+ customer.postal_code = hash['postalCode']
19
+ customer.phone = hash['phone']
20
+ customer.street = hash['street']
21
+ customer.type = hash['type']
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V2
5
+ module Models
6
+ class Merchant
7
+ attr_accessor :checkout_uri, :confirmation_uri, :partner_id, :notification_uri,
8
+ :validation_uri, :terms_uri, :integration_info, :reference
9
+
10
+ def self.from_hash(hash)
11
+ new.tap do |merchant|
12
+ merchant.checkout_uri = hash['checkoutUri']
13
+ merchant.confirmation_uri = hash['confirmationUri']
14
+ merchant.validation_uri = hash['validationUri']
15
+ merchant.terms_uri = hash['termsUri']
16
+ merchant.partner_id = hash['partnerId']
17
+ merchant.integration_info = hash['integrationInfo']
18
+ merchant.reference = hash['reference']
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end