- Nhà phát triển
- Huỷ vé và hoàn tiền
Huỷ vé và hoàn tiền
Quy trình huỷ vé và hoàn tiền xử lý trường hợp hành khách không tiếp tục chuyến đi sau khi vé đã được xuất thành công. Đối tác tích hợp qua API chỉ có quyền tạo yêu cầu huỷ và xem danh sách yêu cầu của tổ chức mình; các bước duyệt thuộc quyền của các cấp tổ chức phía trên và tổ chức gốc.
Luồng này giải quyết việc gì
Phần tiêu đề “Luồng này giải quyết việc gì”Khách đã có vé nhưng không đi nữa. Bề mặt của đối tác ở luồng này chỉ có hai việc: tạo một yêu cầu huỷ, và xem danh sách yêu cầu huỷ của tổ chức mình. Bạn không duyệt được, không từ chối được, và không thu hồi được. Ba thao tác đó nằm ở tầng nội bộ của Ferry và của các tổ chức cấp trên bạn.
Hệ quả thiết kế: đừng vẽ màn hình duyệt huỷ vé trong sản phẩm của bạn. Màn hình bạn cần dựng là màn hình theo dõi tiến độ: yêu cầu đang nằm ở cấp nào, đã được duyệt tới đâu, và tiền đã hoàn về chưa.
Trước khi bắt đầu
Phần tiêu đề “Trước khi bắt đầu”| Điều kiện cần | Vì sao | Đọc ở đâu |
|---|---|---|
| Booking đang ở trạng thái đã có vé | Chỉ vé đã xuất mới huỷ được | Đặt vé: vòng đời một booking |
| Biết chuỗi tổ chức phía trên dài bao nhiêu cấp | Số cấp quyết định thời gian duyệt | Tổng quan bề mặt tích hợp |
| Tổ chức của bạn còn đủ số dư | Yêu cầu huỷ bị từ chối ngay nếu không đủ tiền trả phí | Tiền: số dư, hạn mức và công nợ |
| Đã khai địa chỉ nhận sự kiện | Luồng này phát nhiều sự kiện trong hệ thống | Webhooks |
| Hiểu ba con số giá | Số tiền hoàn tính trên giá NET ở góc nhìn từng cấp | Giá vé và markup nhiều cấp |
Sơ đồ luồng
Phần tiêu đề “Sơ đồ luồng”Sơ đồ dưới đây cho thấy chuỗi duyệt đi ngược lên từ bạn tới tổ chức gốc, kèm nhánh bị từ chối:
sequenceDiagram autonumber participant P as "Hệ thống của bạn" participant F as "Ferry API" participant U as "Đại lý cấp trên" participant R as "Tổ chức gốc" participant C as "Tác vụ ghi có" participant W as "Địa chỉ nhận webhook"
P->>F: "Gửi yêu cầu huỷ vé kèm lý do" F->>F: "Dựng danh sách toàn chuỗi tổ chức" F->>F: "Kiểm tra số dư của bạn"
alt Không đủ tiền trả phí huỷ F-->>P: "Yêu cầu bị từ chối ngay, không vào chuỗi duyệt" else Đủ tiền F-->>P: "Yêu cầu ở trạng thái đang xử lý" F--)W: "Sự kiện yêu cầu huỷ đã được tạo"
U->>F: "Cấp trên trực tiếp duyệt" Note over F: "Trạng thái riêng của cấp đổi,<br/>trạng thái chung vẫn đang xử lý"
alt Một cấp bất kỳ từ chối U->>F: "Từ chối kèm lý do" F--)W: "Sự kiện bị từ chối" F-->>P: "Cả yêu cầu bị từ chối, vé còn nguyên" else Duyệt hết lên tới gốc R->>F: "Tổ chức gốc duyệt" F->>F: "Nhả ghế và voucher" F->>C: "Ghi có cho từng tổ chức con trong chuỗi" C-->>F: "Ghi có xong hoặc chờ lượt sau" F--)W: "Sự kiện đã hoàn tiền" F-->>P: "Trạng thái chung chuyển sang đã hoàn tiền" end end
loop Theo dõi tiến độ duyệt P->>F: "Tra cứu trạng thái yêu cầu huỷ" F-->>P: "Trạng thái chung và trạng thái riêng từng cấp" endCác bước thực hiện
Phần tiêu đề “Các bước thực hiện”| Bước | Hệ thống của bạn làm gì | Ferry làm gì | Dấu hiệu thành công | Lỗi thường gặp |
|---|---|---|---|---|
| 1 | Kiểm tra booking đang ở trạng thái đã xuất vé | — | Booking ở trạng thái đã có vé | Tạo yêu cầu cho booking chưa xuất vé |
| 2 | Gửi lệnh tạo yêu cầu huỷ kèm vé và lý do | Dựng danh sách toàn chuỗi tổ chức, kiểm tra số dư | Nhận yêu cầu ở trạng thái đang xử lý | Số dư không đủ khiến yêu cầu bị từ chối ngay |
| 3 | Lưu mã yêu cầu huỷ vào cơ sở dữ liệu của bạn | — | Mã yêu cầu đã lưu trong hệ thống của bạn | Chỉ giữ trong bộ nhớ tạm, mất dấu khi tra cứu |
| 4 | Thông báo khách rằng yêu cầu đang chờ duyệt nhiều cấp | Chờ từng cấp thao tác | Khách hiểu tiến độ cần duyệt qua từng cấp | Hứa hẹn mốc thời gian hoàn tiền cố định |
| 5 | Theo dõi trạng thái chung và trạng thái từng cấp | Cập nhật trạng thái riêng của cấp vừa duyệt | Nhìn rõ đang chờ cấp nào duyệt | Chỉ đọc trạng thái chung rồi nghĩ hệ thống bị treo |
| 6 | Khi thấy đã hoàn tiền, đối chiếu nhật ký giao dịch | Nhả ghế, nhả voucher, ghi có cho tổ chức con | Tìm thấy giao dịch hoàn tiền tương ứng | Báo khách đã hoàn xong trước khi tiền thật về |
| 7 | Nếu bị từ chối, đọc lý do và xử lý lại với khách | Ghi nhận lý do từ chối vào yêu cầu | Có lý do cụ thể để giải thích cho khách | Tạo lại yêu cầu mới khi chưa giải quyết nguyên nhân |
Trạng thái
Phần tiêu đề “Trạng thái”Sơ đồ vòng đời một yêu cầu huỷ
Phần tiêu đề “Sơ đồ vòng đời một yêu cầu huỷ”Sơ đồ dưới đây cho thấy vòng đời chuyển đổi trạng thái của một yêu cầu huỷ vé:
stateDiagram-v2 direction LR state "Đang xử lý" as processing state "Đã duyệt" as accept state "Bị từ chối" as reject state "Đã thu hồi" as recall state "Đã hoàn tiền" as refunded
[*] --> processing : Tạo yêu cầu thành công và đủ số dư processing --> accept : Một cấp trong chuỗi duyệt accept --> processing : Vẫn còn cấp phía trên chưa duyệt accept --> refunded : Tổ chức gốc duyệt, hệ thống nhả ghế processing --> reject : Bất kỳ cấp nào từ chối processing --> recall : Khách thu hồi yêu cầu accept --> recall : Khách thu hồi khi gốc chưa duyệtBảng liệt kê trạng thái
Phần tiêu đề “Bảng liệt kê trạng thái”| Nhãn | Ý nghĩa | Bạn làm gì tiếp |
|---|---|---|
| Đang xử lý | Yêu cầu đã vào chuỗi duyệt, chưa hoàn tất | Theo dõi tiến độ, không thao tác gì thêm |
| Đã duyệt | Một hoặc vài cấp đã duyệt, chưa tới tổ chức gốc | Tiếp tục theo dõi, đọc trạng thái riêng để biết đang chờ cấp nào |
| Bị từ chối | Một cấp bất kỳ đã từ chối, có kèm lý do | Đọc lý do, làm việc lại với khách, vé vẫn còn nguyên |
| Đã thu hồi | Khách đã rút lại yêu cầu | Không thao tác được nữa, mọi lệnh khác bị chặn |
| Đã hoàn tiền | Tổ chức gốc đã duyệt, ghế và voucher đã nhả | Đối chiếu nhật ký giao dịch, báo khách sau khi thấy tiền về |
Hai tầng trạng thái cần theo dõi
Phần tiêu đề “Hai tầng trạng thái cần theo dõi”Ngoài trạng thái chung ở bảng trên, mỗi tổ chức trong chuỗi còn mang trạng thái riêng trong danh sách tổ chức liên quan của yêu cầu.
Đây là điểm mấu chốt: khi cấp trên trực tiếp của bạn đã duyệt mà cấp cao hơn chưa duyệt, trạng thái chung vẫn hiển thị là đang xử lý. Nhìn vào trạng thái chung sẽ không thấy chuyển động, trong khi thực tế yêu cầu đã đi lên được một bậc.
Để biết chính xác đang chờ cấp nào thao tác, bạn cần đọc chi tiết yêu cầu và xem trạng thái riêng của từng cấp. Hãy hiển thị thông tin này trên màn hình chăm sóc khách hàng của bạn.
Một quy tắc chặn: khi yêu cầu ở trạng thái Đã thu hồi, mọi thao tác can thiệp khác đều bị chặn hoàn toàn. Không thể duyệt, không thể từ chối, và không thể chỉnh sửa.
Giới hạn và bảo đảm vận hành
Phần tiêu đề “Giới hạn và bảo đảm vận hành”Chuỗi duyệt đi ngược lên nhiều cấp
Phần tiêu đề “Chuỗi duyệt đi ngược lên nhiều cấp”| Bước | Diễn biến trong hệ thống |
|---|---|
| 1 | Tạo yêu cầu: hệ thống dựng danh sách toàn chuỗi tổ chức từ bạn lên tới gốc, mỗi cấp có trạng thái riêng. Hệ thống kiểm tra số dư — thiếu tiền thì yêu cầu bị từ chối ngay. |
| 2 | Từng cấp duyệt từ dưới lên. Cấp cha chỉ duyệt được khi cấp con trực tiếp đã duyệt. |
| 3 | Cấp nào duyệt thì trạng thái riêng của cấp đó đổi, trạng thái chung toàn yêu cầu vẫn là đang xử lý. |
| 4 | Tổ chức gốc duyệt: trạng thái chung chuyển sang đã hoàn tiền, hệ thống nhả ghế và nhả voucher. |
| 5 | Bất kỳ cấp nào từ chối: toàn bộ yêu cầu chuyển sang bị từ chối, kèm lý do cụ thể. |
| 6 | Khách thu hồi: trạng thái chuyển thành đã thu hồi. Không thể thu hồi nếu tổ chức gốc đã duyệt xong. |
Bạn tạo yêu cầu xong thì không thể can thiệp thêm vào quá trình duyệt. Thời gian hoàn tất phụ thuộc vào số cấp tổ chức phía trên và tốc độ thao tác của từng cấp. Hệ thống không có hạn chót tự động cho từng bước duyệt và không có cơ chế tự duyệt khi quá hạn.
Kiểm tra khoá API khi tạo yêu cầu
Phần tiêu đề “Kiểm tra khoá API khi tạo yêu cầu”Lệnh tạo yêu cầu huỷ và lệnh liệt kê yêu cầu huỷ chỉ kiểm tra tính hợp lệ của khoá API, không phân quyền chi tiết theo vai trò nội bộ. Mọi khoá API hợp lệ của tổ chức bạn đều có thể tạo yêu cầu huỷ vé.
Về mặt an toàn, nếu khoá API bị lộ, người cầm khoá có thể tạo yêu cầu huỷ cho bất kỳ vé nào của tổ chức bạn. Hãy tự xây dựng lớp kiểm soát phân quyền ở phía hệ thống của bạn trước khi gọi API này.
Cơ chế hoàn tiền và thời gian xử lý
Phần tiêu đề “Cơ chế hoàn tiền và thời gian xử lý”| Chặng | Cơ chế | Thời gian |
|---|---|---|
| Ghi có cho tổ chức con | Hệ thống thử ghi có ngay khi tổ chức gốc duyệt | Tức thì nếu xử lý thành công |
| Lần ghi có thất bại | Tác vụ định kỳ quét lại các khoản chờ xử lý | Mỗi 15 phút một lượt |
| Bản ghi treo giữa chừng | Thu hồi về hàng chờ để thử lại | Sau 10 phút |
| Thất bại sau nhiều lượt | Hệ thống phát cảnh báo tài chính | Sau 3 lần thất bại liên tiếp |
| Tiền của khách hàng cuối | Ghi bằng loại giao dịch hoàn tiền riêng | Cùng lúc với bước tổ chức gốc duyệt |
Thao tác ghi có an toàn khi lặp lại, được khoá theo mã yêu cầu huỷ. Tác vụ định kỳ chạy lại sẽ không cộng tiền hai lần, bạn không cần tự chống trùng cho khoản tiền hoàn này.
Tuy nhiên, lệnh tạo yêu cầu huỷ không có khoá chống lặp. Khi gặp timeout, hãy tra cứu danh sách yêu cầu trước thay vì gửi lệnh tạo mới ngay lập tức.
Ánh xạ trạng thái thanh toán khi huỷ
Phần tiêu đề “Ánh xạ trạng thái thanh toán khi huỷ”| Trạng thái thanh toán trước huỷ | Sau khi huỷ xong |
|---|---|
| Chưa trả | Đã huỷ |
| Trả thiếu | Đã huỷ — hệ thống không có trạng thái hoàn một phần |
| Đã trả | Đã hoàn |
| Đã trả bằng nợ | Đã hoàn — phần tiền mặt được hoàn lại, phần nợ được xoá |
Lưu ý: hệ thống không có trạng thái “hoàn tiền một phần”. Booking trả thiếu bị huỷ sẽ mang trạng thái đã huỷ, và phần tiền đã thu được đối soát qua nhật ký giao dịch chứ không thể hiện riêng ở trạng thái đơn.
Sự kiện webhook nên đăng ký
Phần tiêu đề “Sự kiện webhook nên đăng ký”Để không phải liên tục gọi API tra cứu trạng thái, bạn nên đăng ký các sự kiện sau:
- Yêu cầu huỷ được tạo
- Yêu cầu huỷ được tạo bởi tổ chức con
- Yêu cầu huỷ được cập nhật
- Yêu cầu huỷ được duyệt
- Yêu cầu huỷ bị từ chối
- Yêu cầu huỷ được duyệt kèm hoàn tiền
- Yêu cầu huỷ đã hoàn tiền
- Yêu cầu huỷ bị thu hồi
- Vé đã được nhả
Chi tiết về cách khai báo địa chỉ nhận và các lưu ý vận hành xem tại Webhooks.
Lỗi thường gặp và cách xử lý
Phần tiêu đề “Lỗi thường gặp và cách xử lý”| Triệu chứng | Nguyên nhân | Cách xử lý | Có nên gọi lại không |
|---|---|---|---|
| Yêu cầu bị từ chối ngay khi vừa tạo | Số dư không đủ để trả phí huỷ (mã lỗi 160105) | Nạp tiền vào tài khoản tổ chức rồi tạo lại | Không — gọi lại khi chưa nạp tiền vẫn thất bại |
| Trạng thái chung đứng yên nhiều giờ | Chuỗi duyệt đang chờ một cấp phía trên thao tác | Đọc trạng thái riêng từng cấp để biết đang chờ ai, sau đó liên hệ cấp đó | Không — gọi lại API không đẩy nhanh tiến độ duyệt |
| Không tìm thấy lệnh duyệt yêu cầu | Đối tác không có quyền duyệt, đây là thiết kế hệ thống | Cấp trên trong chuỗi tổ chức sẽ duyệt trên giao diện quản trị | Không áp dụng |
| Yêu cầu chuyển sang đã thu hồi | Khách đã rút lại yêu cầu qua kênh khác | Chấp nhận trạng thái này; mọi thao tác khác bị khoá | Không |
| Trạng thái đã hoàn tiền nhưng tiền chưa về | Tác vụ ghi có chạy theo chu kỳ 15 phút | Chờ hết chu kỳ, kiểm tra nhật ký giao dịch để xác nhận | Không |
| Tiền không về sau nhiều chu kỳ | Ghi có thất bại nhiều lần, hệ thống đã phát cảnh báo | Liên hệ Ferry hỗ trợ kèm mã yêu cầu huỷ | Không |
| Không nhận được sự kiện webhook nào | Điều kiện lọc của địa chỉ nhận sai cú pháp | Gỡ bỏ hoặc sửa điều kiện lọc, thử lại bằng thao tác thật | Không |
| Hai yêu cầu huỷ trùng nhau cho cùng một vé | Đã gọi lại lệnh tạo sau khi gặp sự cố timeout | Liên hệ Ferry để huỷ bản ghi bị trùng | Không |
Tra cứu trên giao diện tài liệu API
Phần tiêu đề “Tra cứu trên giao diện tài liệu API”Trang này tương ứng với nhóm Cancel Ticket Requests trên giao diện tra cứu https://api.ferry.vn/docs, cùng hai nhóm phụ trợ để đối chiếu dữ liệu:
| Mục tiêu tra cứu | Nhóm trên giao diện API |
|---|---|
| Cấu trúc dữ liệu khi tạo yêu cầu huỷ vé | Cancel Ticket Requests |
| Liệt kê danh sách yêu cầu huỷ và tham số lọc | Cancel Ticket Requests |
| Giao dịch hoàn tiền tương ứng | Transactions |
| Trạng thái booking sau khi hoàn tất huỷ | Bookings |
Trên giao diện tài liệu API, nhóm Cancel Ticket Requests chỉ hiển thị các endpoint mà đối tác được phép gọi (tạo và xem danh sách). Các endpoint duyệt, từ chối hay thu hồi thuộc quyền quản trị nội bộ nên không xuất hiện cho đối tác bên ngoài.
Đọc tiếp
Phần tiêu đề “Đọc tiếp”| Trang | Đọc khi nào |
|---|---|
| Đặt vé: vòng đời một booking | Cần nắm trạng thái booking thay đổi ra sao trong lúc chờ duyệt huỷ |
| Tiền: số dư, hạn mức và công nợ | Cần đối chiếu giao dịch hoàn tiền và chu kỳ ghi có định kỳ |
| Xuất vé và đơn hàng | Cần xử lý huỷ booking bị lỗi xuất vé một phần |
| Webhooks | Cần đăng ký sự kiện và tránh bẫy điều kiện lọc cú pháp |
| Giá vé và markup nhiều cấp | Cần hiểu cách tính số tiền hoàn theo từng cấp tổ chức |
| Tổng quan bề mặt tích hợp | Cần hiểu cấu trúc chuỗi duyệt nhiều cấp |
Điểm chưa xác định
Phần tiêu đề “Điểm chưa xác định”| Câu hỏi | Tình trạng |
|---|---|
| Có cam kết thời hạn cho từng bước duyệt không? | Hệ thống không đặt hạn chót tự động cho bước duyệt của từng cấp; thời gian thực tế phụ thuộc quy trình vận hành của các bên. |
| Phí huỷ vé tính theo công thức nào và ai quyết định? | Phụ thuộc chính sách huỷ của từng hãng tàu và quy định của từng cấp tổ chức; hiện chưa có API mở để đối tác tự tra cứu bảng phí. |
| Khách thu hồi yêu cầu bằng kênh nào? | Chưa xác định kênh thao tác; API key đối tác không thể thu hồi hộ khách. |