Skip to content

Commit

Permalink
Guides
Browse files Browse the repository at this point in the history
  • Loading branch information
smily-ivan committed Aug 3, 2023
1 parent db9139a commit c5e3637
Show file tree
Hide file tree
Showing 13 changed files with 935 additions and 34 deletions.
47 changes: 47 additions & 0 deletions content/guides/accounts-synchronization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Accounts synchronization

1. TOC
{:toc}

## Preface

With this endpoint you can import all accounts who wants to publish their listings on your website. As a next step you can sign a contracts with these accounts if needed, create accounts on your side, etc.

## Get all accounts

You can find detailed specification in [Swagger documentation](https://demo.platforms.bookingsync.com/api-docs/index.html)

> This endpoint does not support pagination.
> Don't forget to disable accounts and their rentals if you don't see them anymore in current list
> We suggest to do synchronization of accounts every 12-24 hours.
~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}"
}
}
request = Excon.new(URI.join(api_url, "/api/ota/v1/accounts").to_s, options)
response = request.request({ method: :get })

response.status

already_import_accounts_ids = get_imported_accounts_ids # get an array of already imported accounts, Ex result: [1,2,3]

json = JSON.parse(response.body)
json["data"].each do |account|
# Import accounts
import_account(account["id"], account["attributes"]["name"])
end

accounts_for_disabling = already_import_accounts_ids - json["data"].pluck("id")
disable_accounts_and_rentals(accounts_for_disabling) # Disable accounts
~~~
40 changes: 40 additions & 0 deletions content/guides/api-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Smily Channel API Overview

1. TOC
{:toc}

## What is Smily Channel API?

Channel API allows you to sync Smily properties to your own website (aka Channel). You can choose which properties or accounts to display or not, get rentals availabilities, book rentals and collect payments.

## Who is Smily Channel API for?

TODO

## Why would I use Smily Channel API?

This API was developed to make integration with our partners easier. If you want to look at all features of our system, please refer to [BookingSync Universe API ](https://developers.bookingsync.com/).

## How the Smily Channel API works?

In general, there are 3 steps you have to do:

1. Manage accounts that are ready to publish their listings on your website - regularly refresh the list and onboard them.
2. Manage rentals of onboarded accounts - regularly refresh descriptions, prices and availabilities.
3. Manage bookings. This step depends on how you want to process the payments - on your side, or on our side.


The API is fully [JSONAPI 1.0 compliant](http://jsonapi.org).

1. Get accounts
2. approve/reject them
3. sign contracts/register/oboarding/etc
4. get rentals of approved accounts
4.1 Get rentals info (refresh once a day)
4.2 Get rentals availabilities (refresh every hour)
4.3 Get rentals prices (every 12 hours)
4.4 Remove unpublished rentals
5. Booking creation:
5.1 Create quote to confirm price and availability.
5.2 Create booking with price not less than in quote response
5.4 Create payment to confirm booking
86 changes: 86 additions & 0 deletions content/guides/booking-cancelation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Booking cancelation

1. TOC
{:toc}

## Preface

Bookings could be canceled according to the rental's cancelation policy. You can get cancelation policy from rental's enpoint, usually it looks like:

~~~js
"cancelation-policy-items": [
{
"id": "1",
"penalty-percentage": 10,
"eligible-days": 2,
"message-translations": {
"en": "Lorem ipsum",
"fr": "Lorem ipsum"
}
}
]
~~~

In this case you can cancel the booking not later than 2 days before check-in. And penalty will be 10% from the booking final price.

## Booking cancelation

You can find detailed specification in [Swagger documentation](https://demo.platforms.bookingsync.com/api-docs/index.html)

~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}"
}
}

request = Excon.new(URI.join(api_url, "/bookings/#{booking_id}/cancel").to_s, options)
payload = {
data: {
attributes: {
"cancelation-reason": "canceled_by_traveller_other",
"cancelation-description": "health concern",
"channel-cancelation-cost": "80.0",
"currency": "USD"
},
type: "bookings",
id: booking_id
}
}
response = request.request({
method: :patch,
body: payload.to_json
})

json = JSON.parse(response.body)
if response.status == 200
booking_canceled_at = json["data"]["attributes"]["canceled-at"]
# update new booking information
else
handle_errors(json)
end
~~~

In some cases you can get a 422 error. Response will look like this:

~~~js
{
"errors" => [
{
"code" => "100",
"detail" => "currency - provided currency for cancelation must be the same as the one from booking",
"source" => {
"pointer" => "/data/attributes/currency"
},
"status" => "422",
"title" => "provided currency for cancelation must be the same as the one from booking"
}
]
}
~~~
160 changes: 160 additions & 0 deletions content/guides/create-a-booking-payments-on-partner-side.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Create a booking and handle payment on partner's side

1. TOC
{:toc}

## Preface

There are 2 ways of handling payments: using Smily payment gateway or process payment on partner side. This document explains second option - how to handle payments on partner's side.

## Create a quote

Before creating a booking, you have to confirm the price and availability of rental. To do that, you have to create a quote.

~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}"
}
}

request = Excon.new(URI.join(api_url, "/api/ota/v1/quotes").to_s, options)
payload = {
data: {
attributes: {
"start-at": "2023-08-04",
"end-at": "2023-08-11",
"adults": 20,
"children": 0,
"rental-id": 428
},
type: "quotes"
}
}
response = request.request({
method: :post,
body: payload.to_json
})

json = JSON.parse(response.body)
if response.status == 201
price = json["data"]["attributes"]["final-price"]
booking_url = json["data"]["attributes"]["booking-url"]
# Now you can create booking via API or redirect user to booking_url
else
handle_errors(json)
end
~~~

## Create a booking

Once you have successfully created a Quote, you can make a booking request. To do that you have to provide all information about the client, dates, rental ID and price.

> Price should not be less than `final-price` you got from Quote request
~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}",
"Idempotency-Key" => get_order_uuid # optional but useful header, read comments below
}
}

request = Excon.new(URI.join(api_url, "/api/ota/v1/bookings").to_s, options)
payload = {
data: {
attributes: {
"start-at": "2020-09-04T16:00:00.000Z", # "2020-09-04" works too
"end-at": "2020-09-11T10:00:00.000Z", # "2020-09-11" works too
"adults": 2,
"children": 1,
"final-price": "176.0",
"currency": "EUR",
"rental-id": 1,
"client-first-name": "Rich",
"client-last-name": "Piana",
"client-email": "[email protected]",
"client-phone-number": "123123123",
"client-country-code": "US"
},
type: "quotes"
}
}
response = request.request({
method: :post,
body: payload.to_json
})

json = JSON.parse(response.body)
if response.status == 201
booking_id = json["data"]["id"]
# save this booking id
else
handle_errors(json)
end
~~~

TODO: confirm it
If created booking has field `tentative-expires-at`, it means it could be canceled automatically if you won't create any payment. So, as a next step, we have to create payments.

We recommend to always set `Idempotency-Key` header. This header allow to avoid duplicates creation. For example if you tried to create a booking and because of network connection or some other error you could not get response, you can safely retry your request and get the correct response, because for a given key, every success response will be cached for 6 hours.
We recommend to generate UUID for each order and use it in `Idempotency-Key` header.

## Create a payment

When you handled payment for the booking, you have to notify our us about that. Otherwise booking could be canceled.

~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}",
"Idempotency-Key" => get_payment_uuid # optional but useful header, read comments below
}
}

request = Excon.new(URI.join(api_url, "/api/ota/v1/payments").to_s, options)
payload = {
data: {
attributes: {
"amount": "100.0",
"currency": "EUR",
"paid-at": "2020-09-10T05:30:18.321Z",
"kind": "credit-card",
"booking-id": booking_id
},
type: "payments"
}
}
response = request.request({
method: :post,
body: payload.to_json
})

json = JSON.parse(response.body)
if response.status == 201
booking_id = json["data"]["id"]
# save this booking id
else
handle_errors(json)
end
~~~

Payments endpoint also support `Idempotency-Key` header. To ensure idempotent writes and frictionless integration, it is highly recommended to provide `Idempotency-Key` header. For a given key, every success response will be cached for 6 hours. Thanks to that, you can safely retry write operation.
55 changes: 55 additions & 0 deletions content/guides/create-a-booking-with-smily-payment-gateway.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Create a booking and handle payments with Smily payment gateway

1. TOC
{:toc}

## Preface

There are 2 ways of handling payments: using Smily payment gateway or process payment on partner side. This document explains first option - how to handle payments with Smily payment gateway.

## Create a quote

Before creating a booking, you have to confirm the price and availability of rental. To do that, you have to create a quote.

~~~ruby
token = "<YOUR_TOKEN>"
api_url = "<API_URL>"
media_type = "application/vnd.api+json"
options = {
headers: {
"User-Agent" => "Api client",
"Accept" => media_type,
"Content-Type" => media_type,
"Authorization" => "Bearer #{token}"
}
}

request = Excon.new(URI.join(api_url, "/api/ota/v1/quotes").to_s, options)
payload = {
data: {
attributes: {
"start-at": "2023-08-04",
"end-at": "2023-08-11",
"adults": 20,
"children": 0,
"rental-id": 428
},
type: "quotes"
}
}
response = request.request({
method: :post,
body: payload.to_json
})

json = JSON.parse(response.body)
if response.status == 201
price = json["data"]["attributes"]["final-price"]
booking_url = json["data"]["attributes"]["booking-url"]
# Now you can create booking via API or redirect user to booking_url
else
handle_errors(json)
end
~~~

If you don't have own payment gateway, you can just redirect user to `booking_url`. That's it :)
Loading

0 comments on commit c5e3637

Please sign in to comment.