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.
- checksums.yaml +5 -5
- data/MIT-LICENSE +16 -17
- data/README.md +228 -0
- data/lib/payson_api.rb +55 -22
- data/lib/payson_api/v1/client.rb +80 -0
- data/lib/payson_api/v1/config.rb +63 -0
- data/lib/payson_api/v1/envelope.rb +27 -0
- data/lib/payson_api/v1/errors/unknown_currency_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_fees_payer_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_funding_constraint_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_guarantee_offering_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_locale_error.rb +13 -0
- data/lib/payson_api/v1/errors/unknown_payment_action_error.rb +13 -0
- data/lib/payson_api/v1/funding.rb +38 -0
- data/lib/payson_api/v1/order_item.rb +43 -0
- data/lib/payson_api/v1/receiver.rb +46 -0
- data/lib/payson_api/v1/remote_error.rb +36 -0
- data/lib/payson_api/v1/requests/ipn.rb +19 -0
- data/lib/payson_api/v1/requests/payment.rb +68 -0
- data/lib/payson_api/v1/requests/payment_details.rb +19 -0
- data/lib/payson_api/v1/requests/payment_update.rb +27 -0
- data/lib/payson_api/v1/responses/ipn.rb +43 -0
- data/lib/payson_api/v1/responses/payment.rb +25 -0
- data/lib/payson_api/v1/responses/payment_details.rb +50 -0
- data/lib/payson_api/v1/responses/payment_update.rb +20 -0
- data/lib/payson_api/v1/responses/validate.rb +19 -0
- data/lib/payson_api/v1/sender.rb +28 -0
- data/lib/payson_api/v1/shipping_address.rb +34 -0
- data/lib/payson_api/v2/client.rb +67 -0
- data/lib/payson_api/v2/config.rb +51 -0
- data/lib/payson_api/v2/errors/unauthorized_error.rb +10 -0
- data/lib/payson_api/v2/errors/validation_error.rb +16 -0
- data/lib/payson_api/v2/models/account.rb +23 -0
- data/lib/payson_api/v2/models/checkout.rb +28 -0
- data/lib/payson_api/v2/models/customer.rb +27 -0
- data/lib/payson_api/v2/models/merchant.rb +24 -0
- data/lib/payson_api/v2/models/order.rb +32 -0
- data/lib/payson_api/v2/models/order_item.rb +33 -0
- data/lib/payson_api/v2/requests/create_checkout.rb +26 -0
- data/lib/payson_api/v2/requests/customer.rb +23 -0
- data/lib/payson_api/v2/requests/list_checkouts.rb +23 -0
- data/lib/payson_api/v2/requests/merchant.rb +25 -0
- data/lib/payson_api/v2/requests/order.rb +22 -0
- data/lib/payson_api/v2/requests/order_item.rb +27 -0
- data/lib/payson_api/v2/requests/update_checkout.rb +25 -0
- data/lib/payson_api/version.rb +3 -1
- metadata +70 -53
- data/.gitignore +0 -7
- data/.travis.yml +0 -5
- data/Gemfile +0 -2
- data/Guardfile +0 -9
- data/README.rdoc +0 -155
- data/Rakefile +0 -24
- data/lib/payson_api/client.rb +0 -79
- data/lib/payson_api/config.rb +0 -50
- data/lib/payson_api/envelope.rb +0 -21
- data/lib/payson_api/funding.rb +0 -34
- data/lib/payson_api/order_item.rb +0 -52
- data/lib/payson_api/receiver.rb +0 -52
- data/lib/payson_api/remote_error.rb +0 -31
- data/lib/payson_api/request/ipn.rb +0 -15
- data/lib/payson_api/request/payment.rb +0 -68
- data/lib/payson_api/request/payment_details.rb +0 -15
- data/lib/payson_api/request/payment_update.rb +0 -22
- data/lib/payson_api/response/ipn.rb +0 -36
- data/lib/payson_api/response/payment.rb +0 -22
- data/lib/payson_api/response/payment_details.rb +0 -43
- data/lib/payson_api/response/payment_update.rb +0 -16
- data/lib/payson_api/response/validate.rb +0 -15
- data/lib/payson_api/sender.rb +0 -29
- data/lib/payson_api/shipping_address.rb +0 -36
- data/payson_api.gemspec +0 -23
- data/test/fixtures/config.yml +0 -2
- data/test/fixtures/payment_data.yml +0 -37
- data/test/integration/config_test.rb +0 -15
- data/test/integration/payment_details_test.rb +0 -21
- data/test/integration/payment_test.rb +0 -65
- 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,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
|