---
title: "Refund Payment"
method: POST
path: "/admin/payments/{payment_id}/refund"
tags: ["admin"]
---

# Refund Payment

`POST /admin/payments/{payment_id}/refund`

Issue a Stripe refund for a payment.

After refund:
- For subscription payments: cancel subscription and downgrade user to free tier
- For credit pack payments: deduct the corresponding credits from user

Security:
- Uses FOR UPDATE lock to prevent race conditions
- Only allows full refund of remaining credits (no partial refunds)
- Aborts if Stripe subscription cancellation fails

## Path parameters

- `payment_id` string, uuid, required

## Request body

- RefundRequest — Request to issue a refund.
  - `amount_cents` integer, nullable — Optional refund amount in cents (defaults to full).
  - `reason` string, nullable — Refund reason for audit/logging.

## Response `200`

Successful Response

- RefundResponse — Refund record.
  - `id` string, uuid, required
  - `user_id` string, uuid, required
  - `subscription_id` string, uuid, nullable, required
  - `payment_id` string, uuid, nullable, required
  - `stripe_refund_id` string, required
  - `amount_cents` integer, required
  - `currency` string, required
  - `status` string, required
  - `reason` string, nullable, required
  - `receipt_url` string, nullable, required
  - `created_at` string, date-time, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/meganova/apis/fastapi.md) · [All operations](https://skmtc.net/meganova/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/meganova/fastapi/revisions/2b2bab8b9017/schema)
