17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/rubyqrpay/validator.rb', line 17
def self.validate_payload(opts)
schema = Dry::Validation.Schema do
configure do
def self.messages
super.merge(
en: { errors: { valid_currency: 'currency is not valid',
country_code?: 'country is not valid',
valid_language_reference: 'language_reference is not valid',
agregator_id_presence: 'agregator must be filled',
valid_merchant_account_32: 'field is too long',
valid_merchant_account_33: 'field is too long',
valid_additional_data: 'field is too long'} }
)
end
def country_code?(value)
ISO3166::Country.find_country_by_alpha2(value)
end
end
validate(valid_currency: :currency) do |currency|
Money::Currency.find_by_iso_numeric(currency)
end
rule(valid_country: [:country]) do |country|
country.filled?.then(country.country_code?)
end
rule(fixed_fee: [:convenience_indicator, :fixed_fee]) do |indicator, fixed|
indicator.eql?(2).then(fixed.filled?)
end
rule(percentage_fee: [:convenience_indicator, :percentage_fee]) do |indicator, percentage|
indicator.eql?(3).then(percentage.filled?)
end
rule(agregator_id_presence: [:agregator_id, :merchant_account_33]) do |agregator_id, merchant_account_33|
merchant_account_33.filled?.then(agregator_id.filled?)
end
optional(:agregator_id).maybe(:str?, format?: ANS_PATTERN)
required(:merchant_account_32).schema do
required(:service_code_erip).filled(:str?)
optional(:payer_unique_id).maybe(:str?)
optional(:payer_number).maybe(:str?)
optional(:amount_edit_possibility).maybe(:bool?)
end
optional(:merchant_account_33).schema do
required(:service_producer_code).filled(:str?)
optional(:service_code).maybe(:str?)
optional(:outlet).maybe(:str?)
optional(:order_code).maybe(:str?)
end
validate(valid_merchant_account_32: [:merchant_account_32]) do |merchant_account_32|
(0..99).include? merchant_account_32.to_h.values.join.size
end
validate(valid_merchant_account_33: [:merchant_account_33]) do |merchant_account_33|
(0..99).include? merchant_account_33.to_h.values.join.size
end
validate(valid_additional_data: [:additional_data]) do |additional_data|
(0..99).include? additional_data.to_h.values.join.size
end
required(:currency).filled(:int?)
optional(:convenience_indicator).maybe(:int?, gteq?: 1, lteq?: 3)
optional(:fixed_fee).maybe(:float?, gteq?: MIN_FIXED, lteq?: MAX_FIXED)
optional(:percentage_fee).maybe(:float?, gteq?: MIN_PERCENT, lteq?: MAX_PERCENT)
optional(:merchant_category_code).maybe(:int?, gteq?: MIN_MCC, lt?: MAX_MCC)
optional(:amount).maybe(:float?, gteq?: MIN_FIXED, lteq?: MAX_FIXED)
required(:country).filled(:str?)
required(:merchant_name).filled(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:merchant_city).maybe(:str?, max_size?: 15, format?: ANS_PATTERN)
optional(:postal_code).maybe(:str?, max_size?: 10, format?: ANS_PATTERN)
optional(:additional_data).schema do
optional(:bill_number).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:mobile_number).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:store_label).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:loyalty_number).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:reference_label).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:customer_label).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:terminal_label).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:purpose_of_transaction).maybe(:str?, max_size?: 25, format?: ANS_PATTERN)
optional(:consumer_data_request).maybe(format?: CONSUMER_DATA_REQUEST_PATTERN)
end
optional(:merchant_information_language).schema do
validate(valid_language_reference: :language_reference) do |language_reference|
Iso639[language_reference]
end
required(:language_reference).filled(:str?, max_size?: 2)
required(:name_alternate).filled(:str?, max_size?: 25)
optional(:city_alternate).maybe(:str?, max_size?: 15)
end
end
result = schema.call(opts)
if result.success?
opts
else
raise ArgumentError, result.errors.first.to_s
end
end
|