- The client calls
/api/client/job/payment/:jobIdto create a Stripe Checkout session. - The user completes payment on the Stripe-hosted checkout page.
- Stripe sends a
checkout.session.completedevent to the/webhookendpoint. - The webhook handler creates the escrow record and the contract.
- The client calls
PATCH /api/client/release-fund/:contractIdto request fund release after the work is done. - An admin approves the release via
PUT /api/admin/escrow/release-fund/:contractId, which transfers the funds to the freelancer’s wallet.
All monetary values are in INR (Indian Rupees). Stripe amounts are passed in paise (1 INR = 100 paise), so the server multiplies the
rate by 100 when creating the checkout session.POST /api/client/job/payment/:jobId
Create a Stripe Checkout session for a job. The client is redirected to the returned session URL to complete payment. Auth required: Yes —client role
Path parameters
MongoDB ObjectId of the job being paid for.
Request body
Job title displayed on the Stripe checkout page.
Amount in INR. Converted to paise internally before being sent to Stripe.
MongoDB ObjectId of the freelancer being hired. Stored in the Stripe session metadata so the webhook can create the contract.
Response
The Stripe Checkout session ID. Use this with
stripe.redirectToCheckout({ sessionId }) on the frontend to redirect the user.cURL
POST /webhook
Stripe sends signed events to this endpoint after a payment succeeds. The handler verifies the Stripe signature and processescheckout.session.completed events to create escrow records.
Auth required: No (Stripe-signed, verified with STRIPE_WEBHOOK_SECRET)
Request headers
Stripe-generated signature used to verify the event originated from Stripe.
Behavior
When acheckout.session.completed event is received:
- The session
metadata(jobId,clientId,freelancerId) is extracted. - An escrow record is created with
status: "funded". - A platform fee is calculated and stored.
- The
freelancerEarning(amount minus platform fee) is stored on the escrow record.
200 status code.
cURL
POST /api/client/review/rate-freelancer/:clientId
Submit a star rating and written review for a freelancer after a contract is completed. Auth required: Yes —client role
Path parameters
MongoDB ObjectId of the client submitting the review.
Request body
MongoDB ObjectId of the freelancer being reviewed.
MongoDB ObjectId of the completed contract this review is for.
Integer from
1 to 5.Written review text.
Response
Confirmation that the review was saved.
The created review document.
cURL
GET /api/client/review/show-reviews/:freelancerId
Retrieve all reviews for a specific freelancer. Auth required: NoPath parameters
MongoDB ObjectId of the freelancer.
Response
Array of review objects. Each review includesrating, description, clientId, and createdAt.
cURL
PUT /api/admin/escrow/release-fund/:contractId
Admin approves a pending fund-release request. Transfers thefreelancerEarning amount from the escrow record to the freelancer’s wallet.
Auth required: Yes — admin role
Path parameters
MongoDB ObjectId of the contract whose funds should be released.
Response
Confirmation that funds were released.
Updated escrow record reflecting the
released status.The client must have first called
PATCH /api/client/release-fund/:contractId to set releaseFundStatus to Requested before an admin can approve the release.cURL
PUT /api/admin/escrow/refund-client/:contractId/:clientId
Refund the escrowed funds to the client. Used when a contract is canceled or disputed. Auth required: Yes —admin or client role
Path parameters
MongoDB ObjectId of the contract.
MongoDB ObjectId of the client to refund.
Request body
Short reason code for the cancellation (e.g.,
"freelancer_unresponsive").Detailed description of the cancellation reason.
Response
Confirmation that the refund was processed.
Updated escrow record reflecting
status: "refunded".cURL
POST /api/media/upload
Upload an image or video file for use in chat messages. Returns the stored URL and media type. Auth required: No (protected at the application level via session)Request body
Send the file asmultipart/form-data with the field name media.
Image or video file. Images are detected by MIME type prefix
image/; all other files are treated as video.Response
The URL of the uploaded file as returned by the storage provider (Cloudinary).
image or video, determined by the uploaded file’s MIME type.cURL
