skip to Main Content

I am trying it fetch all orders from the specific date range in Shopify. The problem is I am only able to get 250 orders. I am using the following code.

<div id="main-content1">
    <div class="container-fluid">
        <?php
            function nextorders($lastorderno,$orderfm,$orderto,$orders) {
                $orders_obj_url = 'XXXXXXXXXXXXXXXXXXX.myshopify.com/admin/api/2019-10/orders.json&since_id='.$lastorderno.'&status=any&created_at_min='.$orderfm.'T00:00:00&created_at_max='.$orderto.'T23:59:59&fields=created_at,id,order_status_url,total_price_set,number,note,note_attributes';
                $orders_content = @file_get_contents( $orders_obj_url );
                $orders_json = json_decode( $orders_content, true );
                $orders_new = $orders_json['orders'];
                $orders = $orders_json['orders'];
                if ($remaningprder > 0) {
                    $lastorderno = $orders['0']["number"];                    
                    nextorders($lastorderno,$orderfm,$orderto,$orders_new);
                }
                return $orders_new;
            }
            if ($_POST) {
                $orderfm = date("Y-m-d", strtotime($_POST['start']));
                $orderto = date("Y-m-d", strtotime($_POST['end']));
                $orders_obj_url = 'XXXXXXXXXXXXXXXXXXX.myshopify.com/admin/api/2019-10/orders.json?limit=250&fields=created_at,id,order_status_url,total_price_set,number,note,note_attributes&status=any&created_at_min='.$orderfm.'T00:00:00&created_at_max='.$orderto.'T23:59:59';
                $orders_content = @file_get_contents( $orders_obj_url );
                $orders_json = json_decode( $orders_content, true );
                $orders = $orders_json['orders'];
                if (count($orders) > 249) {
                    $remaningprder = $total_order - count($orders);
                    $lastorderno = $orders['0']["number"];
                    $orders = nextorders($lastorderno,$orderfm,$orderto,$orders);
                }
            }
        ?> 

        <div class="row clearfix" style="margin-top:20px;margin-bottom:20px;">
            <div class="offset-lg-3 offset-md-3 col-lg-6 col-md-6">
            </div>
            <div class="offset-lg-3 offset-md-3 col-lg-6 col-md-6">
                <div>
                    <form method="POST" action="">
                        <label>Date Range</label>                                    
                        <div class="input-daterange input-group" data-provide="datepicker">
                            <input type="text" class="input-sm form-control" value="<?=$startset;?>" name="start" autocomplete="off">
                            <span class="input-group-addon range-to">to</span>
                            <input type="text" class="input-sm form-control" value="<?=$endset; ?>" name="end" autocomplete="off">
                            <div class="input-group-append">
                                <button class="btn btn-outline-secondary" type="submit">Search</button>
                            </div>
                        </div>
                    </form>
                </div>                    
            </div>
        </div>          

        <div class="row clearfix">
            <div class="col-lg-12">
                <div class="card">
                    <div class="header">
                        <h2>Last order</h2>
                        <ul class="header-dropdown dropdown">
                            <li><a href="javascript:void(0);" class="full-screen"><i class="icon-frame"></i></a></li>
                        </ul>
                    </div>
                    <div class="body">
                        <div class="table-responsive hide-table">
                            <?php if (count($orders) > 0) { ?>
                            <table class="table table-striped table-hover dataTable js-exportable">
                                <thead>
                                    <tr>
                                        <th>#</th>
                                        <th>Order No</th>
                                        <th>Amount</th>
                                        <th>Token</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <?php 
                                      $i=1; 
                                      foreach ($orders as $order) { 
                                    ?>
                                    <tr>
                                      <th scope="row" data-title="Date"><?=$i++;?></th>
                                      <td data-title="Order No"><a href="<?=$order["order_status_url"];?>" target="_blank"><?=$order["number"];?></a></td>
                                      <td data-title="Amount"><?=$order["total_price_set"]["shop_money"]["amount"];?></td>
                                      <td data-title="Token"></td>
                                    </tr>
                                    <?php } ?>
                                </tbody>                                
                                </table>
                            <?php } ?>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

And then use the $orders variable to create the output table. It is only sowing 250 orders even if I increase the order limit.

Can anyone help me with this

Thanks

2

Answers


  1. You need to use the page_info-based paging that Shopify uses. Essentially, you need to look at the headers of the return, and call a new URL from there if applicable (if there are more results available).

    Unfortunately this means you can’t use get_file_contents() since it doesn’t allow you to view the headers. Check out curl or another library to make proper HTTP requests.

    The relevant Shopify docs are here: https://help.shopify.com/en/api/guides/paginated-rest-results

    Login or Signup to reply.
  2. This is an old question I know, but perhaps someone can find use of this answer.

    There is a way to get all orders by using the since_id option in the fetch url and cURL. This way you get 250 (or a number of your choosing below 250 since that is the max number you can fetch in one go) orders, starting with the order id 0. This will start at the first order. From here, you loop and fetch orders from (using since_id) the last order in the previous call. And when the number of orders returned is below the number of orders you fetch in each call, you exit.

    Example from a Symfony (5) app:

    private function getShopifyOrders(): array
        {
            $this->store_name = $this->params->get('app.shopify_store_name');
            $this->api_key = $this->params->get('app.shopify_api_key');
            $this->api_pass = $this->params->get('app.shopify_password');
            $this->api_url = 'https://' . $this->api_key . ':' . $this->api_pass . '@' . $this->store_name;
            $last = 0;
            $allOrders = [];
            while (true) {
                $orders_url = $this->api_url . '/admin/orders.json?limit=250&status=any&since_id=' . $last;
                error_log($orders_url); // Show each call in the log for reference
                $ch = curl_init($orders_url);
                curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                $response = curl_exec($ch);
                $orders = json_decode($response);
    
                foreach ( $orders->orders as $order ) {
                    $allOrders[] = $order;
                    $last = $order->id;
                }
    
                if ( count( $orders->orders ) < 250 ) {
                    break;
                }
            }
    
            return $allOrders;
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search