rubyqrpay 0.2.5 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 59502deb4d7f08b922a541ffa45dccdd7b88b14b
4
- data.tar.gz: 4c97542691d2b12acaa0b9a05c70d8ba1147ff15
2
+ SHA256:
3
+ metadata.gz: d3e431b3cb8540694aec95035725418b3627d3ace9f0b8edbd2372ca63ce10b2
4
+ data.tar.gz: 180f8e10cb3d6bb79b19afce69c91cc4b3831d049166caabdc93a2721c8de050
5
5
  SHA512:
6
- metadata.gz: 6d782c66cfc7e0f449750ca369bb1ed200451f654dfb9eaed005647eae7aecd9d6a6c1001d36a7179bec0395b0081c9bfac4b855eed03e2fc49da84e29af57f4
7
- data.tar.gz: e4107eff02ba2dae9c07bb9779294cb5f17cdd4c5bfcd3028c7b32ac3ea8af716a39064f5081ed09b692d58b73eb777450ae701787ea1cec4561ce7ae2296ef8
6
+ metadata.gz: f4656882f4c829fba413a39557ddbe456ca9cd6bd902584f543acdb8fbe53f6e87287566b05d1af2eb8fbfabaa5c9b8650c651d072a408e79bc0441c68b8609b
7
+ data.tar.gz: 841331771b9e2c2ba27ac82413d6831c49fa843f479bf7b71107d356f80abf60bd1b21cae02ca056e442d9ce7bd73a7da1e4e2c8a1f0b83d8b6231f8490701ef
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubyqrpay (0.2.5)
4
+ rubyqrpay (0.3.0)
5
5
  countries (~> 2.1)
6
6
  digest-crc (~> 0.4)
7
7
  dry-validation (~> 0.11)
@@ -95,4 +95,4 @@ DEPENDENCIES
95
95
  rubyqrpay!
96
96
 
97
97
  BUNDLED WITH
98
- 1.16.2
98
+ 1.17.3
data/lib/rubyqrpay.rb CHANGED
@@ -1 +1,2 @@
1
1
  require_relative 'rubyqrpay/generator'
2
+ require_relative 'rubyqrpay/parser'
@@ -1,61 +1,59 @@
1
1
  module Rubyqrpay
2
- class Generator
3
- ID_PAYLOAD_FORMAT = '00'
4
- ID_POI_METHOD = '01'
5
- ID_MERCHANT_INFORMATION_32 = '32'
6
- ID_MERCHANT_INFORMATION_33 = '33'
7
- ID_MERCHANT_CATEGORY_CODE = '52'
8
- ID_TRANSACTION_CURRENCY = '53'
9
- ID_TRANSACTION_AMOUNT = '54'
10
- ID_TIP_OF_CONVENIENCE_INDICATOR = '55'
11
- ID_VALUE_OF_CONVENIENCE_FEE_FIXED = '56'
12
- ID_VALUE_OF_CONVENIENCE_FEE_PERCENTAGE = '57'
13
- ID_COUNTRY = '58'
14
- ID_MERCHANT_NAME = '59'
15
- ID_MERCHANT_CITY = '60'
16
- ID_POSTAL_CODE = '61'
17
- ID_ADDITIONAL_DATA_FIELD = '62'
18
- ID_MERCHANT_INFORMATION_LANGUAGE = '64'
19
- ID_CRC = '63'
2
+ ID_PAYLOAD_FORMAT = '00'
3
+ ID_POI_METHOD = '01'
4
+ ID_MERCHANT_INFORMATION_32 = '32'
5
+ ID_MERCHANT_INFORMATION_33 = '33'
6
+ ID_MERCHANT_CATEGORY_CODE = '52'
7
+ ID_TRANSACTION_CURRENCY = '53'
8
+ ID_TRANSACTION_AMOUNT = '54'
9
+ ID_TIP_OF_CONVENIENCE_INDICATOR = '55'
10
+ ID_VALUE_OF_CONVENIENCE_FEE_FIXED = '56'
11
+ ID_VALUE_OF_CONVENIENCE_FEE_PERCENTAGE = '57'
12
+ ID_COUNTRY = '58'
13
+ ID_MERCHANT_NAME = '59'
14
+ ID_MERCHANT_CITY = '60'
15
+ ID_POSTAL_CODE = '61'
16
+ ID_ADDITIONAL_DATA_FIELD = '62'
17
+ ID_MERCHANT_INFORMATION_LANGUAGE = '64'
18
+ ID_CRC = '63'
20
19
 
21
- PAYLOAD_FORMAT_EMV_QRCPS_MERCHANT_PRESENTED_MODE = '01'
22
- POI_METHOD_STATIC = '11'
23
- POI_METHOD_DYNAMIC = '12'
24
- CONVENIENCE_INDICATOR_FIXED = '02'
25
- CONVENIENCE_INDICATOR_PERCENTAGE = '03'
26
- MERCHANT_INFORMATION_TEMPLATE_ID_GUID = '00'
27
- # ID_MERCHANT_INFORMATION_32
28
- ID_SERVICE_CODE_ERIP = '01'
29
- ID_PAYER_UNIQUE = '10'
30
- ID_PAYER_NUMBER = '11'
31
- ID_AMOUNT_EDIT_POSSIBILITY = '12'
32
- # ID_MERCHANT_INFORMATION_33
33
- ID_SERVICE_PRODUCER_CODE = '03'
34
- ID_SERVICE_CODE = '04'
35
- ID_OUTLET = '05'
36
- ID_ORDER_CODE = '06'
37
- # ID_ADDITIONAL_DATA_FIELD
38
- ID_BILL_NUMBER = '01'
39
- ID_MOBILE_NUMBER = '02'
40
- ID_STORE_LABEL = '03'
41
- ID_LOYALTY_NUMBER = '04'
42
- ID_REFERENCE_LABEL = '05'
43
- ID_CUSTOMER_LABEL = '06'
44
- ID_TERMINAL_LABEL = '07'
45
- ID_PURPOSE_OF_TRANSACTION = '08'
46
- ID_CONSUMER_DATA_REQUEST = '09'
47
- # ID_MERCHANT_INFORMATION_LANGUAGE
48
- ID_LANGUAGE_REFERENCE = '00'
49
- ID_MERCHANT_NAME_ALTERNATE = '01'
50
- ID_MERCHANT_CITY_ALTERNATE = '02'
20
+ PAYLOAD_FORMAT_EMV_QRCPS_MERCHANT_PRESENTED_MODE = '01'
21
+ POI_METHOD_STATIC = '11'
22
+ POI_METHOD_DYNAMIC = '12'
23
+ CONVENIENCE_INDICATOR_FIXED = '02'
24
+ CONVENIENCE_INDICATOR_PERCENTAGE = '03'
25
+ MERCHANT_INFORMATION_TEMPLATE_ID_GUID = '00'
26
+ # ID_MERCHANT_INFORMATION_32
27
+ ID_SERVICE_CODE_ERIP = '01'
28
+ ID_PAYER_UNIQUE = '10'
29
+ ID_PAYER_NUMBER = '11'
30
+ ID_AMOUNT_EDIT_POSSIBILITY = '12'
31
+ # ID_MERCHANT_INFORMATION_33
32
+ ID_SERVICE_PRODUCER_CODE = '03'
33
+ ID_SERVICE_CODE = '04'
34
+ ID_OUTLET = '05'
35
+ ID_ORDER_CODE = '06'
36
+ # ID_ADDITIONAL_DATA_FIELD
37
+ ID_BILL_NUMBER = '01'
38
+ ID_MOBILE_NUMBER = '02'
39
+ ID_STORE_LABEL = '03'
40
+ ID_LOYALTY_NUMBER = '04'
41
+ ID_REFERENCE_LABEL = '05'
42
+ ID_CUSTOMER_LABEL = '06'
43
+ ID_TERMINAL_LABEL = '07'
44
+ ID_PURPOSE_OF_TRANSACTION = '08'
45
+ ID_CONSUMER_DATA_REQUEST = '09'
46
+ # ID_MERCHANT_INFORMATION_LANGUAGE
47
+ ID_LANGUAGE_REFERENCE = '00'
48
+ ID_MERCHANT_NAME_ALTERNATE = '01'
49
+ ID_MERCHANT_CITY_ALTERNATE = '02'
51
50
 
52
- GUID_PROMPTPAY_32 = 'by.raschet'
53
- GUID_PROMPTPAY_33 = 'by.epos.'
54
- CRC_SYMBOL_SIZE = '04'
55
- AEP_DEFAULT = '11'
56
- AEP_FALSE = '12'
51
+ GUID_PROMPTPAY_32 = 'by.raschet'
52
+ GUID_PROMPTPAY_33 = 'by.epos.'
53
+ CRC_SYMBOL_SIZE = '04'
54
+ AEP_DEFAULT = '11'
55
+ AEP_FALSE = '12'
57
56
 
58
- K_SIZE_FUNC = 0.15
59
- B_SIZE_FUNC = 140
60
- end
57
+ K_SIZE_FUNC = 0.15
58
+ B_SIZE_FUNC = 140
61
59
  end
@@ -12,7 +12,7 @@ module Rubyqrpay
12
12
  opts = Rubyqrpay::Validator.validate_payload(opts)
13
13
  unless opts.nil?
14
14
  payload = generation(opts)
15
- percent_encode payload
15
+ # percent_encode payload # Temporary solution to fix invalid BNB URI decode
16
16
  end
17
17
  end
18
18
 
@@ -50,7 +50,7 @@ module Rubyqrpay
50
50
  ID_MERCHANT_CATEGORY_CODE => mcc_format(opts[:merchant_category_code]),
51
51
  ID_TRANSACTION_CURRENCY => opts[:currency],
52
52
  ID_TRANSACTION_AMOUNT => format_amount(opts[:amount]),
53
- ID_TIP_OF_CONVENIENCE_INDICATOR => opts[:convenience_indicator],
53
+ ID_TIP_OF_CONVENIENCE_INDICATOR => format_indicator(opts[:convenience_indicator]),
54
54
  ID_COUNTRY => opts[:country],
55
55
  ID_MERCHANT_NAME => opts[:merchant_name],
56
56
  ID_MERCHANT_CITY => opts[:merchant_city],
@@ -135,7 +135,7 @@ module Rubyqrpay
135
135
 
136
136
  def self.join_hash(hash)
137
137
  hash.map do |id, value|
138
- value = value.to_s
138
+ value = percent_encode(value.to_s).gsub(/\%.{2}/, '')
139
139
  unless value.empty?
140
140
  len = "00#{value.size}".slice(-2..-1)
141
141
  id + len + value
@@ -156,10 +156,14 @@ module Rubyqrpay
156
156
  end
157
157
 
158
158
  def self.crc(data)
159
- data += ID_CRC + CRC_SYMBOL_SIZE
160
- x = Digest::CRC16CCITT.new
161
- x.update(data)
162
- ID_CRC + CRC_SYMBOL_SIZE + x.hexdigest.upcase
159
+ # === old algorithm
160
+ # data += ID_CRC + CRC_SYMBOL_SIZE
161
+ # x = Digest::CRC16CCITT.new
162
+ # x.update(data)
163
+ # ID_CRC + CRC_SYMBOL_SIZE + x.hexdigest.upcase
164
+
165
+ # === updated algorithm
166
+ ID_CRC + CRC_SYMBOL_SIZE + Digest::SHA256.hexdigest(data).slice(-4..-1).upcase
163
167
  end
164
168
 
165
169
  def self.mcc_format(mcc)
@@ -0,0 +1,36 @@
1
+ module Rubyqrpay
2
+ class Parser
3
+ NESTED_DATA_IDS = [ID_MERCHANT_INFORMATION_32,
4
+ ID_MERCHANT_INFORMATION_33,
5
+ ID_ADDITIONAL_DATA_FIELD,
6
+ ID_MERCHANT_INFORMATION_LANGUAGE]
7
+
8
+ class << self
9
+ def parse_payload(payload)
10
+ parse_to_params(URI.unescape payload)
11
+ end
12
+
13
+ private
14
+
15
+ def parse_to_params(payload)
16
+ {}.tap do |params|
17
+ index = 0
18
+
19
+ until payload[index + 4].nil?
20
+ key = payload[index, 2]
21
+ size = payload[index + 2, 2].to_i
22
+ value = payload[index + 4, size]
23
+
24
+ params[key] = if NESTED_DATA_IDS.include? key
25
+ parse_to_params value
26
+ else
27
+ value
28
+ end
29
+
30
+ index += 4 + size
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -6,7 +6,7 @@ require 'iso639'
6
6
  module Rubyqrpay
7
7
  class Validator
8
8
  CONSUMER_DATA_REQUEST_PATTERN = /^(A?E?M|E?M?A|M?A?E|A?M?E|E?M?A|M?E?A)$/
9
- ANS_PATTERN = /[[:ascii:]]/
9
+ ANS_PATTERN = /^[[:ascii:]]*$/
10
10
  MIN_MCC = 0
11
11
  MAX_MCC = 10_000
12
12
  MIN_FIXED = 0.01
@@ -87,8 +87,8 @@ module Rubyqrpay
87
87
  optional(:percentage_fee).maybe(:float?, gteq?: MIN_PERCENT, lteq?: MAX_PERCENT)
88
88
  optional(:merchant_category_code).maybe(:int?, gteq?: MIN_MCC, lt?: MAX_MCC)
89
89
  optional(:amount).maybe(:float?, gteq?: MIN_FIXED, lteq?: MAX_FIXED)
90
- optional(:country).maybe(:str?)
91
- optional(:merchant_name).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
90
+ required(:country).filled(:str?)
91
+ required(:merchant_name).filled(:str?, max_size?: 25, format?: ANS_PATTERN)
92
92
  optional(:merchant_city).maybe(:str?, max_size?: 15, format?: ANS_PATTERN)
93
93
  optional(:postal_code).maybe(:str?, max_size?: 10, format?: ANS_PATTERN)
94
94
 
@@ -1,3 +1,4 @@
1
1
  module Rubyqrpay
2
- VERSION = "0.2.5"
2
+ VERSION = "0.4.1"
3
+ # compatible with ERIP API documentation from 20.05.2020
3
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyqrpay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Shpalov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-30 00:00:00.000000000 Z
11
+ date: 2021-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -157,6 +157,7 @@ files:
157
157
  - lib/rubyqrpay.rb
158
158
  - lib/rubyqrpay/constants.rb
159
159
  - lib/rubyqrpay/generator.rb
160
+ - lib/rubyqrpay/parser.rb
160
161
  - lib/rubyqrpay/validator.rb
161
162
  - lib/rubyqrpay/version.rb
162
163
  - rubyqrpay.gemspec
@@ -179,10 +180,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
180
  - !ruby/object:Gem::Version
180
181
  version: '0'
181
182
  requirements: []
182
- rubyforge_project:
183
- rubygems_version: 2.6.14
183
+ rubygems_version: 3.1.2
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: Ruby prompt pay QR-code generator
187
187
  test_files: []
188
- has_rdoc: