「加個信用卡付款」聽起來是一件事。等你真的做台灣電商,會發現付款方式至少八種:信用卡、分期、ATM 虛擬帳號、超商代碼、超商條碼、WebATM、LINE Pay、Apple Pay,還有貨到付款。而且每一種走的路完全不同——有些付完款當下就知道成功,有些是給你一組帳號、幾天後客人去繳費你才知道。

這篇拆一個真實電商平台怎麼設計這條「付款方式分流」,以及一個你沒得選的硬限制:卡號你根本不能存

為什麼是八種?因為市場逼的

先講一個誠實的:支援這麼多付款方式,不是我一開始就想鋪這麼廣,是被逼的。台灣的消費習慣就是這樣——你只收信用卡,一大票習慣用 ATM 轉帳、超商繳費的客人直接流失。這不是「要不要支援」的技術選擇,是「不支援就沒生意」的市場現實。

所以付款分流的設計目標很清楚:新增一種付款方式,不能動到訂單主流程。八種付款方式是八條分支,但它們最後都要匯回同一套訂單狀態機。

關鍵分野:即時付款 vs 非即時付款

八種方式表面上五花八門,但設計上只分兩類,而這個分類直接決定訂單狀態機怎麼走:

即時付款(信用卡、分期、行動支付):客人按下去、金流商當下回你成功或失敗。付款結果和下單幾乎同步。

非即時付款(ATM 虛擬帳號、超商代碼/條碼):客人下單時,金流商給你一組繳費帳號或代碼,加一個繳費期限。錢還沒進來。客人可能今天下單、後天才去超商繳,也可能根本不繳。

這個分野的殺傷力在於:非即時付款的訂單,錢還沒到,你的訂單要停在哪一態?

即時付款很單純——complete_checkout 建單即 PAID,因為錢確實到了。非即時付款不行:你收到的第一通 callback 只是「取號成功」,不是「付款成功」。這時候建單要建成 PENDING而且不能扣庫存(錢都還沒到,扣了萬一客人不繳,庫存就被卡死)。等客人真的去繳費,金流商發第二通 callback,你才把它推到 PAID

所以非即時付款是兩通 callback的流程:第一通取號建 PENDING 單、第二通繳費完成轉 PAID。這條「兩通 callback」的設計,是付款方式分流最容易被忽略、也最容易寫錯的地方。(callback 本身怎麼驗、怎麼防重複,是下一篇的主題。)

綁卡:為什麼你只能存 token,不能存卡號

「記住我的卡,下次一鍵付款」——這個功能背後有一條你沒得商量的紅線:你不能把信用卡卡號存進自己的資料庫。

這不是「最佳實踐」「建議這樣做」的等級。這是 PCI-DSS(信用卡產業資料安全標準)的法規要求,存了就是違法。真的把卡號、有效期、驗證碼存進你的 DB,一旦外洩,那是法律責任,不是「工程沒做好」而已。

所以綁卡的正確做法是 tokenization(代碼化):你把卡號交給金流商,金流商回你一個 token(一串沒有意義的代碼),你只存這個 token。下次付款,你拿 token 去跟金流商說「用這張」,真正的卡號從頭到尾只在金流商那邊,你的系統碰都沒碰過。

tokenization 的價值不只是安全——它縮小了你的合規稽核範圍。你的系統裡沒有任何卡號,PCI-DSS 要稽核的東西就少一大半。「不碰卡號」本身就是一種設計上的減負。

這其實是一條跨系統的通則:合規決定你能存什麼。不是先設計完資料模型再想合規,是合規一開始就限制了你的資料模型長什麼樣。(同樣的道理,命盤/生辰這種敏感個資也是——先有保存政策,才有資料表。)

收:付款分流的三個設計點

  1. 新增付款方式不能動訂單主流程——八條分支最後匯回同一套狀態機,這樣加第九種才不會全身動。
  2. 即時 vs 非即時決定訂單停在哪——非即時付款「錢還沒到」,訂單停 PENDING、不扣庫存,等第二通 callback 才轉 PAID。
  3. 合規是硬限制不是選項——卡號不能存(PCI-DSS),綁卡用 token,這條沒得商量。

接下來往哪走