Skip to content

Refund handling

Refund handling ​

INFO

This document represents an architecture decision record (ADR) and has been mirrored from the ADR section in our Shopware 6 repository. You can find the original version here

Context ​

Shopware offers no way of unified refund handling. This results in every payment extension either implementing it themselves or not at all.

Decision ​

We want to implement the following structure to offer a unified refund handling for all extension types.

New refund data structure ​

A payment extension will need to persist its actual captures to use the refund handling. Those captures are bound to a specific OrderTransaction. The capture has an amount, allows saving an external reference.

OrderTransactionCapture ​

A capture is directly associated with a transaction. This relation is n order_transaction_captures to 1 order_transaction.

Database table ​

TypeField nameReferences
BINARY(16)id
BINARY(16)transaction_idorder_transaction.id
BINARY(16)state_idstate_machine_state.id
VARCHAR(255) NULLexternal_reference
LONGTEXTamount
LONGTEXT NULLcustom_fields

Entity ​

TypeProperty name
stringid
stringtransactionId
stringstateId
string/nullexternalReference
floattotalAmount
CalculatedPriceamount
array/nullcustomFields
OrderTransactionEntity/nulltransaction
StateMachineStateEntity/nullstateMachineState
OrderTransactionRefundCollection/nullrefunds

OrderTransactionCaptureRefund ​

A refund is directly associated with a capture. This relation is n order_transaction_capture_refunds to 1 order_transaction_capture.

Database table ​

TypeField nameReferences
BINARY(16)id
BINARY(16)capture_idorder_transaction_capture.id
BINARY(16)state_idstate_machine_state.id
VARCHAR(255) NULLreason
LONGTEXTamount
LONGTEXT NULLcustom_fields
VARCHAR(255) NULLexternal_reference

Entity ​

TypeProperty name
stringid
stringcaptureId
stringstateId
string/nullexternalReference
string/nullreason
floattotalAmount
CalculatedPriceamount
array/nullcustomFields
StateMachineStateEntity/nullstateMachineState
OrderTransactionCaptureEntity/nulltransactionCapture
OrderTransactionCaptureRefundPositionCollection/nullpositions

OrderTransactionCaptureRefundPosition ​

Refund positions are optional and only there if a refund is position-specific. They relate n order_transaction_capture_refund_positions to 1 order_transaction_capture_refund.

Database table ​

TypeField nameReferences
BINARY(16)id
BINARY(16)refund_idorder_transaction_capture_refund.id
BINARY(16)line_item_idorder_line_item.id
INT(11)quantity
VARCHAR(255) NULLreason
LONGTEXTrefund_amount
LONGTEXT NULLcustom_fields

Entity ​

TypeProperty name
stringid
stringrefundId
stringlineItemId
string/nullreason
intquantity
floatrefundPrice
CalculatedPricerefundAmount
array/nullcustomFields
OrderLineItemEntity/nulllineItem
OrderTransactionCaptureRefundEntity/nullorderTransactionCaptureRefund

Changes to existing entities ​

PaymentMethod ​

  • Add refundHandlingEnabled computed field if payment method handler implements RefundHandlerInterface

OrderTransaction ​

  • Add OneToManyAssociation OrderTransactionCaptureCollection captures

OrderLineItem ​

  • Add OneToManyAssociation OrderTransactionCaptureRefundPositionCollection|null refundPositions

State machine ​

Add 2 new state machines for OrderTransactionCapture and OrderTransactionCaptureRefund.

OrderTransactionCapture ​

We want to add the following states to a new order_transaction_capture.state state machine:

  • pending
  • completed
  • failed

OrderTransactionCaptureRefund ​

We want to add the following states to a new order_transaction_capture_refund.state state machine:

  • open
  • in_progress
  • cancelled
  • failed
  • completed

PaymentRefundHandlerInterface ​

Add an interface as outlined below:

php
public function refund(string $orderRefundId, Context $context): void;

PaymentRefundProcessor ​

The PaymentRefundProcessor gets triggered via a corresponding Admin-API action and contains the method processRefund as outlined below:

php
public function processRefund(string $refundId, Context $context): Response;

Apps ​

The whole refund handling should be available for apps and plugins. The following changes are required to allow apps to handle refunds.

\Shopware\Core\Framework\App\Manifest\Xml\PaymentMethod ​

Add refundUrl to the manifest PaymentMethod. Also change the xsd accordingly.

AppRefundHandler ​

Add an AppRefundHandler, which assembles payloads and talks to the app refund endpoint.

Captures and apps ​

Captures are written over the Admin-API endpoint.

Was this page helpful?
UnsatisfiedSatisfied
Be the first to vote!
0.0 / 5  (0 votes)