문제

How can we get the customer order history over the rest API with the customer token.

If I'm trying the url

/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=customer_email&searchCriteria[filter_groups][0][filters][0][value]=bob@fett.com&searchCriteria[filter_groups][0][filters][0][condition_type]=like

I'm getting this:

{
    "message": "The consumer isn't authorized to access %resources.",
    "parameters": {
        "resources": "Magento_Sales::actions_view"
    },
    "trace": "#0 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/module-webapi/Controller/Rest/RequestValidator.php(68): Magento\\Webapi\\Controller\\Rest\\RequestValidator->checkPermissions()\n#1 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/module-webapi/Controller/Rest/InputParamsResolver.php(80): Magento\\Webapi\\Controller\\Rest\\RequestValidator->validate()\n#2 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Webapi\\Controller\\Rest\\InputParamsResolver->resolve()\n#3 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\Webapi\\Controller\\Rest\\InputParamsResolver\\Interceptor->___callParent('resolve', Array)\n#4 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Webapi\\Controller\\Rest\\InputParamsResolver\\Interceptor->Magento\\Framework\\Interception\\{closure}()\n#5 /var/www/vhosts/store-api.silverwax.ca/httpdocs/generated/code/Magento/Webapi/Controller/Rest/InputParamsResolver/Interceptor.php(26): Magento\\Webapi\\Controller\\Rest\\InputParamsResolver\\Interceptor->___callPlugins('resolve', Array, Array)\n#6 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/module-webapi/Controller/Rest/SynchronousRequestProcessor.php(85): Magento\\Webapi\\Controller\\Rest\\InputParamsResolver\\Interceptor->resolve()\n#7 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/module-webapi/Controller/Rest.php(188): Magento\\Webapi\\Controller\\Rest\\SynchronousRequestProcessor->process(Object(Magento\\Framework\\Webapi\\Rest\\Request\\Proxy))\n#8 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Webapi\\Controller\\Rest->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#9 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\Webapi\\Controller\\Rest\\Interceptor->___callParent('dispatch', Array)\n#10 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\Webapi\\Controller\\Rest\\Interceptor->Magento\\Framework\\Interception\\{closure}(Object(Magento\\Framework\\App\\Request\\Http))\n#11 /var/www/vhosts/store-api.silverwax.ca/httpdocs/generated/code/Magento/Webapi/Controller/Rest/Interceptor.php(26): Magento\\Webapi\\Controller\\Rest\\Interceptor->___callPlugins('dispatch', Array, Array)\n#12 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/App/Http.php(136): Magento\\Webapi\\Controller\\Rest\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#13 /var/www/vhosts/store-api.silverwax.ca/httpdocs/generated/code/Magento/Framework/App/Http/Interceptor.php(24): Magento\\Framework\\App\\Http->launch()\n#14 /var/www/vhosts/store-api.silverwax.ca/httpdocs/vendor/magento/framework/App/Bootstrap.php(258): Magento\\Framework\\App\\Http\\Interceptor->launch()\n#15 /var/www/vhosts/store-api.silverwax.ca/httpdocs/index.php(39): Magento\\Framework\\App\\Bootstrap->run(Object(Magento\\Framework\\App\\Http\\Interceptor))\n#16 {main}"
}

I've tried to the proposal of @aaditya in the question but it's doesn't work.

도움이 되었습니까?

해결책

To extend the rest API endpoint of orders(which is originally customer has no access) in order to access it using customer's token, You have to create a custom endpoint as well otherwise the endpoint /V1/orders will still inaccessible for the customer.
Check below example:

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/orders/custom" method="GET">
        <service class="Magento\Sales\Api\OrderRepositoryInterface" method="getList"/>
        <resources>
            <resource ref="self"/>
        </resources>
    </route>
</routes>  

And you can use the custom endpoint /V1/orders/custom to get orders list of the customer using customer's token.

다른 팁

@fmsthird is correct in regards having to create a custom endpoint, however I resorted to creating a new class that depends on \Magento\Sales\Api\OrderRepositoryInterface rather than calling that class directly. From there I've created a new method that the endpoint utilises, and then calls the getList method from there. As that method expects a parameter of type \Magento\Framework\Api\SearchCriteriaInterface, this has to be built yourself first, but the advantage of this is you can tailor it to do some more filtering. Here's what I've built when I was faced with this task (you'll need to create the equivalent interface):

Your\Module\Model\Order.php

namespace Your\Module\Model;

class Order implements \Your\Module\Api\OrderInterface {

    /**
     * @var \Magento\Sales\Api\OrderRepositoryInterface
     */
    public $_orderRepository;

    /**
     * @var \Magento\Framework\Api\SearchCriteriaBuilder
     */
    public $_searchCriteriaBuilder;

    /**
     * @var \Magento\Framework\Api\FilterBuilder
     */
    public $_filterBuilder;

    /**
     * @var \Magento\Framework\Webapi\Rest\Request
     */
    public $_request;

    public function __construct(
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
        \Magento\Framework\Api\FilterBuilder $filterBuilder,
        \Magento\Framework\Webapi\Rest\Request $request
    ) {
        $this->_orderRepository = $orderRepository;
        $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->_filterBuilder = $filterBuilder;
        $this->_request = $request;
    }

    /**
     * Find entities by customer ID
     * Accepts 'page' and 'show' GET params 
     *
     * @param int $customerId
     * @return \Magento\Sales\Api\Data\OrderSearchResultInterface
     */
    public function getListForCustomer($customerId) {
        $filters = [
            $this->_filterBuilder->setField('customer_id')->setValue($customerId)->create()
        ];
        $searchCriteria = $this->_searchCriteriaBuilder->addFilters($filters)->create();
        $searchCriteria->setCurrentPage( $this->_request->getParam('page', 1) );
        $searchCriteria->setPageSize( $this->_request->getParam('show', 20) );
        return $this->_orderRepository->getList($searchCriteria);
    }    
}

Your\Module\etc\webapi.xml

<!-- Orders from the site -->
<route url="/V1/orders/mine" method="GET">
    <service class="Your\Module\Api\OrderInterface" method="getListForCustomer"/>
    <resources>
        <resource ref="self"/>
    </resources>
    <data>
        <parameter name="customerId" force="true">%customer_id%</parameter>
    </data>
</route>

You should now be able to retrieve the orders for the customer via their key automatically with /V1/orders/mine, without any of the search criteria parts in the URL. You may also notice that the Order class depends on Magento\Framework\Webapi\Rest\Request to retrieve GET parameters from the used URL, which can be used to get paginated results - I'm not sure if that's the proper way of doing this, but it works for me! :-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 magento.stackexchange
scroll top