<p>You don't want to use a separate web request to call the controller action of Craft Commerce. This has numerous downsides beyond your current problem with the missing session. It will negatively impact performance, double the roundtrip time and increase the server load.</p>
<p>Instead, if you want to call a controller action of Craft or another plugin from one of your own controllers, you can simply do so using the <a href="https://docs.craftcms.com/api/v4/craft-web-application.html#public-methods" rel="nofollow noreferrer"><code>craft\web\Application::runAction</code></a> method. Put this in your controller:</p>
<pre class="lang-php prettyprint-override"><code>$response = \Craft::$app-&gt;runAction('commerce/cart/update-cart');
</code></pre>
<p><code>$response</code> will be a <a href="https://www.yiiframework.com/doc/api/2.0/yii-web-response" rel="nofollow noreferrer"><code>Response</code> object</a> that you can inspect to check if the action executed successfully. Or return it from your controller action to return whatever the given action returned to the client.</p>

CC BY-SA 4.0
2022-06-24T11:39:19.843Z
That sounds nice, was not aware of this function! I'm going to try
Maarten Heideman
CC BY-SA 4.0
2022-06-26T14:01:24.463Z
The 'commerce/cart/update-cart' returns the cart if action submit is successfully. But runAction returns a response object and the data and content in that response object are empty (error and success). How get te return data of the action (cart)?
Maarten Heideman
CC BY-SA 4.0
2022-06-27T07:30:39.660Z
@MaartenHeideman Looks like the controller only returns a Response object with model data if the request accepts JSON: https://github.com/craftcms/cms/blob/main/src/web/Controller.php#L244-L272
MoritzLost
CC BY-SA 4.0
2022-06-27T19:16:04.910Z
`Craft::$app->runAction('commerce/cart/update-cart', $this->asJson($postData));` Send the post data as json like this makes that the response returns some data (the original posted data). But this action should return the cart data. That I'll need for proper messages for example. The curl request did return the cart but missing the session info. Any suggestions?
Maarten Heideman
CC BY-SA 4.0
2022-06-28T15:47:33.227Z
@MarteenHeidemann The controller action sets the cart as a [route parameter](https://github.com/craftcms/commerce/blob/76631f59c1eed5b233be7fd9d0f8c709a9606986/src/controllers/CartController.php#L449-L451). So you should be able to access the updated cart object through the URL manager – [`Craft::$app->getUrlManager()->getRouteParams()`](https://docs.craftcms.com/api/v4/craft-web-urlmanager.html#method-getrouteparams)
MoritzLost
CC BY-SA 4.0
2022-06-23T13:06:33.940Z
2022-06-23T13:06:33.940Z
MoritzLost
<p>I am building a onepagecheckout for craft commerce 3. I created a custom controller to submit cart and payment info in one form submit. I'll call the default updateCart action with a curl request and send the formdata with it. This works but create a new cart eachtime instead of update the current cart in the current session. How i'll update the current cart instead of create a new one?</p>
<p>this is my custom action</p>
<pre><code>&lt;?php

namespace modules\modulename\controllers;

use Craft;
use craft\web\Controller;
use craft\helpers\UrlHelper;

class CheckoutController extends Controller
{

    protected $allowAnonymous = true;

    public function actionCheckout(){
        // Require POST request
        $this-&gt;requirePostRequest();
        // Get params
        $data = $this-&gt;request-&gt;post();

        try {
            $url = UrlHelper::siteUrl() . &quot;actions/commerce/cart/update-cart&quot;;
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            $resp = curl_exec($curl);
            $jsonResponse = \json_decode($resp);

            // Show error if fails
            if(!empty($jsonResponse)) {
                if($jsonResponse-&gt;success){
                    Craft::$app-&gt;session-&gt;setError($jsonResponse-&gt;message);
                } else {
                    Craft::$app-&gt;session-&gt;setError($jsonResponse-&gt;error);
                }
            } else{
                Craft::$app-&gt;session-&gt;setError('mis');
            }
            curl_close($curl);
        } catch (\Throwable $th) {
            throw $th;
        }


        $redirect = UrlHelper::siteUrl() . &quot;webshop/checkout/onepagecheckout&quot;;
        $this-&gt;redirect($redirect);

        Craft::$app-&gt;end();
    }
}
</code></pre>

<plugin-craftcommerce3><session><cart>
How to make a curl request with a session to an action url?
# How to make a curl request with a session to an action url?

(Asked by: username_0 on 2022-06-22)

I am building a onepagecheckout for craft commerce 3. I created a custom controller to submit cart and payment info in one form submit. I'll call the default updateCart action with a curl request and send the formdata with it. This works but create a new cart eachtime instead of update the current cart in the current session. How i'll update the current cart instead of create a new one?
this is my custom action
requirePostRequest();
        // Get params
        $data = $this->request->post();

        try {
            $url = UrlHelper::siteUrl() . "actions/commerce/cart/update-cart";
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            $resp = curl_exec($curl);
            $jsonResponse = \json_decode($resp);

            // Show error if fails
            if(!empty($jsonResponse)) {
                if($jsonResponse->success){
                    Craft::$app->session->setError($jsonResponse->message);
                } else {
                    Craft::$app->session->setError($jsonResponse->error);
                }
            } else{
                Craft::$app->session->setError('mis');
            }
            curl_close($curl);
        } catch (\Throwable $th) {
            throw $th;
        }


        $redirect = UrlHelper::siteUrl() . "webshop/checkout/onepagecheckout";
        $this->redirect($redirect);

        Craft::$app->end();
    }
}

**Tags:** plugin-craftcommerce3, session, cart


---

## 1 answers

### Answer by username_1 on 2022-06-23. Score: 2 | Accepted answer

You don't want to use a separate web request to call the controller action of Craft Commerce. This has numerous downsides beyond your current problem with the missing session. It will negatively impact performance, double the roundtrip time and increase the server load.
Instead, if you want to call a controller action of Craft or another plugin from one of your own controllers, you can simply do so using the craft\web\Application::runAction method. Put this in your controller:
$response = \Craft::$app->runAction('commerce/cart/update-cart');

$response will be a Response object that you can inspect to check if the action executed successfully. Or return it from your controller action to return whatever the given action returned to the client.

> **Comments:**
> **username_0**: That sounds nice, was not aware of this function! I'm going to try  
> **username_0**: The 'commerce/cart/update-cart' returns the cart if action submit is successfully. But runAction returns a response object and the data and content in that response object are empty (error and success). How get te return data of the action (cart)?  
> **username_1**: @MaartenHeideman Looks like the controller only returns a Response object with model data if the request accepts JSON: https://github.com/craftcms/cms/blob/main/src/web/Controller.php#L244-L272  
> **username_0**: `Craft::$app->runAction('commerce/cart/update-cart', $this->asJson($postData));` Send the post data as json like this makes that the response returns some data (the original posted data). But this action should return the cart data. That I'll need for proper messages for example. The curl request did return the cart but missing the session info. Any suggestions?  
> **username_1**: @MarteenHeidemann The controller action sets the cart as a [route parameter](https://github.com/craftcms/commerce/blob/76631f59c1eed5b233be7fd9d0f8c709a9606986/src/controllers/CartController.php#L449-L451). So you should be able to access the updated cart object through the URL manager – [`Craft::$app->getUrlManager()->getRouteParams()`](https://docs.craftcms.com/api/v4/craft-web-urlmanager.html#method-getrouteparams)  

---

