Skip to main content

max / makenotwork

1.3 KB · 47 lines History Blame Raw
1 //! Self-service refund endpoint for creators.
2
3 use axum::Json;
4 use axum::extract::{Path, State};
5 use axum::response::IntoResponse;
6 use serde::Deserialize;
7 use sqlx::PgPool;
8
9 use crate::{
10 Billing,
11 auth::AuthUser,
12 db::{ItemId, TransactionId},
13 error::Result,
14 };
15
16 #[derive(Debug, Deserialize)]
17 pub(crate) struct RefundRequest {
18 pub transaction_id: TransactionId,
19 }
20
21 /// Issue a line-scoped refund for one transaction on this item.
22 ///
23 /// A thin wrapper over [`crate::payments::refund::refund`], which holds every
24 /// check and the atomic claim. The described Sales panel
25 /// (`crate::quasi::item_sales`) calls the same core from its writes-only nest,
26 /// so the money path exists once (`b25dd957`). This route stays for API
27 /// consumers.
28 #[tracing::instrument(skip_all, name = "items::refund_transaction")]
29 pub(in crate::routes::api) async fn refund_transaction(
30 State(db): State<PgPool>,
31 State(payments): State<Billing>,
32 AuthUser(user): AuthUser,
33 Path(id): Path<ItemId>,
34 Json(req): Json<RefundRequest>,
35 ) -> Result<impl IntoResponse> {
36 crate::payments::refund::refund(
37 &db,
38 payments.payment_caps.refundable.as_ref(),
39 &user,
40 id,
41 req.transaction_id,
42 )
43 .await?;
44
45 Ok(Json(serde_json::json!({ "ok": true })))
46 }
47