paypoint-blue 0.3.0 → 0.4.0
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.
- 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
|