Home
Introduction to Module Reference Guide
Magento_Sales module
Magento_Sales module
Magento_Sales module is responsible for order processing and appearance in the system.
Magento_Sales module manages next system entities and flows:
order management
invoice management
shipment management (including track management)
credit memos management
Magento_Sales module is required for Magento_Checkout module to perform checkout operations.
Public API
InvoiceOrder
The InvoiceOrder service introduces a capability to execute Magento native business flow of the Sales module using API .
With this service you can:
create an invoice document (full or partial)
capture money placed with order payment
notify a customer about document creation
change order status and state
Parameters
Name
Description
Format
Example
Required / Optional
Default value
orderId
An identifier of a target order for operation.
Integer
Required
items
An array of order items that will be included to invoice. By default, the invoice will contain all order items.
Array of items with a format according to \Magento\Sales\Api\Data\InvoiceItemCreationInterface
.
[
{
"order_item_id" : 1 ,
"qty" : 2
},
{
"order_item_id" : 2 ,
"qty" : 0.5
}
]
Optional (required, when invoice must contain particular order items.
[]
capture
Flag that sets whether the customer’s payment can be captured using an online payments system (for example, PayPal). IMPORTANT: If you created Invoice with the flag set to default value (false
), you will not be able to capture money in Magento on the corresponding Invoice.
Boolean
Optional
false
notify
Flag that activates e-mail notification about new invoice for a customer. If true
, the service will notify a customer. If false
, the service won’t notify a customer.
Boolean
Optional
false
appendComment
Flag that determines whether a comment
argument must be included in an e-mail notification. If true
, the service adds the comment.
Boolean
Optional
false
comment
The comment to add to an invoice. Specify a comment if appendComment
is set to true
.
A format according to \Magento\Sales\Api\Data\InvoiceCommentCreationInterface
.
{
"comment" : "The first Invoice" ,
"is_visible_on_front" : true
}
Optional
null
arguments
Additional arguments. Reserved for use by extension modules.
A format according to \Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface
.
Optional
null
Return values
The service returns an identifier of the created Invoice.
REST
POST Endpoint
http://<magento_host>/rest/<store_code>/V1/order/<orderId>/invoice
REST declaration
etc/webapi.xml
<route url= "/V1/order/:orderId/invoice" method= "POST" >
<service class= "Magento\Sales\Api\InvoiceOrderInterface" method= "execute" />
<resources>
<resource ref= "Magento_Sales::sales" />
</resources>
</route>
SOAP
SOAP Endpoint
http://<magento_host>/soap/<store_code>?wsdl&services=salesInvoiceOrderV1
PHP interface
\Magento\Sales\Api\InvoiceOrderInterface
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Api ;
/**
* Class InvoiceOrderInterface
*
* @api
* @since 100.1.2
*/
interface InvoiceOrderInterface
{
/**
* @param int $orderId
* @param bool|false $capture
* @param \Magento\Sales\Api\Data\InvoiceItemCreationInterface[] $items
* @param bool|false $notify
* @param bool|false $appendComment
* @param Data\InvoiceCommentCreationInterface|null $comment
* @param Data\InvoiceCreationArgumentsInterface|null $arguments
* @return int
* @since 100.1.2
*/
public function execute (
$orderId ,
$capture = false ,
array $items = [],
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\InvoiceCommentCreationInterface $comment = null ,
\Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface $arguments = null
);
}
PHP implementation
\Magento\Sales\Model\InvoiceOrder
Click to show/hide included code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model ;
use Magento\Framework\App\ResourceConnection ;
use Magento\Sales\Api\Data\InvoiceCommentCreationInterface ;
use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface ;
use Magento\Sales\Api\InvoiceOrderInterface ;
use Magento\Sales\Api\OrderRepositoryInterface ;
use Magento\Sales\Model\Order\Config as OrderConfig ;
use Magento\Sales\Model\Order\Invoice\NotifierInterface ;
use Magento\Sales\Model\Order\InvoiceDocumentFactory ;
use Magento\Sales\Model\Order\InvoiceRepository ;
use Magento\Sales\Model\Order\OrderStateResolverInterface ;
use Magento\Sales\Model\Order\PaymentAdapterInterface ;
use Magento\Sales\Model\Order\Validation\InvoiceOrderInterface as InvoiceOrderValidator ;
use Psr\Log\LoggerInterface ;
/**
* Class InvoiceOrder
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class InvoiceOrder implements InvoiceOrderInterface
{
/**
* @var ResourceConnection
*/
private $resourceConnection ;
/**
* @var OrderRepositoryInterface
*/
private $orderRepository ;
/**
* @var InvoiceDocumentFactory
*/
private $invoiceDocumentFactory ;
/**
* @var PaymentAdapterInterface
*/
private $paymentAdapter ;
/**
* @var OrderStateResolverInterface
*/
private $orderStateResolver ;
/**
* @var OrderConfig
*/
private $config ;
/**
* @var InvoiceRepository
*/
private $invoiceRepository ;
/**
* @var InvoiceOrderValidator
*/
private $invoiceOrderValidator ;
/**
* @var NotifierInterface
*/
private $notifierInterface ;
/**
* @var LoggerInterface
*/
private $logger ;
/**
* InvoiceOrder constructor.
* @param ResourceConnection $resourceConnection
* @param OrderRepositoryInterface $orderRepository
* @param InvoiceDocumentFactory $invoiceDocumentFactory
* @param PaymentAdapterInterface $paymentAdapter
* @param OrderStateResolverInterface $orderStateResolver
* @param OrderConfig $config
* @param InvoiceRepository $invoiceRepository
* @param InvoiceOrderValidator $invoiceOrderValidator
* @param NotifierInterface $notifierInterface
* @param LoggerInterface $logger
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct (
ResourceConnection $resourceConnection ,
OrderRepositoryInterface $orderRepository ,
InvoiceDocumentFactory $invoiceDocumentFactory ,
PaymentAdapterInterface $paymentAdapter ,
OrderStateResolverInterface $orderStateResolver ,
OrderConfig $config ,
InvoiceRepository $invoiceRepository ,
InvoiceOrderValidator $invoiceOrderValidator ,
NotifierInterface $notifierInterface ,
LoggerInterface $logger
) {
$this -> resourceConnection = $resourceConnection ;
$this -> orderRepository = $orderRepository ;
$this -> invoiceDocumentFactory = $invoiceDocumentFactory ;
$this -> paymentAdapter = $paymentAdapter ;
$this -> orderStateResolver = $orderStateResolver ;
$this -> config = $config ;
$this -> invoiceRepository = $invoiceRepository ;
$this -> invoiceOrderValidator = $invoiceOrderValidator ;
$this -> notifierInterface = $notifierInterface ;
$this -> logger = $logger ;
}
/**
* @param int $orderId
* @param bool $capture
* @param array $items
* @param bool $notify
* @param bool $appendComment
* @param \Magento\Sales\Api\Data\InvoiceCommentCreationInterface|null $comment
* @param \Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface|null $arguments
* @return int
* @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
* @throws \Magento\Sales\Api\Exception\CouldNotInvoiceExceptionInterface
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \DomainException
*/
public function execute (
$orderId ,
$capture = false ,
array $items = [],
$notify = false ,
$appendComment = false ,
InvoiceCommentCreationInterface $comment = null ,
InvoiceCreationArgumentsInterface $arguments = null
) {
$connection = $this -> resourceConnection -> getConnection ( 'sales' );
$order = $this -> orderRepository -> get ( $orderId );
$invoice = $this -> invoiceDocumentFactory -> create (
$order ,
$items ,
$comment ,
( $appendComment && $notify ),
$arguments
);
$errorMessages = $this -> invoiceOrderValidator -> validate (
$order ,
$invoice ,
$capture ,
$items ,
$notify ,
$appendComment ,
$comment ,
$arguments
);
if ( $errorMessages -> hasMessages ()) {
throw new \Magento\Sales\Exception\DocumentValidationException (
__ ( "Invoice Document Validation Error(s): \n " . implode ( " \n " , $errorMessages -> getMessages ()))
);
}
$connection -> beginTransaction ();
try {
$order = $this -> paymentAdapter -> pay ( $order , $invoice , $capture );
$order -> setState (
$this -> orderStateResolver -> getStateForOrder ( $order , [ OrderStateResolverInterface :: IN_PROGRESS ])
);
$order -> setStatus ( $this -> config -> getStateDefaultStatus ( $order -> getState ()));
$invoice -> setState ( \Magento\Sales\Model\Order\Invoice :: STATE_PAID );
$this -> invoiceRepository -> save ( $invoice );
$this -> orderRepository -> save ( $order );
$connection -> commit ();
} catch ( \Exception $e ) {
$this -> logger -> critical ( $e );
$connection -> rollBack ();
throw new \Magento\Sales\Exception\CouldNotInvoiceException (
__ ( 'Could not save an invoice, see error log for details' )
);
}
if ( $notify ) {
if ( ! $appendComment ) {
$comment = null ;
}
$this -> notifierInterface -> notify ( $order , $invoice , $comment );
}
return $invoice -> getEntityId ();
}
}
Exceptions
In case of failure, it returns an error object. Example in REST:
{
"message" : "Creditmemo Document Validation Error(s): \n We can't create creditmemo for the order. \n The most money available to refund is 0."
}
Extension points
The service implementation contains extension points marked with @api
annotation. Extension developers can use APIs to extend service logic.
RefundInvoice
The RefundInvoice service introduces a capability to execute Magento native business flow of the Sales module using API.
Please note, that current service is available only for invoices created using online payment methods. If you try to apply it to an Invoice created using offline payment method, system will throw a validation error.
With this service you can:
create a Credit Memo (complete or partial) for particular Invoice
add details about refunded items to an Order
change status and state of an Order according to performed actions
notify a customer about performed refund operation
Service parameters
Name
Description
Format
Example
Required/Optional
Default value
invoiceId
An identifier of a target Invoice for operation.
Integer
Required
items
An array of invoice items included to a Credit Memo. By
default, the service will create a Credit Memo for all
invoice items.
Array of items with a format according to
\Magento\Sales\Api\Data\CreditmemoItemCreationInterface
.
[
{
"order_item_id" : 1 ,
"qty" : 2
},
{
"order_item_id" : 2 ,
"qty" : 0.5
}
]
Optional (required, when a Credit Memo must contain
particular order items)
[]
isOnline
Flag that determines whether funds should be returned to a
customer via online payment system (PayPal for example) or
not.
Boolean
Optional
false
notify
Flag that activates e-mail notification about Credit Memo
creation. If true
, the service notifies a
customer; if false
, it doesn't.
Boolean
Optional
false
appendComment
Flag that activates addition of a comment
argument to the e-mail notification. If true
and comment
contains data, the service will
add the comment to an e-mail notification.
Boolean
Optional
false
comment
A comment to Credit Memo.
A format according to the
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface
.
{
"comment" : "The first Credit Memo" ,
"is_visible_on_front" : true
}
Optional
null
arguments
Additional arguments for the service. Can be used by
extension modules.
A format according to
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface
.
{
"shipping_amount" : 10.00 ,
"adjustment_positive" : 5.00 ,
"adjustment_negative" : 5.00
}
A parameter shipping_amount
behaves like at the Credit Memo creation page in the Admin
area. If shipping amount is not specified, then shipping
amount from a target Invoice is refunded automatically. To
specify a shipping amount, consider shipping tax displays
settings.
Optional
null
Return values
The service returns an identifier of a created Credit Memo.
REST
POST Endpoint
http://<magento_host>/rest/<store_code>/V1/invoice/<invoiceId>/refund
REST Declaration
etc/webapi.xml
<route url= "/V1/invoice/:invoiceId/refund" method= "POST" >
<service class= "Magento\Sales\Api\RefundInvoiceInterface" method= "execute" />
<resources>
<resource ref= "Magento_Sales::sales" />
</resources>
</route>
SOAP
SOAP Endpoint
http://<magento_host>/soap/<store_code>?wsdl&services=salesRefundInvoiceV1
PHP interface
\Magento\Sales\Api\RefundInvoiceInterface
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Api ;
/**
* Interface RefundInvoiceInterface
*
* @api
* @since 100.1.3
*/
interface RefundInvoiceInterface
{
/**
* Create refund for invoice
*
* @param int $invoiceId
* @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items
* @param bool|null $isOnline
* @param bool|null $notify
* @param bool|null $appendComment
* @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
* @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
* @return int
* @since 100.1.3
*/
public function execute (
$invoiceId ,
array $items = [],
$isOnline = false ,
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null ,
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
);
}
PHP implementation
\Magento\Sales\Model\RefundInvoice
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model ;
use Magento\Framework\App\ResourceConnection ;
use Magento\Sales\Api\CreditmemoRepositoryInterface ;
use Magento\Sales\Api\InvoiceRepositoryInterface ;
use Magento\Sales\Api\OrderRepositoryInterface ;
use Magento\Sales\Api\RefundInvoiceInterface ;
use Magento\Sales\Model\Order\Config as OrderConfig ;
use Magento\Sales\Model\Order\Creditmemo\NotifierInterface ;
use Magento\Sales\Model\Order\CreditmemoDocumentFactory ;
use Magento\Sales\Model\Order\OrderStateResolverInterface ;
use Magento\Sales\Model\Order\RefundAdapterInterface ;
use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface as RefundInvoiceValidator ;
use Psr\Log\LoggerInterface ;
/**
* Class RefundInvoice
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class RefundInvoice implements RefundInvoiceInterface
{
/**
* @var ResourceConnection
*/
private $resourceConnection ;
/**
* @var OrderStateResolverInterface
*/
private $orderStateResolver ;
/**
* @var OrderRepositoryInterface
*/
private $orderRepository ;
/**
* @var InvoiceRepositoryInterface
*/
private $invoiceRepository ;
/**
* @var CreditmemoRepositoryInterface
*/
private $creditmemoRepository ;
/**
* @var RefundAdapterInterface
*/
private $refundAdapter ;
/**
* @var CreditmemoDocumentFactory
*/
private $creditmemoDocumentFactory ;
/**
* @var NotifierInterface
*/
private $notifier ;
/**
* @var OrderConfig
*/
private $config ;
/**
* @var LoggerInterface
*/
private $logger ;
/**
* @var RefundInvoiceValidator
*/
private $validator ;
/**
* RefundInvoice constructor.
*
* @param ResourceConnection $resourceConnection
* @param OrderStateResolverInterface $orderStateResolver
* @param OrderRepositoryInterface $orderRepository
* @param InvoiceRepositoryInterface $invoiceRepository
* @param RefundInvoiceValidator $validator
* @param CreditmemoRepositoryInterface $creditmemoRepository
* @param RefundAdapterInterface $refundAdapter
* @param CreditmemoDocumentFactory $creditmemoDocumentFactory
* @param NotifierInterface $notifier
* @param OrderConfig $config
* @param LoggerInterface $logger
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct (
ResourceConnection $resourceConnection ,
OrderStateResolverInterface $orderStateResolver ,
OrderRepositoryInterface $orderRepository ,
InvoiceRepositoryInterface $invoiceRepository ,
RefundInvoiceValidator $validator ,
CreditmemoRepositoryInterface $creditmemoRepository ,
RefundAdapterInterface $refundAdapter ,
CreditmemoDocumentFactory $creditmemoDocumentFactory ,
NotifierInterface $notifier ,
OrderConfig $config ,
LoggerInterface $logger
) {
$this -> resourceConnection = $resourceConnection ;
$this -> orderStateResolver = $orderStateResolver ;
$this -> orderRepository = $orderRepository ;
$this -> invoiceRepository = $invoiceRepository ;
$this -> validator = $validator ;
$this -> creditmemoRepository = $creditmemoRepository ;
$this -> refundAdapter = $refundAdapter ;
$this -> creditmemoDocumentFactory = $creditmemoDocumentFactory ;
$this -> notifier = $notifier ;
$this -> config = $config ;
$this -> logger = $logger ;
}
/**
* @inheritdoc
*/
public function execute (
$invoiceId ,
array $items = [],
$isOnline = false ,
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null ,
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
) {
$connection = $this -> resourceConnection -> getConnection ( 'sales' );
$invoice = $this -> invoiceRepository -> get ( $invoiceId );
$order = $this -> orderRepository -> get ( $invoice -> getOrderId ());
$creditmemo = $this -> creditmemoDocumentFactory -> createFromInvoice (
$invoice ,
$items ,
$comment ,
( $appendComment && $notify ),
$arguments
);
$validationMessages = $this -> validator -> validate (
$invoice ,
$order ,
$creditmemo ,
$items ,
$isOnline ,
$notify ,
$appendComment ,
$comment ,
$arguments
);
if ( $validationMessages -> hasMessages ()) {
throw new \Magento\Sales\Exception\DocumentValidationException (
__ ( "Creditmemo Document Validation Error(s): \n " . implode ( " \n " , $validationMessages -> getMessages ()))
);
}
$connection -> beginTransaction ();
try {
$creditmemo -> setState ( \Magento\Sales\Model\Order\Creditmemo :: STATE_REFUNDED );
$order -> setCustomerNoteNotify ( $notify );
$order = $this -> refundAdapter -> refund ( $creditmemo , $order , $isOnline );
$order -> setState (
$this -> orderStateResolver -> getStateForOrder ( $order , [])
);
$order -> setStatus ( $this -> config -> getStateDefaultStatus ( $order -> getState ()));
if ( ! $isOnline ) {
$invoice -> setIsUsedForRefund ( true );
$invoice -> setBaseTotalRefunded (
$invoice -> getBaseTotalRefunded () + $creditmemo -> getBaseGrandTotal ()
);
}
$this -> invoiceRepository -> save ( $invoice );
$order = $this -> orderRepository -> save ( $order );
$creditmemo = $this -> creditmemoRepository -> save ( $creditmemo );
$connection -> commit ();
} catch ( \Exception $e ) {
$this -> logger -> critical ( $e );
$connection -> rollBack ();
throw new \Magento\Sales\Exception\CouldNotRefundException (
__ ( 'Could not save a Creditmemo, see error log for details' )
);
}
if ( $notify ) {
if ( ! $appendComment ) {
$comment = null ;
}
$this -> notifier -> notify ( $order , $creditmemo , $comment );
}
return $creditmemo -> getEntityId ();
}
}
Exceptions
In case of failure, it returns an error object. Example in REST:
{
"message" : "Creditmemo Document Validation Error(s): \n We can't create creditmemo for the order. \n The most money available to refund is 0."
}
Extension points
The service contains extension points marked with @api
annotation. Extension developers can use APIs to extend service logic.
RefundOrder
With the RefundOrder service you can:
create a Credit Memo (complete or partial) for a particular Order
add details about refunded items to an Order
change status and state of an Order according to performed actions
notify a customer about performed refund operation
Service parameters
Name
Description
Format
Example
Required/Optional
Default value
orderId
An identifier of a target Order for operation.
Integer
Required
items
An array of Order items included to a Credit Memo. By
default, the service will create a Credit Memo for all
Order items.
Array of items with a format according to
\Magento\Sales\Api\Data\CreditmemoItemCreationInterface
.
[
{
"order_item_id" : 1 ,
"qty" : 2
},
{
"order_item_id" : 2 ,
"qty" : 0.5
}
]
Optional (required, when a Credit Memo must contain
particular order items)
[]
notify
Flag that activates e-mail notification about Credit Memo
creation. If true
, the service notifies a
customer; if false
, it doesn't.
Boolean
Optional
false
appendComment
Flag that activates addition of a comment
argument to the e-mail notification. If true
and comment
contains data, the service will
add the comment to an e-mail notification.
Boolean
Optional
false
comment
A comment to Credit Memo.
A format according to the
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface
.
{
"comment" : "The first Credit Memo" ,
"is_visible_on_front" : true
}
Optional
null
arguments
Additional arguments for the service. Can be used by
extension modules.
A format according to
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface
.
{
"shipping_amount" : 10.00 ,
"adjustment_positive" : 5.00 ,
"adjustment_negative" : 5.00
}
A parameter shipping_amount
behaves like at the Credit Memo creation page in the Admin
area. If shipping amount is not specified, then shipping
amount from a target Invoice is refunded automatically. To
specify a shipping amount, consider shipping tax displays
settings.
Optional
null
Return values
The service returns an identifier of a created Credit Memo.
REST
POST Endpoint
http://<magento_host>/rest/<store_code>/V1/order/<orderId>/refund
REST Declaration
etc/webapi.xml
<route url= "/V1/order/:orderId/refund" method= "POST" >
<service class= "Magento\Sales\Api\RefundOrderInterface" method= "execute" />
<resources>
<resource ref= "Magento_Sales::sales" />
</resources>
</route>
SOAP
SOAP Endpoint
http://<magento_host>/soap/<store_code>?wsdl&services=salesRefundOrderV1
PHP interface
\Magento\Sales\Api\RefundOrderInterface
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Api ;
/**
* Interface RefundOrderInterface
*
* @api
* @since 100.1.3
*/
interface RefundOrderInterface
{
/**
* Create offline refund for order
*
* @param int $orderId
* @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items
* @param bool|null $notify
* @param bool|null $appendComment
* @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
* @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
* @return int
* @since 100.1.3
*/
public function execute (
$orderId ,
array $items = [],
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null ,
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
);
}
PHP implementation
\Magento\Sales\Model\RefundOrder
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model ;
use Magento\Framework\App\ResourceConnection ;
use Magento\Sales\Api\CreditmemoRepositoryInterface ;
use Magento\Sales\Api\OrderRepositoryInterface ;
use Magento\Sales\Api\RefundOrderInterface ;
use Magento\Sales\Model\Order\Config as OrderConfig ;
use Magento\Sales\Model\Order\Creditmemo\NotifierInterface ;
use Magento\Sales\Model\Order\CreditmemoDocumentFactory ;
use Magento\Sales\Model\Order\OrderStateResolverInterface ;
use Magento\Sales\Model\Order\RefundAdapterInterface ;
use Magento\Sales\Model\Order\Validation\RefundOrderInterface as RefundOrderValidator ;
use Psr\Log\LoggerInterface ;
/**
* Class RefundOrder
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class RefundOrder implements RefundOrderInterface
{
/**
* @var ResourceConnection
*/
private $resourceConnection ;
/**
* @var OrderStateResolverInterface
*/
private $orderStateResolver ;
/**
* @var OrderRepositoryInterface
*/
private $orderRepository ;
/**
* @var CreditmemoRepositoryInterface
*/
private $creditmemoRepository ;
/**
* @var RefundAdapterInterface
*/
private $refundAdapter ;
/**
* @var CreditmemoDocumentFactory
*/
private $creditmemoDocumentFactory ;
/**
* @var RefundOrderValidator
*/
private $validator ;
/**
* @var NotifierInterface
*/
private $notifier ;
/**
* @var OrderConfig
*/
private $config ;
/**
* @var LoggerInterface
*/
private $logger ;
/**
* RefundOrder constructor.
*
* @param ResourceConnection $resourceConnection
* @param OrderStateResolverInterface $orderStateResolver
* @param OrderRepositoryInterface $orderRepository
* @param CreditmemoRepositoryInterface $creditmemoRepository
* @param RefundAdapterInterface $refundAdapter
* @param CreditmemoDocumentFactory $creditmemoDocumentFactory
* @param RefundOrderValidator $validator
* @param NotifierInterface $notifier
* @param OrderConfig $config
* @param LoggerInterface $logger
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct (
ResourceConnection $resourceConnection ,
OrderStateResolverInterface $orderStateResolver ,
OrderRepositoryInterface $orderRepository ,
CreditmemoRepositoryInterface $creditmemoRepository ,
RefundAdapterInterface $refundAdapter ,
CreditmemoDocumentFactory $creditmemoDocumentFactory ,
RefundOrderValidator $validator ,
NotifierInterface $notifier ,
OrderConfig $config ,
LoggerInterface $logger
) {
$this -> resourceConnection = $resourceConnection ;
$this -> orderStateResolver = $orderStateResolver ;
$this -> orderRepository = $orderRepository ;
$this -> creditmemoRepository = $creditmemoRepository ;
$this -> refundAdapter = $refundAdapter ;
$this -> creditmemoDocumentFactory = $creditmemoDocumentFactory ;
$this -> validator = $validator ;
$this -> notifier = $notifier ;
$this -> config = $config ;
$this -> logger = $logger ;
}
/**
* @inheritdoc
*/
public function execute (
$orderId ,
array $items = [],
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null ,
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
) {
$connection = $this -> resourceConnection -> getConnection ( 'sales' );
$order = $this -> orderRepository -> get ( $orderId );
$creditmemo = $this -> creditmemoDocumentFactory -> createFromOrder (
$order ,
$items ,
$comment ,
( $appendComment && $notify ),
$arguments
);
$validationMessages = $this -> validator -> validate (
$order ,
$creditmemo ,
$items ,
$notify ,
$appendComment ,
$comment ,
$arguments
);
if ( $validationMessages -> hasMessages ()) {
throw new \Magento\Sales\Exception\DocumentValidationException (
__ ( "Creditmemo Document Validation Error(s): \n " . implode ( " \n " , $validationMessages -> getMessages ()))
);
}
$connection -> beginTransaction ();
try {
$creditmemo -> setState ( \Magento\Sales\Model\Order\Creditmemo :: STATE_REFUNDED );
$order -> setCustomerNoteNotify ( $notify );
$order = $this -> refundAdapter -> refund ( $creditmemo , $order );
$order -> setState (
$this -> orderStateResolver -> getStateForOrder ( $order , [])
);
$order -> setStatus ( $this -> config -> getStateDefaultStatus ( $order -> getState ()));
$order = $this -> orderRepository -> save ( $order );
$creditmemo = $this -> creditmemoRepository -> save ( $creditmemo );
$connection -> commit ();
} catch ( \Exception $e ) {
$this -> logger -> critical ( $e );
$connection -> rollBack ();
throw new \Magento\Sales\Exception\CouldNotRefundException (
__ ( 'Could not save a Creditmemo, see error log for details' )
);
}
if ( $notify ) {
if ( ! $appendComment ) {
$comment = null ;
}
$this -> notifier -> notify ( $order , $creditmemo , $comment );
}
return $creditmemo -> getEntityId ();
}
}
Exceptions
In case of failure, it returns an error object. Example in REST:
{
"message" : "Creditmemo Document Validation Error(s): \n We can't create creditmemo for the order. \n The most money available to refund is 0."
}
Extension points
The service contains extension points marked with @api
annotation. Extension developers can use APIs to extend service logic.
ShipOrder
With the ShipOrder service you can:
create a shipment document (full or partial)
add details about shipped items into an order
change status and state of an order according to performed actions
notify the customer of a new shipment document
Service parameters
Name
Description
Format
Example
Required/Optional
Default value
orderId
An identifier of a target order for operation.
Integer
Required
items
An array of order items included to a shipment. By default, the service will create a shipment for all order items.
Array of items with a format according to \Magento\Sales\Api\Data\ShipmentItemCreationInterface
.
[
{
"order_item_id" : 1 ,
"qty" : 2
},
{
"order_item_id" : 2 ,
"qty" : 0.5
}
]
Optional (required, when a shipment document must contain particular order items)
[]
notify
Flag that activates e-mail notification about shipment details. If true
, the service notifies a customer; if false
, it doesn't.
Boolean
Optional
false
appendComment
Flag that activates addition of a comment
argument to the e-mail notification. If true
and comment
contains data, the service will add the comment to an e-mail notification.
Boolean
Optional
false
comment
A comment about a shipment.
A format according to the
\Magento\Sales\Api\Data\CreditmemoCommentCreationInterface
interface.
{
"comment" : "The first Invoice" ,
"is_visible_on_front" : true
}
Optional
null
tracks
A list of track numbers attached to a shipment.
Array of objects with a format according to
\Magento\Sales\Api\Data\ShipmentTrackCreationInterface>
.
[
{
"track_number" : "132456789" ,
"title" : "United States Postal Service" ,
"carrier_code" : "usps"
}
]
Optional
[]
packages
A list of packages attached to a shipment.
Array of objects with a format according to
\Magento\Sales\Api\Data\ShipmentPackageCreationInterface
.
[
{
"extension_attributes" :
{
"ups" :
{
"weight" : 20 ,
"height" : 15 ,
"width" : 20
}
}
}
]
Optional
[]
arguments
Additional arguments for the service. Can be used by
extension modules.
A format according to the
\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface
interface.
Optional
null
Return values
The service returns the identifier of a created shipment.
REST
POST Endpoint
http://<magento_host>/rest/<store_code>/V1/order/<orderId>/ship
REST Declaration
etc/webapi.xml
<route url= "/V1/order/:orderId/ship" method= "POST" >
<service class= "Magento\Sales\Api\ShipOrderInterface" method= "execute" />
<resources>
<resource ref= "Magento_Sales::sales" />
</resources>
</route>
SOAP
SOAP Endpoint
http://<magento_host>/soap/<store_code>?wsdl&services=salesShipOrderV1
PHP interface
\Magento\Sales\Api\ShipOrderInterface
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Api ;
/**
* Class ShipOrderInterface
*
* @api
* @since 100.1.2
*/
interface ShipOrderInterface
{
/**
* Creates new Shipment for given Order.
*
* @param int $orderId
* @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items
* @param bool $notify
* @param bool $appendComment
* @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
* @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks
* @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages
* @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
* @return int Id of created Shipment.
* @since 100.1.2
*/
public function execute (
$orderId ,
array $items = [],
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null ,
array $tracks = [],
array $packages = [],
\Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
);
}
PHP implementation
\Magento\Sales\Model\ShipOrder
Click to show/hide a code <?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Sales\Model ;
use Magento\Framework\App\ResourceConnection ;
use Magento\Sales\Api\OrderRepositoryInterface ;
use Magento\Sales\Api\ShipmentRepositoryInterface ;
use Magento\Sales\Api\ShipOrderInterface ;
use Magento\Sales\Model\Order\Config as OrderConfig ;
use Magento\Sales\Model\Order\OrderStateResolverInterface ;
use Magento\Sales\Model\Order\ShipmentDocumentFactory ;
use Magento\Sales\Model\Order\Shipment\NotifierInterface ;
use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface ;
use Magento\Sales\Model\Order\Validation\ShipOrderInterface as ShipOrderValidator ;
use Psr\Log\LoggerInterface ;
/**
* Class ShipOrder
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ShipOrder implements ShipOrderInterface
{
/**
* @var ResourceConnection
*/
private $resourceConnection ;
/**
* @var OrderRepositoryInterface
*/
private $orderRepository ;
/**
* @var ShipmentDocumentFactory
*/
private $shipmentDocumentFactory ;
/**
* @var OrderStateResolverInterface
*/
private $orderStateResolver ;
/**
* @var OrderConfig
*/
private $config ;
/**
* @var ShipmentRepositoryInterface
*/
private $shipmentRepository ;
/**
* @var ShipOrderValidator
*/
private $shipOrderValidator ;
/**
* @var NotifierInterface
*/
private $notifierInterface ;
/**
* @var LoggerInterface
*/
private $logger ;
/**
* @var OrderRegistrarInterface
*/
private $orderRegistrar ;
/**
* @param ResourceConnection $resourceConnection
* @param OrderRepositoryInterface $orderRepository
* @param ShipmentDocumentFactory $shipmentDocumentFactory
* @param OrderStateResolverInterface $orderStateResolver
* @param OrderConfig $config
* @param ShipmentRepositoryInterface $shipmentRepository
* @param ShipOrderValidator $shipOrderValidator
* @param NotifierInterface $notifierInterface
* @param OrderRegistrarInterface $orderRegistrar
* @param LoggerInterface $logger
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct (
ResourceConnection $resourceConnection ,
OrderRepositoryInterface $orderRepository ,
ShipmentDocumentFactory $shipmentDocumentFactory ,
OrderStateResolverInterface $orderStateResolver ,
OrderConfig $config ,
ShipmentRepositoryInterface $shipmentRepository ,
ShipOrderValidator $shipOrderValidator ,
NotifierInterface $notifierInterface ,
OrderRegistrarInterface $orderRegistrar ,
LoggerInterface $logger
) {
$this -> resourceConnection = $resourceConnection ;
$this -> orderRepository = $orderRepository ;
$this -> shipmentDocumentFactory = $shipmentDocumentFactory ;
$this -> orderStateResolver = $orderStateResolver ;
$this -> config = $config ;
$this -> shipmentRepository = $shipmentRepository ;
$this -> shipOrderValidator = $shipOrderValidator ;
$this -> notifierInterface = $notifierInterface ;
$this -> logger = $logger ;
$this -> orderRegistrar = $orderRegistrar ;
}
/**
* @param int $orderId
* @param \Magento\Sales\Api\Data\ShipmentItemCreationInterface[] $items
* @param bool $notify
* @param bool $appendComment
* @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
* @param \Magento\Sales\Api\Data\ShipmentTrackCreationInterface[] $tracks
* @param \Magento\Sales\Api\Data\ShipmentPackageCreationInterface[] $packages
* @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
* @return int
* @throws \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
* @throws \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface
* @throws \Magento\Framework\Exception\InputException
* @throws \Magento\Framework\Exception\NoSuchEntityException
* @throws \DomainException
*/
public function execute (
$orderId ,
array $items = [],
$notify = false ,
$appendComment = false ,
\Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null ,
array $tracks = [],
array $packages = [],
\Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
) {
$connection = $this -> resourceConnection -> getConnection ( 'sales' );
$order = $this -> orderRepository -> get ( $orderId );
$shipment = $this -> shipmentDocumentFactory -> create (
$order ,
$items ,
$tracks ,
$comment ,
( $appendComment && $notify ),
$packages ,
$arguments
);
$validationMessages = $this -> shipOrderValidator -> validate (
$order ,
$shipment ,
$items ,
$notify ,
$appendComment ,
$comment ,
$tracks ,
$packages
);
if ( $validationMessages -> hasMessages ()) {
throw new \Magento\Sales\Exception\DocumentValidationException (
__ ( "Shipment Document Validation Error(s): \n " . implode ( " \n " , $validationMessages -> getMessages ()))
);
}
$connection -> beginTransaction ();
try {
$this -> orderRegistrar -> register ( $order , $shipment );
$order -> setState (
$this -> orderStateResolver -> getStateForOrder ( $order , [ OrderStateResolverInterface :: IN_PROGRESS ])
);
$order -> setStatus ( $this -> config -> getStateDefaultStatus ( $order -> getState ()));
$this -> shipmentRepository -> save ( $shipment );
$this -> orderRepository -> save ( $order );
$connection -> commit ();
} catch ( \Exception $e ) {
$this -> logger -> critical ( $e );
$connection -> rollBack ();
throw new \Magento\Sales\Exception\CouldNotShipException (
__ ( 'Could not save a shipment, see error log for details' )
);
}
if ( $notify ) {
if ( ! $appendComment ) {
$comment = null ;
}
$this -> notifierInterface -> notify ( $order , $shipment , $comment );
}
return $shipment -> getEntityId ();
}
}
Exceptions
In case of failure, it returns an error object. Example in REST:
{
"message" : "Creditmemo Document Validation Error(s): \n We can't create creditmemo for the order. \n The most money available to refund is 0."
}
Extension points
The service contains extension points marked with @api
annotation. Extension developers can use APIs to extend service logic.