bankscrap-santander 2.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fffe15fd930409314c9d094f0dd83cacc92421bc
4
+ data.tar.gz: 249762ea851947668ba414238bb02646ea48cbe7
5
+ SHA512:
6
+ metadata.gz: 3e9c840b2456a31487e60aead8ca849753e5c541286b3406a3b5923b235cca1f0f5bd8559a97a6d78f2d92b2237e3bdc4566271c31dec3227671e6598a3d7371
7
+ data.tar.gz: 81ad254b2c20f50aae6736753cd8534c23389b815ba59889b5f905e62df50601a3dc20bc1617a4444457537cb6ffa61d296f3b06aaf859b2082ad20f98bccf53
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bankscrap-santander.gemspec
4
+ gemspec
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # Bankscrap::Santander
2
+
3
+ [Bankscrap](https://github.com/bankscrap/bankscrap) adapter for Santander.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'bankscrap-santander'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install bankscrap-santander
20
+
21
+ ## Usage
22
+
23
+ ### From terminal
24
+ #### Bank account balance
25
+
26
+ $ bankscrap balance Santander --credentials=user:YOUR_USER password:YOUR_PASSWORD
27
+
28
+
29
+ #### Transactions
30
+
31
+ $ bankscrap transactions Santander --credentials=user:YOUR_USER password:YOUR_PASSWORD
32
+ $ bankscrap transactions Santander --credentials=user:YOUR_USER password:YOUR_PASSWORD --from dd-mm-yyyy --to dd-mm-yyyy
33
+
34
+ ---
35
+
36
+ For more details on usage instructions please read [Bankscrap readme](https://github.com/bankscrap/bankscrap/#usage).
37
+
38
+ ### From Ruby code
39
+
40
+ ```ruby
41
+ require 'bankscrap-santander'
42
+ santander = Bankscrap::Santander::Bank.new(YOUR_USER, YOUR_PASSWORD, extra_args: {arg: EXTRA_ARG_1})
43
+ ```
44
+
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it ( https://github.com/bankscrap/bankscrap-santander/fork )
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create a new Pull Request
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bankscrap/santander/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'bankscrap-santander'
8
+ spec.version = Bankscrap::Santander::VERSION
9
+ spec.authors = ['Your Name']
10
+ spec.email = ['your@email.com']
11
+ spec.summary = 'Santander adapter for Bankscrap'
12
+ spec.homepage = ''
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_runtime_dependency 'bankscrap'
21
+ spec.add_development_dependency 'bundler', '~> 1.7'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'byebug', '~> 8.0'
24
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'bankscrap/santander/bank'
2
+ require_relative 'bankscrap/santander/version'
@@ -0,0 +1,7 @@
1
+ module Bankscrap
2
+ module Santander
3
+ class Account < ::Bankscrap::Account
4
+ attr_accessor :contract_id
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,289 @@
1
+ require 'bankscrap'
2
+ require 'securerandom'
3
+ require 'open-uri'
4
+ require_relative 'account.rb'
5
+
6
+ module Bankscrap
7
+ module Santander
8
+ class Bank < ::Bankscrap::Bank
9
+
10
+ # Define the endpoints for the Bank API here
11
+ HOST = 'www.bsan.mobi'
12
+ BASE_ENDPOINT = 'https://www.bsan.mobi'
13
+ LOGIN_ENDPOINT = '/SANMOV_IPAD_NSeg_ENS/ws/SANMOVNS_Def_Listener'
14
+ PRODUCTS_ENDPOINT = '/SCH_BAMOBI_WS_ENS/ws/BAMOBI_WS_Def_Listener'
15
+ ACCOUNT_ENDPOINT = '/SCH_BAMOBI_WS_ENS/ws/BAMOBI_WS_Def_Listener'
16
+ USER_AGENT = 'ksoap2-android/2.6.0+'
17
+
18
+ def initialize(credentials = {})
19
+ @public_ip = public_ip
20
+
21
+ super do
22
+ default_headers
23
+ end
24
+ end
25
+
26
+ # Fetch all the accounts for the given user
27
+ #
28
+ # Should returns an array of Bankscrap::Account objects
29
+ def fetch_accounts
30
+ log 'fetch_accounts'
31
+
32
+ headers = { "SOAPAction" => "http://www.isban.es/webservices/BAMOBI/Posglobal/F_bamobi_posicionglobal_lip/internet/BAMOBIPGL/v1/obtenerPosGlobal_LIP" }
33
+
34
+ response = with_headers(headers) { post(BASE_ENDPOINT + PRODUCTS_ENDPOINT, fields: xml_products) }
35
+
36
+ document = parse_context(response)
37
+
38
+ document.xpath('//cuentas/cuenta').map { |data| build_account(data) }
39
+ end
40
+
41
+ # Fetch all the cards for the given user
42
+ #
43
+ # Should returns an array of Bankscrap::Card objects
44
+ def fetch_cards
45
+ log 'fetch_cards'
46
+
47
+ headers = { "SOAPAction" => "http://www.isban.es/webservices/BAMOBI/Posglobal/F_bamobi_posicionglobal_lip/internet/BAMOBIPGL/v1/obtenerPosGlobal_LIP" }
48
+
49
+ response = with_headers(headers) { post(BASE_ENDPOINT + PRODUCTS_ENDPOINT, fields: xml_products) }
50
+
51
+ document = parse_context(response)
52
+
53
+ document.xpath('//tarjetas/tarjeta').map { |data| build_card(data) }
54
+ end
55
+
56
+ # Fetch all the loan for the given user
57
+ #
58
+ # Should returns an array of Bankscrap::Loan objects
59
+ def fetch_loans
60
+ log 'fetch_loans'
61
+
62
+ headers = { "SOAPAction" => "http://www.isban.es/webservices/BAMOBI/Posglobal/F_bamobi_posicionglobal_lip/internet/BAMOBIPGL/v1/obtenerPosGlobal_LIP" }
63
+
64
+ response = with_headers(headers) { post(BASE_ENDPOINT + PRODUCTS_ENDPOINT, fields: xml_products) }
65
+
66
+ document = parse_context(response)
67
+
68
+ document.xpath('//prestamos/prestamo').map { |data| build_loan(data) }
69
+ end
70
+
71
+ # Fetch transactions for the given account.
72
+ #
73
+ # Account should be a Bankscrap::Account object
74
+ # Should returns an array of Bankscrap::Account objects
75
+ def fetch_transactions_for(account, start_date: Date.today - 1.month, end_date: Date.today)
76
+ headers = { "SOAPAction" => "http://www.isban.es/webservices/BAMOBI/Cuentas/F_bamobi_cuentas_lip/internet/BAMOBICTA/v1/listaMovCuentasFechas_LIP" }
77
+ transactions = []
78
+ end_page = false
79
+ repo = nil
80
+ importe_cta = nil
81
+
82
+ # Loop over pagination
83
+ until end_page
84
+ response = with_headers(headers) { post(BASE_ENDPOINT + ACCOUNT_ENDPOINT,
85
+ fields: xml_account(account, start_date, end_date, repo, importe_cta)) }
86
+ document = parse_context(response)
87
+
88
+ transactions += document.xpath('//listadoMovimientos/movimiento').map { |data| build_transaction(data, account) }
89
+
90
+ repo = document.at_xpath('//methodResult/repo')
91
+ importe_cta = document.at_xpath('//methodResult/importeCta')
92
+ end_page = !(value_at_xpath(document, '//methodResult/finLista') == 'N')
93
+ end
94
+
95
+ transactions
96
+ end
97
+
98
+ private
99
+
100
+ def default_headers
101
+ add_headers(
102
+ 'Content-Type' => 'text/xml; charset=utf-8',
103
+ 'User-Agent' => USER_AGENT,
104
+ 'Host' => HOST,
105
+ 'Connection' => 'Keep-Alive',
106
+ 'Accept-Encoding' => 'gzip'
107
+ )
108
+ end
109
+
110
+ def public_ip
111
+ log 'getting public ip'
112
+ ip = open("http://api.ipify.org").read
113
+ log "public ip: [#{ip}]"
114
+ ip
115
+ end
116
+
117
+ def format_user(user)
118
+ user.upcase
119
+ end
120
+
121
+ # First request to login
122
+ def login
123
+ log 'login'
124
+ headers = { "SOAPAction" => "http://www.isban.es/webservices/TECHNICAL_FACADES/Security/F_facseg_security/internet/loginServicesNSegSAN/v1/authenticateCredential" }
125
+ response = with_headers(headers) { post(BASE_ENDPOINT + LOGIN_ENDPOINT, fields: xml_login) }
126
+ parse_context(response)
127
+ end
128
+
129
+ # Build an Account object from API data
130
+ def build_account(data)
131
+ currency = value_at_xpath(data, 'impSaldoActual/DIVISA')
132
+ Account.new(
133
+ bank: self,
134
+ id: value_at_xpath(data, 'comunes/contratoID/NUMERO_DE_CONTRATO'),
135
+ name: value_at_xpath(data, 'comunes/descContrato'),
136
+ available_balance: money(value_at_xpath(data, 'importeDispAut/IMPORTE'), currency),
137
+ balance: money(value_at_xpath(data, 'impSaldoActual/IMPORTE'), currency),
138
+ iban: value_at_xpath(data, 'IBAN').tr(' ', ''),
139
+ description: value_at_xpath(data, 'comunes/alias') || value_at_xpath(data, 'comunes/descContrato'),
140
+ contract_id: data.at_xpath('contratoIDViejo').children.to_s
141
+ )
142
+ end
143
+
144
+ # Build an Card object from API data
145
+ def build_card(data)
146
+ currency = value_at_xpath(data, 'impSaldoDispuesto/DIVISA', 'EUR')
147
+ Card.new(
148
+ bank: self,
149
+ id: value_at_xpath(data, 'comunes/contratoID/NUMERO_DE_CONTRATO'),
150
+ name: value_at_xpath(data, 'comunes/descContrato'),
151
+ pan: value_at_xpath(data, 'pan'),
152
+ amount: money(value_at_xpath(data, 'impSaldoDispuesto/IMPORTE'), currency),
153
+ avaliable: money(value_at_xpath(data, 'impDisponible/IMPORTE'), currency),
154
+ description: value_at_xpath(data, 'comunes/alias') || value_at_xpath(data, 'comunes/descContrato'),
155
+ is_credit: data.at_xpath('descTipoTarjeta').children.to_s == "Crédito"
156
+ )
157
+ end
158
+
159
+ # Build an Loan object from API data
160
+ def build_loan(data)
161
+ currency = value_at_xpath(data, 'impSaldoDispuesto/DIVISA')
162
+ Loan.new(
163
+ bank: self,
164
+ id: value_at_xpath(data, 'comunes/contratoID/NUMERO_DE_CONTRATO'),
165
+ name: value_at_xpath(data, 'comunes/descContrato'),
166
+ amount: money(value_at_xpath(data, 'impSaldoDispuesto/IMPORTE'), currency),
167
+ description: value_at_xpath(data, 'comunes/alias') || value_at_xpath(data, 'comunes/descContrato'),
168
+ )
169
+ end
170
+
171
+ # Build a transaction object from API data
172
+ def build_transaction(data, account)
173
+ currency = value_at_xpath(data, 'importe/DIVISA')
174
+ balance = money(value_at_xpath(data, 'importeSaldo/IMPORTE'), value_at_xpath(data, 'importeSaldo/DIVISA'))
175
+ Transaction.new(
176
+ account: account,
177
+ id: value_at_xpath(data, 'numeroMovimiento'),
178
+ amount: money(value_at_xpath(data, 'importe/IMPORTE'), currency),
179
+ description: value_at_xpath(data, 'descripcion'),
180
+ effective_date: Date.strptime(value_at_xpath(data, 'fechaValor'), "%Y-%m-%d"),
181
+ # TODO Falta fecha operacion
182
+ balance: balance
183
+ )
184
+ end
185
+
186
+ def parse_context(xml)
187
+ document = Nokogiri::XML(xml)
188
+ @token_credential = value_at_xpath(document, '//tokenCredential', @token_credential)
189
+ @user_data = document.at_xpath('//methodResult/datosUsuario') || @user_data
190
+ document
191
+ end
192
+
193
+ def xml_security_header
194
+ <<-security
195
+ <v:Header>
196
+ <n0:Security v:actor="http://www.isban.es/soap/actor/wssecurityB64" v:mustUnderstand="1" n1:role="wsssecurity" xmlns:n0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:n1="http://www.w3.org/2003/05/soap-envelope">
197
+ <n0:BinarySecurityToken n2:Id="SSOToken" ValueType="esquema" EncodingType="hwsse:Base64Binary" xmlns:n2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">#{@token_credential}</n0:BinarySecurityToken>
198
+ </n0:Security>
199
+ </v:Header>
200
+ security
201
+ end
202
+
203
+ def xml_datos_cabecera
204
+ <<-datos
205
+ <datosCabecera i:type=":datosCabecera">
206
+ <version i:type="d:string">4.7.1</version>
207
+ <terminalID i:type="d:string">Android</terminalID>
208
+ <idioma i:type="d:string">es-ES</idioma>
209
+ </datosCabecera>
210
+ datos
211
+ end
212
+
213
+ def xml_products
214
+ <<-products
215
+ <v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
216
+ #{xml_security_header}
217
+ <v:Body>
218
+ <n3:obtenerPosGlobal_LIP facade="BAMOBIPGL" xmlns:n3="http://www.isban.es/webservices/BAMOBI/Posglobal/F_bamobi_posicionglobal_lip/internet/BAMOBIPGL/v1/">
219
+ <entrada i:type=":entrada">#{xml_datos_cabecera}</entrada>
220
+ </n3:obtenerPosGlobal_LIP>
221
+ </v:Body>
222
+ </v:Envelope>
223
+ products
224
+ end
225
+
226
+ def xml_login
227
+ <<-login
228
+ <v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
229
+ <v:Header />
230
+ <v:Body>
231
+ <n0:authenticateCredential facade="loginServicesNSegSAN" xmlns:n0="http://www.isban.es/webservices/TECHNICAL_FACADES/Security/F_facseg_security/internet/loginServicesNSegSAN/v1">
232
+ <CB_AuthenticationData i:type=":CB_AuthenticationData">
233
+ <documento i:type=":documento">
234
+ <CODIGO_DOCUM_PERSONA_CORP i:type="d:string">#{@user}</CODIGO_DOCUM_PERSONA_CORP>
235
+ <TIPO_DOCUM_PERSONA_CORP i:type="d:string">N</TIPO_DOCUM_PERSONA_CORP>
236
+ </documento>
237
+ <password i:type="d:string">#{@password}</password>
238
+ </CB_AuthenticationData>
239
+ <userAddress i:type="d:string">#{@public_ip}</userAddress>
240
+ </n0:authenticateCredential>
241
+ </v:Body>
242
+ </v:Envelope>
243
+ login
244
+ end
245
+
246
+ def xml_date(date)
247
+ <<-date
248
+ <dia i:type="d:int">#{date.day}</dia>
249
+ <mes i:type="d:int">#{date.month}</mes>
250
+ <anyo i:type="d:int">#{date.year}</anyo>
251
+ date
252
+ end
253
+
254
+ def xml_account(account, from_date, to_date, repo, importe_cta)
255
+ is_pagination = repo ? 'S' : 'N'
256
+ xml_from_date = xml_date(from_date)
257
+ xml_to_date = xml_date(to_date)
258
+ <<-account
259
+ <v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" xmlns:v="http://schemas.xmlsoap.org/soap/envelope/">
260
+ #{xml_security_header}
261
+ <v:Body>
262
+ <n3:listaMovCuentasFechas_LIP facade="BAMOBICTA" xmlns:n3="http://www.isban.es/webservices/BAMOBI/Cuentas/F_bamobi_cuentas_lip/internet/BAMOBICTA/v1/">
263
+ <entrada i:type=":entrada">
264
+ #{xml_datos_cabecera}
265
+ <datosConexion i:type=":datosConexion">#{@user_data.children.to_s}</datosConexion>
266
+ <contratoID i:type=":contratoID">#{account.contract_id.to_s}</contratoID>
267
+ #{importe_cta}
268
+ <fechaDesde i:type=":fechaDesde">#{xml_from_date}</fechaDesde>
269
+ <fechaHasta i:type=":fechaHasta">#{xml_to_date}</fechaHasta>
270
+ <esUnaPaginacion i:type="d:string">#{is_pagination}</esUnaPaginacion>
271
+ #{repo}
272
+ </entrada>
273
+ </n3:listaMovCuentasFechas_LIP>
274
+ </v:Body>
275
+ </v:Envelope>
276
+ account
277
+ end
278
+
279
+ def value_at_xpath(node, xpath, default = '')
280
+ value = node.at_xpath(xpath)
281
+ value && !value.content.blank? ? value.content.strip : default
282
+ end
283
+
284
+ def money(data, currency)
285
+ Money.new(data.gsub('.', ''), currency)
286
+ end
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,5 @@
1
+ module Bankscrap
2
+ module Santander
3
+ VERSION = '2.0.0'.freeze
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bankscrap-santander
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Your Name
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bankscrap
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '8.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '8.0'
69
+ description:
70
+ email:
71
+ - your@email.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - bankscrap-santander.gemspec
82
+ - lib/bankscrap-santander.rb
83
+ - lib/bankscrap/santander/account.rb
84
+ - lib/bankscrap/santander/bank.rb
85
+ - lib/bankscrap/santander/version.rb
86
+ homepage: ''
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.6.14
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Santander adapter for Bankscrap
110
+ test_files: []