Provider 送出報價流程

文件狀態:初版,依 pro360_api_82quote_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 bidprovider 對 request 的報價 row
quote requestconsumer 的需求案件
quote serviceprovider 的服務身份

前置檢查

送出報價前通常要先確認:

  • 操作者必須是 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 = now
  • quote_bids.quote_status_id = InProgress
  • quote_bids.provider_status_id = InProgress
  • quote_bids.is_interested = 1
  • quote_bids.is_paid_for_subscription = 1
  • quote_bids.is_contact_charge = 0
  • quote_requests.quote_bid_count + 1

一般手動報價會占用 request 的報價名額。若達上限,會送 task_event_queue.request_bid_count_limit

保證回覆 / Contact Charge 報價

常見效果:

  • quote_bids.quote_sent_on = now
  • quote_bids.quote_status_id = InProgress
  • quote_bids.provider_status_id = InProgress
  • quote_bids.is_interested = 1
  • quote_bids.is_auto_quote = 1
  • quote_bids.is_contact_charge = 1
  • quote_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_idint,但新版 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_notequote_amountpricing_unit、flat / hourly / required / quote 等欄位
unread staterequestor 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
couponsite fee reason 若包含 coupon,會 fulfill coupon 並綁定 quote bid
category service更新 quote_categories_quote_services.last_quote_sent_on
FETNETFETNET requestor unread counter 可能增加
referralprovider 第一筆報價時可能觸發 referral check

Notification

新報價通知 consumer 的主要 event:

event_queue.Receive_Quote

常見 tasks:

tasktemplate
MoEngageReceive_Quote
email110 New Quote Received Notification
life55688 emaillife55688-110 New Quote Received Notification
push / web pushpush.content.project.quoted
SMSsms.receive_quote
life55688 SMSlife55688-sms.receive_quote
FETNET pushpro360-quote

排查時不要只查 event_queue。worker 可能已搬到 log:

event_queue
event_queue_log_1
event_queue_log_2
event_queue_log_3
event_queue_log_4

Queue 判讀規則請連到:

Task Event

常見 task event:

event_key用途
quote_bid_calc_counter重算 provider / request / service counter
new_quote_bid_rating新報價後更新平均回覆時間等報價統計
request_bid_count_limitrequest 報價數達上限後觸發後續處理
request_sent_countcontact 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 chargequote_bid_site_fees, quote_bid_calls
報價紀錄quote_activities, messages
couponquote_coupons, quote_coupon_campaigns
notificationevent_queue, event_queue_log_1..4, task_event_queue, task_event_queue_log
身份與短連結security_hashes, short_urls
referraluser_referrals, free_credit_events, user_internal_logs

排查順序

  1. 先確認 API response 的 errorstatus
  2. quote_bids:狀態、quote_sent_onis_contact_chargetotal_site_feequote_user_subscription_log_id
  3. quote_requests:是否 closed / expired / hired、quote_bid_count 是否正確。
  4. 若牽涉扣款,查 transactionsquote_user_subscription_logswallet_balance_logs
  5. 若牽涉 card / prime,查 application log 與 tap_pay_charge_logs
  6. quote_activities.SubmitQuote
  7. event_queue.Receive_Quoteevent_queue_log_1..4
  8. task_event_queue.new_quote_bid_ratingtask_event_queue_log
  9. 若是 contact charge,再查 quote_bid_site_feesquote_bid_callsrequest_sent_count
  10. 若是第一筆報價,再查 referral 相關資料。

常見誤判

  • 看到 event_queue 空,不代表沒有送通知;可能 worker 已搬到 event_queue_log_1..4
  • quote_bids/rating.jsonquote_bids/change_status/rating/{id}.json 不是同一個 legacy 主線。
  • prime 不是必填;wallet 不足且沒有有效 card 時才會因缺卡被擋。
  • wallet 不足時不一定馬上刷卡;可能只是先寫 unpaid auto quote debt。
  • contact charge 報價不等於 consumer 已聯絡 provider;它是 provider 先送保證回覆報價,後續是否收 contact charge 還要看聯絡流程。