POST /users/update_auto_refill.json
狀態
已補 action / routing / PHPUnit;legacy / new staging success path 已驗證。
這支 API 主流程只負責更新使用者的自動儲值方案設定;不在此 API 直接刷卡、不建立 transaction、不寫 event queue。
操作路徑
Web 帳號付款設定頁顯示目前自動扣款方案:
https://staging.pro360.com.tw/dashboard/settings在「自動扣款設定」點「更改方案」後會進入:
https://staging.pro360.com.tw/dashboard/pricing/changing選擇自動儲值方案或「依實際費用扣款」後儲存,前端送:
POST /users/update_auto_refill.json前端來源:
| 檔案 | 行為 |
|---|---|
/Users/mattsu/Documents/Site/web-app/modules/components/dashboard/account/PaymentSettings.js:101-138 | 顯示目前自動扣款設定,點「更改方案」導到 /dashboard/pricing/changing。 |
/Users/mattsu/Documents/Site/web-app/modules/components/dashboard/PriceView.js:259-289 | 儲存方案時呼叫 `updateRefillPackage(selectedIdRefill |
/Users/mattsu/Documents/Site/web-app/modules/components/dashboard/PriceView.js:378-381 | 綁卡完成後也會呼叫 updateRefillPackage() 套用選擇方案。 |
/Users/mattsu/Documents/Site/web-app/modules/utils/api-manager.js:1257-1268 | 呼叫 /users/update_auto_refill.json;有 package_id 才放進 FormData。 |
/Users/mattsu/Documents/Site/web-app/modules/actions/index.js:272-285 | 呼叫後重新抓 getMeBrief() 更新前端 user info。 |
Legacy 對照
| 項目 | legacy |
|---|---|
| Controller | /Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/UsersController.php:6345-6379 |
| request data helper | /Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/AppController.php:1233-1239 |
| JSON response helper | /Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/AppController.php:1307-1311 |
| API error handler | /Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/AppController.php:1320-1343 |
| generic exception handler | /Users/mattsu/Documents/Site/get-lancer-php56/app/Controller/AppController.php:1351-1361 |
| package helper | /Users/mattsu/Documents/Site/get-lancer-php56/app/Model/Package.php:11-17 |
Legacy 流程:
- 必須是 JSON request,且
RestApiHelper::hasValidApiSession($this)通過。 - 從 session 取得
user_id。 - 讀取 flat body 欄位
package_id,不是User[package_id]。 - 若
package_id非空,檢查packages.id = package_id AND is_active = 1 AND is_auto_refill = 1。 - 找不到 active auto refill package 時丟一般
Exception('package_id_not_found', 2)。 - 更新
users.auto_refill_package_id:package_idempty 時寫0package_id非 empty 時寫該值
- 回
{"status":"success","error":0}。
Session helper 行為:
- legacy
RestApiHelper::hasValidApiSession()不加users.is_active = 1guard;只要 API key、session row、user row 有效即可。 - blocked user 會直接回 HTTP 403 +
{"error":5,"message":"Blocked User"}。 - legacy session helper 的 DB load path 會更新
users.iphone_last_access/last_access_client,且符合 returned PRO 條件時可能寫task_queue的returnedQuoteService。
New 對照
| 項目 | new |
|---|---|
| Endpoint | Endpoint/V1/Users.php:885-943 已補 update_auto_refill()。 |
| Routing | Lib/Common/RouterRule/Mapping.php:100-103 已補 users/update_auto_refill\.json explicit mapping。 |
| package helper | Lib/Model/Package.php:23-28 已有 getActiveAutoRefillPackageById(),條件與 legacy helper 對齊。 |
| user response field | Endpoint/V1/Users.php:59-66、Lib/Model/User.php:298-306 已包含 auto_refill_package_id,成功後前端 getMeBrief() 可讀到更新值。 |
已搬移:
Endpoint/V1/Users.php::update_auto_refill()Mapping.phpexplicit route:users/update_auto_refill\.json- PHPUnit:
tests/UsersUpdateAutoRefillTest.php
Request
成功設定方案:
POST /users/update_auto_refill.json
package_id=<active auto refill package id>取消自動儲值 / 改成依實際費用扣款:
POST /users/update_auto_refill.json前端 updateRefillPackage() 在 package_id 為 null / 0 時不送欄位;legacy 會因 empty($package_id) 寫回 0。
Response
成功:
{"status":"success","error":0}Invalid request / invalid session:
{"error":1,"status":"invalid request"}Invalid package:
legacy 丟一般 Exception('package_id_not_found', 2),會走 handleException(),不是回 error=2:
{"error":999,"status":"<err_new_api_999 translated message>"}Blocked user:
{"error":5,"message":"Blocked User"}DB Side Effect
| table | 欄位 | 行為 |
|---|---|---|
users | auto_refill_package_id | 更新成 valid package id,或 empty package 時更新成 0。 |
users | modified | legacy User->save() 會更新 modified;new 明確 modified = NOW() 對齊。 |
Session helper side effect:
| table | 欄位 / row | 行為 |
|---|---|---|
users | iphone_last_access, last_access_client | legacy session helper DB load path 會更新;new 用 legacy session resolver 保留。 |
task_queue | returnedQuoteService | user 有 active service、quote_service_count > 0 且 iphone_last_access 超過 180 天時才可能寫入。 |
不應新增的 side effect:
- 不直接刷卡
- 不新增
transactions - 不新增
stripe_charges - 不新增
quote_user_subscription_logs - 不新增 event queue / task event queue
- 不更新
user_permission_preferences.payment_auto_refill - 不更新 wallet / debt / credit card customer
Payment 關係
這支 API 只設定 users.auto_refill_package_id。後續真正自動儲值發生在 quote bid / Stripe customer 付款流程讀取這個欄位時:
- legacy
Package::getActiveAutoRefillPackageById()條件是id、is_auto_refill = 1、is_active = 1。 - new
Lib/Model/Package.php:23-28已有同條件 helper。
因此搬移時不可把「設定方案」誤做成「立即扣款」。
測試計畫
PHPUnit 至少覆蓋:
- 有效 session + valid auto refill package:更新
users.auto_refill_package_id,response 為status=success,error=0。 - 有效 session + empty body:更新
users.auto_refill_package_id = 0。 - 有效 session +
package_id=0:依 legacyempty()語意更新users.auto_refill_package_id = 0。 - inactive user + valid session:不新增 active guard,仍可更新。
- 有效 session + inactive / non-auto-refill / missing package:回 legacy-shaped
error=999,且不更新 user。 - blocked user:回 HTTP 403 +
{"error":5,"message":"Blocked User"},且不更新 user。 - missing / invalid session:回
error=1,status=invalid request。 - negative test:確認不寫 transaction / event queue / task event queue,且不更新
user_permission_preferences.payment_auto_refill。
local container PHP 8.2:
docker exec -w /project-data cd63f9147e8d vendor/bin/phpunit tests/UsersUpdateAutoRefillTest.php
OK (7 tests, 52 assertions)Legacy staging 驗證:
- 2026-07-06 curl
package_id=36回{"status":"success","error":0}。 - DB 確認 user
8616的users.auto_refill_package_id = 36,packages.id=36為 active auto refill package。 - 當日未看到此 API 直接新增
transactions/event_queue/task_event_queue。
New staging 驗證:
- 2026-07-06 07:44:18 curl 空 body 回
{"status":"success","error":0};request log context 為空 body[]。 - 2026-07-06 07:45:50 curl
package_id=36回{"status":"success","error":0};request log context 有{"package_id":"36"}。 - DB 確認 session
6htrhsu7n3203fcg5t8maih0h2對到 user8616,且 finalusers.auto_refill_package_id = 36、users.modified = 2026-07-06 07:45:50。 - DB 確認
packages.id=36為 active auto refill package:is_active=1、is_auto_refill=1。 - 近 2 小時未看到 user
8616因本 API 直接新增transactions/event_queue/task_event_queue。 - 空 body 呼叫後理論上會先寫
0,但第二次package_id=36已覆蓋 final DB state;本次只能從 request log 確認空 body 有進入新版 endpoint。
待確認
- 若要驗證空 body 實際 DB intermediate state,需單獨呼叫空 body 後立即查
users.auto_refill_package_id = 0,再呼叫package_id=36還原。