API Reference

Hướng dẫn API (Liên kết đặt chỗ đối tác)

Xác thực

API GOVIGO dùng xác thực bằng API key. Hãy thêm header X-API-Key vào mọi yêu cầu.

Ví dụ header yêu cầu
GET /api/golf-clubs/plans.php?golf_club_id=1 HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
API key được cấp từ trang quản trị. Mỗi key có các scope (quyền); hãy dùng key được cấp scope phù hợp với thao tác cần thiết. Đối tác đặt chỗ được cấp key loại partner.

Các scope khả dụng:

ScopeMô tả
golf_clubs:readXem thông tin sân golf / gói
tee_times:readXem tình trạng trống / lịch giá
reservations:readXem báo giá / thông tin đặt chỗ
reservations:writeTạo / sửa / hủy đặt chỗ
webhooks:read / webhooks:writeXem/quản lý Webhook (thông báo cho các đặt chỗ của chính bạn) (mô tả sau)

Định dạng phản hồi chung

Tất cả phản hồi API được trả về theo định dạng chung sau.

{
  "success": true,
  "data": { ... },
  "message": "",
  "http_code": 200
}
TrườngKiểuMô tả
successbooleantrue khi thành công, false khi thất bại
dataobject|nullDữ liệu phản hồi (null khi lỗi)
messagestringThông điệp (nội dung lỗi khi có lỗi)
http_codeintegerMã trạng thái HTTP

Mã lỗi

Mã HTTPÝ nghĩaMô tả
400Bad RequestTham số yêu cầu không hợp lệ
401UnauthorizedAPI key không hợp lệ hoặc thiếu
403ForbiddenThiếu scope
404Not FoundTài nguyên không tồn tại (hoặc không có quyền)
405Method Not AllowedPhương thức HTTP không hợp lệ
409ConflictXung đột tài nguyên (đặt trùng, trạng thái không sửa được, v.v.)
429Too Many RequestsVượt giới hạn tần suất
500Internal Server ErrorLỗi nội bộ máy chủ

Tra cứu & phân quyền đặt chỗ

Có thể tham chiếu đặt chỗ bằng hai khóa.

KhóaMô tả
reservation_id / idID đặt chỗ nội bộ GOVIGO (số nguyên). Được trả về trong phản hồi.
external_refID tham chiếu đặt chỗ của hệ thống đối tác (chuỗi). Nếu truyền khi tạo, sau đó có thể tra cứu / sửa / hủy bằng ID của chính bạn. Khuyến nghị dùng.
Phân quyền (quan trọng): API key áp dụng phạm vi chủ sở hữu. Key đối tác chỉ tham chiếu / thao tác được trên các đặt chỗ do chính nó tạo. Chỉ định ID đặt chỗ của bên khác sẽ trả về 404 Not Found. Hãy giữ external_ref duy nhất trong cùng một đối tác (trùng sẽ trả về đặt chỗ hiện có).

Kiểm tra kết nối

GET /api/ping.php any

Kiểm tra tính hợp lệ của API key, chủ sở hữu, scope được cấp và giới hạn tần suất. Dùng để kiểm tra kết nối ban đầu (không cần scope).

Ví dụ phản hồi
{
  "success": true,
  "data": {
    "authenticated": true,
    "owner": { "type": "partner", "id": 3, "name": "Partner A" },
    "key_prefix": "a1b2c3d4",
    "scopes": ["golf_clubs:read", "tee_times:read", "reservations:read", "reservations:write"],
    "rate_limit": 120,
    "expires_at": null,
    "server_time": "2026-06-01T10:00:00+07:00"
  },
  "message": "pong",
  "http_code": 200
}

Thông tin sân golf & gói

GET /api/golf-clubs/detail.php golf_clubs:read

Lấy thông tin chi tiết sân golf. Bỏ qua id để trả về danh sách.

Tham sốKiểuBắt buộcMô tả
idintegerTùy chọnID sân golf
countryintegerTùy chọnMã quốc gia (0=Việt Nam, 1=Thái Lan, 2=Nhật Bản). Hiện chỉ cung cấp Việt Nam (0) (các quốc gia khác không trả về kết quả)
langstringTùy chọnNgôn ngữ trả về: ja (mặc định) / en / vi / kr / cn. Giá trị khác trả về 400
updated_sincestringTùy chọnThời điểm ISO 8601 (ví dụ 2026-10-01T00:00:00Z). Chỉ trả về các sân có updated_at từ thời điểm này trở đi (không có = count: 0)
Ví dụ phản hồi (lang=en)
{
  "success": true,
  "data": {
    "lang": "en",
    "count": 1,
    "golf_clubs": [
      {
        "id": 1,
        "name": "Sample Golf Club",
        "area": "Central (Da Nang / Hue)",
        "area_code": 3,
        "country": 0,
        "address": "Xa Loc Vinh, Phu Loc, Hue, Viet Nam",
        "google_map": "https://maps.google.com/...",
        "latitude": 16.3312358,
        "longitude": 107.9558334,
        "phone": "+842343695880",
        "opening_hours": "05:30-18:00",
        "description": "Located about an hour's drive from Da Nang ...",
        "access": null,
        "courses": [
          { "name": "Lagoon Course", "holes": 18, "par": 71, "length_yards": 7101, "designer": "Sir Nick Faldo" }
        ],
        "course_info": "18 holes, Par 71 / 7,101 yards",
        "remark": "Located about an hour's drive from Da Nang ...",
        "opened_on": "2013-03-01",
        "dress_code": "Collared shirts required ...",
        "cancel_policy": "Free cancellation up to 9 days before tee time ...",
        "main_image": {
          "url": "https://govigolf.com/images/golf_club_top_picture/xxx.jpg",
          "thumbnail_url": "https://govigolf.com/images/golf_club_picture/thumb/xxx.jpg"
        },
        "images": [
          { "url": "https://govigolf.com/images/golf_club_picture/yyy.jpg",
            "thumbnail_url": "https://govigolf.com/api/golf-clubs/thumbnail.php?src=..." }
        ],
        "facilities": {
          "driving_range": { "available": true,  "note": null },
          "pro_shop":      { "available": true,  "note": null },
          "restaurant":    { "available": true,  "note": null },
          "lesson":        { "available": false, "note": null },
          "night_golf":    { "available": false },
          "note": null
        },
        "updated_at": "2026-08-18T09:30:40Z",
        "rental": {
          "club_available": true,
          "club_fee": 300000,
          "shoes_available": false,
          "shoes_fee": null
        },
        "options": {
          "rental_cart":      { "available": true,  "included": true,  "fee": null },
          "rental_umbrella":  { "available": false, "included": false, "fee": null },
          "caddy":            { "available": true,  "included": true,  "fee": null },
          "caddy_designate":  { "available": true,  "included": false, "fee": 200000 },
          "caddybag_storage": { "available": false, "included": false, "fee": null },
          "sent_caddybag":    { "available": false, "included": false, "fee": null },
          "accompany":        { "available": false, "included": false, "fee": null },
          "pickup":           { "available": false, "description": null }
        }
      }
    ]
  },
  "message": "Golf club information retrieved.",
  "http_code": 200
}
Ngôn ngữ: name / area / description / access / course_info / remark / dress_code / cancel_policy / facilities.note được trả về theo lang. Nếu chưa có bản dịch, hệ thống dùng ngôn ngữ thay thế theo thứ tự vi / kr / cn → en → ja, và en → ja (kr / cn hiện chủ yếu là tiếng Anh). address chỉ có cách ghi địa phương. facilities.*.note chỉ có tiếng Nhật nên chỉ trả về khi lang=ja.
Các trường chính
descriptionGiới thiệu sân golf.
accessThông tin đường đi (chỉ khi có đăng ký, nếu không là null).
coursesThông số từng sân (tên, số hố, par, tổng chiều dài theo yard, nhà thiết kế). Sân có nhiều course sẽ có nhiều mục. Chưa đăng ký là []; trường chưa đăng ký là null.
course_infoTổng quan sân (văn bản tự do). Số hố, par, chiều dài có thể được ghi ở đây kể cả khi courses trống. Nếu có cả hai thì trả về cả hai.
opening_hoursGiờ mở cửa (ví dụ 05:30-18:00; null nếu chưa đăng ký).
cancel_policyChính sách hủy dành cho khách hàng.
latitude / longitudeTọa độ (null nếu chưa có).
phoneSố điện thoại chính (null nếu không có).
opened_onNgày khai trương (YYYY-MM-DD, null nếu không rõ).
main_image / imagesẢnh chính và ảnh giới thiệu (tối đa 5). thumbnail_url là bản thu nhỏ (cạnh dài 480px). Không phân loại ảnh (sân, nhà câu lạc bộ…).
facilitiesCó hay không: sân tập, cửa hàng, nhà hàng, lớp học, chơi đêm.
updated_atThời điểm cập nhật mới nhất (UTC) của thông tin cơ bản, tọa độ, giới thiệu và thông số sân. Không bao gồm giá và gói (xem /api/golf-clubs/plans.php).
area / area_codeTên khu vực và mã khu vực (xem bảng dưới).
Mã khu vực (Việt Nam)
area_codejaenvi
0北部(ハノイ)North (Hanoi)Miền Bắc (Hà Nội)
1北部(ハイフォン)North (Hai Phong)Miền Bắc (Hải Phòng)
2北部(その他)North (Other)Miền Bắc (Khác)
3中部(ダナン・フエ)Central (Da Nang / Hue)Miền Trung (Đà Nẵng / Huế)
4中部(その他)Central (Other)Miền Trung (Khác)
5南部(ホーチミン)South (Ho Chi Minh City)Miền Nam (TP. Hồ Chí Minh)
6南部(その他)South (Other)Miền Nam (Khác)
7南部(ニャチャン)South (Nha Trang)Miền Nam (Nha Trang)
8南部(フーコック)South (Phu Quoc)Miền Nam (Phú Quốc)
rental (gậy / giày) là dịch vụ thuê có thể chỉ định làm tham số đặt chỗ trong API này (quote / create). options (xe điện, caddy, đưa đón…) chỉ là thông tin tham khảo (không đặt được qua API); trả về tình trạng cung cấp (available), có bao gồm trong mọi gói hay không (included) và phí (fee) để hiển thị và kiểm soát phía đối tác. included: true nghĩa là đã bao gồm trong giá gói, không tính thêm phí (xe điện và caddy ở hầu hết sân), nên fee là null. available: true với fee: null và included: false nghĩa là phí được báo giá riêng. rental chỉ là available: true khi đã có phí.
Sử dụng nội dung: Hình ảnh và nội dung giới thiệu có thể được hiển thị trên website và ứng dụng của Quý công ty chỉ nhằm mục đích nhận đặt chỗ qua GOVIGO.
GET /api/golf-clubs/plans.php golf_clubs:read

Lấy danh sách gói của sân golf. id lấy ở đây chính là golf_plan_id (bắt buộc) khi đặt chỗ.

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerBắt buộcID sân golf
datestringTùy chọnChỉ các gói hiệu lực vào ngày chỉ định (YYYY-MM-DD)
langstringTùy chọnNgôn ngữ trả về: ja (mặc định) / en / vi / kr / cn. Giá trị khác trả về 400
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "golf_club_id": 1,
    "lang": "ja",
    "count": 1,
    "plans": [
      {
        "id": 10,
        "source": "golf_plan",
        "name": "Gói ngày thường",
        "day_type": "weekday",
        "price_local": 1500000,
        "price_inbound": 2000000,
        "partner_price_local": 1450000,
        "partner_price_inbound": 1850000,
        "apply_period": { "from": "2026-01-01", "to": "2026-12-31" },
        "time_ranges": [{ "from": "06:00", "to": "10:00" }],
        "minimum_players": 1,
        "summary": "Gói ưu đãi chỉ ngày thường",
        "cancel_policy": "Hủy miễn phí đến 3 ngày trước",
        "rental_club_fee": 300000,
        "rental_shoes_fee": 100000
      }
    ]
  },
  "message": "",
  "http_code": 200
}
price_local là giá nội địa, price_inbound là giá inbound (khách thăm). Khi đặt / báo giá, giá tương ứng được áp dụng theo số người chơi từng loại (local / inbound, có thể trộn lẫn trong cùng một đặt chỗ). Đặt / báo giá được xác định theo partner_price_local / partner_price_inbound (giá đối tác). Chỉ các gói có bookable: true (source: golf_plan) mới đặt được. cancel_policy là chính sách hủy hiển thị cho khách: trả về chính sách riêng của gói nếu có, nếu không thì trả về chính sách hủy của sân golf. name / summary / cancel_policy được trả về theo ngôn ngữ lang. Nếu chưa có bản dịch, hệ thống dùng ngôn ngữ thay thế theo cùng thứ tự với /api/golf-clubs/detail.php (vi / kr / cn → en → ja, en → ja). Với cancel_policy, ở mỗi ngôn ngữ, quy định riêng của gói được ưu tiên, sau đó đến quy định của sân golf. time_ranges là các khung giờ tee time có thể đặt với gói này (tối đa 3, bao gồm hai đầu; mảng rỗng nghĩa là không giới hạn giờ). Nếu tee_time khi đặt nằm ngoài mọi khung giờ, yêu cầu trả về 409.

Tình trạng trống

GET /api/tee-times/available.php tee_times:read

Lấy các khung giờ tee trống cho ngày chỉ định. Nếu dùng khung giờ tee, truyền tee_time_slot_id khi đặt (tùy chọn).

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerBắt buộcID sân golf
datestringBắt buộcNgày (YYYY-MM-DD)
langstringTùy chọnNgôn ngữ trả về: ja (mặc định) / en / vi / kr / cn. Giá trị khác trả về 400
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "golf_club_id": 1,
    "date": "2026-03-15",
    "lang": "en",
    "is_closed": false,
    "count": 1,
    "slots": [
      {
        "slot_id": 101,
        "course_id": 3,
        "course_name": "Lake Course",
        "tee_date": "2026-03-15",
        "tee_time": "07:00",
        "total_slots": 4,
        "available_slots": 2,
        "allow_join": true,
        "plan": { "id": 10, "name": "Gói ngày thường", "price": 1500000 }
      }
    ]
  },
  "message": "",
  "http_code": 200
}
course_name và plan.name được trả về theo ngôn ngữ lang, dùng tên mà sân golf đã đăng ký cho từng ngôn ngữ. Nếu chưa có, hệ thống dùng tên thay thế theo thứ tự: vi / kr / cn → en → tên đã đăng ký, en → tên đã đăng ký.
GET /api/tee-times/min-prices.php tee_times:read

Lấy giá tối thiểu theo ngày trong tháng chỉ định (để hiển thị lịch).

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerBắt buộcID sân golf
yearintegerTùy chọnNăm (mặc định: năm nay)
monthintegerTùy chọnTháng (mặc định: tháng này)
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "golf_club_id": 1,
    "year": 2026,
    "month": 3,
    "prices": {
      "2026-03-01": 1500000,
      "2026-03-02": 1800000
    }
  },
  "message": "",
  "http_code": 200
}

Báo giá

GET /api/reservations/quote.php reservations:read

Lấy số tiền cuối cùng trước khi tạo đặt chỗ. API create tính lại bằng cùng logic nên khớp với báo giá này. Số tiền trả về là giá đối tác (giá thường trừ chiết khấu đối tác).

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerBắt buộcID sân golf
golf_plan_idintegerBắt buộcID gói (id từ plans)
local_playersintegerBắt buộc*Số người chơi theo giá nội địa
inbound_playersintegerBắt buộc*Số người chơi theo giá inbound (* phải có ít nhất một trong hai. Tổng 1-20. Có thể trộn lẫn)
datestringTùy chọnNgày chơi (YYYY-MM-DD). Nếu có, kiểm tra cả thời hạn áp dụng / ngày trong tuần của gói
tee_timestringTùy chọnGiờ tee time mong muốn (HH:MM). Nếu có, hệ thống kiểm tra cả khung giờ của gói (time_ranges trong plans); ngoài khung giờ trả về 409
rental_clubintegerTùy chọnSố bộ gậy thuê (chỉ ở sân có cung cấp)
rental_shoesintegerTùy chọnSố đôi giày thuê (chỉ ở sân có cung cấp)
Việc cho thuê gậy/giày khác nhau tùy từng sân golf. Kiểm tra tình trạng cung cấp và phí trước khi đặt qua /api/golf-clubs/detail.php (rental.club_available / shoes_available) hoặc /api/golf-clubs/plans.php (rental_club_fee / rental_shoes_fee; null = không cung cấp). Nếu chỉ định số lượng tại sân không cung cấp (chưa thiết lập phí) sẽ trả về lỗi 409 (không tạo báo giá/đặt chỗ với phí bằng 0).
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "plan_id": 10,
    "plan_name": "Gói ngày thường",
    "time_ranges": [{ "from": "06:00", "to": "10:00" }],
    "players": {
      "local":   { "count": 2, "regular_unit_price": 1500000, "discount_per_player": 50000, "unit_price": 1450000, "amount": 2900000 },
      "inbound": { "count": 2, "regular_unit_price": 2000000, "discount_per_player": 150000, "unit_price": 1850000, "amount": 3700000 }
    },
    "player_count": 4,
    "minimum_players": 1,
    "base_amount": 6600000,
    "rental": {
      "club_count": 2, "club_fee": 600000,
      "shoes_count": 0, "shoes_fee": 0,
      "subtotal": 600000
    },
    "currency": "VND",
    "total_amount": 7200000,
    "golf_club_id": 1
  },
  "message": "Quote calculated.",
  "http_code": 200
}
time_ranges trong phản hồi là các khung giờ có thể đặt của gói (giống plans).

Đặt chỗ

POST /api/reservations/create.php reservations:write

Tạo đặt chỗ mới. Thân yêu cầu là JSON. Số tiền (total_amount) được tính lại ở máy chủ từ golf_plan_id, nên không cần chỉ định trong yêu cầu.

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerBắt buộcID sân golf
golf_plan_idintegerBắt buộcID gói (id từ plans)
tee_datestringBắt buộcNgày chơi(YYYY-MM-DD)
customer_namestringBắt buộcTên người đặt
customer_emailstringBắt buộcEmail người đặt
customer_phonestringTùy chọnSĐT người đặt (nếu có sẽ lưu làm thông tin liên hệ của người đặt)
playersobjectBắt buộcSố người chơi theo loại giá {local?, inbound?} (có thể trộn lẫn; tổng 1-20)
tee_timestringBắt buộc*Giờ tee time mong muốn (HH:MM). * Bắt buộc với đặt chỗ thông thường không có tee_time_slot_id (bỏ trống trả về 400). Phải nằm trong khung giờ của gói (time_ranges trong plans); ngoài khung giờ trả về 409. Không dùng cho đặt chỗ theo khung giờ thời gian thực
tee_time_slot_idintegerTùy chọnNếu chỉ định, xác nhận tức thì theo khung real-time và phản ánh lên bảng giờ tee của sân golf (lấy qua available). Ngày của khung phải khớp với tee_date. Nếu bỏ qua, là đặt thường (yêu cầu)
optionsobjectTùy chọnThuê v.v. {rental_club, rental_shoes}
remarkstringTùy chọnGhi chú
attendeesarrayTùy chọnDanh sách người đi cùng ({name, email?, phone?})
external_refstringTùy chọnID tham chiếu đặt chỗ của đối tác (khuyến nghị, duy nhất)
Ví dụ yêu cầu
POST /api/reservations/create.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "golf_club_id": 1,
  "golf_plan_id": 10,
  "tee_date": "2026-03-15",
  "customer_name": "Taro Tanaka",
  "customer_email": "tanaka@example.com",
  "customer_phone": "090-1234-5678",
  "players": { "local": 2, "inbound": 2 },
  "options": { "rental_club": 2 },
  "external_ref": "EXT-2026-00500"
}
Ví dụ phản hồi (201 Created)
{
  "success": true,
  "data": {
    "reservation_id": 500,
    "status": 1,
    "golf_club_id": 1,
    "tee_date": "2026-03-15",
    "tee_time": "08:00",
    "player_count": 4,
    "players": { "local": 2, "inbound": 2 },
    "total_amount": 7200000,
    "source": "api_partner"
  },
  "message": "Reservation created successfully.",
  "http_code": 201
}
GET /api/reservations/list.php reservations:read

Lấy danh sách đặt chỗ (chỉ đặt chỗ do bạn tạo). Hỗ trợ phân trang.

Tham sốKiểuBắt buộcMô tả
golf_club_idintegerTùy chọnLọc theo ID sân golf
statusintegerTùy chọnMã trạng thái (1=đã yêu cầu, 2=sân đang xác nhận, 3=yêu cầu thanh toán, 4=đã thanh toán/xác nhận, 5=đang đổi lịch, 6=yêu cầu hủy, 7=đang hủy(không hoàn), 8=đang hủy(có hoàn), 9=hoàn tất, 10=hoàn tất(đã hủy))
date_fromstringTùy chọnNgày chơi bắt đầu (YYYY-MM-DD)
date_tostringTùy chọnNgày chơi kết thúc (YYYY-MM-DD)
pageintegerTùy chọnSố trang (mặc định: 1)
per_pageintegerTùy chọnSố mục mỗi trang (mặc định: 20, tối đa: 100)
sortstringTùy chọnTrường sắp xếp (tee_date / created)
orderstringTùy chọnThứ tự sắp xếp (asc / desc)
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "reservations": [
      {
        "id": 500,
        "golf_club_id": 1,
        "golf_club_name": "Sample Golf Club",
        "customer_name": "Taro Tanaka",
        "tee_date": "2026-03-15",
        "tee_time": "08:00",
        "player_count": 4,
        "players": { "local": 2, "inbound": 2 },
        "total_amount": 7200000,
        "status": "1.đã yêu cầu",
        "status_code": 1,
        "source": "api_partner",
        "external_ref": "EXT-2026-00500",
        "created_at": "2026-03-01 10:00:00"
      }
    ],
    "pagination": {
      "page": 1, "per_page": 20, "total_count": 1,
      "total_pages": 1, "has_next": false, "has_prev": false
    }
  },
  "message": "",
  "http_code": 200
}
GET /api/reservations/detail.php reservations:read

Lấy chi tiết đặt chỗ. Chỉ định id hoặc external_ref.

Tham sốKiểuBắt buộcMô tả
idintegermột trongID đặt chỗ GOVIGO
external_refstringmột trongID tham chiếu đối tác
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "reservation": {
      "id": 500,
      "golf_club_id": 1,
      "golf_club_name": "Sample Golf Club",
      "plan_id": 10,
      "plan_name": "Gói ngày thường",
      "customer_name": "Taro Tanaka",
      "customer_email": "tanaka@example.com",
      "customer_phone": "090-1234-5678",
      "tee_date": "2026-03-15",
      "tee_time": "08:00",
      "player_count": 4,
      "players": { "local": 2, "inbound": 2 },
      "total_amount": 7200000,
      "remark": null,
      "options": { "rental_club": 2, "rental_shoes": 0 },
      "status": "1.đã yêu cầu",
      "status_code": 1,
      "source": "api_partner",
      "external_ref": "EXT-2026-00500",
      "created_at": "2026-03-01 10:00:00",
      "updated_at": "2026-03-01 10:00:00",
      "attendees": [
        { "name": "Hanako Sato", "email": null, "phone": null }
      ]
    }
  },
  "message": "",
  "http_code": 200
}
POST /api/reservations/update.php reservations:write

Cập nhật đặt chỗ. Chỉ cập nhật các trường được chỉ định. Nếu players / options thay đổi, total_amount được tính lại ở máy chủ. players được hiểu giống như khi tạo đặt chỗ: các loại bị bỏ qua được coi là 0 người (luôn chỉ định số người cho tất cả các loại). Với đặt real-time, thay đổi tổng số người cũng điều chỉnh tồn kho phía sân golf. Đặt chỗ đã hủy (status=6-8) / hoàn tất (status=9,10) không thể sửa.

Tham sốKiểuBắt buộcMô tả
reservation_id / external_refinteger/stringBắt buộc (một trong)Khóa tham chiếu của đặt chỗ mục tiêu
playersobjectTùy chọnSố người chơi theo loại giá {local?, inbound?} (tính lại tổng tiền; các loại bị bỏ qua được coi là 0)
optionsobjectTùy chọnThuê v.v. (tính lại tiền khi đổi)
customer_name / customer_email / customer_phonestringTùy chọnThông tin người đặt
tee_datestringTùy chọnNgày chơi(YYYY-MM-DD). Đặt real-time (có tee_time_slot_id) không thể thay đổi (hãy hủy rồi tạo lại)
remarkstringTùy chọnGhi chú
attendeesarrayTùy chọnNgười đi cùng (thay toàn bộ nếu chỉ định)
Ví dụ yêu cầu
POST /api/reservations/update.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "external_ref": "EXT-2026-00500",
  "players": { "local": 2, "inbound": 1 },
  "remark": "Hủy 1 người"
}
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "reservation_id": 500,
    "golf_club_id": 1,
    "plan_id": 10,
    "player_count": 3,
    "players": { "local": 2, "inbound": 1 },
    "total_amount": 5350000,
    "status": "1.đã yêu cầu",
    "status_code": 1,
    "external_ref": "EXT-2026-00500",
    "updated_at": "2026-03-02 09:00:00"
  },
  "message": "Reservation updated.",
  "http_code": 200
}
POST /api/reservations/cancel.php reservations:write

Hủy đặt chỗ. Chỉ định reservation_id hoặc external_ref. Giống đặt chỗ hội viên, được tiếp nhận như yêu cầu hủy (status=6) và nhân viên xác nhận. Tồn kho khung real-time được khôi phục khi hủy được xác nhận (không khôi phục ở thời điểm yêu cầu). Đặt chỗ đang hủy (status=6-8) / hoàn tất (status=9,10) không thể hủy.

Tham sốKiểuBắt buộcMô tả
reservation_id / external_refinteger/stringBắt buộc (một trong)Khóa tham chiếu của đặt chỗ mục tiêu
reasonstringTùy chọnLý do hủy
Ví dụ yêu cầu
POST /api/reservations/cancel.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "external_ref": "EXT-2026-00500",
  "reason": "Do thay đổi lịch"
}
Ví dụ phản hồi
{
  "success": true,
  "data": {
    "reservation_id": 500,
    "status": "cancel_requested",
    "status_code": 6,
    "cancelled_at": "2026-03-02T10:00:00+07:00"
  },
  "message": "Reservation cancelled successfully.",
  "http_code": 200
}

Webhook

Cơ chế thông báo cho hệ thống của bạn về thay đổi trạng thái của các đặt chỗ do chính bạn (đối tác) tạo. Mọi đặt chỗ tạo bằng API key của bạn đều được áp dụng, bất kể sân golf nào (không cần golf_club_id). Thông báo gửi qua HTTPS POST khi có sự kiện.

Sự kiện khả dụng:
reservation.created (tạo) / reservation.updated (thay đổi nội dung: số người, tùy chọn...) / reservation.status_changed (chuyển trạng thái) / reservation.cancelled (hủy) / *(tất cả sự kiện)
Khác biệt giữa reservation.cancelled và reservation.status_changed:
reservation.status_changed phát ra ở mọi lần chuyển trạng thái (payload gồm old_status / new_status). reservation.cancelled là sự kiện tiện lợi phát ra thêm khi đặt chỗ đạt trạng thái hủy đã xác nhận (status 10 = confirmed cancellation) — không phát ra khi mới chỉ là yêu cầu hủy (status 6), vì yêu cầu vẫn có thể bị từ chối. Do đó khi hủy đã xác nhận sẽ phát cả hai. Để theo dõi việc hủy từ giai đoạn yêu cầu, hãy theo dõi reservation.status_changed với new_status=6.
Danh sách trạng thái (status / *_status_label)
MãLabelMô tả
1requestedYêu cầu đặt sân
2confirmingĐang xác nhận với sân golf
3payment_waitingChờ thanh toán
4paidĐã xác nhận thanh toán. Khi schedule_confirmed là false, giờ tee time chưa được giữ (chỉ xác nhận thanh toán); true khi lịch đã xác định
5reschedule_requestedĐang cập nhật thông tin đặt sân
6cancel_requestedYêu cầu hủy
7cancelling_no_refundĐang hủy (không hoàn tiền)
8cancelling_with_refundĐang hủy (có hoàn tiền)
9completedHoàn tất (đã chơi)
10cancelledHoàn tất (đã hủy)
POST /api/webhooks/subscribe.php webhooks:write

Đăng ký URL nhận Webhook. Phạm vi gửi tự động giới hạn ở các đặt chỗ do bạn tạo.

Tham sốKiểuBắt buộcMô tả
urlstringBắt buộcURL nhận Webhook (bắt buộc HTTPS)
eventsarrayBắt buộcLoại sự kiện đăng ký
Ví dụ yêu cầu
POST /api/webhooks/subscribe.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{
  "url": "https://your-system.com/webhook/govigo",
  "events": ["reservation.created", "reservation.status_changed", "reservation.cancelled"]
}
Ví dụ phản hồi (201 Created)
{
  "success": true,
  "data": {
    "subscription_id": 10,
    "url": "https://your-system.com/webhook/govigo",
    "events": ["reservation.created", "reservation.status_changed", "reservation.cancelled"],
    "secret": "a1b2c3d4e5f6..."
  },
  "message": "",
  "http_code": 201
}
secret dùng để xác minh HMAC của payload Webhook. Hãy xác minh X-Webhook-Signature: sha256=... khi nhận để xác nhận tính hợp lệ. Payload của reservation.status_changed bao gồm old_status / new_status (số) và old_status_label / new_status_label.
GET /api/webhooks/list.php webhooks:read

Lấy danh sách Webhook đã đăng ký (không cần tham số).

Ví dụ phản hồi
{
  "success": true,
  "data": {
    "count": 1,
    "subscriptions": [
      {
        "id": 10,
        "url": "https://your-system.com/webhook/govigo",
        "events": ["reservation.created", "reservation.status_changed"],
        "is_active": true,
        "created_at": "2026-03-01 10:00:00",
        "updated_at": "2026-03-01 10:00:00"
      }
    ]
  },
  "message": "",
  "http_code": 200
}
POST /api/webhooks/unsubscribe.php webhooks:write

Hủy đăng ký một Webhook đã đăng ký.

Tham sốKiểuBắt buộcMô tả
subscription_idintegerBắt buộcID đăng ký cần hủy
Ví dụ yêu cầu
POST /api/webhooks/unsubscribe.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{ "subscription_id": 10 }
POST /api/webhooks/test.php webhooks:write

Gửi thông báo thử đến Webhook đã đăng ký để kiểm tra kết nối URL và xác minh chữ ký.

Tham sốKiểuBắt buộcMô tả
subscription_idintegerBắt buộcID đăng ký cần thử
Ví dụ yêu cầu
POST /api/webhooks/test.php HTTP/1.1
Host: govigolf.com
X-API-Key: YOUR_API_KEY
Content-Type: application/json

{ "subscription_id": 10 }