API Documentation 技術文件

Get api token

Using Simplybook API methods require an authentification. To authorize in Simplybook API you need to get an access key — access-token. In order to get this access-token you should call the JSON-RPC method getToken on http://user-api.simplybook.me/login service passing your personal API-key. You can copy your API-key at admin interface: go to the 'Plugins' link and select API plugin 'Settings'.

var token = loginClient.getToken(companyLogin, apiKey);

var loginClient = new JSONRpcClient({
	'url': 'https://user-api.simplybook.me/login',
	'onerror': function (error) {
		alert(error);
	}
});
var token = loginClient.getToken('{companyLogin}', '{apiKey}');
輸出結果
回應內容
HTTP 請求

Get event list

You have just received auth token. Now you need to create JSON RPC Client, set http headers and then use this client to get data from Simplybook server. To get services list use getEventList() function as it is shown in code example below.

var events = client.getEventList();

var client = new JSONRpcClient({
	'url': 'https://user-api.simplybook.me',
	'headers': {
		'X-Company-Login': '{companyLogin}',
		'X-Token': '{token}'
	},
	'onerror': function (error) {
		alert(error);
	}
});
var services = client.getEventList();
輸出結果
回應內容
HTTP 請求

Get performer list

Also you need to get list of all service performers. For this purpose use getUnitList() function.

var units = client.getUnitList();

var performers = client.getUnitList();
輸出結果
回應內容
HTTP 請求

Filter performers by service

Now let users select service and then performer. Please note that services can be attached to certain performer or can be provided by any performer from list. That is why you should filter performers before users make selection, use unit_map param in service object for this. See code example below.

// fetch service and performers selects here
var serviceId;
var performerId;
jQuery('#select_event_id').empty();
jQuery('#select_unit_id').empty();
jQuery('#select_event_id').append('<option value=""></option>');
jQuery('#select_unit_id').append('<option value=""></option>');
for (var id in services) {
    jQuery('#select_event_id').append('<option value="' + id + '">' + services[id].name + '</option>');
}
for (var id in performers) {
    jQuery('#select_unit_id').append('<option value="' + id + '">' + performers[id].name + '</option>');
}
jQuery('#select_event_id').change(function () {
	// service id
	serviceId = jQuery(this).val();
	var selectedService = services[serviceId];
	// filter available performers
	if (selectedService) {
		if (typeof(selectedService.unit_map) != 'undefined' && selectedService.unit_map.length) {
			jQuery('#select_unit_id option').attr('disabled', true);
			jQuery('#select_unit_id option[value=""]').attr('disabled', false);
			for (var i = 0; i < selectedService.unit_map.length; i++) {
				jQuery('#select_unit_id option[value="' + selectedService.unit_map[i] + '"]').attr('disabled', false);
			}
		} else {
			jQuery('#select_unit_id option').attr('disabled', false);
		}
	}
	jQuery('#eventId').val(serviceId).change();
});
jQuery('#select_unit_id').change(function () {
	performerId = jQuery(this).val();
});

Get closest day with available time slots

After user has selected service and perfomer you should get first working day for the selected performer and set it as datepicker active date. Use getFirstWorkingDay() function for this purpose.

var firstWorkingDay = client.getFirstWorkingDay(performerId);

var firstWorkingDay = client.getFirstWorkingDay(performerId);
輸出結果
回應內容
HTTP 請求

Disable not working time in calendar

Becides setting active date in your datepicker you also can disable dayoffs in it using data of work calendar. See how the getWorkCalendar() function works in code example.

workCalendar = client.getWorkCalendar(year, month, performerId);

// Init datepicker.
var workCalendar = {};
jQuery('#datepicker').datepicker({
	'onChangeMonthYear': function (year, month, inst) {
		workCalendar = client.getWorkCalendar(year, month, performerId);
		jQuery('#datepicker').datepicker('refresh');
	},
	'beforeShowDay': function (date) {
		var year = date.getFullYear();
		var month = ("0" + (date.getMonth() + 1)).slice(-2);
		var day = ("0" + date.getDate()).slice(-2);
		var date = year + '-' + month + '-' + day;
		if (typeof(workCalendar[date]) != 'undefined') {
			if (parseInt(workCalendar[date].is_day_off) == 1) {
				return [false, "", ""];
			}
		}
		return [true, "", ""];
	}
});
var firstWorkingDateArr = firstWorkingDay.split('-');
workCalendar = client.getWorkCalendar(firstWorkingDateArr[0], firstWorkingDateArr[1], performerId);

jQuery('#datepicker').datepicker('refresh');
輸出結果
回應內容
HTTP 請求

Get available time slots

When user has selected a date you can load time intervals when service is available to be booked. Use the getStartTimeMatrix() function to get list of start time of time slots.

var startMatrix = client.getStartTimeMatrix(from, to, eventId, unitId, count)

// Handle date selection
var count = 1; // How many slots book
function formatDate(date) {
	var year = date.getFullYear();
	var month = ("0" + (date.getMonth() + 1)).slice(-2);
	var day = ("0" + date.getDate()).slice(-2);
	
	return year + '-' + month + '-' + day;
}

function drawMatrix(matrix) {
	jQuery('#starttime').empty();
	
	for (var i = 0; i < matrix.length; i++) {
		jQuery('#starttime').append('<span data-time="' + matrix[i] + '">' + matrix[i] + '</span>');
	}
	jQuery('#starttime span').click(function () {
		startTime = jQuery(this).data('time');
		
		jQuery('#starttime span').removeClass('selected');
		jQuery(this).addClass('selected');
	});
}

jQuery('#datepicker').datepicker('option', 'onSelect', function () {
	var startDate = formatDate(jQuery(this).datepicker('getDate'));
	jQuery('#dateFrom, #dateTo').val(startDate);
	
	var startMatrix = client.getStartTimeMatrix(startDate, startDate, serviceId, performerId, count);
	
	drawMatrix(startMatrix[startDate]);
});
var startMatrix = client.getStartTimeMatrix(firstWorkingDay, firstWorkingDay, serviceId, performerId, count);
drawMatrix(startMatrix[firstWorkingDay]);
輸出結果
回應內容
HTTP 請求

Check if additional fields plugin is activated

Now check if additional fields plugin is active to define what should be shown to client in the next step. See isPluginActivated() function usage example.

var additionalFieldsActivated = client.isPluginActivated('event_field');

var additionalFieldsActivated = client.isPluginActivated('event_field');
輸出結果
回應內容
HTTP 請求

Get additional fields

If addtional fields plugin is active, you should load additional field list using getAdditionalFields() function and add them to client details form.

// load additional fields
var additionalFields = [];

function clearAdditionalFields() {
	jQuery('#additional-fields').empty();
	additionalFields = [];
}

function addAdditionalField(field) {
	var container = jQuery('<div class="form-group"></div>');
	var title = jQuery('<div class="control-label">' + field.title + '</div>');
			
	container.append(title);
			
	var fieldContainer = jQuery('<div class="field"></div>');
			
	container.append(fieldContainer);
			
	var fieldNode = null;
	switch (field.type) {
		case 'checkbox':
			fieldNode = jQuery('<input type="checkbox" name="' + field.name + '" id="' + field.name + '" value="1" />');
			if (field['default']) {
				fieldNode.attr('checked', true);
			}
			break;
		case 'select':
			fieldNode = jQuery('<select class="select select2" name="' + field.name + '" id="' + field.name + '"></select>');
			var values = field.values.split(',');
			for (var k = 0; k < values.length; k++) {
				fieldNode.append(jQuery('<option value="' + values[k].trim() + '">' + values[k].trim() + '</option>'));
			}
			if (field['default']) {
				fieldNode.val(field['default']);
			}
			break;
		case 'textarea':
			fieldNode = jQuery('<textarea name="' + field.name + '" id="' + field.name + '"></textarea>');
			if (field['default']) {
				fieldNode.val(field['default']);
			}
			break;
		default:
			fieldNode = jQuery('<input type="text" name="' + field.name + '" id="' + field.name + '" />');
			if (field['default']) {
				fieldNode.val(field['default']);
			}
			break;
	}
	if (fieldNode) {
		if (field.type == 'checkbox') {
			fieldNode.addClass('checkbox');
		} else {
			fieldNode.addClass('form-control');
		}
		fieldContainer.append(fieldNode);
		jQuery('#additional-fields').append(container);
	}
}

if (additionalFieldsActivated) {
	clearAdditionalFields();
	additionalFields = client.getAdditionalFields(serviceId);
	for (var i = 0; i < additionalFields.length; i++) {
		addAdditionalField(additionalFields[i]);
	}
}
輸出結果
回應內容
HTTP 請求

Perform booking

After client has filled his information into additional fields you should start booking process by calling book() method.

// Collect client data
var clientData = {
	'name': jQuery('#clientName').val(),
	'email': jQuery('#clientEmail').val(),
	'phone': jQuery('#clientPhone').val()
};
// Collect additional fields
var additionalFieldValues = {};
jQuery('#additional-fields input, #additional-fields select, #additional-fields textarea').each(function () {
	var val = '';
	if (jQuery(this).attr('type') == 'checkbox') {
		if (jQuery(this).is(':checked')) {
			val = 1;
		} else {
			val = 0;
		}
	} else {
		val = jQuery(this).val();
	}
	additionalFieldValues[jQuery(this).attr('name')] = val;
});
var count = 1;

var result = client.book(serviceId, performerId, startDate, startTime, clientData, additionalFieldValues, count);
輸出結果
回應內容
HTTP 請求

Summary

It was simple example how you can use Simplybook API. Check out all available API methods here. Feel free to contact us and ask any questions.

Thank you for reading!

為何數以千計的客戶都選擇使用 SimplyBook.me 的 API 呢?

簡單俐落的介面,輕鬆打造專屬的預約系統

輕鬆的加入所有需要的客製化功能

線上預約即時更新 - 您的顧客可以 24 小時不分日夜預約您的服務。

我們整合多種實用功能,打造專屬預約管理 App 應用,點擊這裡查看更多 相關預約管理功能

開發人員

保持完善的顧客體驗,讓顧客在瀏覽您的服務時,即可直接預約您提供的服務!

提供您的客戶發現在地商家時會想採取的動作,藉此讓您的網站或應用程式更加貼切、迷人、更有效益。我們的 API 讓您輕鬆在您的網頁上直接添加一個「現在預約」的按鈕,以讓您的客戶能夠不分日夜做即時預約。 我們提供一個更妥善、適切及有效的方式,讓您的顧客在瀏覽您的網站或 APP 時,能夠直接預約您的服務,不用再被引導到其他網頁來輸入資料。SimplyBook.me 提供完整的 API 串接,您可以在既有的官網中加入「立即預約」的按鈕,讓顧客隨時隨地預約您的服務。

我的的 API 提供您所需的預約數據存取權限,讓您架構並客製化合適的線上預約系統。

藉由將顧客連結至您的營業時間表,我們會創造一個全新的交易層面。我們相信直接在您的應用程式或網站上預約將允許我們提供您實際的有效顧客,而不僅是潛在顧客。