feat(orders): implement QA audit fixes — return flow, refund webhook, TS cleanup
Convex backend (AUDIT-5–10): - schema: add returnLabelUrl, returnTrackingNumber, returnCarrier fields + by_return_tracking_number_and_carrier and by_stripe_payment_intent_id indexes - orders: markReturnReceived now sets status="completed"; add getOrderByPaymentIntent and applyReturnAccepted internal helpers - returnActions: add acceptReturn action — creates Shippo return label (is_return:true), persists label data, sends return label email to customer - stripeActions: handle refund.updated webhook to auto-mark orders refunded via Stripe Dashboard - shippoWebhook: add getOrderByReturnTracking; applyTrackingUpdate extended with isReturnTracking flag (return events use return_tracking_update type, skip delivered transition) - emails: add sendReturnLabelEmail; fulfillmentActions: createShippingLabel action Admin UI (AUDIT-1–6): - OrderActionsBar: full rewrite per authoritative action matrix; remove UpdateStatusDialog; add AcceptReturnButton for delivered+returnRequested state - AcceptReturnButton: new action component matching CreateLabelButton pattern - FulfilmentCard: add returnLabelUrl prop; show "Return label" row; rename outbound label to "Outbound label" when both are present - statusConfig: add return_accepted to OrderEventType and EVENT_TYPE_LABELS - orders detail page and all supporting cards/components Storefront & shared (TS fixes): - checkout/success, CheckoutErrorState, OrderReviewStep, PaymentStep: replace Button as/color/isLoading/variant="flat" with HeroUI v3-compatible props - ReviewList: isLoading → isPending for HeroUI v3 Button - packages/utils: add return and completed entries to ORDER_STATUS_LABELS/COLORS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,26 @@ export const handleWebhook = internalAction({
|
||||
(event.data.object as Stripe.Checkout.Session).id,
|
||||
);
|
||||
break;
|
||||
case "refund.updated": {
|
||||
const refund = event.data.object as Stripe.Refund;
|
||||
if (refund.status === "succeeded" && refund.payment_intent) {
|
||||
const paymentIntentId =
|
||||
typeof refund.payment_intent === "string"
|
||||
? refund.payment_intent
|
||||
: refund.payment_intent.id;
|
||||
const order = await ctx.runQuery(
|
||||
internal.orders.getOrderByPaymentIntent,
|
||||
{ stripePaymentIntentId: paymentIntentId },
|
||||
);
|
||||
if (order && order.paymentStatus !== "refunded") {
|
||||
await ctx.runMutation(internal.orders.applyRefund, {
|
||||
id: order._id,
|
||||
adminUserId: order.userId,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
console.log("Unhandled Stripe event type:", event.type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user