Provider 送出報價流程
文件狀態:初版,依 pro360_api_82 的 quote_bids/change_status/rating 遷移整理。
最後驗證日期:2026-05-11。
主要來源:
pro360_api_82/Lib/Model/QuoteBid.php::processChangeStatusRating()pro360_api_82/Lib/Model/QuoteBid.php::sendReceiveQuoteNotification()get-lancer-php56/app/Plugin/Quotes/Controller/QuoteBidsController.php::change_status(..., rating, ...)get-lancer-php56/app/Plugin/Quotes/Model/QuoteBid.php::sendReceiveQuoteNotification()
這份文件回答什麼
這份文件整理「provider 送出報價」這類業務動作的共通規則。重點是讓後續排查任何送出報價相關 API 時,可以快速知道主流程、扣款、notification、referral 與主要資料表。
不回答:
- 單一 API path 的 route mapping 細節。
- 單一 endpoint 的完整 request / response migration checklist。
- 每張資料表的欄位字典。
- 實測 curl 與一次性測試 ID。
單一 endpoint 細節請回到 專案 migration 文件,例如:
API 路由與遷移/API Migration/pro360_api_82/api_migration/details/quote_bids/change_status/rating.md
快速流程
Provider 送出報價
-> 驗證 provider 身份與報價資格
-> 確認 request / bid 還能報價
-> 判斷一般手動報價或保證回覆 / contact charge
-> 計算 site fee
-> 處理 wallet / card / prime / unpaid debt
-> 更新 quote_bids / quote_requests
-> 建立 activity / message / template / coupon side effect
-> 送 Receive_Quote notification
-> 送 new_quote_bid_rating / counter 類 task event
-> 第一筆報價時檢查 referral主要角色
| 角色 | 說明 |
|---|---|
| provider | 報價者,必須是目標 quote_bids.provider_user_id |
| requestor / consumer | 發案者,接收報價通知 |
| quote bid | provider 對 request 的報價 row |
| quote request | consumer 的需求案件 |
| quote service | provider 的服務身份 |
前置檢查
送出報價前通常要先確認:
- 操作者必須是 bid provider。
- provider 電話已驗證。
- provider 沒有被 blocked user / blocked user config / fraud tag 擋下。
- provider 符合 category limitation。
- auto quote card 若已失效,需阻擋。
- request 未 archived / closed / expired。
- request 尚未 hired。
- bid 尚未送出,且不是 auto quote / narrow match 等不允許手動報價的狀態。
- 同 provider 不應已用其他 bid 對同一 request 進入
InProgress/Hired。 - request 報價數未達上限。
報價型態
一般手動報價
常見效果:
quote_bids.quote_sent_on = nowquote_bids.quote_status_id = InProgressquote_bids.provider_status_id = InProgressquote_bids.is_interested = 1quote_bids.is_paid_for_subscription = 1quote_bids.is_contact_charge = 0quote_requests.quote_bid_count + 1
一般手動報價會占用 request 的報價名額。若達上限,會送 task_event_queue.request_bid_count_limit。
保證回覆 / Contact Charge 報價
常見效果:
quote_bids.quote_sent_on = nowquote_bids.quote_status_id = InProgressquote_bids.provider_status_id = InProgressquote_bids.is_interested = 1quote_bids.is_auto_quote = 1quote_bids.is_contact_charge = 1quote_bids.is_want_to_contact_provider = 0- 建立
quote_bid_site_fees - 建立
quote_bid_calls
contact charge 不直接增加 quote_requests.quote_bid_count,但會建立可聯絡 / 通話相關 row,並送 request_sent_count 類 task event。
扣款規則
site fee 由 quote request / quote bid 狀態計算,會受到 manual fee、auto fee、contact charge fee、coupon、折扣與特殊模式影響。
一般手動報價扣款順序:
site fee = 0
-> 不扣款,但仍會寫報價狀態與 side effect
wallet 足額
-> 扣 users.available_wallet_amount
-> 寫 wallet_balance_logs
-> 寫 transactions.QuotePaymentForSubmission
-> 寫 quote_user_subscription_logs.real_pay_date
wallet 不足,但有 auto quote card 或 prime
-> 先寫 transactions.QuotePaymentForSubmissionAutoQuote,real_pay_date = null
-> 先寫 quote_user_subscription_logs,real_pay_date = null
-> 若 debt 達門檻或需要立即扣款,再用 default card 或 prime 付清 unpaid debt
wallet 不足,且沒有 auto quote card / prime
-> 阻擋報價prime 是 TapPay 前端取得的一次性 token,常見用途:
- debt 未達扣款門檻時,只綁卡。
- debt 達門檻時,用 prime 立即付清 auto quote debt。
- foreign card / cool down / retry 類錯誤要對應 API error 與 bank result。
注意:quote_user_subscription_logs.quote_bid_id 是 int,但新版 quote_bids.id 已可能超過 signed int 上限。若 quote_bid_id > 2147483647,subscription log 的 quote_bid_id 可能被寫成 2147483647。排查時要優先用 quote_bids.quote_user_subscription_log_id -> quote_user_subscription_logs.id,不要只用 quote_user_subscription_logs.quote_bid_id 反查。
扣款細節請連到:
成功後共用 Side Effect
送出報價成功後,除了主要狀態更新,通常還會有:
| 類型 | 說明 |
|---|---|
| 報價內容 | 更新 price_note、quote_amount、pricing_unit、flat / hourly / required / quote 等欄位 |
| unread state | requestor unread、quote viewed reset、provider last read time 更新 |
| activity | 建立 quote_activities.SubmitQuote;更新報價時可能是 UpdateQuote |
| attachments | 報價附件會寫入 quote conversation message |
| quote template | 更新 users.last_used_template_id,必要時更新 quote_templates.quote_service_id / quote_category_id |
| coupon | site fee reason 若包含 coupon,會 fulfill coupon 並綁定 quote bid |
| category service | 更新 quote_categories_quote_services.last_quote_sent_on |
| FETNET | FETNET requestor unread counter 可能增加 |
| referral | provider 第一筆報價時可能觸發 referral check |
Notification
新報價通知 consumer 的主要 event:
event_queue.Receive_Quote常見 tasks:
| task | template |
|---|---|
| MoEngage | Receive_Quote |
110 New Quote Received Notification | |
| life55688 email | life55688-110 New Quote Received Notification |
| push / web push | push.content.project.quoted |
| SMS | sms.receive_quote |
| life55688 SMS | life55688-sms.receive_quote |
| FETNET push | pro360-quote |
排查時不要只查 event_queue。worker 可能已搬到 log:
event_queue
event_queue_log_1
event_queue_log_2
event_queue_log_3
event_queue_log_4Queue 判讀規則請連到:
Task Event
常見 task event:
| event_key | 用途 |
|---|---|
quote_bid_calc_counter | 重算 provider / request / service counter |
new_quote_bid_rating | 新報價後更新平均回覆時間等報價統計 |
request_bid_count_limit | request 報價數達上限後觸發後續處理 |
request_sent_count | contact charge 轉保證回覆報價後更新 sent count |
task queue 也要接受 queue 或 log 任一存在:
task_event_queue
task_event_queue_log主要資料表
| 類型 | 資料表 |
|---|---|
| 報價狀態 | quote_bids |
| 案件狀態與報價數 | quote_requests, quote_request_limit_ids |
| provider 服務 | quote_services, quote_categories_quote_services |
| 扣款 | transactions, quote_user_subscription_logs, wallet_balance_logs, stripe_customers, tap_pay_charge_logs |
| contact charge | quote_bid_site_fees, quote_bid_calls |
| 報價紀錄 | quote_activities, messages |
| coupon | quote_coupons, quote_coupon_campaigns |
| notification | event_queue, event_queue_log_1..4, task_event_queue, task_event_queue_log |
| 身份與短連結 | security_hashes, short_urls |
| referral | user_referrals, free_credit_events, user_internal_logs |
排查順序
- 先確認 API response 的
error與status。 - 查
quote_bids:狀態、quote_sent_on、is_contact_charge、total_site_fee、quote_user_subscription_log_id。 - 查
quote_requests:是否 closed / expired / hired、quote_bid_count是否正確。 - 若牽涉扣款,查
transactions、quote_user_subscription_logs、wallet_balance_logs。 - 若牽涉 card / prime,查 application log 與
tap_pay_charge_logs。 - 查
quote_activities.SubmitQuote。 - 查
event_queue.Receive_Quote或event_queue_log_1..4。 - 查
task_event_queue.new_quote_bid_rating或task_event_queue_log。 - 若是 contact charge,再查
quote_bid_site_fees、quote_bid_calls、request_sent_count。 - 若是第一筆報價,再查 referral 相關資料。
常見誤判
- 看到
event_queue空,不代表沒有送通知;可能 worker 已搬到event_queue_log_1..4。 quote_bids/rating.json和quote_bids/change_status/rating/{id}.json不是同一個 legacy 主線。prime不是必填;wallet 不足且沒有有效 card 時才會因缺卡被擋。- wallet 不足時不一定馬上刷卡;可能只是先寫 unpaid auto quote debt。
- contact charge 報價不等於 consumer 已聯絡 provider;它是 provider 先送保證回覆報價,後續是否收 contact charge 還要看聯絡流程。