api_url = defined('LALAMOVELINK') ? LALAMOVELINK : ''; $this->api_secret = defined('LALAMOVESECRET') ? LALAMOVESECRET : ''; $this->api_key = defined('LALAMOVEAPIKEY') ? LALAMOVEAPIKEY : ''; helper("general"); $this->outlet = new Outlet(); } public function requestQuotation($selected_date = null, $selected_time = null, $total_amount = null, $outlet_id = null, $latitude = null, $longitude = null, $address = null) { //check service type if($total_amount > 150){ $service_type = 'CAR'; }else{ $service_type = 'MOTORCYCLE'; } //get outlet details $outlet_data = $this->outlet->where('id', $outlet_id)->first(); $outlet_address = $outlet_data['address']; $outlet_latitude = $outlet_data['latitude']; $outlet_longitude = $outlet_data['longitude']; // echo($outlet_latitude);exit; $stops = [ [ "coordinates" => [ "lat" => $outlet_latitude, "lng" => $outlet_longitude ], "address" => $outlet_address ], [ "coordinates" => [ "lat" => $latitude, "lng" => $longitude ], "address" => $address ] ]; $request_data = [ "data" => [ 'serviceType' => $service_type, 'stops' => $stops, 'language' => 'en_MY' ] ]; //handling preorder if($selected_date && $selected_time){ // Convert local Y-m-d H:i:s to UTC ISO 8601 format $local_datetime = $selected_date . ' ' . $selected_time; $dt = new \DateTime($local_datetime, new \DateTimeZone('Asia/Kuala_Lumpur')); $request_data['data']['scheduleAt'] = $dt->format('Y-m-d\TH:i:s\Z'); } $request_body = json_encode($request_data); $timestamp = time() * 1000; $raw_signature = $timestamp . "\r\nPOST\r\n/v3/quotations\r\n\r\n" . $request_body; $signature = hash_hmac('sha256', $raw_signature, $this->api_secret); $token = $this->api_key.':'.$timestamp.':'.$signature; $headers = [ 'Authorization: hmac ' . $token, 'Content-Type: application/json', 'Market: MY', 'Request-ID: 211b9d85-ips-476f-8675-b61ec923cc27' ]; $response = send_api_request('POST', $this->api_url.'/quotations', $headers, $request_body); $log_lalamove = new LogLalamove(); $log_lalamove->insert([ 'url' => $this->api_url.'/quotations', 'request' => $request_body, 'respond' => json_encode($response), 'quotation_id' => $response['data']['quotationId'] ?? null, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]); return $response; } public function submitOrder($order_id){ $orders = new Orders(); $order = $orders->select('orders.*, customer_addresses.name as recipient_name, customer_addresses.phone as recipient_phone, customer_addresses.note as recipient_note, log_lalamove.quotation_id, log_lalamove.respond, outlets.pic_name, outlets.pic_phone') ->join('log_lalamove', 'log_lalamove.quotation_id = orders.lalamove_quot_id') ->join('outlets', 'outlets.id = orders.outlet_id') ->join('customer_addresses', 'customer_addresses.id = orders.customer_address_id AND customer_addresses.deleted_at IS NULL', 'left') ->where('orders.id', $order_id) ->where('orders.deleted_at', null) ->first(); $quotation_id = $order['lalamove_quot_id']; $quotation_data = json_decode($order['respond'], true); $request_data = [ "data" => [ 'quotationId' => $quotation_id, "sender" => [ "stopId" => $quotation_data['data']['stops'][0]['stopId'], "name" => $order['pic_name'] ?? 'US Pizza', "phone" => $order['pic_phone'] ?? '+60123456789' ], "recipients" => [ [ "stopId" => $quotation_data['data']['stops'][1]['stopId'], "name" => $order['recipient_name'], "phone" => $order['recipient_phone'] ? '+6'.$order['recipient_phone'] : '+60123456789', "remarks" => $order['recipient_note'] ] ], "isPODEnabled" => true, "partner" => "USPizza Delivery", "metadata" => [ "order_id" => $order['id'], ] ] ]; $request_body = json_encode($request_data); $timestamp = time() * 1000; $raw_signature = $timestamp . "\r\nPOST\r\n/v3/orders\r\n\r\n" . $request_body; $signature = hash_hmac('sha256', $raw_signature, $this->api_secret); $token = $this->api_key.':'.$timestamp.':'.$signature; $headers = [ 'Authorization: hmac ' . $token, 'Content-Type: application/json', 'Market: MY', 'Request-ID: 211b9d85-ips-476f-8675-b61ec923cc27' ]; $response = send_api_request('POST', $this->api_url.'/orders', $headers, $request_body); $log_lalamove = new LogLalamove(); $log_lalamove->insert([ 'url' => $this->api_url.'/orders', 'request' => $request_body, 'respond' => json_encode($response), 'quotation_id' => $quotation_id, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]); return $response; } public function handleWebhook($data){ //compare signature $signature = $data['signature']; $timestamp = $data['timestamp']; $http_verb = 'POST'; $path = '/api/lalamove/webhook'; $json_body = json_encode($data['data'], JSON_UNESCAPED_SLASHES); $raw_signature = $timestamp . "\r\n" . $http_verb . "\r\n" . $path . "\r\n\r\n" . $json_body; $mysignature = hash_hmac('sha256', $raw_signature, $this->api_secret); if($signature == $mysignature){ $log_lalamove = new LogLalamove(); $log_lalamove->insert([ 'url' => $this->api_url.'/webhook', 'request' => json_encode($data), 'respond' => $data['eventType'] == 'ORDER_STATUS_CHANGED' ? 'ORDER_STATUS_CHANGED ('.$data['data']['order']['orderId'].'): '.$data['data']['order']['status'] : $data['eventType'], 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]); if($data['eventType'] == 'ORDER_STATUS_CHANGED'){ $orders = new Orders(); $order = $orders->select('orders.*, customer_addresses.phone as recipient_phone, order_deliveries.tracking_link') ->join('customer_addresses', 'customer_addresses.id = orders.customer_address_id AND customer_addresses.deleted_at IS NULL', 'left') ->join('order_deliveries', 'order_deliveries.order_id = orders.id') ->where('order_deliveries.provider_name', 'Lalamove') ->where('order_deliveries.provider_order_id', $data['data']['order']['orderId']) ->first(); if($order){ $order_id = $order['id']; $lalamove_order_id = $data['data']['order']['orderId']; $order_status = 'pending'; switch($data['data']['order']['status']){ case 'ON_GOING': $order_status = 'on_the_way'; break; case 'PICKED_UP': $order_status = 'picked_up'; break; case 'COMPLETED': $order_status = 'completed'; break; case 'CANCELLED': $order_status = 'cancelled'; break; } $orders->update($order_id, ['status' => $order_status]); //send notification to customer $message = ''; switch($order_status){ case 'on_the_way': $message = "🚚 Your order [**".$order['order_so']."**] is on the way!\nThe driver is delivering your food now.\nPlease get ready to receive it.\nHere is the tracking link: \n\n" . $order['tracking_link']; break; case 'completed': $message = "🎉 Your order [**".$order['order_so']."**] has been completed.\nWe hope you enjoy your meal!\nThank you for ordering with us."; break; } if($message){ $wato = new Wato(); $wato->pushNotification($order['recipient_phone'], $message); } if($order_status == 'completed'){ //get order details $order_details = $this->getOrderDetails($lalamove_order_id); $pod_details = $order_details['data']['stops'][1]['POD']; if($pod_details['status'] == 'DELIVERED' || $pod_details['status'] == 'SIGNED'){ $order_deliveries = new OrderDeliveries(); $delivery_records = $order_deliveries->where('order_id', $order_id) ->where('provider_name', 'Lalamove') ->where('provider_order_id', $lalamove_order_id) ->get()->getResultArray(); if (!empty($delivery_records)) { // Update delivery status to completed $order_deliveries->where('order_id', $order_id) ->where('provider_name', 'Lalamove') ->where('provider_order_id', $lalamove_order_id) ->set(['POD_url' => $pod_details['image'], 'delivered_at' => $pod_details['deliveredAt']]) ->update(); } } } elseif($order_status == 'cancelled'){ // Update delivery status to cancelled // $order_deliveries = new OrderDeliveries(); // $order_deliveries->where('order_id', $order_id) // ->where('provider_name', 'Lalamove') // ->where('provider_order_id', $lalamove_order_id) // ->set(['status' => 'cancelled', 'cancelled_at' => date('Y-m-d H:i:s')]) // ->update(); } } } } return true; } public function getOrderDetails($lalamove_order_id){ $timestamp = time() * 1000; $raw_signature = $timestamp . "\r\nGET\r\n/v3/orders/" . $lalamove_order_id . "\r\n\r\n"; $signature = hash_hmac('sha256', $raw_signature, $this->api_secret); $token = $this->api_key.':'.$timestamp.':'.$signature; $headers = [ 'Authorization: hmac ' . $token, 'Content-Type: application/json', 'Market: MY', 'Request-ID: 211b9d85-ips-476f-8675-b61ec923cc27' ]; $response = send_api_request('GET', $this->api_url.'/orders/'.$lalamove_order_id, $headers); return $response; } }