payson_api 0.4.2 → 1.0.1

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 -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