eps-rapid 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +57 -0
- data/.rspec +3 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.MD +20 -0
- data/Gemfile +15 -0
- data/LICENSE +24 -0
- data/README.md +421 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/eps-rapid.gemspec +30 -0
- data/lib/eps-rapid.rb +31 -0
- data/lib/eps-rapid/booking.rb +21 -0
- data/lib/eps-rapid/client.rb +129 -0
- data/lib/eps-rapid/content.rb +25 -0
- data/lib/eps-rapid/errors/exceptions.rb +21 -0
- data/lib/eps-rapid/errors/http_status_codes.rb +16 -0
- data/lib/eps-rapid/geography.rb +29 -0
- data/lib/eps-rapid/manage_booking.rb +25 -0
- data/lib/eps-rapid/notifications.rb +13 -0
- data/lib/eps-rapid/recommendations.rb +13 -0
- data/lib/eps-rapid/shopping.rb +25 -0
- data/lib/eps-rapid/version.rb +5 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5fcdfecec2d521bca0534edc175c3d63bce638bade075f6fb0cf1997194464a9
|
4
|
+
data.tar.gz: 42d0f1ea2b4b540ee29ec526120860cbad9ee4803b17a3845330614dac0d3be2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 583aebae3bbb10667e34fc5d07833bc3ed970d1c4d4baaced5e99930c3e68f006ca479e5d9033c7a1131f6746dab29736e571078dfac2f73e0b21c149d4e2561
|
7
|
+
data.tar.gz: d2c5a079b12a22b7117ac1f340c718b2ae945dcc17303522410bd63e0386833017854ccc52c160146e72986dcb4a54e3c18a6e50d417fe710d37b1da32cf208c
|
data/.gitignore
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
|
14
|
+
.byebug_history
|
15
|
+
.DS_Store
|
16
|
+
.rspec_status
|
17
|
+
Gemfile.lock
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
## Specific to RubyMotion:
|
22
|
+
.dat*
|
23
|
+
.repl_history
|
24
|
+
build/
|
25
|
+
*.bridgesupport
|
26
|
+
build-iPhoneOS/
|
27
|
+
build-iPhoneSimulator/
|
28
|
+
|
29
|
+
## Specific to RubyMotion (use of CocoaPods):
|
30
|
+
#
|
31
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
32
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
33
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
34
|
+
#
|
35
|
+
# vendor/Pods/
|
36
|
+
|
37
|
+
## Documentation cache and generated files:
|
38
|
+
/.yardoc/
|
39
|
+
/_yardoc/
|
40
|
+
/doc/
|
41
|
+
/rdoc/
|
42
|
+
|
43
|
+
## Environment normalization:
|
44
|
+
/.bundle/
|
45
|
+
/vendor/bundle
|
46
|
+
/lib/bundler/man/
|
47
|
+
|
48
|
+
# for a library or gem, you might want to ignore these files since the code is
|
49
|
+
# intended to run in multiple environments; otherwise, check them in:
|
50
|
+
# .ruby-version
|
51
|
+
# .ruby-gemset
|
52
|
+
|
53
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
54
|
+
.rvmrc
|
55
|
+
|
56
|
+
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
|
57
|
+
# .rubocop-https?--*
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
DisabledByDefault: false
|
4
|
+
DisplayCopNames: true
|
5
|
+
TargetRubyVersion: 2.6.2
|
6
|
+
Exclude:
|
7
|
+
- 'bin/*'
|
8
|
+
- 'spec/spec_helper.rb'
|
9
|
+
- 'eps-rapid.gemspec'
|
10
|
+
Documentation:
|
11
|
+
Enabled: false
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Max: 25
|
14
|
+
Metrics/ClassLength:
|
15
|
+
Max: 120
|
16
|
+
Metrics/CyclomaticComplexity:
|
17
|
+
Max: 12
|
18
|
+
Metrics/PerceivedComplexity:
|
19
|
+
Max: 12
|
20
|
+
Metrics/LineLength:
|
21
|
+
Max: 120
|
22
|
+
Lint/UselessAssignment:
|
23
|
+
Enabled: true
|
24
|
+
Metrics/BlockLength:
|
25
|
+
Enabled: false
|
26
|
+
Metrics/AbcSize:
|
27
|
+
Enabled: true
|
28
|
+
Max: 35
|
29
|
+
Naming/FileName:
|
30
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.MD
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
### Version 1.0.0
|
2
|
+
# Added
|
3
|
+
- Client(#geogrphy-resource)
|
4
|
+
- Error handling(#geogrphy-resource)
|
5
|
+
- Geography resource(#geogrphy-resource)
|
6
|
+
- Content resource(#content-resource)
|
7
|
+
- Shopping resource(#shopping-resource)
|
8
|
+
- Booking resource(#booking-resource)
|
9
|
+
- Manage booking resource(#booking-resource)
|
10
|
+
- Added methods put and delete to the client(#booking-resource)
|
11
|
+
- Recommendations resource(#recommendation-resource)
|
12
|
+
- Notifications resource(#notifications-resource)
|
13
|
+
# Changed
|
14
|
+
- Updated readme.md
|
15
|
+
- Add test header to request(#shopping-resource)
|
16
|
+
# Patched
|
17
|
+
- Move preparing uri params to client.rb(#content-resource)
|
18
|
+
- Move recommendation rate from Shopping to Recommendations class(#recommendation-resource)
|
19
|
+
# Removed
|
20
|
+
- Remove redundant methods get_by_link & post_by_link form client(#booking-resource)
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in eps_rapid.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
gem 'rake', '~> 12.0'
|
9
|
+
gem 'rspec', '~> 3.0'
|
10
|
+
gem 'rubocop', '~> 1.11', require: false
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'byebug'
|
14
|
+
gem 'webmock'
|
15
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
4
|
+
distribute this software, either in source code form or as a compiled
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
6
|
+
means.
|
7
|
+
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
9
|
+
of this software dedicate any and all copyright interest in the
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
11
|
+
of the public at large and to the detriment of our heirs and
|
12
|
+
successors. We intend this dedication to be an overt act of
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
14
|
+
software under copyright law.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
For more information, please refer to <https://unlicense.org>
|
data/README.md
ADDED
@@ -0,0 +1,421 @@
|
|
1
|
+
# eps-rapid
|
2
|
+
Ruby gem for the eps-rapid 2.4 API
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'eps-rapid'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
```$ bundle install```
|
15
|
+
|
16
|
+
## Configuration
|
17
|
+
```ruby
|
18
|
+
EpsRapid.configure do |c|
|
19
|
+
c.api_key = 'YOUR_API_KEY'
|
20
|
+
c.secret_key = 'YOUR_SECRET_KEY'
|
21
|
+
c.base_path = 'BASE_PATH'
|
22
|
+
c.language = 'en-US'
|
23
|
+
end
|
24
|
+
```
|
25
|
+
Base path depends of environment and can be `https://test.ean.com/2.4` or `https://api.ean.com/2.4`
|
26
|
+
Language is desired language for the response as a subset of BCP47 format that only uses hyphenated pairs of two-digit language and country codes. Supported languages: https://developer.expediapartnersolutions.com/reference/language-options/
|
27
|
+
|
28
|
+
### Geography API
|
29
|
+
The EPS Rapid Geography APIs provide you with access to geographic definitions and property mappings for over 600,000 regions and airports.
|
30
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-geography-docs-2-4/
|
31
|
+
#### Methods
|
32
|
+
```ruby
|
33
|
+
EpsRapid::Geography.regions_list(ancestor_id: 2, include: 'standard, property_ids')
|
34
|
+
```
|
35
|
+
Returns the geographic definition and property mappings of regions matching the specified parameters.
|
36
|
+
|
37
|
+
Method accept two arguments:
|
38
|
+
- `ancestor_id` ID of the ancestor of regions to retrieve. Refer to the list of top level of regions https://developer.expediapartnersolutions.com/reference/geography-reference-lists-2-2/ .
|
39
|
+
Required: false.
|
40
|
+
- `include` Options for which content to return in the response. This parameter can be supplied multiple times with different values. The standard and details options cannot be requested together. The value must be lower case. Supported values: `standard, details, property_ids, property_ids_expanded`.
|
41
|
+
Required: false, default: 'standard'.
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
EpsRapid::Geography.region(602962, include: 'details, property_ids')
|
45
|
+
```
|
46
|
+
Returns the geographic definition and property mappings for the requested Region ID. The response is a single JSON formatted region object.
|
47
|
+
|
48
|
+
Method accept two arguments:
|
49
|
+
- `region_id` ID of the region to retrieve.
|
50
|
+
Required: true.
|
51
|
+
- `include` Options for which content to return in the response. This parameter can be supplied multiple times with different values. The value must be lower case. Supported values: `details, property_ids, property_ids_expanded`.
|
52
|
+
Required: false, default: 'details'.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
EpsRapid::Geography.create_polygon([[-93.446782, 37.169329],[-93.4244,37.169432]])
|
56
|
+
```
|
57
|
+
Returns the properties within an custom polygon that represents a multi-city area or smaller.
|
58
|
+
The coordinates of the polygon should be in GeoJSON format and the polygon must conform to the following restrictions:
|
59
|
+
Polygon size - diagonal distance of the polygon must be less than 500km
|
60
|
+
Polygon type - only single polygons are supported
|
61
|
+
Number of coordinates - must be <= 2000
|
62
|
+
|
63
|
+
Method accept one argument:
|
64
|
+
- `body` Array of coordinates.
|
65
|
+
Required: true.
|
66
|
+
|
67
|
+
### Content API
|
68
|
+
The EPS Rapid Content APIs provide you with access to content for all of EPS’s properties.
|
69
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-content-docs-2-4/
|
70
|
+
#### Methods
|
71
|
+
```ruby
|
72
|
+
EpsRapid::Content.content_list(property_id: '123456, 2345678', brand_id: '12345, 23456', business_model: 'expedia_collect')
|
73
|
+
```
|
74
|
+
Search property content for active properties in the requested language.
|
75
|
+
When searching with query parameter, property_id, you may request 1 to 250 properties at a time.
|
76
|
+
Method accept arguments:
|
77
|
+
- `brand_id` The ID of the brand you want to search for. This parameter can be supplied multiple times with different values, which will include properties that match any of the requested brand IDs.
|
78
|
+
Required: false.
|
79
|
+
- `business_model` Search for properties with the requested business model enabled. This parameter can be supplied multiple times with different values, which will return all properties that match any of the requested business models. The value must be lower case.
|
80
|
+
Required: false.
|
81
|
+
- `category_id_exclude` Search to exclude properties that do not have the requested category ID - https://developer.expediapartnersolutions.com/reference/content-reference-lists-2-4/. If this parameter is not supplied, all category IDs are included. This parameter can be supplied multiple times with different values, which will exclude properties that match any of the requested category IDs.
|
82
|
+
Required: false.
|
83
|
+
- `chain_id` The ID of the chain you want to search for. These chain IDs can be positive and negative numbers. This parameter can be supplied multiple times with different values, which will include properties that match any of the requested chain IDs.
|
84
|
+
Required: false.
|
85
|
+
- `country_code` Search for properties with the requested country code, in ISO 3166-1 alpha-2 format. This parameter can be supplied multiple times with different values, which will include properties that match any of the requested country codes.
|
86
|
+
Required: false.
|
87
|
+
- `date_added_end` Search for properties added on or before the requested UTC date, in ISO 8601 format (YYYY-MM-DD).
|
88
|
+
Required: false.
|
89
|
+
- `date_added_start` Search for properties added on or after the requested UTC date, in ISO 8601 format (YYYY-MM-DD).
|
90
|
+
Required: false.
|
91
|
+
- `date_updated_end` Search for properties updated on or before the requested UTC date, in ISO 8601 format (YYYY-MM-DD).
|
92
|
+
Required: false.
|
93
|
+
- `date_updated_start` Search for properties updated on or after the requested UTC date, in ISO 8601 format (YYYY-MM-DD).
|
94
|
+
Required: false.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
EpsRapid::Content.guest_review(123456)
|
98
|
+
```
|
99
|
+
Note: Property Guest Reviews are only available if your account is configured for access and all launch requirements have been followed. Please find the launch requirements here https://support.expediapartnersolutions.com/hc/en-us/articles/360008646799 and contact your Account Manager for more details.
|
100
|
+
The response is an individual Guest Reviews object containing up to 10 guest reviews for the requested active property.
|
101
|
+
To ensure you always show the latest guest reviews, this call should be made whenever a customer looks at the details for a specific property.
|
102
|
+
|
103
|
+
Method accept one argument:
|
104
|
+
- `property_id` Expedia Property ID.
|
105
|
+
Required: true.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
EpsRapid::Content.catalog_file
|
109
|
+
```
|
110
|
+
Returns a link to download the master list of EPS’s active properties in the requested language. The response includes high-level details about each property.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
EpsRapid::Content.content_file
|
114
|
+
```
|
115
|
+
Returns a link to download all content for all of EPS’s active properties in the requested language. The response includes property-level, room-level and rate-level information.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
EpsRapid::Content.chains
|
119
|
+
```
|
120
|
+
Returns a complete collection of chains recognized by the Rapid API.
|
121
|
+
Chains represent a parent company which can have multiple brands associated with it. A brand can only be associated with one chain. For example, Hilton Worldwide is a chain that has multiple associated brands including Doubletree, Hampton Inn and Embassy Suites.
|
122
|
+
The response is a JSON map where the key is the chain ID and the value is a chain object. Each chain object also contains a map of its related brands.
|
123
|
+
Note that the set of chain IDs and brand IDs are totally independent of one another. It is possible for a chain and a brand to both use the same number as their ID, but this is just a coincidence that holds no meaning.
|
124
|
+
Chain and brand names are provided in English only.
|
125
|
+
|
126
|
+
### Shopping API
|
127
|
+
The EPS Rapid Shopping API provides you with access to live rates and availability for over 500,000 properties globally.
|
128
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-shopping-docs-2-4/
|
129
|
+
#### Methods
|
130
|
+
```ruby
|
131
|
+
EpsRapid::Content.availability(occupancy: '2-9,4;2-8,6', property_id: '12345,567899', country_code: 'US', sales_environment: 'hotel_package', sales_channel: 'website', checkin: '2021-05-01', checkout: '2021-05-03', currency: 'USD', rate_plan_count: '1')
|
132
|
+
```
|
133
|
+
Returns rates on available room types for specified properties (maximum of 250 properties per request). The response includes rate details such as promos, whether the rate is refundable, cancellation penalties and a full price breakdown to meet the price display requirements for your market.
|
134
|
+
Note: If there are no available rooms, the response will be an empty array.
|
135
|
+
Multiple rooms of the same type may be requested by including multiple instances of the `occupancy` parameter.
|
136
|
+
The `nightly` array includes each individual night’s charges. When the total price includes fees, charges, or adjustments that are not divided by night, these amounts will be included in the stay rate array, which details charges applied to the entire stay (each check-in).
|
137
|
+
|
138
|
+
Method accept arguments:
|
139
|
+
- `checkin` Check-in date, in ISO 8601 format (YYYY-MM-DD).
|
140
|
+
Required: true.
|
141
|
+
- `checkout` Check-out date, in ISO 8601 format (YYYY-MM-DD). Availability can be searched up to 500 days in advance of this date. Total length of stay cannot exceed 28 nights.
|
142
|
+
Required: true.
|
143
|
+
- `currency` Requested currency for the rates, in ISO 4217 format. Currency Options: https://developer.expediapartnersolutions.com/reference/currency-options/
|
144
|
+
Required: true.
|
145
|
+
- `country_code` The country code of the traveler’s point of sale, in ISO 3166-1 alpha-2 format. This should represent the country where the shopping transaction is taking place. For more information see: https://www.iso.org/obp/ui/#search/code/ .
|
146
|
+
Required: true.
|
147
|
+
- `occupancy` Defines the requested occupancy for a single room. Each room must have at least 1 adult occupant.
|
148
|
+
Format: `numberOfAdults[-firstChildAge[,nextChildAge]]`
|
149
|
+
To request multiple rooms (of the same type), include one instance of occupancy for each room requested. Up to 8 rooms may be requested or booked at once. Examples:
|
150
|
+
1) 2 adults, one 9-year-old and one 4-year-old would be represented by `occupancy=2-9,4`.
|
151
|
+
2) A multi-room request to lodge an additional 2 adults would be represented by `occupancy=2-9,4;occupancy=2`.
|
152
|
+
Required: true.
|
153
|
+
- `property_id` The ID of the property you want to search for. You can provide 1 to 250 property_id parameters.
|
154
|
+
Required: true.
|
155
|
+
- `sales_channel` You must provide the sales channel for the display of rates. EPS dynamically provides the best content for optimal conversion on each sales channel. If you have a sales channel that is not currently supported in this list, please contact our support team.
|
156
|
+
1) `website` - Standard website accessed from the customer’s computer
|
157
|
+
2) `agent_tool` - Your own agent tool used by your call center or retail store agent
|
158
|
+
3) `mobile_app` - An application installed on a phone or tablet device
|
159
|
+
4) `mobile_web` - A web browser application on a phone or tablet device
|
160
|
+
5) `meta` - Rates will be passed to and displayed on a 3rd party comparison website
|
161
|
+
6) `cache` - Rates will be used to populate a local cache.
|
162
|
+
Required: true.
|
163
|
+
- `sales_environment` You must provide the sales environment in which rates will be sold. EPS dynamically provides the best content for optimal conversion. If you have a sales environment that is not currently supported in this list, please contact our support team.
|
164
|
+
1) `hotel_package` - Use when selling the hotel with a transport product, e.g. flight & hotel.
|
165
|
+
2) `hotel_only` - Use when selling the hotel as an individual product.
|
166
|
+
3) `loyalty` - Use when you are selling the hotel as part of a loyalty program and the price is converted to points.
|
167
|
+
Required: true.
|
168
|
+
- `filter` Single filter type. Send multiple instances of this parameter to request multiple filters.
|
169
|
+
1) `refundable` - Filters results to only show fully refundable rates.
|
170
|
+
2) `expedia_collect` - Filters results to only show rates where payment is collected by Expedia at the time of booking. These properties can be eligible for payments via Expedia Affiliate Collect(EAC).
|
171
|
+
3) `property_collect` - Filters results to only show rates where payment is collected by the property after booking. This can include rates that require a deposit by the property, dependent upon the deposit policies.
|
172
|
+
Required: false.
|
173
|
+
- `rate_plan_count` The number of rates to return per property. The rate’s price determines which rates are returned e.g. a rateplancount=4 will return the lowest 4 rates, but the rates are not ordered from lowest to highest or vice versa in the response. The lowest rate has been proven to provide the best conversion rate and so a value of 1 is recommended.
|
174
|
+
The value must be greater than 0.
|
175
|
+
Required: true.
|
176
|
+
- `rate_option` Request specific rate options for each property. Send multiple instances of this parameter to request multiple rate options.
|
177
|
+
Accepted values:
|
178
|
+
1) `member` - Return member rates for each property. This feature must be enabled and requires a user to be logged in to request these rates.
|
179
|
+
2) `net_rates` - Return net rates for each property. This feature must be enabled to request these rates.
|
180
|
+
3) `cross_sell` - Identify if the traffic is coming from a cross sell booking. Where the traveler has booked another service (flight, car, activities…) before hotel.
|
181
|
+
Required: false.
|
182
|
+
- 'test' Shop calls have a test header that can be used to return set responses with the following keywords: https://developer.expediapartnersolutions.com/reference/rapid-shopping-test-request/ under keyword `Shop`.
|
183
|
+
Required: false.
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
EpsRapid::Shopping.price_check('properties/599536/rooms/201125633/rates/234071214?token=C~Oj46Zz8xJD', test: 'matched')
|
187
|
+
```
|
188
|
+
Confirms the price returned by the Property Availability response. Use this API to verify a previously-selected rate is still valid before booking. If the price is matched, the response returns a link to request a booking. If the price has changed, the response returns new price details and a booking link for the new price. If the rate is no longer available, the response will return a new Property Availability request link to search again for different rates. In the event of a price change, go back to Property Availability and book the property at the new price or return to additional rates for the property.
|
189
|
+
Method accept two arguments:
|
190
|
+
- `path` A link to price check, should be taken from `availability` response under key `...{'links': {'price_check': {'href': 'price check link'}` without EPS API version in the path.
|
191
|
+
Required: true.
|
192
|
+
- `test` Price check calls have a test header that can be used to return set responses with the following keywords: https://developer.expediapartnersolutions.com/reference/rapid-shopping-test-request/ under keyword `Price Check`.
|
193
|
+
Required: false.
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
EpsRapid::Shopping.payment_options('properties/599536/payment-options?token=C~Oj46Zz8xJD')
|
197
|
+
```
|
198
|
+
Returns the accepted payment options. Use this API to power your checkout page and display valid forms of payment, ensuring a smooth booking.
|
199
|
+
Method accept one argument:
|
200
|
+
- `path` A link to payment options, should be taken from `availability` response under key `...{'links': {'payment_options': {'href': 'payment options link'}` without EPS API version in the path.
|
201
|
+
Required: true.
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
EpsRapid::Shopping.deposit_policies('properties/12345/deposit-policies?token=REhZAQsABAE', test: 'all')
|
205
|
+
```
|
206
|
+
This link will be available in the shop response when rates require a deposit. It returns the amounts and dates for when any deposits are due. Deposit information is obtained by making a deposit-policies API call using this link.
|
207
|
+
Method accept two arguments:
|
208
|
+
- `path` A link to deposit policy, should be taken from `availability` response under key `...{'links': {'deposit_policies': {'href': 'deposit policies link'}` without EPS API version in the path.
|
209
|
+
Required: true.
|
210
|
+
- `test` Deposit Policy calls have a test header that can be used to return set responses with the following keywords: https://developer.expediapartnersolutions.com/reference/rapid-shopping-test-request/ under keyword `Deposit Policy`.
|
211
|
+
Required: false.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
EpsRapid::Shopping.additional_rates('properties/12345/availability?token=REhZAQsAB')
|
215
|
+
```
|
216
|
+
Returns additional rates.
|
217
|
+
Method accept one argument:
|
218
|
+
- `path` A link to additional rates, should be taken from `availability` response under key `...{'links': {'additional_rates': {'href': 'additional rates link'}` without EPS API version in the path.
|
219
|
+
Required: true.
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
EpsRapid::Shopping.recommendation_rates('properties/12345/availability?token=REhZAQsAB')
|
223
|
+
```
|
224
|
+
Returns recommendation rates.
|
225
|
+
Method accept one argument:
|
226
|
+
- `path` A link to recommendation rates, should be taken from `availability` response under key `...{'links': {'recommendations': {'href': 'additional rates link'}` without EPS API version in the path.
|
227
|
+
Required: true.
|
228
|
+
|
229
|
+
### Booking API
|
230
|
+
The EPS Rapid Booking API allows you to book rooms & rates confirmed by the price check response.
|
231
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-booking-docs-2-4/
|
232
|
+
#### Methods
|
233
|
+
```ruby
|
234
|
+
EpsRapid::Booking.register_payment('payment-sessions?token=ABSDBV', {version": "1", "browser_accept_header": "*/*", ...}, customer_ip: '127.0.0.1')
|
235
|
+
```
|
236
|
+
This method only applies to transactions where EPS takes the customer’s payment information. This includes both Expedia Collect and Property Collect transactions.
|
237
|
+
This link will be available in the Price Check response if payment registration is required. It returns a payment session ID and a link to create a booking. This will be the first step in the booking flow only if you’ve opted into Two-Factor Authentication to comply with the September 2019 EU Regulations for PSD2.
|
238
|
+
Method accept arguments:
|
239
|
+
- `path` A link to open payment session. This link will be available in the Price Check response if payment registration is required.
|
240
|
+
Required: true.
|
241
|
+
- `body` Json object. Requirements check under `PaymentSessionsRequestBody` in https://developer.expediapartnersolutions.com/documentation/rapid-booking-docs-2-4/#/Booking/post_payment_sessions .
|
242
|
+
Required: true.
|
243
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
244
|
+
Required: true.
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
EpsRapid::Booking.create_booking('itineraries/7562428514179?token=QldfCGlcUA4DVVhW', {affiliate_reference_id: "4480ABC", hold: false, email: "john@example.com",...}, customer_ip: '127.0.0.1')
|
248
|
+
```
|
249
|
+
The link will be available in the Price Check response or in the register payments response when Two-Factor Authentication is used. It returns an itinerary id and links to retrieve reservation details, cancel a held booking, resume a held booking or complete payment session. Please note that depending on the state of the booking, the response will contain only the applicable link(s).
|
250
|
+
Method accept arguments:
|
251
|
+
- `path` A link to create booking, should be taken from `EpsRapid::Shopping.price_check` response under key `...{'links': {'book': {'href': 'create booking link'}` without EPS API version in the path.
|
252
|
+
Required: true.
|
253
|
+
- `body` Json object. Requirements check under `ItineraryRequestBody` in https://developer.expediapartnersolutions.com/documentation/rapid-booking-docs-2-4/#/Booking/post_itineraries
|
254
|
+
Required: true.
|
255
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
256
|
+
Required: true.
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
EpsRapid::Booking.resume_booking('itineraries/7562428514179?token=ABE3TYUj23', customer_ip: '127.0.0.1')
|
260
|
+
```
|
261
|
+
This link will be available in the booking response after creating a held booking.
|
262
|
+
Method accept arguments:
|
263
|
+
- `path` A link to resume booking, should be taken from `EpsRapid::Booking.create_booking` response under key `href` from `...{'links': [{'rel': 'resume', method: 'put', 'href': 'resume booking link'}]}` without EPS API version in the path.
|
264
|
+
Required: true.
|
265
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
266
|
+
Required: true.
|
267
|
+
|
268
|
+
```ruby
|
269
|
+
EpsRapid::Booking.complete_payment_session('itineraries/7562428514179/payment-sessions?token=ABE3TYUj23', customer_ip: '127.0.0.1')
|
270
|
+
```
|
271
|
+
This link will be available in the booking response only if you’ve opted into Two-Factor Authentication to comply with the September 2019 EU Regulations for PSD2.
|
272
|
+
Method accept arguments:
|
273
|
+
- `path` A link to complete payment session.
|
274
|
+
Required: true.
|
275
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
276
|
+
Required: true.
|
277
|
+
|
278
|
+
### Manage Booking API
|
279
|
+
The EPS Rapid Manage Booking API allows you to discover how to use the Retrieve, Change and Cancel API calls to manage existing itineraries.
|
280
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-manage-booking-docs-2-4/
|
281
|
+
#### Methods
|
282
|
+
```ruby
|
283
|
+
EpsRapid::ManageBooking.retrieve_bookings(email: 'test@example.com', affiliate_reference_id: '4480ABCQXCZS', customer_ip: '127.0.0.1')
|
284
|
+
```
|
285
|
+
This can be called directly without a token when an affiliate reference id is provided. It returns details about bookings associated with an affiliate reference id, along with cancel links to cancel the bookings.
|
286
|
+
Method accept arguments:
|
287
|
+
- `email` Email associated with the booking.
|
288
|
+
Required: true
|
289
|
+
- `affiliate_reference_id` The affilliate reference id value. This field supports a maximum of 28 characters.
|
290
|
+
Required: true.
|
291
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
292
|
+
Required: true.
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
EpsRapid::ManageBooking.retrieve_booking('7372514319381', token: 'ABDE34Tj', email: 'test@example.com', customer_ip: '127.0.0.1')
|
296
|
+
```
|
297
|
+
This call returns itinerary details and links to resume or cancel the booking.
|
298
|
+
Method accept arguments:
|
299
|
+
- `itinerary_id` This parameter is used only to prefix the token value - no ID value is used.
|
300
|
+
Required: true.
|
301
|
+
- `token` Provided as part of the link object and used to maintain state across calls. This simplifies each subsequent call by limiting the amount of information required at each step and reduces the potential for errors. Token values cannot be viewed or changed.
|
302
|
+
Required: false.
|
303
|
+
- `email` Email associated with the booking.
|
304
|
+
Required: true if the token is not provided the request.
|
305
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
306
|
+
Required: true.
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
EpsRapid::ManageBooking.cancel_held_booking('itineraries/7562428514179?token=ABE3TYUj23', customer_ip: '127.0.0.1')
|
310
|
+
```
|
311
|
+
This link will be available in a held booking response.
|
312
|
+
Method accept arguments:
|
313
|
+
- `path` A link to cancel held booking, should be taken from `retrieve` response under key `...{'links': {'cancel': {'href': 'cancel booking link'}` without EPS API version in the path.
|
314
|
+
Required: true.
|
315
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
316
|
+
Required: true.
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
EpsRapid::ManageBooking.cancel_room('itineraries/7372514319381/rooms/512dab07-c9b7-494c-a517-05763aed4768?token=QFlCEVhQR', customer_ip: '127.0.0.1')
|
320
|
+
```
|
321
|
+
This link will be available in the retrieve response.
|
322
|
+
Method accept arguments:
|
323
|
+
- `path` A link to cancel room booking, should be taken from `retrieve` response under key `...{'links': {'cancel': {'href': 'cancel room link'}` without EPS API version in the path.
|
324
|
+
Required: true.
|
325
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
326
|
+
Required: true.
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
EpsRapid::ManageBooking.change_room('itineraries/7372514319381/rooms/512dab07-c9b7-494c-a517-05763aed4768?token=QFlCEVhQR', {given_name: 'Jhon', family_name: 'Smith', ...}, customer_ip: '127.0.0.1')
|
330
|
+
```
|
331
|
+
This link will be available in the retrieve response. Changes in smoking preference and special request will be passed along to the property and are not guaranteed.
|
332
|
+
Method accept arguments:
|
333
|
+
- `path` A link to cancel room booking, should be taken from `retrieve` response under key `...{'links': {'change': {'href': 'cancel room link'}` without EPS API version in the path.
|
334
|
+
Required: true.
|
335
|
+
- `body` Json object. Requirements check under `RoomDetailsRequestBody` in https://developer.expediapartnersolutions.com/documentation/rapid-manage-booking-docs-2-4/#/Manage_Bookings/put_itineraries__itinerary_id__rooms__room_id_
|
336
|
+
Required: true.
|
337
|
+
- `customer_ip` IP address of the customer, as captured by your integration. Send IPV4 addresses only. Ensure your integration passes the customer’s IP, not your own. This value helps determine their location and assign the correct payment gateway.
|
338
|
+
Required: true.
|
339
|
+
|
340
|
+
### Recommendations API
|
341
|
+
Data-driven personalized property recommendations.
|
342
|
+
https://developer.expediapartnersolutions.com/documentation/rapid-recommendations-2-4/
|
343
|
+
#### Methods
|
344
|
+
```ruby
|
345
|
+
EpsRapid::Recommendations.recommendations(checkin: '2021-05-20', checkout: '2021-05-22', destination_iata_airport_code: 'SEA', currency: 'USD', country_code: 'US', occupancy: '2', sales_channel: 'website', sales_environment: 'hotel_package', rate_plan_count: 1)
|
346
|
+
```
|
347
|
+
Calculates recommended properties based on the provided flight itinerary. Returns a sorted list of available properties; the first property in the response is the “strongest recommendation”. For each property, rates on available room types for properties is returned.
|
348
|
+
Method accept arguments:
|
349
|
+
- `checkin` Check-in date, in ISO 8601 format (YYYY-MM-DD).
|
350
|
+
Required: true.
|
351
|
+
- `checkout` Check-out date, in ISO 8601 format (YYYY-MM-DD). Availability can be searched up to 500 days in advance of this date. Total length of stay cannot exceed 28 nights.
|
352
|
+
Required: true.
|
353
|
+
- `destination_iata_airport_code' 3-character IATA airport code of the destination airport. The code must be upper case.
|
354
|
+
Required: true.
|
355
|
+
- `origin_iata_airport_code` 3-character IATA airport code of the origin airport. The code must be upper case.
|
356
|
+
Required: false.
|
357
|
+
- `cabin_class` The cabin class of the ticket. Use the highest cabin class if the journey inclues multiple cabin classes.
|
358
|
+
Accepted values:
|
359
|
+
1) `economy` - Economy cabin class.
|
360
|
+
2) `premium_economy` - Premium economy cabin class.
|
361
|
+
3) `business` - Business cabin class.
|
362
|
+
4) `first` - First cabin class.
|
363
|
+
Required: false.
|
364
|
+
- `iata_airline_code` 2-character IATA airline code.
|
365
|
+
Required: false.
|
366
|
+
- `arrival` Arrival date and time, in extended ISO 8601 format.
|
367
|
+
Required: false.
|
368
|
+
- `currency` Requested currency for the rates, in ISO 4217 format. Currency Options: https://developer.expediapartnersolutions.com/reference/currency-options/
|
369
|
+
Required: true.
|
370
|
+
- `country_code` The country code of the traveler’s point of sale, in ISO 3166-1 alpha-2 format. This should represent the country where the shopping transaction is taking place. For more information see: https://www.iso.org/obp/ui/#search/code/ .
|
371
|
+
Required: true.
|
372
|
+
- `occupancy` Defines the requested occupancy for a single room. Each room must have at least 1 adult occupant.
|
373
|
+
Format: `numberOfAdults[-firstChildAge[,nextChildAge]]`
|
374
|
+
To request multiple rooms (of the same type), include one instance of occupancy for each room requested. Up to 8 rooms may be requested or booked at once. Examples:
|
375
|
+
1) 2 adults, one 9-year-old and one 4-year-old would be represented by `occupancy=2-9,4`.
|
376
|
+
2) A multi-room request to lodge an additional 2 adults would be represented by `occupancy=2-9,4;occupancy=2`.
|
377
|
+
Required: true.
|
378
|
+
- `sales_channel` You must provide the sales channel for the display of rates. EPS dynamically provides the best content for optimal conversion on each sales channel. If you have a sales channel that is not currently supported in this list, please contact our support team.
|
379
|
+
1) `website` - Standard website accessed from the customer’s computer
|
380
|
+
2) `agent_tool` - Your own agent tool used by your call center or retail store agent
|
381
|
+
3) `mobile_app` - An application installed on a phone or tablet device
|
382
|
+
4) `mobile_web` - A web browser application on a phone or tablet device
|
383
|
+
5) `meta` - Rates will be passed to and displayed on a 3rd party comparison website
|
384
|
+
6) `cache` - Rates will be used to populate a local cache.
|
385
|
+
Required: true.
|
386
|
+
- `sales_environment` You must provide the sales environment in which rates will be sold. EPS dynamically provides the best content for optimal conversion. If you have a sales environment that is not currently supported in this list, please contact our support team.
|
387
|
+
1) `hotel_package` - Use when selling the hotel with a transport product, e.g. flight & hotel.
|
388
|
+
2) `hotel_only` - Use when selling the hotel as an individual product.
|
389
|
+
3) `loyalty` - Use when you are selling the hotel as part of a loyalty program and the price is converted to points.
|
390
|
+
Required: true.
|
391
|
+
- `filter` Single filter type. Send multiple instances of this parameter to request multiple filters.
|
392
|
+
1) `refundable` - Filters results to only show fully refundable rates.
|
393
|
+
2) `expedia_collect` - Filters results to only show rates where payment is collected by Expedia at the time of booking. These properties can be eligible for payments via Expedia Affiliate Collect(EAC).
|
394
|
+
3) `property_collect` - Filters results to only show rates where payment is collected by the property after booking. This can include rates that require a deposit by the property, dependent upon the deposit policies.
|
395
|
+
Required: false.
|
396
|
+
- `rate_plan_count` The number of rates to return per property. The rate’s price determines which rates are returned e.g. a rateplancount=4 will return the lowest 4 rates, but the rates are not ordered from lowest to highest or vice versa in the response. The lowest rate has been proven to provide the best conversion rate and so a value of 1 is recommended.
|
397
|
+
The value must be greater than 0.
|
398
|
+
Required: true.
|
399
|
+
- `rate_option` Request specific rate options for each property. Send multiple instances of this parameter to request multiple rate options.
|
400
|
+
Accepted values:
|
401
|
+
1) `member` - Return member rates for each property. This feature must be enabled and requires a user to be logged in to request these rates.
|
402
|
+
2) `net_rates` - Return net rates for each property. This feature must be enabled to request these rates.
|
403
|
+
3) `cross_sell` - Identify if the traffic is coming from a cross sell booking. Where the traveler has booked another service (flight, car, activities…) before hotel.
|
404
|
+
Required: false.
|
405
|
+
|
406
|
+
### Notifications API
|
407
|
+
EPS Notifications is a solution that lets you integrate with EPS more closely than ever. When changes occur that can impact your business, EPS will push details of the change directly to your systems via standard POST messages. With our push notifications, you can remain informed, simplify operations, and scale your business.
|
408
|
+
https://developer.expediapartnersolutions.com/documentation/notifications/
|
409
|
+
#### Methods
|
410
|
+
```ruby
|
411
|
+
EpsRapid::Notifications.test_notification_event('itinerary.agent.create')
|
412
|
+
```
|
413
|
+
This request triggers a test notification according to the specified event_type. All event types supported by the Notifications API are available to test.
|
414
|
+
Method accept one argument:
|
415
|
+
- `event_type` The event type of the requested test notification.
|
416
|
+
Required: true.
|
417
|
+
|
418
|
+
```ruby
|
419
|
+
EpsRapid::Notifications.undeliverable_notifications
|
420
|
+
```
|
421
|
+
This request returns any undelivered notifications for your subscription and test endpoints.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'eps-rapid'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/eps-rapid.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'lib/eps-rapid/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'eps-rapid'
|
5
|
+
spec.version = EpsRapid::VERSION
|
6
|
+
spec.authors = ['Igor Leonenko']
|
7
|
+
spec.email = ['igrleon@gmail.com']
|
8
|
+
|
9
|
+
spec.summary = 'Ruby wrapper for the expediapartnersolutions.com api '
|
10
|
+
spec.description = spec.summary
|
11
|
+
spec.homepage = 'https://github.com/advalley/eps-rapid'
|
12
|
+
spec.license = 'MIT'
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
14
|
+
|
15
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
16
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
17
|
+
spec.metadata['changelog_uri'] = 'https://github.com/advalley/eps-rapid/blob/main/CHANGELOG.MD'
|
18
|
+
|
19
|
+
# Specify which files should be added to the gem when it is released.
|
20
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
21
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
22
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
end
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
27
|
+
|
28
|
+
spec.add_development_dependency 'rspec'
|
29
|
+
spec.add_development_dependency 'rubocop', '~> 1.8.1'
|
30
|
+
end
|
data/lib/eps-rapid.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eps-rapid/version'
|
4
|
+
require 'eps-rapid/client'
|
5
|
+
require 'eps-rapid/errors/exceptions'
|
6
|
+
require 'eps-rapid/errors/http_status_codes'
|
7
|
+
require 'eps-rapid/geography'
|
8
|
+
require 'eps-rapid/content'
|
9
|
+
require 'eps-rapid/shopping'
|
10
|
+
require 'eps-rapid/booking'
|
11
|
+
require 'eps-rapid/manage_booking'
|
12
|
+
require 'eps-rapid/recommendations'
|
13
|
+
require 'eps-rapid/notifications'
|
14
|
+
require 'digest'
|
15
|
+
|
16
|
+
module EpsRapid
|
17
|
+
class << self
|
18
|
+
attr_accessor :api_key, :secret_key, :base_path, :language
|
19
|
+
|
20
|
+
def configure
|
21
|
+
yield(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def auth_header
|
25
|
+
timestamp = Time.now.to_i
|
26
|
+
to_be_hashed = "#{api_key}#{secret_key}#{timestamp}"
|
27
|
+
signature = Digest::SHA2.new(512).hexdigest(to_be_hashed)
|
28
|
+
"EAN apikey=#{api_key},signature=#{signature},timestamp=#{timestamp}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Booking
|
5
|
+
def self.register_payment(path, body, **params)
|
6
|
+
EpsRapid::Client.post(path, body, params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.create_booking(path, body, **params)
|
10
|
+
EpsRapid::Client.post(path, body, params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.resume_booking(path, **params)
|
14
|
+
EpsRapid::Client.put(path, params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.complete_payment_session(path, **params)
|
18
|
+
EpsRapid::Client.put(path, params)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/https'
|
4
|
+
require 'cgi'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module EpsRapid
|
8
|
+
class Client
|
9
|
+
class << self
|
10
|
+
def get(path, **params)
|
11
|
+
uri = generate_uri(path, params)
|
12
|
+
req = Net::HTTP::Get.new(uri)
|
13
|
+
test_header, customer_ip_header = additional_headers(params)
|
14
|
+
|
15
|
+
fetch_data(uri, req, test_header, customer_ip_header)
|
16
|
+
end
|
17
|
+
|
18
|
+
def post(path, body, **params)
|
19
|
+
uri = generate_uri(path, params)
|
20
|
+
req = Net::HTTP::Post.new(uri)
|
21
|
+
req.body = body.to_json
|
22
|
+
test_header, customer_ip_header = additional_headers(params)
|
23
|
+
|
24
|
+
fetch_data(uri, req, test_header, customer_ip_header)
|
25
|
+
end
|
26
|
+
|
27
|
+
def put(path, body = {}, **params)
|
28
|
+
uri = generate_uri(path, params)
|
29
|
+
req = Net::HTTP::Put.new(uri)
|
30
|
+
req.body = body.to_json
|
31
|
+
test_header, customer_ip_header = additional_headers(params)
|
32
|
+
|
33
|
+
fetch_data(uri, req, test_header, customer_ip_header)
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete(path, **params)
|
37
|
+
uri = generate_uri(path, params)
|
38
|
+
req = Net::HTTP::Delete.new(uri)
|
39
|
+
test_header, customer_ip_header = additional_headers(params)
|
40
|
+
|
41
|
+
fetch_data(uri, req, test_header, customer_ip_header)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def generate_uri(path, **params)
|
47
|
+
uri = URI("#{EpsRapid.base_path}/#{path}")
|
48
|
+
params.merge!({ language: EpsRapid.language })
|
49
|
+
transformed_params = transform_params(params)
|
50
|
+
transformed_params.delete(:customer_ip)
|
51
|
+
uri.query = URI.encode_www_form(transformed_params) unless path.include?('token')
|
52
|
+
|
53
|
+
uri
|
54
|
+
end
|
55
|
+
|
56
|
+
def transform_params(**params)
|
57
|
+
params.each do |k, v|
|
58
|
+
params[k] =
|
59
|
+
if k == :occupancy
|
60
|
+
v.to_s.tr(' ', '').split(';')
|
61
|
+
else
|
62
|
+
v.to_s.tr(' ', '').split(',')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def additional_headers(params)
|
68
|
+
test_header = params.key?(:test) ? params[:test] : ''
|
69
|
+
customer_ip_header = params.key?(:customer_ip) ? params[:customer_ip] : ''
|
70
|
+
|
71
|
+
[test_header, customer_ip_header]
|
72
|
+
end
|
73
|
+
|
74
|
+
def fetch_data(uri, req, test_header, customer_ip)
|
75
|
+
req['Authorization'] = EpsRapid.auth_header
|
76
|
+
req['Accept'] = 'application/json'
|
77
|
+
req['Content-Type'] = 'application/json'
|
78
|
+
req['Customer-Ip'] = customer_ip if customer_ip != ''
|
79
|
+
req['Test'] = test_header if test_header != ''
|
80
|
+
|
81
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
|
82
|
+
|
83
|
+
case response.code.to_i
|
84
|
+
when HttpStatusCodes::HTTP_OK_CODE, HttpStatusCodes::HTTP_CREATED_CODE
|
85
|
+
JSON.parse(response.body)
|
86
|
+
when HttpStatusCodes::HTTP_NO_CONTENT_CODE
|
87
|
+
'Code: 204, No content'
|
88
|
+
else
|
89
|
+
raise error_class(response.code), "Code: #{response.code}, Error: #{map_error_messages(response.body)}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def error_class(code)
|
94
|
+
case code.to_i
|
95
|
+
when HttpStatusCodes::HTTP_BAD_REQUEST_CODE
|
96
|
+
Exceptions::BadRequestError
|
97
|
+
when HttpStatusCodes::HTTP_UNAUTHORIZED_CODE
|
98
|
+
Exceptions::UnauthorizedError
|
99
|
+
when HttpStatusCodes::HTTP_FORBIDDEN_CODE
|
100
|
+
Exceptions::ForbiddenError
|
101
|
+
when HttpStatusCodes::HTTP_NOT_FOUND_CODE
|
102
|
+
Exceptions::NotFoundError
|
103
|
+
when HttpStatusCodes::HTTP_SESSION_GONE_CODE
|
104
|
+
Exceptions::SessionGoneError
|
105
|
+
when HttpStatusCodes::HTTP_UPGRADE_REQUIRED_CODE
|
106
|
+
Exceptions::UpgradeRequiredError
|
107
|
+
when HttpStatusCodes::HTTP_TOO_MANY_REQUESTS_CODE
|
108
|
+
Exceptions::TooManyRequestsError
|
109
|
+
else
|
110
|
+
Exceptions::EpsRapidError
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def map_error_messages(error_response)
|
115
|
+
errors = []
|
116
|
+
parsed_errors = JSON.parse(error_response)
|
117
|
+
|
118
|
+
if parsed_errors['errors']&.any?
|
119
|
+
parsed_errors['errors'].each do |error|
|
120
|
+
errors << error['message']
|
121
|
+
end
|
122
|
+
errors.join(' ')
|
123
|
+
else
|
124
|
+
parsed_errors['message']
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Content
|
5
|
+
def self.content_list(**params)
|
6
|
+
EpsRapid::Client.get('properties/content', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.guest_review(property_id)
|
10
|
+
EpsRapid::Client.get("properties/#{property_id}/guest-reviews")
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.catalog_file
|
14
|
+
EpsRapid::Client.get('files/properties/catalog')
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.content_file
|
18
|
+
EpsRapid::Client.get('files/properties/content')
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.chains
|
22
|
+
EpsRapid::Client.get('chains')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
module Exceptions
|
5
|
+
class EpsRapidError < StandardError; end
|
6
|
+
|
7
|
+
class BadRequestError < StandardError; end
|
8
|
+
|
9
|
+
class UnauthorizedError < StandardError; end
|
10
|
+
|
11
|
+
class ForbiddenError < StandardError; end
|
12
|
+
|
13
|
+
class NotFoundError < StandardError; end
|
14
|
+
|
15
|
+
class SessionGoneError < StandardError; end
|
16
|
+
|
17
|
+
class UpgradeRequiredError < StandardError; end
|
18
|
+
|
19
|
+
class TooManyRequestsError < StandardError; end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
module HttpStatusCodes
|
5
|
+
HTTP_OK_CODE = 200
|
6
|
+
HTTP_CREATED_CODE = 201
|
7
|
+
HTTP_NO_CONTENT_CODE = 204
|
8
|
+
HTTP_BAD_REQUEST_CODE = 400
|
9
|
+
HTTP_UNAUTHORIZED_CODE = 401
|
10
|
+
HTTP_FORBIDDEN_CODE = 403
|
11
|
+
HTTP_NOT_FOUND_CODE = 404
|
12
|
+
HTTP_SESSION_GONE_CODE = 410
|
13
|
+
HTTP_UPGRADE_REQUIRED_CODE = 426
|
14
|
+
HTTP_TOO_MANY_REQUESTS_CODE = 429
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Geography
|
5
|
+
def self.regions_list(**params)
|
6
|
+
params.merge!({ include: 'standard' }) if params[:include].nil?
|
7
|
+
EpsRapid::Client.get('regions', params)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.region(region_id, **params)
|
11
|
+
params.merge!({ include: 'details' }) if params[:include].nil?
|
12
|
+
EpsRapid::Client.get("regions/#{region_id}", params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create_polygon(body)
|
16
|
+
params = { include: 'property_ids' }
|
17
|
+
body =
|
18
|
+
{
|
19
|
+
type: 'Polygon',
|
20
|
+
coordinates: [body]
|
21
|
+
}
|
22
|
+
EpsRapid::Client.post('properties/geography', body, params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.map_includes(includes)
|
26
|
+
includes.gsub(' ', '').split(',')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class ManageBooking
|
5
|
+
def self.retrieve_bookings(**params)
|
6
|
+
EpsRapid::Client.get('itineraries', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.retrieve_booking(itinerary_id, **params)
|
10
|
+
EpsRapid::Client.get("itineraries/#{itinerary_id}", params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.cancel_held_booking(path, **params)
|
14
|
+
EpsRapid::Client.delete(path, params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.cancel_room(path, **params)
|
18
|
+
EpsRapid::Client.delete(path, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.change_room(path, body, **params)
|
22
|
+
EpsRapid::Client.put(path, body, params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Notifications
|
5
|
+
def self.test_notification_event(event)
|
6
|
+
EpsRapid::Client.get("notifications/#{event}")
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.undeliverable_notifications
|
10
|
+
EpsRapid::Client.get('notifications/undeliverable')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Recommendations
|
5
|
+
def self.recommendations(**params)
|
6
|
+
EpsRapid::Client.get('properties/availability', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.alternative_recommendations(**params)
|
10
|
+
EpsRapid::Client.get('properties/availability', params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EpsRapid
|
4
|
+
class Shopping
|
5
|
+
def self.availability(**params)
|
6
|
+
EpsRapid::Client.get('properties/availability', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.price_check(path, **params)
|
10
|
+
EpsRapid::Client.get(path, params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.payment_options(path, **params)
|
14
|
+
EpsRapid::Client.get(path, params)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.deposit_policies(path, **params)
|
18
|
+
EpsRapid::Client.get(path, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.additional_rates(path, **params)
|
22
|
+
EpsRapid::Client.get(path, params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eps-rapid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Igor Leonenko
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.8.1
|
41
|
+
description: Ruby wrapper for the expediapartnersolutions.com api
|
42
|
+
email:
|
43
|
+
- igrleon@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- ".rspec"
|
50
|
+
- ".rubocop.yml"
|
51
|
+
- ".travis.yml"
|
52
|
+
- CHANGELOG.MD
|
53
|
+
- Gemfile
|
54
|
+
- LICENSE
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/console
|
58
|
+
- bin/setup
|
59
|
+
- eps-rapid.gemspec
|
60
|
+
- lib/eps-rapid.rb
|
61
|
+
- lib/eps-rapid/booking.rb
|
62
|
+
- lib/eps-rapid/client.rb
|
63
|
+
- lib/eps-rapid/content.rb
|
64
|
+
- lib/eps-rapid/errors/exceptions.rb
|
65
|
+
- lib/eps-rapid/errors/http_status_codes.rb
|
66
|
+
- lib/eps-rapid/geography.rb
|
67
|
+
- lib/eps-rapid/manage_booking.rb
|
68
|
+
- lib/eps-rapid/notifications.rb
|
69
|
+
- lib/eps-rapid/recommendations.rb
|
70
|
+
- lib/eps-rapid/shopping.rb
|
71
|
+
- lib/eps-rapid/version.rb
|
72
|
+
homepage: https://github.com/advalley/eps-rapid
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata:
|
76
|
+
homepage_uri: https://github.com/advalley/eps-rapid
|
77
|
+
source_code_uri: https://github.com/advalley/eps-rapid
|
78
|
+
changelog_uri: https://github.com/advalley/eps-rapid/blob/main/CHANGELOG.MD
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 2.3.0
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubygems_version: 3.0.3
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Ruby wrapper for the expediapartnersolutions.com api
|
98
|
+
test_files: []
|