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