Skip to main content
POST
/
api
/
payments
/
admin
/
refund
/
:purchaseId
curl -X POST https://api.vaniykempire.com/api/payments/admin/refund/65f1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer ADMIN_JWT_TOKEN"
{
  "message": "Refund successful",
  "purchase": {
    "_id": "65f1a2b3c4d5e6f7g8h9i0j1",
    "user": "507f1f77bcf86cd799439011",
    "content": "507f191e810c19729de860ea",
    "amount": 29.99,
    "stripePaymentIntentId": "pi_3MtwBwLkdIwHu7ix28a3tqPa",
    "status": "refunded",
    "purchasedAt": "2024-03-15T10:30:00.000Z"
  }
}
Administrator endpoint for issuing refunds on completed purchases. Creates a refund in Stripe and updates the purchase status to refunded.

Authentication

Requires authentication with administrator privileges.
This endpoint requires admin role. Regular users will receive a 403 Forbidden response.

Path Parameters

purchaseId
string
required
The MongoDB ObjectId of the purchase to refund. Must be a completed purchase.

Refund Rules

  • Only purchases with status completed can be refunded
  • Cannot refund purchases that are pending, failed, or already refunded
  • Refund is processed through Stripe’s refund API
  • Full amount is refunded (partial refunds not supported)
  • Purchase status is updated to refunded upon success

Response

message
string
Success message confirming the refund
purchase
object
Updated purchase object with refunded status

Stripe Refund Process

  1. Endpoint receives refund request with purchaseId
  2. Server validates purchase exists and has status completed
  3. Server calls Stripe refund API: stripe.refunds.create({ payment_intent: stripePaymentIntentId })
  4. Stripe processes full refund to original payment method
  5. If Stripe refund succeeds, purchase status updated to refunded
  6. Refunded amount returns to customer’s card in 5-10 business days

Stripe Refund Details

  • Refund amount: Full payment amount (partial refunds not supported)
  • Refund destination: Original payment method
  • Refund timeline: 5-10 business days for card refunds
  • Stripe fees: Stripe fees are not returned for refunds
  • Refund status: Must be succeeded for purchase to be marked as refunded
curl -X POST https://api.vaniykempire.com/api/payments/admin/refund/65f1a2b3c4d5e6f7g8h9i0j1 \
  -H "Authorization: Bearer ADMIN_JWT_TOKEN"
{
  "message": "Refund successful",
  "purchase": {
    "_id": "65f1a2b3c4d5e6f7g8h9i0j1",
    "user": "507f1f77bcf86cd799439011",
    "content": "507f191e810c19729de860ea",
    "amount": 29.99,
    "stripePaymentIntentId": "pi_3MtwBwLkdIwHu7ix28a3tqPa",
    "status": "refunded",
    "purchasedAt": "2024-03-15T10:30:00.000Z"
  }
}

Error Scenarios

ScenarioStatus CodeError Message
Purchase not found404”Purchase not found”
Purchase is pending400”Only completed purchases can be refunded”
Purchase is failed400”Only completed purchases can be refunded”
Already refunded400”Only completed purchases can be refunded”
Stripe refund fails400”Refund failed”
Not authenticated401”Not authenticated”
Not admin403”Admin access required”
Server error500Error message details

Refund Limitations

  • Stripe charges are not refunded
  • Only full refunds are supported (no partial refunds)
  • Refunds cannot be reversed once processed
  • Some payment methods may take longer than 10 business days

Best Practices

  1. Verify purchase details before refunding
  2. Document refund reason in admin logs or external system
  3. Notify the customer about the refund via email
  4. Check Stripe Dashboard to confirm refund processed
  5. Consider partial refunds for specific use cases (requires code modification)

Use Cases

  • Customer requests refund for purchased content
  • Content was incorrectly charged
  • Quality issues with content
  • Duplicate purchase by user
  • Accidental purchase
  • Customer service resolution

Notifications

This endpoint does NOT automatically notify users. Implement email notifications separately to inform customers about refunds.

Idempotency

Calling this endpoint multiple times on the same purchase:
  1. First call: Creates refund, updates status to refunded, returns success
  2. Subsequent calls: Returns 400 error “Only completed purchases can be refunded”
This prevents accidental double refunds.

Stripe Dashboard

After issuing a refund:
  1. Go to Stripe Dashboard → Payments
  2. Search for payment intent ID
  3. View refund details and status
  4. Monitor refund completion

Implementation Notes

  • Requires authenticate and requireAdmin middleware
  • Full refund only (entire payment intent amount)
  • User and content fields are not populated in response
  • Refund is synchronous (waits for Stripe response)
  • Stripe refund status must be succeeded for purchase update
  • Source: src/controllers/paymentController.js:182-217

Testing

Test Mode

Use Stripe test mode to test refunds without real money:
// Use test API keys
const stripe = require('stripe')('sk_test_...');

// Create test payment
// Issue refund using test purchase ID
// Verify refund in Stripe test dashboard

Test Cards

Stripe provides test cards that simulate different refund scenarios:
  • 4242 4242 4242 4242 - Successful refunds
  • 4000 0000 0000 0259 - Successful charges with dispute risk

Monitoring

Track refund metrics:
  • Total refunds per month
  • Refund rate (refunds / total purchases)
  • Average refund amount
  • Common refund reasons (requires manual tracking)
  • Refund processing time

Build docs developers (and LLMs) love