Skip to main content
POST
Verify Payment and Activate Subscription
This endpoint verifies the Razorpay payment signature using HMAC-SHA256, creates a project, and activates the user’s subscription with automated expiry notifications.

Authentication

Requires JWT authentication via the verifyJWT middleware.

Request Body

string
required
The payment ID returned by Razorpay after successful payment
string
required
The order ID created in the init endpoint
string
required
The signature generated by Razorpay to verify payment authenticity

Signature Verification

The endpoint verifies payment authenticity using HMAC-SHA256:
Implementation details in verify.controller.js:20.
The KEY_SECRET is your Razorpay API secret. Never expose this on the client side. Signature verification must always happen on the server.

Subscription Duration

The subscription end date is calculated based on the environment:

Production Environment

  • Start Date: Current timestamp
  • End Date: Current timestamp + (months × 30 days)
  • Expiry Warning: 5 days before end date (months × 25 days)

Development/Test Environment

  • Start Date: Current timestamp
  • End Date: Current timestamp + 60 minutes
  • Expiry Warning: 2 minutes before end
See implementation in verify.controller.js:54.

Response

boolean
Indicates successful payment verification
object
User’s subscription status (if available)
string
The ID of the newly created project
string
Success message: "Payment verified successfully!"

Activation Flow

On successful verification, the endpoint performs the following operations:

1. Verify Pending Order

  • Fetches PendingOrder matching user ID and order ID
  • Validates order exists and status is not already "completed"
  • Prevents duplicate processing

2. Create Completed Order

Creates a CompletedOrder record with:
  • userid: User ID
  • orderid: Razorpay order ID
  • months: Subscription duration
  • amount: Payment amount in paise
  • plan: Subscription plan (“pro”)
  • status: "completed"
  • projectid: Reference to created project

3. Create Project

Creates a new Project with:
  • paymentId: Reference to CompletedOrder
  • plan: Subscription plan (“pro”)
  • startDate: Current timestamp
  • endDate: Calculated expiry date
  • owner: Authenticated user ID

4. Schedule Background Jobs

Three Bull queue jobs are scheduled:

Expiry Warning Notification

Subscription Start Notification

Subscription Expiry Handler

See verify.controller.js:87.

5. Update Order Status

Marks PendingOrder status as "completed" to prevent reprocessing.

Request Example

Response Examples

Success Response

Missing Parameters

User Not Found

Order Not Found

Already Processed

Invalid Signature

Server Error

Security Considerations

Always verify the signature on the server side. Never trust payment verification from the client.
  1. Signature Verification: Uses HMAC-SHA256 with your Razorpay secret key
  2. Duplicate Prevention: Checks if order is already processed
  3. User Authentication: Requires valid JWT token
  4. Order Ownership: Verifies order belongs to authenticated user
  5. Expiry Protection: Pending orders auto-delete after 2 hours

Database Schema

CompletedOrder

Project Updates

Integration Example

Error Handling

The endpoint handles several error scenarios:
  1. Missing payment details (400): Returns error if any required field is missing
  2. Invalid user (400): User must be authenticated
  3. Order not found (400): Order must exist in PendingOrders
  4. Already processed (400): Prevents duplicate subscription activation
  5. Signature mismatch (400): Payment verification failed
  6. Server errors (500): Database or Razorpay API errors

Best Practices

  1. Idempotency: The endpoint checks for already-processed orders
  2. Atomic Operations: Uses database transactions where possible
  3. Background Jobs: Email notifications are queued, not blocking
  4. Error Logging: Errors are logged to console for debugging
  5. Webhook Integration: Consider adding Razorpay webhooks for redundancy
In production, implement webhook verification as a backup to handle edge cases where the user closes the browser before the verify call completes.