Skip to content

Order Refund

First-Pass Node Dossier

This page is an evidence-backed node dossier generated from the domain hierarchy and node questionnaire.

What It Is

OrderRefund is the payment-settlement record that captures money returned against a specific order payment, optionally links that refund to an operational return, and tracks gateway status or reasons.

Parent hierarchy:

  • Payments & Billing
  • Refunds And Balance Recovery
  • Order Refund

Primary implementation paths:

  • packages/framework/src/Models/OrderRefund.php
  • packages/framework/src/Http/Controllers/Api/Admin/OrderRefundsController.php
  • packages/framework/src/Actions/OrderRefund
  • packages/framework/src/Actions/PaymentGateway
  • packages/framework/src/Actions/Stripe/CreateStripeOrderPaymentRefund.php

What Users Can Do With It

Direct capabilities

Operators can:

  • list refund records under an order
  • create refund records through the admin API
  • create refunds tied to an order return
  • send refund emails when the refund succeeds

Indirect capabilities

Other workflows use OrderRefund to:

  • refund selected order items
  • refund and cancel an unfulfilled order
  • invoice qualifying customer-satisfaction refunds
  • update order balance and paid-state calculations

Things users cannot do directly

This pass did not find a standalone packaged admin refund page. Refund creation is exposed through nested order APIs and parent order actions rather than a shared refund workspace.

Where It Is Managed

ChannelRoleNotes
Admin nested orders.refunds APIDirectMain packaged list and creation surface
Order refund actionsParent-ownedSelected-item and cancel-and-refund flows create refund records
Order return workflowsIndirectA refund can link back to an OrderReturn
Customer visibilityIndirectSuccess emails and accounting outputs expose the outcome

Sources:

  • packages/framework/src/Http/Controllers/Api/Admin/OrderRefundsController.php
  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php
  • packages/framework/src/Actions/OrderRefund/RefundSelectedItems.php
  • packages/framework/src/Actions/OrderRefund/RefundAndCancelOrder.php

Channel-Level Field Coverage

Create flow

Creating a refund validates:

  • order_payment_id
  • amount
  • reason_type
  • reason
  • optional order_return_id
  • optional note
  • optional status
  • optional send_email

sc_object_id is also supported for webhook-created or externally-sourced refunds.

Source:

  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

Reason fields

The shared package distinguishes between:

  • reason_type, which is a strict enum
  • reason, which is a required free-form string

Gateway-facing refund reasons can differ again from the local business reason stored on the refund row.

Sources:

  • packages/framework/src/Enums/OrderRefund/RefundReasonType.php
  • packages/framework/src/Models/OrderRefund.php
  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

List and show surface

The admin refund list can include:

  • orderPayment
  • orderPayment.paymentGateway
  • orderReturn

Source:

  • packages/framework/src/Http/Controllers/Api/Admin/OrderRefundsController.php

Configuration And Data Model

Key model characteristics:

  • soft-deletable
  • UUID-based
  • activity-logged
  • linked to one order payment and optionally one order return
  • supports an invoice() morph-one relationship

Important relationships:

  • order()
  • orderReturn()
  • orderPayment()
  • createdByUser()
  • invoice()

Source:

  • packages/framework/src/Models/OrderRefund.php

Relationships

OrderRefund directly connects:

  • payment settlement
  • order balance adjustment
  • return-linked recovery
  • refund emails
  • invoice generation for qualifying refunds

Practical dependents:

  • order amount due
  • refund reporting
  • invoice generation
  • customer communication

Rules And Downstream Effects

Refund guardrails

Refund creation blocks:

  • payments already fully refunded
  • payments with failed status
  • refund amounts greater than the remaining captured refundable amount

Source:

  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

Gateway-specific execution

Refund execution dispatches by gateway type:

  • Stripe
  • manual
  • Shopify

Sources:

  • packages/framework/src/Models/OrderRefund.php
  • packages/framework/src/Actions/Stripe/CreateStripeOrderPaymentRefund.php
  • packages/framework/src/Actions/PaymentGateway/Manual/CreateOrderPaymentRefund.php

Imported-versus-executed refunds

sc_object_id is the key split in the creation flow:

  • when it is absent, the shared package executes the refund against the gateway
  • when it is present, the row is treated as imported or synced and gateway execution is skipped

Source:

  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

Order side effects

After a refund is created, the shared package:

  • saves gateway status and status reason
  • recalculates the order
  • dispatches OrderRefundCreated

Source:

  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

Nested-route caveat

The shared admin refund route is nested under an order, but refund creation trusts order_payment_id and does not use the path order as a hard ownership guard in the first-pass shared controller layer.

Sources:

  • packages/framework/src/Http/Controllers/Api/Admin/OrderRefundsController.php
  • packages/framework/src/Actions/OrderRefund/CreateOrderRefund.php

Refund email gating

Refund emails are only sent when:

  • the refund-email feature is enabled
  • the refund status is not pending or failed

Source:

  • packages/framework/src/Actions/OrderRefund/SendOrderRefundEmail.php

Status inconsistency

Refund status values are not a single clean enum across channels:

  • local flows commonly use success
  • Stripe sync commonly uses succeeded
  • disputes can store statuses such as lost

That matters because some order and email logic only checks selected status values.

Sources:

  • packages/framework/src/Actions/PaymentGateway/Manual/CreateOrderPaymentRefund.php
  • packages/framework/src/Actions/Stripe/SyncStripeOrderPaymentRefunds.php
  • packages/framework/src/Actions/Stripe/SyncStripeDispute.php
  • packages/framework/src/Actions/OrderRefund/SendOrderRefundEmail.php

Integrations And Automation

Refund orchestration

The refund layer is used by:

  • selected-item refunds
  • multi-payment refund splitting
  • refund-and-cancel flows

Sources:

  • packages/framework/src/Actions/OrderRefund/RefundSelectedItems.php
  • packages/framework/src/Actions/OrderRefund/RefundMultiplePayments.php
  • packages/framework/src/Actions/OrderRefund/RefundAndCancelOrder.php

Invoice generation

Customer-satisfaction refunds are eligible for scheduled invoice generation when they succeed.

Sources:

  • packages/framework/src/Actions/Invoice/GenerateInvoices.php
  • packages/framework/src/Actions/Invoice/CreateInvoiceFromRefund.php

Where It Appears To End Users

OrderRefund is mostly an operator and accounting concept.

Customers experience it through:

  • refund emails
  • order-balance changes
  • downstream invoice or accounting communication

The shared storefront inspected in this pass does not expose a standalone refund-history page.

Current Documentation Takeaways

  1. OrderRefund is the payment-settlement side of recovery, not the same thing as an operational return.
  2. Refund creation is strongly validated, gateway-specific, and can be imported rather than executed when the refund already exists upstream.
  3. One operator refund action can fan out into multiple refund rows because each row belongs to a single payment.
  4. Refund records matter for order balance, email communication, and selective invoice generation.

Open Questions

  • This first pass did not inspect host-app finance dashboards that may surface refund records beyond the shared nested admin API.