Razorpay 模型
| Razorpay 概念 | 在 InsForge 中的意義 |
|---|---|
| Item | 帶金額的可銷售單位。鏡像同步至 payments.razorpay_items。 |
| Plan | 圍繞某個 Item 建立的週期性訂閱定義。鏡像同步至 payments.razorpay_plans。 |
| Order | 一次性付款物件。透過 POST /api/payments/razorpay/{environment}/orders 建立,並鏡像同步至 payments.razorpay_orders。 |
| Payment | 服務商回傳的付款結果。透過 Webhook 與同步投影到 payments.transactions。 |
| Subscription | 與某個 Plan 綁定的 Razorpay 訂閱。鏡像同步至 payments.razorpay_subscriptions。 |
| Webhook event | 存放於 payments.webhook_events 中且 provider = 'razorpay' 的已驗證服務商事件。 |
payments.razorpay_subscriptions 的 RLS UPDATE 政策檢查呼叫方之後,用於取消、暫停與恢復訂閱。
對於一次性產品,建立 Razorpay Order 時只需提供金額、幣別和 receipt 即可。不過,仍建議為可銷售的產品建立 Razorpay Item,這樣在同步之後,產品目錄就能在 InsForge 與 Razorpay 中可見。請將 Order 視為一次付款嘗試,而非您的產品目錄。
設定
在 Dashboard -> Payments -> Settings 中或透過管理 API 設定test 與 live 的 Razorpay Key ID 與 Key Secret。若尚不存在 Webhook 簽署密鑰,InsForge 會自動產生一個。
Razorpay 的 Webhook 必須在 Razorpay Dashboard 中手動建立。一般的 Razorpay 商戶 API 金鑰不支援自動註冊 Webhook。
- 開啟 Dashboard -> Payments -> Settings -> Webhooks。
- 複製 Razorpay Webhook URL 與 Webhook Secret。
- 在 Razorpay Dashboard 中,使用複製的 URL 與密鑰建立一個 Webhook。
- 選擇 InsForge 處理的事件。
- 儲存 Webhook 並完成一次測試付款以確認送達。
payment.authorizedpayment.capturedpayment.failedorder.paidinvoice.paidinvoice.expiredrefund.createdrefund.processedrefund.failedsubscription.createdsubscription.activatedsubscription.chargedsubscription.updatedsubscription.cancelledsubscription.pausedsubscription.resumedsubscription.haltedsubscription.completedsubscription.expired
一次性訂單
首先建立一個由應用程式擁有的待處理訂單(pending order)。接著使用目前的 InsForge 使用者權杖建立一個 Razorpay Order。POST /api/payments/razorpay/{environment}/orders。回應中包含 checkoutOptions,其中帶有 Razorpay Checkout 原生欄位,例如 key 和 order_id。請在前端載入 https://checkout.razorpay.com/v1/checkout.js,並將這些選項傳給 new Razorpay(options).open()。
如果您的履行觸發器讀取 notes.order_id,請在建立 Order 或 Subscription 時傳入 notes: { order_id: ... }。
在 Razorpay Checkout 回傳 razorpay_order_id、razorpay_payment_id 和 razorpay_signature 之後,請在後端驗證簽章:
訂閱
在建立訂閱之前,請先建立或同步一個 Razorpay Plan。Plan 與 Stripe 的 Price 並非同一回事,它是圍繞 Razorpay Item 建立的週期性定義。POST /api/payments/razorpay/{environment}/subscriptions。回應中包含 checkoutOptions.subscription_id。請使用該訂閱 ID 開啟 Razorpay Checkout。在 Checkout 回傳 razorpay_subscription_id、razorpay_payment_id 和 razorpay_signature 之後,驗證該筆授權付款:
payments.razorpay_subscriptions 上的 INSERT 政策。取消、暫停與恢復操作則會評估同一張表上的 UPDATE 政策。PostgreSQL 也會對 INSERT/UPDATE ... RETURNING 回傳的資料列套用 SELECT 政策,因此當政策檢查需要回傳該資料列時,請確保同一主體(subject)對呼叫方可見。僅授予使用者政策檢查所需的資料表存取權限;對服務商的實際變更操作仍透過後端執行。
Webhook 與履行
Razorpay 的 Checkout 回呼與簽章驗證並不能取代 Webhook。請使用payments.webhook_events 來觸發履行。請勿將履行觸發器附加到諸如 payments.razorpay_subscriptions 之類的服務商鏡像表上;同步與 Webhook 投影可能會獨立於服務商事件送達而更新這些資料列。
同步與儀表板狀態
Razorpay 同步會鏡像 Items、Plans、Customers、Subscriptions、Invoices 和 Payments。Invoices 與 Payments 會填入payments.transactions 這個儀表板/報表投影。Transactions 中包含服務商的參照 ID,例如 payment、invoice、order、subscription 和 refund 的 ID,方便您在 Razorpay Dashboard 中查看原始紀錄。
請將面向使用者的訂單、額度與權益狀態保存在您自己的應用程式資料表中。請將 payments.transactions 視為儀表板/報表狀態,而非主要的業務流程。