parking_ticket 1.0.32 → 1.0.40

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
2
  SHA256:
3
- metadata.gz: 683fc243081f913aef89d5424d206710fa0ddadd4eb8cf431f978046732cc57a
4
- data.tar.gz: 64ee6ac6aedca57693dcd3266e89fb717abc46128ad5900bcaabf0f92656dc94
3
+ metadata.gz: a45be3c94ffccf5e5e1f66abf01a80528a5f9ab95d22b7bbd281996889b3cd5f
4
+ data.tar.gz: 52609368928c5d70bc382619b39bf2962209be2e0456bc90a4e0d89dfb3f0954
5
5
  SHA512:
6
- metadata.gz: aa871a2cba4a8364c5c051e599f1cbc4867cfcf4aa1d50ea5a021f876d45bbba019f292cf22500afff59be800e6ed926f5fa9877e6d15339919b3575a637c3d7
7
- data.tar.gz: 3e240587339c43d75ccc9bdd48586b92daf1c2d1e51011fb82118d51d0372f358941012119fcab2b55896b3a1ba022b4b698c75a26de2273d4b1a4eec194c0b8
6
+ metadata.gz: 50c8f9a60ea1f075914e468fbb7057997397a2fd800003321e0f4e03a4e1efbcfc11b6352b6b3d508b1ac95cd5b823738385b8b8c31c298179cb7a7307a9fa02
7
+ data.tar.gz: 5bc40023e17ed5235bccdbddd27d3e78e4cdea6c7e43ecc58397e81e85be5637ce5418106ffb0ab4f8c447660b65e19312a3da7f0d2979c4d14d00eaff2184a8
data/Gemfile CHANGED
@@ -9,6 +9,13 @@ gem 'rake', '~> 13.0'
9
9
 
10
10
  gem 'rspec', '~> 3.0'
11
11
 
12
+ # VCR, save test suite's http requests and replay them
13
+ gem 'vcr', '~> 6.0'
14
+ # Mock web requests in tests
15
+ gem 'webmock', '~> 3.12'
16
+
17
+ gem 'byebug'
18
+
12
19
  gem 'faraday', '~> 2.7', '>= 2.7.2'
13
20
 
14
21
  gem 'json_matchers'
data/Gemfile.lock CHANGED
@@ -1,21 +1,29 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parking_ticket (1.0.32)
4
+ parking_ticket (1.0.40)
5
5
  faraday
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ addressable (2.8.1)
11
+ public_suffix (>= 2.0.2, < 6.0)
12
+ byebug (11.1.3)
13
+ crack (0.4.5)
14
+ rexml
10
15
  diff-lcs (1.5.0)
11
16
  faraday (2.7.2)
12
17
  faraday-net_http (>= 2.0, < 3.1)
13
18
  ruby2_keywords (>= 0.0.4)
14
19
  faraday-net_http (3.0.2)
20
+ hashdiff (1.0.1)
15
21
  json_matchers (0.11.1)
16
22
  json_schema
17
23
  json_schema (0.21.0)
24
+ public_suffix (5.0.1)
18
25
  rake (13.0.6)
26
+ rexml (3.2.5)
19
27
  rspec (3.12.0)
20
28
  rspec-core (~> 3.12.0)
21
29
  rspec-expectations (~> 3.12.0)
@@ -30,17 +38,25 @@ GEM
30
38
  rspec-support (~> 3.12.0)
31
39
  rspec-support (3.12.0)
32
40
  ruby2_keywords (0.0.5)
41
+ vcr (6.1.0)
42
+ webmock (3.18.1)
43
+ addressable (>= 2.8.0)
44
+ crack (>= 0.3.2)
45
+ hashdiff (>= 0.4.0, < 2.0.0)
33
46
 
34
47
  PLATFORMS
35
48
  arm64-darwin-20
36
49
  x86_64-linux
37
50
 
38
51
  DEPENDENCIES
52
+ byebug
39
53
  faraday (~> 2.7, >= 2.7.2)
40
54
  json_matchers
41
55
  parking_ticket!
42
56
  rake (~> 13.0)
43
57
  rspec (~> 3.0)
58
+ vcr (~> 6.0)
59
+ webmock (~> 3.12)
44
60
 
45
61
  BUNDLED WITH
46
62
  2.2.32
@@ -0,0 +1,64 @@
1
+ require 'byebug'
2
+ module ParkingTicket
3
+ module Clients
4
+ class Adapter
5
+ class << self
6
+ def parent_module
7
+ const_get(name.split('::')[0..-2].join('::'))
8
+ end
9
+
10
+ def valid_credentials?(username, password)
11
+ parent_module::Client.auth(username, password).status == 200
12
+ end
13
+ end
14
+ class Error < StandardError
15
+ end
16
+
17
+ def initialize(username, password)
18
+ @username = username
19
+ @password = password
20
+ end
21
+
22
+ def vehicles
23
+ raise_invalid_credentials! unless valid_credentials?
24
+ fetch_and_map_vehicles
25
+ end
26
+
27
+ def rate_options(zipcode, license_plate)
28
+ raise_invalid_credentials! unless valid_credentials?
29
+ fetch_and_map_rate_options(zipcode, license_plate)
30
+ end
31
+
32
+ def running_ticket(license_plate, zipcode)
33
+ raise_invalid_credentials! unless valid_credentials?
34
+ fetch_and_map_running_ticket(license_plate, zipcode)
35
+ end
36
+
37
+ def payment_methods
38
+ raise_invalid_credentials! unless valid_credentials?
39
+ fetch_and_map_payment_methods
40
+ end
41
+
42
+ def new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
43
+ raise_invalid_credentials! unless valid_credentials?
44
+ return if running_ticket(license_plate, zipcode)
45
+
46
+ request_new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
47
+ end
48
+
49
+ private
50
+
51
+ def client
52
+ @client ||= self.class.parent_module::Client.new(@username, @password)
53
+ end
54
+
55
+ def valid_credentials?
56
+ @valid_credentials ||= self.class.valid_credentials?(@username, @password)
57
+ end
58
+
59
+ def raise_invalid_credentials!
60
+ raise Error, 'Adapter credentials are not valid'
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,95 @@
1
+ module ParkingTicket
2
+ module Clients
3
+ module PayByPhone
4
+ class Adapter < Clients::Adapter
5
+ ACCEPTED_TIME_UNIT_MAPPER = {
6
+ 'Days' => 'days',
7
+ 'Minutes' => 'minutes',
8
+ 'Hours' => 'hours'
9
+ }.freeze
10
+
11
+ PAYMENT_CARD_TYPE_MAPPER = {
12
+ 'MasterCard' => 'master_card',
13
+ 'Visa' => 'visa'
14
+ }.freeze
15
+
16
+ private
17
+
18
+ def fetch_and_map_vehicles
19
+ client.vehicles.map do |vehicle|
20
+ {
21
+ client_internal_id: vehicle['vehicleId'],
22
+ license_plate: vehicle['licensePlate'],
23
+ type: vehicle['type']
24
+ }
25
+ end
26
+ end
27
+
28
+ def fetch_and_map_rate_options(zipcode, license_plate)
29
+ client.rate_options(zipcode, license_plate).map do |rate_option|
30
+ mapped_time_units = rate_option['acceptedTimeUnits'].map do |accepted_time_unit|
31
+ ACCEPTED_TIME_UNIT_MAPPER[accepted_time_unit]
32
+ end
33
+ {
34
+ client_internal_id: rate_option['rateOptionId'],
35
+ name: rate_option['name'],
36
+ type: rate_option['type'],
37
+ accepted_time_units: mapped_time_units
38
+ }
39
+ end
40
+ end
41
+
42
+ def fetch_and_map_running_ticket(license_plate, zipcode)
43
+ client.running_tickets.filter do |ticket|
44
+ ticket.dig('vehicle', 'licensePlate') == license_plate && ticket['locationId'] == zipcode
45
+ end.map do |ticket|
46
+ {
47
+ client_internal_id: ticket['parkingSessionId'],
48
+ starts_on: DateTime.parse(ticket['startTime']),
49
+ ends_on: DateTime.parse(ticket['expireTime']),
50
+ license_plate: ticket.dig('vehicle', 'licensePlate'),
51
+ cost: ticket.dig('segments', 0, 'cost'),
52
+ client: 'PayByPhone'
53
+ }
54
+ end.first
55
+ end
56
+
57
+ def request_new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
58
+ mapped_time_unit = ACCEPTED_TIME_UNIT_MAPPER.key(time_unit)
59
+ payment_method = fetch_and_map_payment_methods.find do |payment_method|
60
+ payment_method[:client_internal_id] == payment_method_id
61
+ end
62
+ quote = fetch_and_map_quote(rate_option_id, zipcode, license_plate, quantity, mapped_time_unit)
63
+ client.new_ticket(
64
+ quote[:client_internal_id],
65
+ payment_method[:client_internal_id],
66
+ zipcode,
67
+ license_plate,
68
+ quantity,
69
+ mapped_time_unit,
70
+ quote[:starts_on]
71
+ )
72
+ end
73
+
74
+ def fetch_and_map_payment_methods
75
+ client.payment_methods['items'].map do |payment_method|
76
+ {
77
+ client_internal_id: payment_method['id'],
78
+ anonymised_card_number: payment_method['maskedCardNumber'][-4..],
79
+ payment_card_type: PAYMENT_CARD_TYPE_MAPPER[payment_method['paymentCardType']]
80
+ }
81
+ end
82
+ end
83
+
84
+ def fetch_and_map_quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
85
+ fetched_quote = client.quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
86
+ {
87
+ client_internal_id: fetched_quote['quoteId'],
88
+ starts_on: fetched_quote['parkingStartTime'],
89
+ ends_on: fetched_quote['parkingExpiryTime']
90
+ }
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,157 @@
1
+ require 'faraday'
2
+ module ParkingTicket
3
+ module Clients
4
+ module PayByPhone
5
+ class Client
6
+ class << self
7
+ def rate_options(token, account_id, zipcode, license_plate)
8
+ connection(token).get("/parking/locations/#{zipcode}/rateOptions",
9
+ {
10
+ parkingAccountId: account_id,
11
+ licensePlate: license_plate
12
+ }).body
13
+ end
14
+
15
+ def vehicles(token)
16
+ connection(token).get('/identity/profileservice/v1/members/vehicles/paybyphone').body
17
+ end
18
+
19
+ def auth(username, password)
20
+ conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
21
+ f.response :json
22
+ end
23
+ conn.post(
24
+ '/token',
25
+ URI.encode_www_form({
26
+ grant_type: 'password',
27
+ username: username,
28
+ password: password,
29
+ client_id: 'paybyphone_web'
30
+ }),
31
+ {
32
+ 'Accept' => 'application/json, text/plain, */*',
33
+ 'X-Pbp-ClientType' => 'WebApp'
34
+ }
35
+ )
36
+ end
37
+
38
+ def account_id(token)
39
+ connection(token).get('/parking/accounts').body.dig(0, 'id')
40
+ end
41
+
42
+ def running_tickets(token, account_id)
43
+ connection(token).get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
44
+ end
45
+
46
+ def quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
47
+ connection(token).get(
48
+ "/parking/accounts/#{account_id}/quote",
49
+ {
50
+ locationId: zipcode,
51
+ licensePlate: license_plate,
52
+ rateOptionId: rate_option_id,
53
+ durationTimeUnit: time_unit,
54
+ durationQuantity: quantity,
55
+ isParkUntil: false,
56
+ parkingAccountId: account_id
57
+ }
58
+ ).body
59
+ end
60
+
61
+ def new_ticket(token, account_id, quote_id, payment_method_id, zipcode, license_plate, quantity, time_unit, start_time)
62
+ connection(token).post(
63
+ "/parking/accounts/#{account_id}/sessions/",
64
+ {
65
+ "expireTime": nil,
66
+ "duration": {
67
+ "quantity": quantity,
68
+ "timeUnit": time_unit
69
+ },
70
+ "licensePlate": license_plate,
71
+ "locationId": zipcode,
72
+ "rateOptionId": '75101',
73
+ "startTime": start_time,
74
+ "quoteId": quote_id,
75
+ "parkingAccountId": account_id,
76
+ "paymentMethod": {
77
+ "paymentMethodType": 'PaymentAccount',
78
+ "payload": {
79
+ "paymentAccountId": payment_method_id,
80
+ "clientBrowserDetails": {
81
+ "browserAcceptHeader": 'text/html',
82
+ "browserColorDepth": '30',
83
+ "browserJavaEnabled": 'false',
84
+ "browserLanguage": 'fr-FR',
85
+ "browserScreenHeight": '900',
86
+ "browserScreenWidth": '1440',
87
+ "browserTimeZone": '-60',
88
+ "browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
89
+ }
90
+ }
91
+ }
92
+ }.to_json
93
+ ).body
94
+ end
95
+
96
+ def payment_methods(token)
97
+ connection(token).get('/payment/v3/accounts').body
98
+ end
99
+
100
+ private
101
+
102
+ def connection(token)
103
+ Faraday.new(
104
+ url: 'https://consumer.paybyphoneapis.com',
105
+ headers: {
106
+ 'Content-Type' => 'application/json',
107
+ 'Authorization' => "Bearer #{token}"
108
+ }
109
+ ) do |f|
110
+ f.response :json
111
+ end
112
+ end
113
+ end
114
+
115
+ def initialize(username, password)
116
+ @username = username
117
+ @password = password
118
+ end
119
+
120
+ def vehicles
121
+ self.class.vehicles(token)
122
+ end
123
+
124
+ def rate_options(zipcode, license_plate)
125
+ self.class.rate_options(token, account_id, zipcode, license_plate)
126
+ end
127
+
128
+ def running_tickets
129
+ self.class.running_tickets(token, account_id)
130
+ end
131
+
132
+ def payment_methods
133
+ self.class.payment_methods(token)
134
+ end
135
+
136
+ def quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
137
+ self.class.quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
138
+ end
139
+
140
+ def new_ticket(quote_id, payment_method_id, zipcode, license_plate, quantity, time_unit, start_time)
141
+ self.class.new_ticket(token, account_id, quote_id, payment_method_id, zipcode, license_plate, quantity,
142
+ time_unit, start_time)
143
+ end
144
+
145
+ private
146
+
147
+ def token
148
+ @token ||= self.class.auth(@username, @password).body['access_token']
149
+ end
150
+
151
+ def account_id
152
+ @account_id ||= self.class.account_id(token)
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ParkingTicket
4
- VERSION = '1.0.32'
4
+ VERSION = '1.0.40'
5
5
  end
@@ -4,15 +4,15 @@ require 'parking_ticket/configuration'
4
4
  require 'parking_ticket/version'
5
5
 
6
6
  # PayByPhone wrapper
7
- require 'client/pay_by_phone/configuration'
8
- require 'client/pay_by_phone/adapter'
9
- require 'client/pay_by_phone/request'
7
+ require 'clients/adapter'
8
+ require 'clients/pay_by_phone/adapter'
9
+ require 'clients/pay_by_phone/client'
10
10
 
11
11
  module ParkingTicket
12
12
  class Base
13
13
  class << self
14
14
  def valid_credentials?(adapter_name, username, password)
15
- adapter = Client::PayByPhone::Adapter if adapter_name == 'pay_by_phone'
15
+ adapter = Clients::PayByPhone::Adapter if adapter_name == 'pay_by_phone'
16
16
  raise Error, 'EasyPark will be handled in the next major release' if adapter_name == 'easy_park'
17
17
  raise Error, "Unhandled adapter : #{adapter_name}" unless adapter
18
18
 
@@ -44,24 +44,30 @@ module ParkingTicket
44
44
  class Error < StandardError
45
45
  end
46
46
 
47
- def initialize(adapter_name, configuration_attributes)
47
+ def initialize(adapter_name, username, password)
48
48
  @adapter_name = adapter_name
49
- @configuration_attributes = configuration_attributes
50
- @result = {}
49
+ @username = username
50
+ @password = password
51
51
  end
52
52
 
53
- def adapter
54
- @adapter ||= load_adapter!
53
+ def vehicles
54
+ adapter.vehicles
55
+ end
56
+
57
+ def rate_options(zipcode, license_plate)
58
+ adapter.rate_options(zipcode, license_plate)
55
59
  end
56
60
 
57
- def renew
58
- adapter.renew unless current_ticket
61
+ def running_ticket(license_plate, zipcode)
62
+ adapter.running_ticket(license_plate, zipcode)
59
63
  end
60
64
 
61
- def current_ticket
62
- ticket = adapter.current_ticket
63
- ticket = self.class.format_ticket(ticket) if self.class.ticket_format && ticket
64
- ticket
65
+ def payment_methods
66
+ adapter.payment_methods
67
+ end
68
+
69
+ def new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
70
+ adapter.new_ticket(license_plate, zipcode, rate_option_id, quantity, time_unit, payment_method_id)
65
71
  end
66
72
 
67
73
  private
@@ -74,24 +80,15 @@ module ParkingTicket
74
80
  end
75
81
 
76
82
  def prepare_pay_by_phone_adapter!
77
- configuration = pay_by_phone_configuration
78
- return Client::PayByPhone::Adapter.new(configuration) if configuration.completed?
79
-
80
- raise Error, 'Uncompleted configuration'
81
- end
82
-
83
- def pay_by_phone_configuration
84
- Client::PayByPhone::Configuration.new do |config|
85
- config.username = @configuration_attributes[:username]
86
- config.password = @configuration_attributes[:password]
87
- config.license_plate = @configuration_attributes[:license_plate]
88
- config.zipcode = @configuration_attributes[:zipcode]
89
- config.card_number = @configuration_attributes[:card_number]
90
- end
83
+ Clients::PayByPhone::Adapter.new(@username, @password)
91
84
  end
92
85
 
93
86
  def prepare_easy_park_adapter!
94
87
  raise Error, 'EasyPark will be handled in the next major release'
95
88
  end
89
+
90
+ def adapter
91
+ @adapter ||= load_adapter!
92
+ end
96
93
  end
97
94
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parking_ticket
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.32
4
+ version: 1.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Ecrepont
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-02-01 00:00:00.000000000 Z
11
+ date: 2023-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -40,9 +40,9 @@ files:
40
40
  - Rakefile
41
41
  - bin/console
42
42
  - bin/setup
43
- - lib/client/pay_by_phone/adapter.rb
44
- - lib/client/pay_by_phone/configuration.rb
45
- - lib/client/pay_by_phone/request.rb
43
+ - lib/clients/adapter.rb
44
+ - lib/clients/pay_by_phone/adapter.rb
45
+ - lib/clients/pay_by_phone/client.rb
46
46
  - lib/parking_ticket.rb
47
47
  - lib/parking_ticket/configuration.rb
48
48
  - lib/parking_ticket/version.rb
@@ -1,71 +0,0 @@
1
- module ParkingTicket
2
- module Client
3
- module PayByPhone
4
- class Adapter
5
- class << self
6
- def valid_credentials?(username, password)
7
- Request.valid_credentials?(username, password)
8
- end
9
- end
10
-
11
- def initialize(configuration)
12
- @configuration = configuration
13
- end
14
-
15
- def valid_credentials?(_username, _password)
16
- request.valid_credentials?(_username, _password)
17
- end
18
-
19
- def covered?
20
- !!current_ticket
21
- end
22
-
23
- def current_ticket
24
- ticket = request.tickets(account_id).find do |ticket|
25
- ticket.dig('vehicle', 'licensePlate') == @configuration.license_plate
26
- end
27
-
28
- return unless ticket
29
-
30
- {
31
- starts_on: DateTime.parse(ticket['startTime']),
32
- ends_on: DateTime.parse(ticket['expireTime']),
33
- license_plate: ticket.dig('vehicle', 'licensePlate'),
34
- cost: ticket.dig('segments', 0, 'cost'),
35
- client: 'PayByPhone',
36
- client_ticket_id: ticket['parkingSessionId']
37
- }
38
- end
39
-
40
- def renew
41
- return if covered?
42
-
43
- quote = request.new_quote(rate_option_id, account_id)
44
- request.new_ticket(account_id, quote['parkingStartTime'], quote['quoteId'], payment_method_id)
45
- end
46
-
47
- private
48
-
49
- def request
50
- @request ||= Request.new(@configuration)
51
- end
52
-
53
- def account_id
54
- @account_id ||= request.accounts.dig(0, 'id')
55
- end
56
-
57
- def payment_method_id
58
- request.payment_methods['items'].find do |payment_method|
59
- payment_method['maskedCardNumber'] == @configuration.card_number
60
- end['id']
61
- end
62
-
63
- def rate_option_id
64
- request.rate_options(account_id).find do |rate_option|
65
- rate_option['type'] == 'RES' && rate_option['licensePlate'] == @configuration.license_plate
66
- end['rateOptionId']
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,9 +0,0 @@
1
- module ParkingTicket
2
- module Client
3
- module PayByPhone
4
- class Configuration < ParkingTicket::Configuration
5
- attr_required :username, :password, :license_plate, :zipcode, :card_number
6
- end
7
- end
8
- end
9
- end
@@ -1,133 +0,0 @@
1
- require 'faraday'
2
- module ParkingTicket
3
- module Client
4
- module PayByPhone
5
- class Request
6
- class << self
7
- def valid_credentials?(username, password)
8
- auth(username, password).status == 200
9
- end
10
-
11
- private
12
-
13
- def auth(username, password)
14
- conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
15
- f.response :json
16
- end
17
- conn.post(
18
- '/token',
19
- URI.encode_www_form({
20
- grant_type: 'password',
21
- username: username,
22
- password: password,
23
- client_id: 'paybyphone_web'
24
- }),
25
- {
26
- 'Accept' => 'application/json, text/plain, */*',
27
- 'X-Pbp-ClientType' => 'WebApp'
28
- }
29
- )
30
- end
31
- end
32
-
33
- def initialize(configuration)
34
- @configuration = configuration
35
- end
36
-
37
- def tickets(account_id)
38
- connection.get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
39
- end
40
-
41
- def new_ticket(account_id, parking_start_time, quote_id, payment_method_id)
42
- connection.post(
43
- "/parking/accounts/#{account_id}/sessions/",
44
- {
45
- "expireTime": nil,
46
- "duration": {
47
- "quantity": '1',
48
- "timeUnit": 'days'
49
- },
50
- "licensePlate": @configuration.license_plate,
51
- "locationId": @configuration.zipcode,
52
- "rateOptionId": '75101',
53
- "startTime": parking_start_time,
54
- "quoteId": quote_id,
55
- "parkingAccountId": account_id,
56
- "paymentMethod": {
57
- "paymentMethodType": 'PaymentAccount',
58
- "payload": {
59
- "paymentAccountId": payment_method_id,
60
- "clientBrowserDetails": {
61
- "browserAcceptHeader": 'text/html',
62
- "browserColorDepth": '30',
63
- "browserJavaEnabled": 'false',
64
- "browserLanguage": 'fr-FR',
65
- "browserScreenHeight": '900',
66
- "browserScreenWidth": '1440',
67
- "browserTimeZone": '-60',
68
- "browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
69
- }
70
- }
71
- }
72
- }.to_json
73
- ).body
74
- end
75
-
76
- def accounts
77
- connection.get('/parking/accounts').body
78
- end
79
-
80
- def vehicles
81
- connection.get('/identity/profileservice/v1/members/vehicles/paybyphone').body
82
- end
83
-
84
- def rate_options(account_id)
85
- connection.get("/parking/locations/#{@configuration.zipcode}/rateOptions",
86
- {
87
- parkingAccountId: account_id,
88
- licensePlate: @configuration.license_plate
89
- }).body
90
- end
91
-
92
- def new_quote(rate_option_id, account_id)
93
- connection.get(
94
- "/parking/accounts/#{account_id}/quote",
95
- {
96
- locationId: @configuration.zipcode,
97
- licensePlate: @configuration.license_plate,
98
- rateOptionId: rate_option_id,
99
- durationTimeUnit: 'Days',
100
- durationQuantity: 1,
101
- isParkUntil: false,
102
- parkingAccountId: account_id
103
- }
104
- ).body
105
- end
106
-
107
- def member
108
- connection.get('/identity/profileservice/v1/members').body
109
- end
110
-
111
- def payment_methods
112
- connection.get('/payment/v3/accounts').body
113
- end
114
-
115
- def connection
116
- @connection ||= Faraday.new(
117
- url: 'https://consumer.paybyphoneapis.com',
118
- headers: {
119
- 'Content-Type' => 'application/json',
120
- 'Authorization' => "Bearer #{token}"
121
- }
122
- ) do |f|
123
- f.response :json
124
- end
125
- end
126
-
127
- def token
128
- self.class.send(:auth, @configuration.username, @configuration.password).body['access_token']
129
- end
130
- end
131
- end
132
- end
133
- end