paypoint-blue 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.overcommit.yml +11 -0
- data/.rubocop.yml +45 -0
- data/Gemfile +1 -1
- data/lib/paypoint/blue/api.rb +31 -37
- data/lib/paypoint/blue/base.rb +16 -21
- data/lib/paypoint/blue/body_extractor.rb +0 -4
- data/lib/paypoint/blue/error.rb +0 -4
- data/lib/paypoint/blue/faraday_runscope.rb +13 -10
- data/lib/paypoint/blue/hash_key_converter.rb +2 -3
- data/lib/paypoint/blue/hosted.rb +27 -30
- data/lib/paypoint/blue/payload_builder.rb +28 -21
- data/lib/paypoint/blue/raise_errors.rb +17 -15
- data/lib/paypoint/blue/utils.rb +7 -8
- data/lib/paypoint/blue/version.rb +2 -2
- data/lib/paypoint/blue.rb +2 -3
- data/support/yard_ext.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0720906c714d8425e8af2ea0bf97a877740caccf
|
4
|
+
data.tar.gz: 8e3711213ea3b1db72eaeeb28a76f60b860ff902
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0eefb28d9180465c528f689e926944210120c67d53c2131ca3000ce5a361a4138dda564e493d82b4e031bcb7c7f12090eb1706a10a94eb2dae4063a7f1e13eeb
|
7
|
+
data.tar.gz: 8a694c43a0bf2dd305ce6ff9fbc29168452b1b10b4c17a751c5cb88bd33890442f0a11f700f903cae09b97bac750ee5e938f2506b3c14be3b38b31adbe59e721
|
data/.overcommit.yml
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
AllCops:
|
2
|
+
Include:
|
3
|
+
- "**/Gemfile"
|
4
|
+
Exclude:
|
5
|
+
- "bin/*"
|
6
|
+
- "support/**/*"
|
7
|
+
- "vendor/**/*"
|
8
|
+
|
9
|
+
### Style ######################################################################
|
10
|
+
|
11
|
+
Style/AlignHash:
|
12
|
+
EnforcedHashRocketStyle: table
|
13
|
+
EnforcedColonStyle: table
|
14
|
+
|
15
|
+
Style/AlignParameters:
|
16
|
+
EnforcedStyle: with_fixed_indentation
|
17
|
+
|
18
|
+
Style/AndOr:
|
19
|
+
EnforcedStyle: conditionals
|
20
|
+
|
21
|
+
Style/BlockDelimiters:
|
22
|
+
EnforcedStyle: line_count_based
|
23
|
+
|
24
|
+
Style/IndentHash:
|
25
|
+
EnforcedStyle: consistent
|
26
|
+
|
27
|
+
Style/MultilineOperationIndentation:
|
28
|
+
EnforcedStyle: indented
|
29
|
+
|
30
|
+
Style/StringLiterals:
|
31
|
+
EnforcedStyle: double_quotes
|
32
|
+
|
33
|
+
Style/StringLiteralsInInterpolation:
|
34
|
+
EnforcedStyle: double_quotes
|
35
|
+
|
36
|
+
# Not enforcing %i() arrays, because they are too similar to %w() and don't have
|
37
|
+
# proper syntax highlighting support for differentiating between them.
|
38
|
+
Style/SymbolArray:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/TrailingComma:
|
42
|
+
EnforcedStyleForMultiline: comma
|
43
|
+
|
44
|
+
Style/ClassAndModuleChildren:
|
45
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/lib/paypoint/blue/api.rb
CHANGED
@@ -2,24 +2,23 @@ require "paypoint/blue/base"
|
|
2
2
|
|
3
3
|
# Client class for the API product.
|
4
4
|
class PayPoint::Blue::API < PayPoint::Blue::Base
|
5
|
-
|
6
5
|
ENDPOINTS = {
|
7
6
|
test: "https://api.mite.paypoint.net:2443/acceptor/rest",
|
8
7
|
live: "https://api.paypoint.net/acceptor/rest",
|
9
8
|
}.freeze
|
10
9
|
|
11
|
-
shortcut :merchant_ref,
|
12
|
-
shortcut :amount,
|
13
|
-
shortcut :currency,
|
14
|
-
shortcut :commerce_type,
|
15
|
-
shortcut :description,
|
16
|
-
shortcut :customer_ref,
|
17
|
-
shortcut :customer_name,
|
10
|
+
shortcut :merchant_ref, "transaction.merchant_ref"
|
11
|
+
shortcut :amount, "transaction.amount"
|
12
|
+
shortcut :currency, "transaction.currency"
|
13
|
+
shortcut :commerce_type, "transaction.commerce_type"
|
14
|
+
shortcut :description, "transaction.description"
|
15
|
+
shortcut :customer_ref, "customer.merchant_ref"
|
16
|
+
shortcut :customer_name, "customer.display_name"
|
18
17
|
|
19
|
-
shortcut :pre_auth_callback,
|
20
|
-
shortcut :post_auth_callback,
|
21
|
-
shortcut :transaction_notification,
|
22
|
-
shortcut :expiry_notification,
|
18
|
+
shortcut :pre_auth_callback, "callbacks.pre_auth_callback.url"
|
19
|
+
shortcut :post_auth_callback, "callbacks.post_auth_callback.url"
|
20
|
+
shortcut :transaction_notification, "callbacks.transaction_notification.url"
|
21
|
+
shortcut :expiry_notification, "callbacks.expiry_notification.url"
|
23
22
|
|
24
23
|
# Test connectivity
|
25
24
|
#
|
@@ -45,11 +44,9 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
45
44
|
#
|
46
45
|
# @return the API response
|
47
46
|
def make_payment(**payload)
|
48
|
-
payload = build_payload
|
49
|
-
|
50
|
-
|
51
|
-
transaction_notification expiry_notification
|
52
|
-
]
|
47
|
+
payload = build_payload payload, defaults: %i(
|
48
|
+
currency commerce_type pre_auth_callback post_auth_callback
|
49
|
+
transaction_notification expiry_notification
|
53
50
|
)
|
54
51
|
client.post "transactions/#{inst_id}/payment", payload
|
55
52
|
end
|
@@ -85,11 +82,9 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
85
82
|
#
|
86
83
|
# @return the API response
|
87
84
|
def capture_authorisation(transaction_id, **payload)
|
88
|
-
payload = build_payload
|
89
|
-
|
90
|
-
|
91
|
-
transaction_notification expiry_notification
|
92
|
-
]
|
85
|
+
payload = build_payload payload, defaults: %i(
|
86
|
+
commerce_type pre_auth_callback post_auth_callback
|
87
|
+
transaction_notification expiry_notification
|
93
88
|
)
|
94
89
|
client.post "transactions/#{inst_id}/#{transaction_id}/capture", payload
|
95
90
|
end
|
@@ -106,11 +101,9 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
106
101
|
#
|
107
102
|
# @return the API response
|
108
103
|
def cancel_authorisation(transaction_id, **payload)
|
109
|
-
payload = build_payload
|
110
|
-
|
111
|
-
|
112
|
-
transaction_notification expiry_notification
|
113
|
-
]
|
104
|
+
payload = build_payload payload, defaults: %i(
|
105
|
+
commerce_type pre_auth_callback post_auth_callback
|
106
|
+
transaction_notification expiry_notification
|
114
107
|
)
|
115
108
|
client.post "transactions/#{inst_id}/#{transaction_id}/cancel", payload
|
116
109
|
end
|
@@ -146,7 +139,7 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
146
139
|
# +amount+ or a +transaction+ hash as a keyword argument.
|
147
140
|
#
|
148
141
|
# @example Partial refund
|
149
|
-
# blue.refund_payment(txn_id, amount: '3.49') # assumes
|
142
|
+
# blue.refund_payment(txn_id, amount: '3.49') # assumes a default currency
|
150
143
|
#
|
151
144
|
# @applies_defaults
|
152
145
|
# only if amount is set: +:currency+, +:commerce_type+
|
@@ -158,9 +151,13 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
158
151
|
#
|
159
152
|
# @return the API response
|
160
153
|
def refund_payment(transaction_id, **payload)
|
161
|
-
defaults = %i
|
162
|
-
|
163
|
-
|
154
|
+
defaults = %i(
|
155
|
+
pre_auth_callback post_auth_callback
|
156
|
+
transaction_notification expiry_notification
|
157
|
+
)
|
158
|
+
if payload[:amount] ||
|
159
|
+
payload[:transaction] && payload[:transaction][:amount]
|
160
|
+
defaults += %i(currency commerce_type)
|
164
161
|
end
|
165
162
|
payload = build_payload(payload, defaults: defaults)
|
166
163
|
client.post "transactions/#{inst_id}/#{transaction_id}/refund", payload
|
@@ -180,13 +177,10 @@ class PayPoint::Blue::API < PayPoint::Blue::Base
|
|
180
177
|
#
|
181
178
|
# @return the API response
|
182
179
|
def submit_payout(**payload)
|
183
|
-
payload = build_payload
|
184
|
-
|
185
|
-
|
186
|
-
transaction_notification expiry_notification
|
187
|
-
]
|
180
|
+
payload = build_payload payload, defaults: %i(
|
181
|
+
currency commerce_type pre_auth_callback post_auth_callback
|
182
|
+
transaction_notification expiry_notification
|
188
183
|
)
|
189
184
|
client.post "transactions/#{inst_id}/payout", payload
|
190
185
|
end
|
191
|
-
|
192
186
|
end
|
data/lib/paypoint/blue/base.rb
CHANGED
@@ -9,7 +9,6 @@ require "paypoint/blue/faraday_runscope"
|
|
9
9
|
|
10
10
|
module PayPoint
|
11
11
|
module Blue
|
12
|
-
|
13
12
|
# Abstract base class for the API clients. Takes care of
|
14
13
|
# initializing the Faraday client by setting up middlewares in the
|
15
14
|
# right order.
|
@@ -25,7 +24,6 @@ module PayPoint
|
|
25
24
|
#
|
26
25
|
# @abstract
|
27
26
|
class Base
|
28
|
-
|
29
27
|
include PayloadBuilder
|
30
28
|
|
31
29
|
# The Faraday client
|
@@ -54,23 +52,18 @@ module PayPoint
|
|
54
52
|
# @option options [String] :runscope when used, all traffic will
|
55
53
|
# pass through the provided {https://www.runscope.com/ Runscope}
|
56
54
|
# bucket, including notification callbacks
|
57
|
-
def initialize(endpoint:,
|
58
|
-
|
59
|
-
|
60
|
-
api_password: ENV['BLUE_API_PASSWORD'],
|
61
|
-
**options)
|
62
|
-
|
63
|
-
@endpoint = get_endpoint_or_override_with(endpoint)
|
55
|
+
def initialize(endpoint:, inst_id: ENV["BLUE_API_INSTALLATION"],
|
56
|
+
api_id: ENV["BLUE_API_ID"], api_password: ENV["BLUE_API_PASSWORD"],
|
57
|
+
**options)
|
64
58
|
|
65
|
-
@
|
66
|
-
@
|
67
|
-
@
|
68
|
-
|
69
|
-
|
70
|
-
@options = options
|
59
|
+
@endpoint = get_endpoint_or_override_with(endpoint)
|
60
|
+
@inst_id = inst_id or fail ArgumentError, "missing inst_id"
|
61
|
+
@api_id = api_id or fail ArgumentError, "missing api_id"
|
62
|
+
@api_password =
|
63
|
+
api_password or fail ArgumentError, "missing api_password"
|
71
64
|
|
72
65
|
self.defaults = options.delete(:defaults)
|
73
|
-
|
66
|
+
@options = options.merge url: @endpoint
|
74
67
|
@client = build_client
|
75
68
|
end
|
76
69
|
|
@@ -79,14 +72,14 @@ module PayPoint
|
|
79
72
|
attr_reader :inst_id, :options
|
80
73
|
|
81
74
|
def get_endpoint_or_override_with(endpoint)
|
82
|
-
self.class.const_get(
|
75
|
+
self.class.const_get("ENDPOINTS").fetch(endpoint, endpoint.to_s)
|
83
76
|
end
|
84
77
|
|
85
78
|
def client_options
|
86
79
|
options.select { |k, _| Faraday::ConnectionOptions.members.include?(k) }
|
87
80
|
end
|
88
81
|
|
89
|
-
def build_client
|
82
|
+
def build_client # rubocop:disable AbcSize, MethodLength
|
90
83
|
Faraday.new(client_options) do |f|
|
91
84
|
unless options[:raw]
|
92
85
|
# This extracts the body and discards all other data from the
|
@@ -101,15 +94,17 @@ module PayPoint
|
|
101
94
|
f.use PayPoint::Blue::HashKeyConverter
|
102
95
|
end
|
103
96
|
f.response :json, content_type: /\bjson$/
|
104
|
-
|
97
|
+
if options[:logger] || options[:log]
|
98
|
+
f.response :logger, options[:logger]
|
99
|
+
end
|
105
100
|
|
106
101
|
# This sends all API traffic through Runscope, including
|
107
102
|
# notifications. It needs to be inserted here before the JSON
|
108
103
|
# request middleware so that it is able to transform
|
109
104
|
# notification URLs too.
|
110
105
|
if options[:runscope]
|
111
|
-
|
112
|
-
|
106
|
+
path_re = /\A(callbacks|session)\.\w+(Callback|Notification)\.url\Z/
|
107
|
+
f.use FaradayRunscope, options[:runscope], transform_paths: path_re
|
113
108
|
end
|
114
109
|
|
115
110
|
f.request :basic_auth, @api_id, @api_password
|
@@ -1,18 +1,14 @@
|
|
1
1
|
module PayPoint
|
2
2
|
module Blue
|
3
|
-
|
4
3
|
# Faraday middleware which extracts the body from the response
|
5
4
|
# object and returns with just that discarding all other meta
|
6
5
|
# information.
|
7
6
|
class BodyExtractor < Faraday::Middleware
|
8
|
-
|
9
7
|
# Extract and return just the body discarding everything else
|
10
8
|
def call(env)
|
11
9
|
response = @app.call(env)
|
12
10
|
response.env[:body]
|
13
11
|
end
|
14
|
-
|
15
12
|
end
|
16
|
-
|
17
13
|
end
|
18
14
|
end
|
data/lib/paypoint/blue/error.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module PayPoint
|
2
2
|
module Blue
|
3
|
-
|
4
3
|
# Abstract error base class
|
5
4
|
# @abstract
|
6
5
|
class Error < StandardError
|
7
|
-
|
8
6
|
# the response that caused the error
|
9
7
|
attr_reader :response
|
10
8
|
|
@@ -53,8 +51,6 @@ module PayPoint
|
|
53
51
|
|
54
52
|
# Specific error class for errors with an +'U'+ outcome code
|
55
53
|
class Suspended < Error; end
|
56
|
-
|
57
54
|
end
|
58
|
-
|
59
55
|
end
|
60
56
|
end
|
@@ -1,5 +1,6 @@
|
|
1
|
+
# Faraday middleware for transforming API endpoint urls and certain urls in JSON
|
2
|
+
# payloads to be proxied by Runscope for tracking and debugging purposes.
|
1
3
|
class FaradayRunscope < Faraday::Middleware
|
2
|
-
|
3
4
|
CUSTOM_PORT = "Runscope-Request-Port".freeze
|
4
5
|
|
5
6
|
def initialize(app, bucket, transform_paths: false)
|
@@ -9,10 +10,7 @@ class FaradayRunscope < Faraday::Middleware
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def call(env)
|
12
|
-
|
13
|
-
env.request_headers[CUSTOM_PORT] = env.url.port.to_s
|
14
|
-
env.url.port = env.url.default_port
|
15
|
-
end
|
13
|
+
handle_custom_port(env)
|
16
14
|
|
17
15
|
transform_url env.url
|
18
16
|
|
@@ -27,6 +25,12 @@ class FaradayRunscope < Faraday::Middleware
|
|
27
25
|
|
28
26
|
attr_accessor :bucket, :transform_paths
|
29
27
|
|
28
|
+
def handle_custom_port(env)
|
29
|
+
return if env.url.port == env.url.default_port
|
30
|
+
env.request_headers[CUSTOM_PORT] = env.url.port.to_s
|
31
|
+
env.url.port = env.url.default_port
|
32
|
+
end
|
33
|
+
|
30
34
|
def transform_url(url)
|
31
35
|
if url.respond_to?(:host=)
|
32
36
|
url.host = runscope_host(url.host)
|
@@ -39,10 +43,10 @@ class FaradayRunscope < Faraday::Middleware
|
|
39
43
|
end
|
40
44
|
|
41
45
|
def runscope_host(host)
|
42
|
-
"#{host.gsub(
|
46
|
+
"#{host.gsub("-", "--").tr(".", "-")}-#{bucket}.runscope.net"
|
43
47
|
end
|
44
48
|
|
45
|
-
def transform_paths!(enum, path=nil)
|
49
|
+
def transform_paths!(enum, path = nil)
|
46
50
|
each_pair(enum) do |key, value|
|
47
51
|
key_path = path ? "#{path}.#{key}" : key.to_s
|
48
52
|
if value.respond_to?(:each_with_index)
|
@@ -66,9 +70,8 @@ class FaradayRunscope < Faraday::Middleware
|
|
66
70
|
end
|
67
71
|
|
68
72
|
def transform_path?(path)
|
69
|
-
transform_paths.any? do |
|
70
|
-
|
73
|
+
transform_paths.any? do |path_pattern|
|
74
|
+
path_pattern.is_a?(Regexp) ? path =~ path_pattern : path == path_pattern
|
71
75
|
end
|
72
76
|
end
|
73
|
-
|
74
77
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module PayPoint
|
2
2
|
module Blue
|
3
|
-
|
4
3
|
# Faraday middleware for converting hash keys in the request payload
|
5
4
|
# from snake_case to camelCase and the other way around in the
|
6
5
|
# response.
|
7
6
|
class HashKeyConverter < Faraday::Middleware
|
8
|
-
|
9
7
|
# Convert hash keys to camelCase in the request and to snake_case
|
10
8
|
# in the response
|
11
9
|
def call(env)
|
@@ -15,7 +13,8 @@ module PayPoint
|
|
15
13
|
|
16
14
|
@app.call(env).on_complete do |response_env|
|
17
15
|
if response_env.body.is_a?(Enumerable)
|
18
|
-
response_env.body =
|
16
|
+
response_env.body =
|
17
|
+
Utils.snakecase_and_symbolize_keys(response_env.body)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
data/lib/paypoint/blue/hosted.rb
CHANGED
@@ -4,26 +4,26 @@ require "paypoint/blue/base"
|
|
4
4
|
|
5
5
|
# Client class for the Hosted product.
|
6
6
|
class PayPoint::Blue::Hosted < PayPoint::Blue::Base
|
7
|
-
|
8
7
|
ENDPOINTS = {
|
9
8
|
test: "https://hosted.mite.paypoint.net/hosted/rest",
|
10
|
-
live: "https://hosted.paypoint.net/hosted/rest"
|
9
|
+
live: "https://hosted.paypoint.net/hosted/rest",
|
11
10
|
}.freeze
|
12
11
|
|
13
|
-
shortcut :merchant_ref,
|
14
|
-
shortcut :amount,
|
15
|
-
shortcut :currency,
|
16
|
-
shortcut :commerce_type,
|
17
|
-
shortcut :description,
|
18
|
-
shortcut :customer_ref,
|
19
|
-
shortcut :customer_name,
|
20
|
-
shortcut :return_url,
|
21
|
-
shortcut :
|
22
|
-
shortcut :
|
12
|
+
shortcut :merchant_ref, "transaction.merchant_reference"
|
13
|
+
shortcut :amount, "transaction.money.amount.fixed"
|
14
|
+
shortcut :currency, "transaction.money.currency"
|
15
|
+
shortcut :commerce_type, "transaction.commerce_type"
|
16
|
+
shortcut :description, "transaction.description"
|
17
|
+
shortcut :customer_ref, "customer.identity.merchant_customer_id"
|
18
|
+
shortcut :customer_name, "customer.details.name"
|
19
|
+
shortcut :return_url, "session.return_url.url"
|
20
|
+
shortcut :cancel_url, "session.cancel_url.url"
|
21
|
+
shortcut :restore_url, "session.restore_url.url"
|
22
|
+
shortcut :skin, "session.skin"
|
23
23
|
|
24
|
-
shortcut :pre_auth_callback,
|
25
|
-
shortcut :post_auth_callback,
|
26
|
-
shortcut :transaction_notification,
|
24
|
+
shortcut :pre_auth_callback, "session.pre_auth_callback.url"
|
25
|
+
shortcut :post_auth_callback, "session.post_auth_callback.url"
|
26
|
+
shortcut :transaction_notification, "session.transaction_notification.url"
|
27
27
|
|
28
28
|
extend Forwardable
|
29
29
|
|
@@ -58,19 +58,18 @@ class PayPoint::Blue::Hosted < PayPoint::Blue::Base
|
|
58
58
|
# @api_url https://developer.paypoint.com/payments/docs/#payments/make_a_payment
|
59
59
|
#
|
60
60
|
# @applies_defaults
|
61
|
-
# +:currency+, +:commerce_type+, +:return_url+, +:
|
62
|
-
# +:pre_auth_callback+, +:post_auth_callback+,
|
61
|
+
# +:currency+, +:commerce_type+, +:return_url+, +:cancel_url+,
|
62
|
+
# +:restore_url+, +:skin+, +:pre_auth_callback+, +:post_auth_callback+,
|
63
|
+
# +:transaction_notification+
|
63
64
|
#
|
64
65
|
# @param [Hash] payload the payload is made up of the keyword
|
65
66
|
# arguments passed to the method
|
66
67
|
#
|
67
68
|
# @return the API response
|
68
69
|
def make_payment(**payload)
|
69
|
-
payload = build_payload
|
70
|
-
|
71
|
-
|
72
|
-
pre_auth_callback post_auth_callback transaction_notification
|
73
|
-
]
|
70
|
+
payload = build_payload payload, defaults: %i(
|
71
|
+
currency commerce_type return_url cancel_url restore_url skin
|
72
|
+
pre_auth_callback post_auth_callback transaction_notification
|
74
73
|
)
|
75
74
|
client.post "sessions/#{inst_id}/payments", build_payload(payload)
|
76
75
|
end
|
@@ -97,21 +96,19 @@ class PayPoint::Blue::Hosted < PayPoint::Blue::Base
|
|
97
96
|
# @api_url https://developer.paypoint.com/payments/docs/#payments/submit_a_payout
|
98
97
|
#
|
99
98
|
# @applies_defaults
|
100
|
-
# +:currency+, +:commerce_type+, +:return_url+, +:
|
101
|
-
# +:pre_auth_callback+, +:post_auth_callback+,
|
99
|
+
# +:currency+, +:commerce_type+, +:return_url+, +:cancel_url+,
|
100
|
+
# +:restore_url+, +:skin+, +:pre_auth_callback+, +:post_auth_callback+,
|
101
|
+
# +:transaction_notification+
|
102
102
|
#
|
103
103
|
# @param [Hash] payload the payload is made up of the keyword
|
104
104
|
# arguments passed to the method
|
105
105
|
#
|
106
106
|
# @return the API response
|
107
107
|
def submit_payout(**payload)
|
108
|
-
payload = build_payload
|
109
|
-
|
110
|
-
|
111
|
-
pre_auth_callback post_auth_callback transaction_notification
|
112
|
-
]
|
108
|
+
payload = build_payload payload, defaults: %i(
|
109
|
+
currency commerce_type return_url cancel_url restore_url skin
|
110
|
+
pre_auth_callback post_auth_callback transaction_notification
|
113
111
|
)
|
114
112
|
client.post "sessions/#{inst_id}/payouts", build_payload(payload)
|
115
113
|
end
|
116
|
-
|
117
114
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
module PayPoint
|
2
2
|
module Blue
|
3
|
-
|
4
3
|
# Provides helper methods for payload construction used throughout
|
5
4
|
# the API. It allows definition of payload shortcuts and default
|
6
5
|
# values.
|
7
6
|
module PayloadBuilder
|
8
|
-
|
9
7
|
def self.included(base)
|
10
8
|
base.extend ClassMethods
|
11
9
|
end
|
12
10
|
|
11
|
+
# Class level methods for PayloadBuilder.
|
13
12
|
module ClassMethods
|
14
13
|
def shortcuts
|
15
14
|
@shortcuts ||= {}
|
@@ -23,10 +22,12 @@ module PayPoint
|
|
23
22
|
# to commonly used paths.
|
24
23
|
#
|
25
24
|
# @example Define and use a shortcut
|
26
|
-
# PayPoint::Blue::Hosted
|
27
|
-
#
|
25
|
+
# class PayPoint::Blue::Hosted
|
26
|
+
# shortcut :amount, "transaction.money.amount.fixed"
|
27
|
+
# end
|
28
|
+
# blue.make_payment(amount: "3.49", ...)
|
28
29
|
# # this will be turned into
|
29
|
-
# # { transaction: { money: { amount: { fixed:
|
30
|
+
# # { transaction: { money: { amount: { fixed: "3.49" } } } }
|
30
31
|
#
|
31
32
|
# @param [Symbol] key the shortcut key
|
32
33
|
# @param [String] path a path into the payload with segments
|
@@ -55,20 +56,7 @@ module PayPoint
|
|
55
56
|
# that should be applied to this payload
|
56
57
|
def build_payload(payload, defaults: [])
|
57
58
|
apply_defaults(payload, defaults)
|
58
|
-
payload
|
59
|
-
if path = self.class.shortcut(key)
|
60
|
-
value = payload.delete(key)
|
61
|
-
segments = path.split('.').map(&:to_sym)
|
62
|
-
leaf = segments.pop
|
63
|
-
leaf_parent = segments.reduce(payload) {|h,k| h[k] ||= {}}
|
64
|
-
leaf_parent[leaf] ||= value
|
65
|
-
|
66
|
-
if key =~ /_(?:callback|notification)\Z/
|
67
|
-
leaf_parent[:format] ||= "REST_JSON"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
payload
|
59
|
+
expand_shortcuts(payload)
|
72
60
|
end
|
73
61
|
|
74
62
|
private
|
@@ -77,14 +65,33 @@ module PayPoint
|
|
77
65
|
return unless defaults
|
78
66
|
|
79
67
|
defaults.each do |key, value|
|
80
|
-
if applicable_defaults.include?(key) && !payload.
|
68
|
+
if applicable_defaults.include?(key) && !payload.key?(key)
|
81
69
|
payload[key] = interpolate_values(value, payload)
|
82
70
|
end
|
83
71
|
end
|
84
72
|
end
|
85
73
|
|
86
74
|
def interpolate_values(value, payload)
|
87
|
-
value.gsub(/%(\w+)%/) {|m| payload[
|
75
|
+
value.gsub(/%(\w+)%/) { |m| payload[Regexp.last_match(1).to_sym] || m }
|
76
|
+
end
|
77
|
+
|
78
|
+
def expand_shortcuts(payload)
|
79
|
+
payload.keys.each do |key|
|
80
|
+
next unless (path = self.class.shortcut(key))
|
81
|
+
expand_shortcut(payload, key, path)
|
82
|
+
end
|
83
|
+
payload
|
84
|
+
end
|
85
|
+
|
86
|
+
def expand_shortcut(payload, key, path)
|
87
|
+
value = payload.delete(key)
|
88
|
+
segments = path.split(".").map(&:to_sym)
|
89
|
+
leaf = segments.pop
|
90
|
+
leaf_parent = segments.reduce(payload) { |a, e| a[e] ||= {} }
|
91
|
+
leaf_parent[leaf] ||= value
|
92
|
+
|
93
|
+
callback_re = /_(?:callback|notification)\Z/
|
94
|
+
leaf_parent[:format] ||= "REST_JSON" if key =~ callback_re
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
@@ -2,10 +2,8 @@ require "paypoint/blue/error"
|
|
2
2
|
|
3
3
|
module PayPoint
|
4
4
|
module Blue
|
5
|
-
|
6
5
|
# Faraday response middleware for handling various error scenarios
|
7
6
|
class RaiseErrors < Faraday::Response::Middleware
|
8
|
-
|
9
7
|
# Raise an error if the response outcome signifies a failure or
|
10
8
|
# the HTTP status code is 400 or greater.
|
11
9
|
#
|
@@ -18,20 +16,12 @@ module PayPoint
|
|
18
16
|
def on_complete(env)
|
19
17
|
outcome = fetch_outcome(env)
|
20
18
|
if outcome
|
21
|
-
|
22
|
-
|
23
|
-
when /^V/ then raise Error::Validation, response_values(env)
|
24
|
-
when /^A/ then raise Error::Auth, response_values(env)
|
25
|
-
when /^C/ then raise Error::Cancelled, response_values(env)
|
26
|
-
when /^X/ then raise Error::External, response_values(env)
|
27
|
-
when /^U/ then raise Error::Suspended, response_values(env)
|
28
|
-
else
|
29
|
-
raise Error::Client, response_values(env)
|
30
|
-
end
|
19
|
+
return if outcome[:reason_code] =~ /^S/
|
20
|
+
fail error_from_outcome(outcome[:reason_code], response_values(env))
|
31
21
|
elsif not_found?(env)
|
32
|
-
|
22
|
+
fail Error::NotFound, response_values(env)
|
33
23
|
elsif client_error?(env)
|
34
|
-
|
24
|
+
fail Error::Client, response_values(env)
|
35
25
|
end
|
36
26
|
end
|
37
27
|
|
@@ -49,11 +39,23 @@ module PayPoint
|
|
49
39
|
env.body.is_a?(Hash) && env.body[:outcome]
|
50
40
|
end
|
51
41
|
|
42
|
+
def error_from_outcome(code, response_values)
|
43
|
+
case code
|
44
|
+
when /^V/ then Error::Validation.new(response_values)
|
45
|
+
when /^A/ then Error::Auth.new(response_values)
|
46
|
+
when /^C/ then Error::Cancelled.new(response_values)
|
47
|
+
when /^X/ then Error::External.new(response_values)
|
48
|
+
when /^U/ then Error::Suspended.new(response_values)
|
49
|
+
else
|
50
|
+
Error::Client.new(response_values)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
52
54
|
def response_values(env)
|
53
55
|
{
|
54
56
|
status: env.status,
|
55
57
|
headers: env.response_headers,
|
56
|
-
body: env.body
|
58
|
+
body: env.body,
|
57
59
|
}
|
58
60
|
end
|
59
61
|
end
|
data/lib/paypoint/blue/utils.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
module PayPoint
|
2
2
|
module Blue
|
3
|
+
# Miscellaneous helper methods used in multiple places.
|
3
4
|
module Utils
|
4
|
-
|
5
|
-
extend self
|
5
|
+
module_function
|
6
6
|
|
7
7
|
def snakecase_and_symbolize_keys(hash)
|
8
8
|
case hash
|
9
9
|
when Hash
|
10
|
-
hash.each_with_object({}) do |(key, value), snakified|
|
10
|
+
hash.each_with_object({},) do |(key, value), snakified|
|
11
11
|
snakified[snakecase(key)] = snakecase_and_symbolize_keys(value)
|
12
12
|
end
|
13
13
|
when Enumerable
|
14
|
-
hash.map {|v| snakecase_and_symbolize_keys(v)}
|
14
|
+
hash.map { |v| snakecase_and_symbolize_keys(v) }
|
15
15
|
else
|
16
16
|
hash
|
17
17
|
end
|
@@ -20,11 +20,11 @@ module PayPoint
|
|
20
20
|
def camelcase_and_symbolize_keys(hash)
|
21
21
|
case hash
|
22
22
|
when Hash
|
23
|
-
hash.each_with_object({}) do |(key, value), camelized|
|
23
|
+
hash.each_with_object({},) do |(key, value), camelized|
|
24
24
|
camelized[camelcase(key)] = camelcase_and_symbolize_keys(value)
|
25
25
|
end
|
26
26
|
when Enumerable
|
27
|
-
hash.map {|v| camelcase_and_symbolize_keys(v)}
|
27
|
+
hash.map { |v| camelcase_and_symbolize_keys(v) }
|
28
28
|
else
|
29
29
|
hash
|
30
30
|
end
|
@@ -42,10 +42,9 @@ module PayPoint
|
|
42
42
|
|
43
43
|
def camelcase(original)
|
44
44
|
string = original.is_a?(Symbol) ? original.to_s : original.dup
|
45
|
-
string.gsub!(/_([a-z\d]*)/) {
|
45
|
+
string.gsub!(/_([a-z\d]*)/) { Regexp.last_match(1).capitalize }
|
46
46
|
string.to_sym
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
data/lib/paypoint/blue.rb
CHANGED
@@ -4,8 +4,8 @@ require "paypoint/blue/hosted"
|
|
4
4
|
require "paypoint/blue/utils"
|
5
5
|
|
6
6
|
module PayPoint
|
7
|
+
# Top level module with helper methods.
|
7
8
|
module Blue
|
8
|
-
|
9
9
|
# Creates a client for the PayPoint Blue API product
|
10
10
|
#
|
11
11
|
# @see PayPoint::Blue::Base#initialize
|
@@ -27,12 +27,11 @@ module PayPoint
|
|
27
27
|
def self.parse_payload(json)
|
28
28
|
payload = json.respond_to?(:read) ? json.read : json.to_s
|
29
29
|
if payload.encoding == Encoding::ASCII_8BIT
|
30
|
-
payload.force_encoding
|
30
|
+
payload.force_encoding "iso-8859-1"
|
31
31
|
end
|
32
32
|
payload = JSON.parse(payload)
|
33
33
|
payload = Utils.snakecase_and_symbolize_keys(payload)
|
34
34
|
Hashie::Mash.new(payload)
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
38
37
|
end
|
data/support/yard_ext.rb
CHANGED
@@ -3,7 +3,7 @@ class ShortcutHandler < YARD::Handlers::Ruby::Base
|
|
3
3
|
namespace_only
|
4
4
|
|
5
5
|
def process
|
6
|
-
unless namespace.docstring.index(
|
6
|
+
unless namespace.docstring.index("== Payload Shortcuts")
|
7
7
|
namespace.docstring += "\n\n== Payload Shortcuts\n"
|
8
8
|
end
|
9
9
|
shortcut = statement.parameters.first.jump(:ident).source
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paypoint-blue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Laszlo Bacsi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -158,6 +158,8 @@ extensions: []
|
|
158
158
|
extra_rdoc_files: []
|
159
159
|
files:
|
160
160
|
- ".gitignore"
|
161
|
+
- ".overcommit.yml"
|
162
|
+
- ".rubocop.yml"
|
161
163
|
- ".travis.yml"
|
162
164
|
- ".yardopts"
|
163
165
|
- Gemfile
|