讓付款那一步可以被跳過,後面的流程才測得動。
電商最難測的不是付款,是付款之後的那一長串:
付款成功 → 訂單轉 paid → 結算點數 → 寄通知信 → 開立發票 → 推送物流單 → 訂閱推進期數
這串東西你想測一次,就得先刷一次卡。用測試卡號、填 3D 驗證、等跳轉、等 notify 回來——一輪五分鐘,而且金流的測試環境,通常本機不能跑完。
於是大家就不測了。
我把付款方式做成同一個介面,所以要多一種假的,就只是多一個實作:
final class InstantSuccessFlow implements PaymentFlow
{
public function start(Order $order, CheckoutInput $input): Response
{
$order->markPaid();
return redirect()->route('account.orders.show', $order)->with('just_placed', true);
}
}
就這樣。 不打任何 API、沒有 return 頁、沒有 notify,直接把訂單標記為已付款。
結帳頁在 local / testing 環境會多出一個「立刻成功」的選項。選它、送出,三秒鐘後你就站在付款成功之後的那個世界裡,可以開始檢查點數有沒有發、信有沒有寄、發票有沒有開。
這點很重要。
如果你寫成 if (app()->environment('local')) { $order->markPaid(); return; } 塞在結帳流程裡,那就是在主流程裡挖了一個洞。那個洞會愈來愈大,而且測試環境跟正式環境走的路就不一樣了。
做成同一個介面的另一個實作,主流程一行都不用改。 解析付款方式、呼叫 start()、後續處理——完全相同的路徑,只有最外層那個物件不同。
當然,這個選項要擋在 local / testing 才出現。
真正該測但幾乎沒人測的,是失敗路徑。
刷卡被拒的時候,訂單應該維持 draft/unpaid、點數不能扣、通知信不能寄、庫存不能動。這些你怎麼驗證?用真金流的話,你得想辦法讓它失敗。
做一個 InstantFailureFlow,一行程式碼就能重現失敗場景。