One POST creates a hosted UPI checkout page. Customers pay to your FamApp UPI directly. NYC-X detects the payment via Gmail IMAP and fires a signed webhook to your server. No PCI scope, no chargebacks, no fees.
nycx_sk_).checkout_url to your customer.payment.success events.All requests use Bearer token authentication with your secret key.
Authorization: Bearer nycx_sk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Never expose your secret key in client-side code. Rotate immediately from the dashboard if leaked.
/api/v1/ordersCreates a payment order and returns a hosted checkout URL that expires in 5 minutes.
amountrequired | number | Payment amount in INR. Positive number, up to 2 decimals. |
description | string | Short human-readable label shown on checkout. |
customer_name | string | Optional. Attached to the order record. |
customer_email | string | Optional. Attached to the order record. |
success_redirect_url | string | Optional. If set, the checkout page auto-redirects here 5s after payment. |
{
"order": {
"id": "8b3e1d24-…",
"amount": 499,
"status": "pending",
"expires_at": "2026-07-08T14:30:00Z",
"success_redirect_url": "https://…"
},
"checkout_url": "https://nyc-x.example.com/checkout/8b3e1d24-…",
"expires_at": "2026-07-08T14:30:00Z"
}curl -X POST https://nyc-x.example.com/api/v1/orders \
-H "Authorization: Bearer nycx_sk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 499,
"description": "Pro plan",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"success_redirect_url": "https://yoursite.com/thank-you"
}'/api/v1/orders/{id}Poll to check if an order is paid, pending, awaiting_utr, or expired. Prefer webhooks over polling in production.
curl https://nyc-x.example.com/api/v1/orders/ORDER_ID \ -H "Authorization: Bearer nycx_sk_YOUR_SECRET_KEY"
NYC-X POSTs a JSON payload to your configured URL when payment state changes. Every request is signed with HMAC-SHA256.
payment.success — payment verified. Fulfill the order.payment.awaiting_utr — multiple pending orders with same amount, waiting on customer UTR.payment.expired — 5-minute timer elapsed without payment.{
"event": "payment.success",
"created_at": "2026-07-08T14:32:15.123Z",
"data": {
"order": {
"id": "8b3e1d24-…",
"amount": 499,
"status": "paid",
"utr": "121273691637",
"transaction_id": "FMPIB6081306209",
"paid_at": "2026-07-08T14:32:14.900Z",
"description": "Pro plan"
}
}
}Compute HMAC-SHA256 of the raw request body using your webhook secret. Compare to the X-NYCX-Signature header in constant time.
import hmac, hashlib
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header)
# In your webhook handler:
# raw = request.body
# sig = request.headers.get("X-NYCX-Signature")
# if not verify(raw, sig, "whsec_xxx"): abort(400)
# event = json.loads(raw)Bot user types /pay 499 → you POST an order → send checkout URL to the chat → unlock content on webhook.
On “Buy Now”, create an order server-side, redirect to checkout_url. Set success_redirect_url to your thank-you page.
Generate a checkout link, paste into an email/PDF invoice. Customer pays UPI directly. Webhook marks invoice paid.
Create an order per student, deliver the download link only after payment.success webhook fires.
| Code | Meaning |
|---|---|
| 400 | Invalid amount or malformed body. |
| 401 | Missing or invalid Bearer token. |
| 403 | Merchant hasn’t completed onboarding. |
| 404 | Order not found. |
| 500 | Server error — safe to retry with same idempotency key. |
Ping @DebjitFr on Telegram — usually replies within a few hours.