payson_api 0.3.3 → 1.0.2

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 -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
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module_function
6
+
7
+ PAYSON_WWW_HOST_ENDPOINT = 'https://www.payson.se'
8
+ PAYSON_WWW_PAY_FORWARD_URL = '/paysecure/?token=%s'
9
+
10
+ PAYSON_API_ENDPOINT = 'https://api.payson.se'
11
+ PAYSON_API_VERSION = '1.0'
12
+ PAYSON_API_PAY_ACTION = 'Pay'
13
+ PAYSON_API_PAYMENT_DETAILS_ACTION = 'PaymentDetails'
14
+ PAYSON_API_PAYMENT_UPDATE_ACTION = 'PaymentUpdate'
15
+ PAYSON_API_PAYMENT_VALIDATE_ACTION = 'Validate'
16
+
17
+ PAYSON_API_TEST_ENDPOINT = 'https://test-api.payson.se'
18
+ PAYSON_WWW_HOST_TEST_ENDPOINT = 'https://test-www.payson.se'
19
+
20
+ LOCALES = %w[SV EN FI].freeze
21
+ CURRENCIES = %w[SEK EUR].freeze
22
+ FEES_PAYERS = %w[EACHRECEIVER SENDER PRIMARYRECEIVER SECONDARYONLY].freeze
23
+ FUNDING_CONSTRAINTS = %w[CREDITCARD BANK INVOICE SMS].freeze
24
+ GUARANTEE_OFFERINGS = %w[OPTIONAL REQUIRED NO].freeze
25
+ PAYMENT_STATUSES = %w[CREATED PENDING PROCESSING COMPLETED CREDITED
26
+ INCOMPLETE ERROR EXPIRED REVERSALERROR ABORTED].freeze
27
+ PAYMENT_TYPES = %w[TRANSFER GUARANTEE INVOICE].freeze
28
+ GUARANTEE_STATUSES = %w[WAITINGFORSEND WAITINGFORACCEPTANCE WAITINGFORRETURN
29
+ WAITINGFORRETURNACCEPTANCE RETURNNOTACCEPTED NOTRECEIVED RETURNNOTRECEIVED
30
+ MONEYRETURNEDTOSENDER RETURNACCEPTED].freeze
31
+ INVOICE_STATUSES = %w[PENDING ORDERCREATED CANCELED SHIPPED DONE CREDITED].freeze
32
+ PAYMENT_ACTIONS = %w[CANCELORDER SHIPORDER CREDITORDER REFUND].freeze
33
+
34
+ def configure
35
+ yield @config ||= Configuration.new # rubocop:disable Naming/MemoizedInstanceVariableName
36
+ end
37
+
38
+ def config
39
+ @config
40
+ end
41
+
42
+ class Configuration
43
+ attr_accessor :api_user_id, :api_password, :test_mode
44
+ end
45
+
46
+ configure do |config|
47
+ config.api_user_id = 'XXXX'
48
+ config.api_password = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
49
+ end
50
+
51
+ def test?
52
+ @config.test_mode || @config.api_user_id == '4'
53
+ end
54
+
55
+ def api_base_url
56
+ test? ? PAYSON_API_TEST_ENDPOINT : PAYSON_API_ENDPOINT
57
+ end
58
+
59
+ def forward_url(token)
60
+ (test? ? PAYSON_WWW_HOST_TEST_ENDPOINT : PAYSON_WWW_HOST_ENDPOINT) + PAYSON_WWW_PAY_FORWARD_URL % token
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+ require 'date'
5
+
6
+ module PaysonAPI
7
+ module V1
8
+ class Envelope
9
+ attr_accessor :ack, :timestamp, :correlation_id
10
+
11
+ FORMAT_STRING = 'responseEnvelope.%s'
12
+
13
+ def initialize(ack, timestamp, correlation_id)
14
+ @ack = ack
15
+ @timestamp = timestamp
16
+ @correlation_id = correlation_id
17
+ end
18
+
19
+ def self.parse(data)
20
+ ack = data[FORMAT_STRING % 'ack']
21
+ timestamp = DateTime.parse(CGI.unescape(data[FORMAT_STRING % 'timestamp'].to_s))
22
+ correlation_id = data[FORMAT_STRING % 'correlationId']
23
+ new(ack, timestamp, correlation_id)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownCurrencyError < StandardError
7
+ def initialize(_msg, currency)
8
+ super("Unknown currency: #{currency}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownFeesPayerError < StandardError
7
+ def initialize(_msg, fees_payer)
8
+ super("Unknown fees payer: #{fees_payer}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownFundingConstraintError < StandardError
7
+ def initialize(_msg, funding_constraint)
8
+ super("Unknown funding constraint: #{funding_constraint}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownGuaranteeOfferingError < StandardError
7
+ def initialize(_msg, guarantee_offering)
8
+ super("Unknown guarantee offering: #{guarantee_offering}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownLocaleError < StandardError
7
+ def initialize(_msg, locale)
8
+ super("Unknown locale: #{locale}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Errors
6
+ class UnknownPaymentActionError < StandardError
7
+ def initialize(_msg, locale)
8
+ super("Unknown payment action: #{locale}")
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ class Funding
6
+ FORMAT_STRING = 'fundingList.fundingConstraint(%d).%s'
7
+ attr_reader :constraint
8
+
9
+ def constraint=(value)
10
+ raise "Unknown funding constraint: #{value}" unless PaysonAPI::V1::FUNDING_CONSTRAINTS.include?(value)
11
+
12
+ @constraint = value
13
+ end
14
+
15
+ def self.to_hash(fundings)
16
+ {}.tap do |hash|
17
+ fundings.each_with_index do |funding, index|
18
+ hash.merge!({
19
+ format(FORMAT_STRING, index, 'constraint') => funding.constraint
20
+ })
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.parse(data)
26
+ [].tap do |fundings|
27
+ i = 0
28
+ while data[format(FORMAT_STRING, i, 'constraint')]
29
+ fundings << new.tap do |f|
30
+ f.constraint = data[format(FORMAT_STRING, i, 'constraint')]
31
+ end
32
+ i += 1
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class OrderItem
8
+ attr_accessor :description, :quantity, :unit_price, :sku, :tax
9
+
10
+ FORMAT_STRING = 'orderItemList.orderItem(%d).%s'
11
+
12
+ def self.to_hash(order_items)
13
+ {}.tap do |hash|
14
+ order_items.each_with_index do |item, index|
15
+ hash.merge!({
16
+ format(FORMAT_STRING, index, 'description') => item.description,
17
+ format(FORMAT_STRING, index, 'unitPrice') => item.unit_price,
18
+ format(FORMAT_STRING, index, 'quantity') => item.quantity,
19
+ format(FORMAT_STRING, index, 'taxPercentage') => item.tax,
20
+ format(FORMAT_STRING, index, 'sku') => item.sku
21
+ })
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.parse(data)
27
+ [].tap do |order_items|
28
+ i = 0
29
+ while data[format(FORMAT_STRING, i, 'description')]
30
+ order_items << new.tap do |item|
31
+ item.description = CGI.unescape(data[format(FORMAT_STRING, i, 'description')].to_s)
32
+ item.unit_price = data[format(FORMAT_STRING, i, 'unitPrice')]
33
+ item.quantity = data[format(FORMAT_STRING, i, 'quantity')]
34
+ item.tax = data[format(FORMAT_STRING, i, 'taxPercentage')]
35
+ item.sku = data[format(FORMAT_STRING, i, 'sku')]
36
+ end
37
+ i += 1
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class Receiver
8
+ FORMAT_STRING = 'receiverList.receiver(%d).%s'
9
+ attr_accessor :email, :amount, :first_name, :last_name, :primary
10
+
11
+ def self.to_hash(receivers)
12
+ {}.tap do |hash|
13
+ receivers.each_with_index do |receiver, index|
14
+ raise 'Invalid receiver' unless receiver.instance_of?(self)
15
+
16
+ hash.merge!({
17
+ format(FORMAT_STRING, index, 'email') => receiver.email,
18
+ format(FORMAT_STRING, index, 'amount') => receiver.amount,
19
+ format(FORMAT_STRING, index, 'firstName') => receiver.first_name,
20
+ format(FORMAT_STRING, index, 'lastName') => receiver.last_name,
21
+ format(FORMAT_STRING, index, 'primary') => receiver.primary
22
+ })
23
+ hash[format(FORMAT_STRING, index, 'firstName')] = receiver.first_name if receiver.first_name
24
+ hash[format(FORMAT_STRING, index, 'lastName')] = receiver.last_name if receiver.last_name
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.parse(data)
30
+ [].tap do |receivers|
31
+ i = 0
32
+ while data[format(FORMAT_STRING, i, 'email')]
33
+ receivers << new.tap do |r|
34
+ r.email = CGI.unescape(data[format(FORMAT_STRING, i, 'email')].to_s)
35
+ r.amount = data[format(FORMAT_STRING, i, 'amount')]
36
+ r.first_name = CGI.unescape(data[format(FORMAT_STRING, i, 'firstName')].to_s)
37
+ r.last_name = CGI.unescape(data[format(FORMAT_STRING, i, 'lastName')].to_s)
38
+ r.primary = data[format(FORMAT_STRING, i, 'primary')]
39
+ end
40
+ i += 1
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module PaysonAPI
6
+ module V1
7
+ class RemoteError
8
+ attr_accessor :id, :message, :parameter
9
+
10
+ FORMAT_STRING = 'errorList.error(%d).%s'
11
+
12
+ def initialize(id, message, parameter)
13
+ @id = id
14
+ @message = message
15
+ @parameter = parameter
16
+ end
17
+
18
+ def self.parse(data)
19
+ [].tap do |errors|
20
+ i = 0
21
+ while data[format(FORMAT_STRING, i, 'errorId')]
22
+ id = data[format(FORMAT_STRING, i, 'errorId')]
23
+ message = CGI.unescape(data[format(FORMAT_STRING, i, 'message')])
24
+ parameter = CGI.unescape(data[format(FORMAT_STRING, i, 'parameter')])
25
+ errors << new(id, message, parameter)
26
+ i += 1
27
+ end
28
+ end
29
+ end
30
+
31
+ def to_s
32
+ "ID: #{@id}, Message: #{@message}, Parameter: #{@parameter}"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Requests
6
+ class IPN
7
+ attr_accessor :data
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def to_s
14
+ @data
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Requests
6
+ class Payment
7
+ attr_accessor :return_url, :cancel_url, :ipn_url, :memo, :sender, :receivers,
8
+ :locale, :currency, :tracking_id, :invoice_fee, :order_items, :fundings,
9
+ :fees_payer, :guarantee_offered, :custom
10
+
11
+ def to_hash # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
12
+ {}.tap do |hash|
13
+ # Append mandatory params
14
+ hash['returnUrl'] = @return_url
15
+ hash['cancelUrl'] = @cancel_url
16
+ hash['memo'] = @memo
17
+ hash.merge!(@sender.to_hash)
18
+ hash.merge!(Receiver.to_hash(@receivers))
19
+
20
+ # Append optional params
21
+ append_locale(hash, @locale) if @locale
22
+ append_currency(hash, @currency) if @currency
23
+ append_fees_payer(hash, @fees_payer) if @fees_payer
24
+ append_guarantee(hash, @guarantee_offered) if @guarantee_offered
25
+ hash.merge!(OrderItem.to_hash(@order_items)) if @order_items
26
+ hash.merge!(Funding.to_hash(@fundings)) if @fundings
27
+ hash['ipnNotificationUrl'] = @ipn_url if @ipn_url
28
+ hash['invoiceFee'] = @invoice_fee if @invoice_fee
29
+ hash['trackingId'] = @tracking_id if @tracking_id
30
+ hash['custom'] = @custom if @custom
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def append_locale(hash, locale)
37
+ raise PaysonAPI::V1::Errors::UnknownCurrencyError(locale) unless LOCALES.include?(locale)
38
+
39
+ hash['localeCode'] = locale
40
+ end
41
+
42
+ def append_currency(hash, currency)
43
+ unless PaysonAPI::V1::CURRENCIES.include?(currency)
44
+ raise PaysonAPI::V1::Errors::UnknownCurrencyError(currency)
45
+ end
46
+
47
+ hash['currencyCode'] = currency
48
+ end
49
+
50
+ def append_guarantee(hash, guarantee_offered)
51
+ unless PaysonAPI::V1::GUARANTEE_OFFERINGS.include?(guarantee_offered)
52
+ raise PaysonAPI::V1::Errors::UnknownGuaranteeOffering(guarantee_offered)
53
+ end
54
+
55
+ hash['guaranteeOffered'] = guarantee_offered
56
+ end
57
+
58
+ def append_fees_payer(hash, fees_payer)
59
+ unless PaysonAPI::V1::FEES_PAYERS.include?(fees_payer)
60
+ raise PaysonAPI::V1::Errors::UnknownFeesPayer(fees_payer)
61
+ end
62
+
63
+ hash['feesPayer'] = fees_payer
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaysonAPI
4
+ module V1
5
+ module Requests
6
+ class PaymentDetails
7
+ attr_accessor :token
8
+
9
+ def initialize(token)
10
+ @token = token
11
+ end
12
+
13
+ def to_hash
14
+ { 'token' => @token }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end