Thư mục này là API dành cho MÁY CHỦ CHÍNH để website con kiểm tra/cập nhật mã nguồn.

Các file chính:
- update-manifest.php: API manifest cho website con gọi tới.
- source-sync-config.php: trang cấu hình riêng cho máy chủ chính.
- ../source-sync-master-data/source-sync-master-config.json: file JSON lưu toàn bộ cấu hình manifest, được tạo tự động khi bạn lưu cấu hình.

Cách cấu hình máy chủ chính bằng giao diện PHP:
1. Upload thư mục source-sync-master-api lên máy chủ chính.
2. Mở file source-sync-master-api/source-sync-config.php.
3. Đổi mật khẩu bảo vệ trang cấu hình tại đầu file:
   $SOURCE_SYNC_CONFIG_PASSWORD = 'doi-mat-khau-quan-tri-nay';
4. Truy cập:
   https://domain-chinh.com/source-sync-master-api/source-sync-config.php
5. Đăng nhập bằng mật khẩu vừa đặt.
6. Upload file ZIP phiên bản mới.
   - File sẽ tự lưu vào /update-packages/
   - ZIP URL sẽ tự đổi thành dạng /update-packages/ten-file.zip
   - SHA256 sẽ tự tính và lưu vào JSON.
7. Điền/cập nhật các cấu hình:
   - Token máy chủ chính
   - Phiên bản mới nhất
   - Ghi chú cập nhật
   - Bắt buộc cập nhật hay không
   - IP máy chủ con được phép, có thể dùng IP public hoặc IP local/private
   - Domain máy chủ con được phép
8. Bấm Lưu cấu hình vào JSON.

Cấu hình sẽ được lưu tại:
source-sync-master-data/source-sync-master-config.json

Bảo mật:
- update-manifest.php vẫn bắt buộc kiểm tra token master_token.
- Website con phải dùng SOURCE_SYNC_API_TOKEN giống master_token trên máy chủ chính.
- ZIP bắt buộc có zip_sha256 hợp lệ.
- Website con sẽ kiểm tra SHA256 trước khi giải nén/cập nhật.
- Có thể giới hạn IP website con bằng allowed_client_ips. Danh sách này chấp nhận cả IP public/NAT mà máy chủ chính nhìn thấy và IP local/private do máy chủ con gửi kèm sau khi token hợp lệ.
- Có thể giới hạn domain website con bằng allowed_client_domains.
- Nếu danh sách IP/domain để trống thì bỏ qua kiểm tra tương ứng.
- Nếu điền cả IP và domain thì request phải khớp cả IP lẫn domain.
- Thư mục data/ có .htaccess chặn truy cập trực tiếp tới file JSON trên Apache.

Cách test manifest:
https://domain-chinh.com/source-sync-master-api/update-manifest.php  (gửi token qua header X-Source-Sync-Token)

Nếu bật whitelist domain máy chủ con, test bằng:
https://domain-chinh.com/source-sync-master-api/update-manifest.php?client_domain=shop-con.example.com  (gửi token qua header X-Source-Sync-Token)

Nếu bật whitelist IP máy chủ con bằng IP local/server IP, có thể test thủ công bằng:
https://domain-chinh.com/source-sync-master-api/update-manifest.php?client_local_ip=14.225.218.36  (gửi token qua header X-Source-Sync-Token)

Cấu hình máy chủ con:
1. Mở includes/config.php trên website con.
2. Sửa nhóm SOURCE SYNC CONFIG:
   - SOURCE_SYNC_ENABLED = true
   - SOURCE_SYNC_MANIFEST_URL = URL file update-manifest.php trên máy chủ chính
   - SOURCE_SYNC_API_TOKEN = token giống master_token trên máy chủ chính
   - SOURCE_SYNC_ALLOWED_MASTER_DOMAINS = danh sách domain máy chủ chính được phép
   - SOURCE_SYNC_ALLOWED_MASTER_IPS = danh sách IP máy chủ chính được phép
   - SOURCE_SYNC_CHECK_INTERVAL_SECONDS = chu kỳ kiểm tra tự động khi admin vào Dashboard

Ví dụ website con:
define('SOURCE_SYNC_ENABLED', true);
define('SOURCE_SYNC_MANIFEST_URL', 'https://main.example.com/source-sync-master-api/update-manifest.php');
define('SOURCE_SYNC_API_TOKEN', 'token-bi-mat');
define('SOURCE_SYNC_ALLOWED_MASTER_DOMAINS', array('main.example.com'));
define('SOURCE_SYNC_ALLOWED_MASTER_IPS', array('123.123.123.123'));

Lưu ý:
- Gói ZIP update nên chứa mã nguồn ở thư mục gốc hoặc trong một thư mục con duy nhất.
- Website con sẽ tự backup trước khi cập nhật.
- Website con không ghi đè data/codes/uploads/config.
- Cấu hình đồng bộ không nhập trong Dashboard; Dashboard chỉ hiển thị trạng thái, nút Kiểm tra ngay và nút Cập nhật mã nguồn.

Ghi chú về IP local/server IP máy chủ con:
- Khi website con gọi update-manifest.php, hệ thống sẽ gửi IP máy chủ con bằng cả header X-Shop-Sync-Local-IP và query client_local_ip.
- Query fallback được thêm để xử lý các hosting/proxy/WAF có thể không truyền header tùy chỉnh vào PHP.
- Vì vậy trên máy chủ chính bạn có thể điền IP server local/listen IP hoặc private IP của máy chủ con vào ô IP máy chủ con được phép, ví dụ 14.225.218.36, 10.x.x.x, 172.16.x.x hoặc 192.168.x.x.
- IP public/NAT mà máy chủ chính nhìn thấy vẫn tiếp tục được hỗ trợ.
