Authorized Manual Verification

這份文件只處理一件事:

  • 手動驗證 search_add authorized
  • 包含前置條件、Postman / staging 操作、DB / event 檢查、清資料方式

對應 Postman collection:

目前文件內建的 fail 範例預設使用:

  • requestor: user_id = 8616
  • provider: user_id = 8617
  • quote_service_id = 9930
  • category: 159

前置條件

1. category 合法允許 Authorize

  • QuoteRequest[match_type] = 2 不代表一定成立
  • category 必須允許 Authorize
    • quote_categories.match_type = 2
    • quote_categories.match_type = 3

如果 category 不允許:

  • request 會先被正規化回 quote_requests.match_type = 1
  • 這種 case 不應當成合法的 authorized 驗證

2. Requestor user

最少需要:

  • session token
  • phone
  • name

Postman 對應:

  • {{session_token}}
  • {{requestor_phone}}
  • {{requestor_name}}

3. Provider user

最少需要:

  • quote_service_id
  • users.is_auto_quote_on = 1
  • category 對應的 quote_service_categories

如果要驗付款成功,還要有:

  • 一筆有效 auto-quote card
    • stripe_customers.is_auto_quote = 1
    • stripe_customers.is_valid = 1

4. 真 sandbox 驗證額外條件

如果要驗真 gateway,而不是 fake:

  • server 可 outbound 到 sandbox gateway
  • SEARCH_ADD_TEST_FAKE_CHARGE_RESULT 未設定
  • merchant / partner key 設定正確

手動 fail 案例先分兩種

1. no valid card

這個案例對應:

  • provider wallet 不足
  • provider 沒有可用的 auto-quote card
  • API 會回 聯繫時付款失敗
  • 不保證 fallback

建議 DB:

UPDATE users
SET available_wallet_amount = 0,
    modified = NOW()
WHERE id = 8617;
UPDATE stripe_customers
SET is_valid = 0,
    modified = NOW()
WHERE id = 3176;

這就是你剛剛 staging 做出的那條路徑。

2. charge fail -> fallback

這個案例對應 legacy 白名單內的 charge 失敗:

  • 101
  • 102
  • 104
  • 105

預期結果是:

  • API 仍然回 聯繫時付款失敗
  • 同時 bid 會被切成 narrow/new leads

建議 DB:

UPDATE users
SET available_wallet_amount = 0,
    modified = NOW()
WHERE id = 8617;

provider 必須保留有效 auto-quote card,例如:

SELECT id, user_id, customer_id, is_auto_quote, is_valid, is_default, country_code, card_info
FROM stripe_customers
WHERE user_id = 8617
ORDER BY id DESC;

這組內建資料目前可直接用的 card 是:

  • stripe_customers.id = 3176
  • user_id = 8617
  • is_auto_quote = 1
  • is_valid = 1
  • is_default = 1
  • card_info = VISA|TW|4242

但這還不夠。

真正要讓它走到 fallback,通常要靠:

  • sandbox 失敗卡 / 失敗 token / 失敗 customer
  • 或 local / test 環境的 fake charge 設定

只改 DB 只能保證:

  • 不走 wallet
  • 會進 charge path

不能單靠 DB 保證一定進 fallback。

Postman 使用方式

一定要改

  1. {{session_token}}
  2. {{quote_service_id}}

視情況改

  1. {{requestor_phone}}
  2. {{requestor_name}}
  3. {{request_description}}

category / form 注意事項

這份 collection 目前預設是:

  • quote_category_id = 159
  • 地毯清洗的 Form / FormTime / FormSummary

如果你把 category 換掉,下面這些也要一起換:

  • Form[...]
  • FormTime[...]
  • FormSummary

不然 request 可能因為 form/category 不匹配而失敗。

驗證順序

建議順序:

  1. wallet 直接付款
  2. sandbox 即時扣款成功
  3. sandbox 即時扣款失敗
  4. 最後才看 auto refill / cooldown / retry / foreign card

怎麼驗有付款成功

假設 response 回:

  • QuoteRequest.id = 19357

先查 bid:

SELECT id, quote_service_id, is_auto_quote, is_narrow_match,
       is_want_to_contact_provider, is_paid_for_subscription,
       contact_provider_on, quote_user_subscription_log_id
FROM quote_bids
WHERE quote_request_id = 19357
ORDER BY id DESC;

你要看到:

  • is_want_to_contact_provider = 1
  • is_paid_for_subscription = 1
  • contact_provider_on 不為空
  • quote_user_subscription_log_id > 0

再確認 quote_user_subscription_log_id 指向 quote_user_subscription_logs.id

SELECT qb.id AS quote_bid_id,
       qb.quote_user_subscription_log_id,
       qusl.id AS subscription_log_id,
       qusl.amount,
       qusl.real_pay_date
FROM quote_bids qb
LEFT JOIN quote_user_subscription_logs qusl
  ON qusl.id = qb.quote_user_subscription_log_id
WHERE qb.quote_request_id = 19357
ORDER BY qb.id DESC;

注意:不要用 quote_user_subscription_log_idtransactions.id。transaction 要用 class='QuoteBid' + foreign_id=quote_bid_id 查。

再查 transaction:

SELECT id, transaction_type_id, foreign_id, amount, real_pay_amount,
       real_pay_date, stripe_charge_id
FROM transactions
WHERE class = 'QuoteBid'
  AND foreign_id IN (
    SELECT id FROM quote_bids WHERE quote_request_id = 19357
  )
ORDER BY id DESC;

wallet 成功

通常會看到:

  • transaction_type_id = 33
  • real_pay_date 不為空

card / debt 成功

通常會看到:

  • 與這筆 bid 相關的 payment / debt transaction
  • real_pay_date 不為空
  • stripe_charge_id 有值

怎麼驗 downstream event

SELECT id, event_key
FROM event_queue
WHERE params LIKE '%"quote_request_id":"19357"%'
   OR params LIKE '%"quote_request_id":19357%'
UNION ALL
SELECT id, event_key
FROM event_queue_log
WHERE params LIKE '%"quote_request_id":"19357"%'
   OR params LIKE '%"quote_request_id":19357%'
ORDER BY id DESC;

想看到的重點:

  • Contact_Pro
  • Auto_Charge_Pro
  • package / auto refill 路徑時,再補看 Purchase_Credit_Pro

注意:

  • event_queue / event_queue_log_1..event_queue_log_4 沒有 quote_request_id 實體欄位,必須從 params
  • worker 可能會把 queue 搬到 log
  • 所以要同時查 queue 與 log

怎麼驗 no valid card

假設 response 回:

  • QuoteRequest.id = 19357

先查 request:

SELECT id, match_type, auto_quote_sent_count, auto_quote_contact_count
FROM quote_requests
WHERE id = 19357;

預期:

  • auto_quote_sent_count = 1
  • auto_quote_contact_count = 0

再查 bid:

SELECT id, quote_service_id, is_auto_quote, is_narrow_match,
       is_want_to_contact_provider, narrow_status_id, is_related,
       contact_provider_on, quote_user_subscription_log_id
FROM quote_bids
WHERE quote_request_id = 19357
ORDER BY id DESC;

預期:

  • 只有原本那筆 authorized auto bid
  • is_auto_quote = 1
  • is_want_to_contact_provider = 0
  • is_narrow_match = 0
  • narrow_status_id = 0
  • 沒有 fallback bid

怎麼驗 charge fail -> fallback

假設 response 回:

  • QuoteRequest.id = 19357

先看 request counter:

SELECT id, match_type, auto_quote_sent_count, auto_quote_contact_count
FROM quote_requests
WHERE id = 19357;

期待:

  • auto_quote_sent_count = 1
  • auto_quote_contact_count = 0

再看最後一筆 bid:

SELECT id, quote_service_id, is_auto_quote, is_narrow_match,
       is_want_to_contact_provider, narrow_status_id, is_related
FROM quote_bids
WHERE quote_request_id = 19357
ORDER BY id DESC;

期待 fallback row 類型接近:

  • is_auto_quote = 0
  • is_narrow_match = 1
  • is_want_to_contact_provider = 1
  • narrow_status_id = 1 (WAITING)

若你要同時確認原本 authorized auto bid 是否存在,可再查:

SELECT id, quote_service_id, is_auto_quote, is_narrow_match, is_want_to_contact_provider
FROM quote_bids
WHERE quote_request_id = 19357
ORDER BY id ASC;

如果 charge fail path 正常,通常會看到:

  • 前面有一筆 authorized auto bid 嘗試
  • 後面補出一筆 narrow / new-leads fallback bid

怎麼清掉這次測試資料

假設:

  • quote_request_id = 19357

先刪 transaction:

DELETE FROM transactions
WHERE class = 'QuoteBid'
  AND foreign_id IN (
    SELECT id FROM quote_bids WHERE quote_request_id = 19357
  );

再刪 request 關聯:

DELETE FROM quote_bid_detect_contents
WHERE quote_bid_id IN (
  SELECT id FROM quote_bids WHERE quote_request_id = 19357
);
 
DELETE FROM read_segment_9_matches WHERE quote_request_id = 19357;
DELETE FROM quote_request_match_infos WHERE quote_request_id = 19357;
DELETE FROM quote_fee_adjust_maps WHERE quote_request_id = 19357;
DELETE FROM quote_group_variable_fee_logs WHERE quote_request_id = 19357;
DELETE FROM quote_request_logs WHERE quote_request_id = 19357;
DELETE FROM quote_request_landing_pages WHERE quote_request_id = 19357;
DELETE FROM quote_form_submission_fields WHERE quote_request_id = 19357;
DELETE FROM quote_form_submissions WHERE quote_request_id = 19357;
DELETE FROM quote_request_limit_ids WHERE quote_request_id = 19357;
DELETE FROM cache_queues WHERE foreign_id = 19357;
DELETE FROM quote_activities WHERE model = 'QuoteRequest' AND foreign_id = 19357;
DELETE FROM quote_bids WHERE quote_request_id = 19357;
DELETE FROM quote_requests WHERE id = 19357;

如果這張單有 external integration,也補刪:

DELETE FROM quote_request_fetnets WHERE quote_request_id = 19357;
DELETE FROM quote_request_life_tokens WHERE quote_request_id = 19357;

最短使用方式

  1. 匯入 Postman collection
  2. session_token
  3. quote_service_id
  4. 確認 category 合法允許 Authorize
  5. 送 request
  6. 用 response 裡的 QuoteRequest.idquote_bids / transactions