Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
|
Download docs/RAZORPAY_SETUP.md from larxius/SentinelScan-WSS: direct link, hf CLI and curl.
- Browser
- Download file 5.59 kB
-
https://huggingface.co/spaces/larxius/SentinelScan-WSS/resolve/main/docs/RAZORPAY_SETUP.md
- Command line
-
hf download hf://spaces/larxius/SentinelScan-WSS/docs/RAZORPAY_SETUP.md
-
curl -L -o RAZORPAY_SETUP.md https://huggingface.co/spaces/larxius/SentinelScan-WSS/resolve/main/docs/RAZORPAY_SETUP.md
5.59 kB
| # Razorpay Payments Setup (India + International) | |
| LarShield pricing uses **Razorpay** for one-time plan purchases: | |
| - **INR** checkout for Indian customers (UPI, cards, netbanking, wallets) | |
| - **USD** checkout for international customers (international cards) | |
| - A **platform fee** is added on top of the plan price at checkout | |
| ## 1. What the customer pays | |
| | Line item | Calculation | | |
| |---|---| | |
| | Service price | Plan price from `subscription_tiers` | | |
| | Platform fee | `PLATFORM_FEE_PERCENT` (default **2%**) of the service price | | |
| | GST | `PLATFORM_FEE_GST_PERCENT` (default **18%**) of the platform fee, **INR only** | | |
| | Total | Service + platform fee + GST | | |
| Example (Quick Scan, INR): | |
| ``` | |
| Service price Rs.499.00 | |
| Platform fee (2%) Rs. 9.98 | |
| GST (18%) Rs. 1.80 | |
| Total payable Rs.510.78 | |
| ``` | |
| USD checkouts add the 2% platform fee only (no Indian GST). | |
| All amounts are recalculated server-side in minor units (paise/cents). | |
| The browser never sends an amount. | |
| ## 2. Create the Razorpay account | |
| 1. Sign up at <https://dashboard.razorpay.com/signup>. | |
| 2. Complete KYC (business PAN, bank account) to move from Test to Live. | |
| 3. **Enable international payments**: Dashboard -> Account & Settings -> Payment methods -> International payments -> Request activation. | |
| 4. **Enable UPI / wallets / netbanking** under Payment methods if they are not already on. | |
| ## 3. Get the API keys | |
| Dashboard -> Account & Settings -> API Keys -> Generate Key. | |
| You get: | |
| ``` | |
| Key ID rzp_test_xxxxxxxxxxxx (or rzp_live_...) | |
| Key Secret xxxxxxxxxxxxxxxxxxxxxxxx | |
| ``` | |
| Store the **Key ID** and **Key Secret** only on the server (HF Secrets). The Key ID is sent to the browser as part of the order response; the Secret is never exposed. | |
| ## 4. Configure the webhook | |
| Dashboard -> Account & Settings -> Webhooks -> Add New Webhook. | |
| - **URL**: `https://<your-space>.hf.space/api/billing/webhook` | |
| - **Secret**: choose a strong random string, save it as `RAZORPAY_WEBHOOK_SECRET` | |
| - **Active events**: | |
| - `payment.captured` | |
| - `order.paid` | |
| - `payment.failed` | |
| The webhook is the safety net: if the customer closes the tab after paying, the webhook still activates the plan. Fulfilment is idempotent (same payment is never credited twice). | |
| ## 5. Environment variables | |
| Set these in **Hugging Face Space -> Settings -> Secrets** (or in `.env` locally): | |
| ```env | |
| RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxx | |
| RAZORPAY_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx | |
| RAZORPAY_WEBHOOK_SECRET=whsec_your_random_secret | |
| PLATFORM_FEE_PERCENT=2 | |
| PLATFORM_FEE_GST_PERCENT=18 | |
| USD_TO_INR_RATE=88 | |
| ``` | |
| Then **Factory Rebuild** the Space. | |
| ## 6. How the flow works | |
| ``` | |
| Pricing card "Get Started" | |
| | | |
| v | |
| POST /api/billing/quote -> service + fee + GST + total (displayed in modal) | |
| | | |
| v | |
| POST /api/billing/create-order -> Razorpay order created, pending Payment row saved | |
| | | |
| v | |
| Razorpay Checkout (UPI / card / netbanking / wallet / international card) | |
| | | |
| v | |
| handler -> POST /api/billing/verify-payment | |
| - HMAC SHA256 signature check | |
| - amount + currency + order id confirmed with Razorpay | |
| - organization tier upgraded | |
| - +3 scan credits added | |
| - audit log written | |
| | | |
| v | |
| Success modal and page reload | |
| Fallback: Razorpay webhook (payment.captured / order.paid) | |
| performs the same activation if the browser never returns. | |
| ``` | |
| ## 7. Test cards | |
| Razorpay test mode: | |
| | Method | Details | | |
| |---|---| | |
| | Card (success) | `4111 1111 1111 1111`, any future expiry, CVV `123` | | |
| | Card (failure) | `5104 0600 0000 0008` | | |
| | UPI (success) | `success@razorpay` | | |
| | UPI (failure) | `failure@razorpay` | | |
| Test mode does not move real money. | |
| ## 8. What gets written to the database | |
| `payments` row: | |
| | Column | Meaning | | |
| |---|---| | |
| | `amount` | Total charged (service + fee + GST), minor units | | |
| | `base_amount` | Service price, minor units | | |
| | `platform_fee` | Platform fee, minor units | | |
| | `tax_amount` | GST, minor units | | |
| | `currency` | `INR` or `USD` | | |
| | `razorpay_order_id` | Razorpay order id | | |
| | `razorpay_payment_id` | Razorpay payment id (unique - idempotency) | | |
| | `status` | `created` -> `successful` / `failed` | | |
| | `tier_id` | `quick` / `advanced` / `deep` | | |
| On success the app also: | |
| - sets `organizations.subscription_tier` to the purchased tier | |
| - adds `+3` to `organization_scan_quotas` for that scan type | |
| - writes an `audit_logs` entry | |
| ## 9. Admin controls | |
| Super Admin -> Dashboard -> **Dynamic Billing Control** edits USD and INR prices. | |
| The API is `PUT /api/billing/tiers/<tier_id>` and accepts: | |
| ```json | |
| { | |
| "monthly_price": 499, | |
| "yearly_price": 4990, | |
| "monthly_price_inr": 49900, | |
| "yearly_price_inr": 499000 | |
| } | |
| ``` | |
| All values are minor units. | |
| ## 10. Troubleshooting | |
| | Symptom | Cause / fix | | |
| |---|---| | |
| | `Payment gateway is not configured yet` | `RAZORPAY_KEY_ID` / `RAZORPAY_KEY_SECRET` missing in Space Secrets, or Space not rebuilt | | |
| | `Could not start the payment` | Invalid keys, or the Razorpay account is not activated for that currency | | |
| | International cards fail | International payments not enabled in Razorpay Dashboard | | |
| | Payment succeeds but plan not upgraded | Webhook URL/secret wrong, or `verify-payment` never reached. Open Razorpay Dashboard -> Payments, copy `pay_...` id, then contact support; the audit log will show whether fulfilment ran | | |
| | `Invalid payment signature` | Wrong `RAZORPAY_KEY_SECRET` for the key id used to create the order | | |
| | Old INR price shown | Update the tier in Super Admin -> Dynamic Billing Control | | |