Authorized Manual Verification
這份文件只處理一件事:
- 手動驗證
search_add authorized - 包含前置條件、Postman / staging 操作、DB / event 檢查、清資料方式
對應 Postman collection:
- search_add_authorized_payment_success.postman_collection.json
- search_add_authorized_charge_fail_fallback.postman_collection.json
- search_add_authorized_no_valid_card.postman_collection.json
目前文件內建的 fail 範例預設使用:
- requestor:
user_id = 8616 - provider:
user_id = 8617 quote_service_id = 9930- category:
159
前置條件
1. category 合法允許 Authorize
QuoteRequest[match_type] = 2不代表一定成立- category 必須允許
Authorizequote_categories.match_type = 2- 或
quote_categories.match_type = 3
如果 category 不允許:
- request 會先被正規化回
quote_requests.match_type = 1 - 這種 case 不應當成合法的
authorized驗證
2. Requestor user
最少需要:
session tokenphonename
Postman 對應:
{{session_token}}{{requestor_phone}}{{requestor_name}}
3. Provider user
最少需要:
quote_service_idusers.is_auto_quote_on = 1- category 對應的
quote_service_categories
如果要驗付款成功,還要有:
- 一筆有效 auto-quote card
stripe_customers.is_auto_quote = 1stripe_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 失敗:
101102104105
預期結果是:
- 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 = 3176user_id = 8617is_auto_quote = 1is_valid = 1is_default = 1card_info = VISA|TW|4242
但這還不夠。
真正要讓它走到 fallback,通常要靠:
- sandbox 失敗卡 / 失敗 token / 失敗 customer
- 或 local / test 環境的 fake charge 設定
只改 DB 只能保證:
- 不走 wallet
- 會進 charge path
不能單靠 DB 保證一定進 fallback。
Postman 使用方式
一定要改
{{session_token}}{{quote_service_id}}
視情況改
{{requestor_phone}}{{requestor_name}}{{request_description}}
category / form 注意事項
這份 collection 目前預設是:
quote_category_id = 159- 地毯清洗的
Form / FormTime / FormSummary
如果你把 category 換掉,下面這些也要一起換:
Form[...]FormTime[...]FormSummary
不然 request 可能因為 form/category 不匹配而失敗。
驗證順序
建議順序:
- wallet 直接付款
- sandbox 即時扣款成功
- sandbox 即時扣款失敗
- 最後才看 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 = 1is_paid_for_subscription = 1contact_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_id 查 transactions.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 = 33real_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_ProAuto_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 = 1auto_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 = 1is_want_to_contact_provider = 0is_narrow_match = 0narrow_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 = 1auto_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 = 0is_narrow_match = 1is_want_to_contact_provider = 1narrow_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;最短使用方式
- 匯入 Postman collection
- 改
session_token - 改
quote_service_id - 確認 category 合法允許
Authorize - 送 request
- 用 response 裡的
QuoteRequest.id查quote_bids/transactions