yp-ruby 0.1.3 → 0.1.4a
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +81 -2
- data/data/gateway_responses.yml +69 -0
- data/lib/base.rb +18 -47
- data/lib/response.rb +36 -0
- data/lib/response/error.rb +16 -0
- data/lib/response/error_logger.rb +53 -0
- data/lib/response/gateway_error.rb +68 -0
- data/lib/response/parser.rb +27 -0
- data/lib/response/validator.rb +21 -0
- data/lib/response/validator/acquirer.rb +27 -0
- data/lib/response/validator/gateway.rb +41 -0
- data/lib/response/validator/signing_key.rb +38 -0
- data/lib/signing_hash_creator.rb +32 -0
- data/lib/transaction_logger.rb +15 -3
- data/lib/version.rb +1 -1
- metadata +15 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f28691645bfdb90373e2524028d93a1e711bb46
|
4
|
+
data.tar.gz: cd6b81278539fbea582bf11dca079e7131f45357
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f933e44afc37aa9a3a244e89c78f6a7ef4f75e6ca20cb8e95dbf57df2557b6fa73afe5ea6b37aa5d0cfefd84ab625bdec24f105c09d16e8e7d712873d766a97
|
7
|
+
data.tar.gz: 299c5520a8dd0234828004f7e5d16e1b4ad404f977deddf700010606b02fb4423e475c933c201964e9c9d36852bfe57b631e433565032dc27a80a4250468f4da
|
data/README.md
CHANGED
@@ -20,7 +20,86 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
Different classes are available for the Gateway actions:
|
24
|
+
|
25
|
+
- Yp::Sale
|
26
|
+
- Yp::Preauth
|
27
|
+
- Yp::Verify
|
28
|
+
|
29
|
+
If you need support for more actions, please [open an issue](https://github.com/andytango/yp-ruby/issues)!
|
30
|
+
|
31
|
+
### Authentication and params
|
32
|
+
|
33
|
+
You will need to pass in the correct parameters according to the Yorkshire Payments integration guide:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
|
37
|
+
signature_key = 'Engine0Milk12Next'
|
38
|
+
|
39
|
+
params = {
|
40
|
+
merchantID: '101381',
|
41
|
+
countryCode: 826,
|
42
|
+
currencyCode: 826,
|
43
|
+
cardNumber: '4012001037141112',
|
44
|
+
cardExpiryMonth: 12,
|
45
|
+
cardExpiryYear: 15,
|
46
|
+
cardCVV: '083',
|
47
|
+
customerName: 'Yorkshire Payments',
|
48
|
+
customerEmail: 'support@yorkshirepayments.com',
|
49
|
+
customerAddress: '16 Test Street',
|
50
|
+
customerPostCode: 'TE15 5ST',
|
51
|
+
orderRef: 'Test purchase'
|
52
|
+
}
|
53
|
+
|
54
|
+
transaction = Yp::Sale.new(signature, params)
|
55
|
+
|
56
|
+
```
|
57
|
+
|
58
|
+
The library will *not* validate your parameters before sending. This feature is coming soon.
|
59
|
+
|
60
|
+
You pass in a callback method as a block, or access the response after the transaction is sent:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
|
64
|
+
transaction.send! do |response|
|
65
|
+
puts response.state # --> 'captured'
|
66
|
+
end
|
67
|
+
|
68
|
+
# OR:
|
69
|
+
|
70
|
+
response = transaction.send!
|
71
|
+
puts response.state # --> 'captured'
|
72
|
+
|
73
|
+
```
|
74
|
+
|
75
|
+
### Error Handling
|
76
|
+
|
77
|
+
The client will raise a number of different types of errors:
|
78
|
+
|
79
|
+
#### Validation Errors
|
80
|
+
|
81
|
+
These occur if we could not perform any validation. This means the response is
|
82
|
+
malformed and can arise if you did not correctly sign your request:
|
83
|
+
|
84
|
+
- Yp::Response::InvalidSignatureError (potentially malicious)
|
85
|
+
- Yp::Response::MissingSignatureError
|
86
|
+
- Yp::Response::MissingResponseCodeError
|
87
|
+
|
88
|
+
#### Gateway Errors
|
89
|
+
|
90
|
+
These occur if, during validation, we found a Gateway error code. These come in
|
91
|
+
three different flavours:
|
92
|
+
|
93
|
+
- Yp::Response::MissingFieldError: _a field was missing in your request_
|
94
|
+
- Yp::Response::InvalidFieldError: _a field value was invalid in your request_
|
95
|
+
- Yp::Response::GatewayError: _the error could not be classified. The gateway's
|
96
|
+
error message will be supplied_
|
97
|
+
|
98
|
+
#### Transaction Declined Error
|
99
|
+
|
100
|
+
This occurs if the transaction has entered the **Declined** state:
|
101
|
+
|
102
|
+
- Yp::Response::DeclinedError
|
24
103
|
|
25
104
|
## Development
|
26
105
|
|
@@ -30,7 +109,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
30
109
|
|
31
110
|
## Contributing
|
32
111
|
|
33
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
112
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/andytango/yp-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
34
113
|
|
35
114
|
|
36
115
|
## License
|
@@ -0,0 +1,69 @@
|
|
1
|
+
missing_field:
|
2
|
+
66048: 'request'
|
3
|
+
66049: 'merchantID'
|
4
|
+
66055: 'action'
|
5
|
+
66056: 'amount'
|
6
|
+
66057: 'currencyCode'
|
7
|
+
66058: 'cardNumber'
|
8
|
+
66059: 'cardExpiryMonth'
|
9
|
+
66060: 'cardExpiryYear'
|
10
|
+
66064: 'cardCVV'
|
11
|
+
66065: 'customerName'
|
12
|
+
66066: 'customerAddress'
|
13
|
+
66067: 'customerPostCode'
|
14
|
+
66068: 'customerEmail'
|
15
|
+
66070: 'countyCode'
|
16
|
+
66087: 'signature'
|
17
|
+
66092: 'threeDSPaRes'
|
18
|
+
66093: 'threeDSECI'
|
19
|
+
66094: 'threeDSCAVV'
|
20
|
+
66095: 'threeDSXID'
|
21
|
+
66096: 'threeDSEnrolled'
|
22
|
+
66097: 'threeDSAuthenticated'
|
23
|
+
66098: 'threeDSCheckPref'
|
24
|
+
66099: 'cv2CheckPref'
|
25
|
+
66100: 'addressCheckPref'
|
26
|
+
66101: 'postcodeCheckPref'
|
27
|
+
66102: 'captureDelay'
|
28
|
+
66103: 'orderDate'
|
29
|
+
66104: 'grossAmount'
|
30
|
+
66105: 'netAmount'
|
31
|
+
66016: 'taxRate'
|
32
|
+
66016: 'taxReason'
|
33
|
+
66160: 'cardExpiryDate'
|
34
|
+
66161: 'cardStartDate'
|
35
|
+
|
36
|
+
invalid_field:
|
37
|
+
66304: 'request'
|
38
|
+
66305: 'merchantID'
|
39
|
+
66311: 'action'
|
40
|
+
66312: 'amount'
|
41
|
+
66313: 'currencyCode'
|
42
|
+
66314: 'cardNumber'
|
43
|
+
66315: 'cardExpiryMonth'
|
44
|
+
66316: 'cardExpiryYear'
|
45
|
+
66317: 'cardCVV'
|
46
|
+
66332: 'customerName'
|
47
|
+
66322: 'customerAddress'
|
48
|
+
66323: 'customerPostCode'
|
49
|
+
66324: 'customerEmail'
|
50
|
+
66326: 'countyCode'
|
51
|
+
66343: 'signature'
|
52
|
+
66348: 'threeDSPaRes'
|
53
|
+
66349: 'threeDSECI'
|
54
|
+
66350: 'threeDSCAVV'
|
55
|
+
66351: 'threeDSXID'
|
56
|
+
66352: 'threeDSEnrolled'
|
57
|
+
66353: 'threeDSAuthenticated'
|
58
|
+
66354: 'threeDSCheckPref'
|
59
|
+
66355: 'cv2CheckPref'
|
60
|
+
66356: 'addressCheckPref'
|
61
|
+
66357: 'postcodeCheckPref'
|
62
|
+
66358: 'captureDelay'
|
63
|
+
66359: 'orderDate'
|
64
|
+
66360: 'grossAmount'
|
65
|
+
66361: 'netAmount'
|
66
|
+
66362: 'taxRate'
|
67
|
+
66363: 'taxReason'
|
68
|
+
66416: 'cardExpiryDate'
|
69
|
+
66417: 'cardStartDate'
|
data/lib/base.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'transaction_logger'
|
2
|
+
require 'signing_hash_creator'
|
3
|
+
require 'response'
|
2
4
|
|
3
5
|
module Yp
|
4
6
|
class Base
|
@@ -15,24 +17,13 @@ module Yp
|
|
15
17
|
@signature_key = signature_key
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
@params.clone.tap do |params|
|
20
|
-
params[:signature] = create_signing_hash
|
21
|
-
TransactionLogger.log_request(params)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def create_signing_hash
|
26
|
-
self.class.digest(self.class.serialize_params(@params) + @signature_key)
|
27
|
-
end
|
28
|
-
|
29
|
-
def send
|
20
|
+
def send!
|
30
21
|
if block_given?
|
31
22
|
RestClient.post(URL, body) do |response|
|
32
|
-
yield(
|
23
|
+
yield(parse_and_validate response)
|
33
24
|
end
|
34
25
|
else
|
35
|
-
|
26
|
+
parse_and_validate(RestClient.post(URL, body))
|
36
27
|
end
|
37
28
|
end
|
38
29
|
|
@@ -59,42 +50,22 @@ module Yp
|
|
59
50
|
{ type: TYPE[type] }
|
60
51
|
end
|
61
52
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
def serialize_params(params)
|
69
|
-
uri_string_from_hash(params)
|
70
|
-
end
|
71
|
-
|
72
|
-
def parse(response)
|
73
|
-
ruby_hash_from_response(CGI::parse(response)).tap do |parsed|
|
74
|
-
TransactionLogger.log_response(parsed)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
def uri_string_from_hash(hash)
|
81
|
-
hash.map { |key, value| uri_query_param(key, value) }.sort.join '&'
|
82
|
-
end
|
83
|
-
|
84
|
-
def uri_query_param(key, value)
|
85
|
-
encode_url_component(key) + '=' + encode_url_component(value)
|
86
|
-
end
|
87
|
-
|
88
|
-
def encode_url_component(key)
|
89
|
-
ERB::Util::url_encode(key).gsub(/%20/, '+')
|
53
|
+
def body
|
54
|
+
@params.clone.tap do |params|
|
55
|
+
params[:signature] = create_signing_hash
|
56
|
+
TransactionLogger.log_request(params)
|
90
57
|
end
|
58
|
+
end
|
91
59
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
end
|
60
|
+
def create_signing_hash
|
61
|
+
SigningHashCreator.new(@params, @signature_key).create
|
62
|
+
end
|
97
63
|
|
64
|
+
def parse_and_validate(response)
|
65
|
+
Response
|
66
|
+
.new(@signature_key, response, TransactionLogger)
|
67
|
+
.parse_and_validate
|
98
68
|
end
|
69
|
+
|
99
70
|
end
|
100
71
|
end
|
data/lib/response.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'response/parser'
|
2
|
+
require 'response/error'
|
3
|
+
require 'response/validator'
|
4
|
+
require 'response/error_logger'
|
5
|
+
|
6
|
+
module Yp
|
7
|
+
class Response
|
8
|
+
def initialize(signature, params, logger)
|
9
|
+
@signature = signature
|
10
|
+
@params = params
|
11
|
+
@logger = logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_and_validate
|
15
|
+
validate!
|
16
|
+
parsed
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def validate!
|
22
|
+
ErrorLogger.new(@logger).log do
|
23
|
+
Validator.new(parsed, @signature).validate!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def parsed
|
28
|
+
@parsed ||= parse_params
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_params
|
32
|
+
Parser.new(@params).parse.tap { |parsed| @logger.log_response(parsed) }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Yp
|
2
|
+
class Response
|
3
|
+
class ValidationError < StandardError
|
4
|
+
def initialize
|
5
|
+
super('Gateway response could not be validated.')
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class InvalidSignatureError < ValidationError; end
|
10
|
+
class MissingSignatureError < ValidationError; end
|
11
|
+
class MissingResponseCodeError < ValidationError; end
|
12
|
+
class MissingResponseMessageError < ValidationError; end
|
13
|
+
|
14
|
+
class DeclinedError < StandardError; end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Yp
|
2
|
+
class Response
|
3
|
+
class ErrorLogger
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :@logger, :fatal, :error
|
7
|
+
|
8
|
+
def initialize(logger)
|
9
|
+
@logger = logger
|
10
|
+
end
|
11
|
+
|
12
|
+
def log
|
13
|
+
begin
|
14
|
+
yield
|
15
|
+
rescue InvalidSignatureError => e
|
16
|
+
log_fatal 'An invalid signature was received', e
|
17
|
+
rescue MissingSignatureError => e
|
18
|
+
log_not_found 'Signature', e
|
19
|
+
rescue MissingResponseCodeError => e
|
20
|
+
log_not_found 'Response Code', e
|
21
|
+
rescue MissingResponseMessageError => e
|
22
|
+
log_not_found 'Response Message', e
|
23
|
+
rescue DeclinedError => e
|
24
|
+
log_error 'Transaction was declined by the acquirer', e
|
25
|
+
rescue MissingFieldError => e
|
26
|
+
log_error 'Gateway responded with missing field', e
|
27
|
+
rescue InvalidFieldError => e
|
28
|
+
log_error 'Gateway responded with invalid field', e
|
29
|
+
rescue GatewayError => e
|
30
|
+
log_error 'Gateway responded with error', e
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def log_not_found(thing, e)
|
37
|
+
log_fatal("#{thing} was not found in the response", e)
|
38
|
+
end
|
39
|
+
|
40
|
+
def log_fatal(str, e)
|
41
|
+
fatal(str)
|
42
|
+
raise e
|
43
|
+
end
|
44
|
+
|
45
|
+
def log_error(str, e)
|
46
|
+
error("#{str} (#{e})")
|
47
|
+
raise e
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Yp
|
4
|
+
class Response
|
5
|
+
class GatewayError < StandardError
|
6
|
+
|
7
|
+
def self.from_response_code(code, message)
|
8
|
+
Factory.new(code, message).error
|
9
|
+
end
|
10
|
+
|
11
|
+
class Factory
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def error_map
|
15
|
+
@error_map ||= load_error_map
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def load_error_map
|
21
|
+
YAML.load(File.read('data/gateway_responses.yml'))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(code, message)
|
26
|
+
@code = code
|
27
|
+
@message = message
|
28
|
+
end
|
29
|
+
|
30
|
+
def error
|
31
|
+
if is_missing_field?
|
32
|
+
MissingFieldError.new(missing_field)
|
33
|
+
elsif is_invalid_field?
|
34
|
+
InvalidFieldError.new(invalid_field)
|
35
|
+
else
|
36
|
+
GatewayError.new(@message)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def is_missing_field?
|
43
|
+
!missing_field.nil?
|
44
|
+
end
|
45
|
+
|
46
|
+
def missing_field
|
47
|
+
@missing_field ||= mapped_error(:missing_field)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_invalid_field?
|
51
|
+
!invalid_field.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def invalid_field
|
55
|
+
@invalid_field ||= mapped_error(:invalid_field)
|
56
|
+
end
|
57
|
+
|
58
|
+
def mapped_error(sym)
|
59
|
+
Factory.error_map[sym.to_s][@code.to_i]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class MissingFieldError < GatewayError; end
|
66
|
+
class InvalidFieldError < GatewayError; end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Yp
|
2
|
+
class Response
|
3
|
+
class Parser
|
4
|
+
|
5
|
+
def initialize(params)
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse
|
10
|
+
ruby_hash_from_response(parse_string)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def parse_string
|
16
|
+
CGI::parse(@params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def ruby_hash_from_response(hash)
|
20
|
+
hash.reduce({}) do |memo, (key, value)|
|
21
|
+
memo.merge({key.to_sym => value.first})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'validator/signing_key'
|
2
|
+
require_relative 'validator/gateway'
|
3
|
+
require_relative 'validator/acquirer'
|
4
|
+
|
5
|
+
module Yp
|
6
|
+
class Response
|
7
|
+
class Validator
|
8
|
+
def initialize(params, signature)
|
9
|
+
@params = params
|
10
|
+
@signature = signature
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate!
|
14
|
+
SigningKey.new(@params, @signature).validate!
|
15
|
+
Gateway.new(@params).validate!
|
16
|
+
Acquirer.new(@params).validate!
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Yp
|
2
|
+
class Response
|
3
|
+
class Validator
|
4
|
+
class Acquirer
|
5
|
+
|
6
|
+
def initialize(params)
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate!
|
11
|
+
!declined? || (raise DeclinedError)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def declined?
|
17
|
+
response_code == 4 || response_code == 5
|
18
|
+
end
|
19
|
+
|
20
|
+
def response_code
|
21
|
+
@response_code ||= @params[:responseCode].to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../gateway_error'
|
2
|
+
|
3
|
+
module Yp
|
4
|
+
class Response
|
5
|
+
class Validator
|
6
|
+
class Gateway
|
7
|
+
|
8
|
+
def initialize(params)
|
9
|
+
@params = params
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate!
|
13
|
+
is_valid_response_code? || (raise error_from_response)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def is_valid_response_code?
|
19
|
+
response_code.to_i <= 5
|
20
|
+
end
|
21
|
+
|
22
|
+
def error_from_response
|
23
|
+
GatewayError.from_response_code(response_code, response_message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def response_code
|
27
|
+
@response_code ||= find_response_code
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_response_code
|
31
|
+
@params[:responseCode] || (raise MissingResponseCodeError)
|
32
|
+
end
|
33
|
+
|
34
|
+
def response_message
|
35
|
+
@params[:responseMessage] || (raise MissingResponseMessageError)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'signing_hash_creator'
|
2
|
+
|
3
|
+
module Yp
|
4
|
+
class Response
|
5
|
+
class Validator
|
6
|
+
class SigningKey
|
7
|
+
|
8
|
+
def initialize(params, signature)
|
9
|
+
@params = params
|
10
|
+
@signature = signature
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate!
|
14
|
+
has_valid_signing_key? || (raise InvalidSignatureError)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def has_valid_signing_key?
|
20
|
+
their_signing_key == our_signing_key
|
21
|
+
end
|
22
|
+
|
23
|
+
def their_signing_key
|
24
|
+
@params[:signature] || (raise MissingSignatureError)
|
25
|
+
end
|
26
|
+
|
27
|
+
def our_signing_key
|
28
|
+
SigningHashCreator.new(signing_key_params, @signature).create
|
29
|
+
end
|
30
|
+
|
31
|
+
def signing_key_params
|
32
|
+
@params.reject { |k, _| k == :signature }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Yp
|
2
|
+
class SigningHashCreator
|
3
|
+
def initialize(params, signature_key)
|
4
|
+
@params = params
|
5
|
+
@signature_key = signature_key
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
self.class.digest(self.class.serialize_params(@params) + @signature_key)
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def digest(str_params)
|
15
|
+
Digest::SHA512.hexdigest str_params
|
16
|
+
end
|
17
|
+
|
18
|
+
def serialize_params(params)
|
19
|
+
params.map { |key, value| uri_query_param(key, value) }.sort.join('&')
|
20
|
+
end
|
21
|
+
|
22
|
+
def uri_query_param(key, value)
|
23
|
+
encode_url_component(key) + '=' + encode_url_component(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def encode_url_component(key)
|
27
|
+
ERB::Util::url_encode(key).gsub(/%20/, '+')
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/transaction_logger.rb
CHANGED
@@ -12,10 +12,22 @@ module Yp
|
|
12
12
|
info 'Response received', params
|
13
13
|
end
|
14
14
|
|
15
|
+
def info(str, params=nil)
|
16
|
+
Yp.logger.info(format(str, params))
|
17
|
+
end
|
18
|
+
|
19
|
+
def error(str)
|
20
|
+
Yp.logger.error(format_message(str))
|
21
|
+
end
|
22
|
+
|
23
|
+
def fatal(str)
|
24
|
+
Yp.logger.fatal(format_message(str))
|
25
|
+
end
|
26
|
+
|
15
27
|
private
|
16
28
|
|
17
|
-
def
|
18
|
-
|
29
|
+
def format(str, params)
|
30
|
+
"#{format_message(str)} #{format_params(params)}"
|
19
31
|
end
|
20
32
|
|
21
33
|
def format_message(str)
|
@@ -23,7 +35,7 @@ module Yp
|
|
23
35
|
end
|
24
36
|
|
25
37
|
def format_params(params)
|
26
|
-
" with params #{filter_card_params(params).to_s}"
|
38
|
+
" with params #{filter_card_params(params).to_s}" unless params.nil?
|
27
39
|
end
|
28
40
|
|
29
41
|
def filter_card_params(hash)
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yp-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4a
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Hall
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -133,12 +133,23 @@ files:
|
|
133
133
|
- Rakefile
|
134
134
|
- bin/console
|
135
135
|
- bin/setup
|
136
|
+
- data/gateway_responses.yml
|
136
137
|
- exe/yp-ruby
|
137
138
|
- lib/base.rb
|
138
139
|
- lib/factory.rb
|
139
140
|
- lib/nil_logger.rb
|
140
141
|
- lib/preauth.rb
|
142
|
+
- lib/response.rb
|
143
|
+
- lib/response/error.rb
|
144
|
+
- lib/response/error_logger.rb
|
145
|
+
- lib/response/gateway_error.rb
|
146
|
+
- lib/response/parser.rb
|
147
|
+
- lib/response/validator.rb
|
148
|
+
- lib/response/validator/acquirer.rb
|
149
|
+
- lib/response/validator/gateway.rb
|
150
|
+
- lib/response/validator/signing_key.rb
|
141
151
|
- lib/sale.rb
|
152
|
+
- lib/signing_hash_creator.rb
|
142
153
|
- lib/transaction_logger.rb
|
143
154
|
- lib/verify.rb
|
144
155
|
- lib/version.rb
|
@@ -160,9 +171,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
171
|
version: '0'
|
161
172
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
162
173
|
requirements:
|
163
|
-
- - "
|
174
|
+
- - ">"
|
164
175
|
- !ruby/object:Gem::Version
|
165
|
-
version:
|
176
|
+
version: 1.3.1
|
166
177
|
requirements: []
|
167
178
|
rubyforge_project:
|
168
179
|
rubygems_version: 2.5.2
|