PayPal 提供「傻瓜式按鈕建立」,但實務上需根據訂單動態產生表單。關鍵在於 IPN (Instant Payment Notification):付款完成後,PayPal 主動 POST 交易資料到你的 notify_url,伺服器端驗證後更新訂單狀態。
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="merchant@example.com">
<input type="hidden" name="item_name" value="商品名稱">
<input type="hidden" name="amount" value="5.95">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="return" value="https://yoursite.com/payment/success">
<input type="hidden" name="cancel_return" value="https://yoursite.com/payment/cancel">
<input type="hidden" name="notify_url" value="https://yoursite.com/payment/ipn">
<input type="hidden" name="custom" value="ORDER_20240101_001">
<input type="hidden" name="rm" value="2">
<input type="image" src="https://www.sandbox.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" alt="PayPal 付款">
</form>
$_POST 所有參數cmd=_notify-validate POST 回 PayPalVERIFIED / INVALIDpayment_status == 'Completed'txn_id 未處理過(防重放)receiver_email 為己方商家信箱PayPal 後台 → Profile → My selling tools → Instant payment notifications → Update → 選擇「Receive IPN messages」→ 填入你的 https://yoursite.com/payment/ipn。
| 問題 | 對策 |
|---|---|
| IPN 收不到 | 確認 HTTPS、防火牆、PayPal IPN 歷史記錄有無重試 |
| 重複處理訂單 | 資料庫 txn_id 設唯一索引,或狀態機防重入 |
| 金額被竄改 | IPN 驗證時嚴格比對金額/幣別/商品編號 |
| Sandbox 郵件收不到 | 查看 Developer 面板 → Email 頁,所有 Sandbox 郵件集中在那裡 |