my_parent_controller(); $this->stripeKeys = json_decode(file_get_contents(APPPATH . 'config/stripe/stripe-api-keys.json'), true); \Stripe\Stripe::setApiKey($this->stripeKeys['secret']); $this->load->model('event_concurrent_process_model'); $this->load->model("event_schedule_model"); $this->load->model("event_model"); } public function index() { $payload = @file_get_contents('php://input'); $event = null; try { /** * Set the `webhook` secret value in your `stripe-api-key.json` * On local your you can get the webhook secret key by running `stripe listen` * Otherwise, find your endpoint's secret in your webhook settings in the Developer Dashboard */ $event = \Stripe\Event::constructFrom( json_decode($payload, true), $_SERVER['HTTP_STRIPE_SIGNATURE'], $this->stripeKeys['webhook'] ); } catch(\UnexpectedValueException $e) { // Invalid payload http_response_code(400); exit(); } // Handle the event switch ($event->type) { case 'payment_intent.succeeded': $paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent $stripePayment = new StripePayment(); $metadata = $paymentIntent->metadata; $booking = json_decode($metadata->booking); $responseStatus = null; if($this->checkProcessExists($booking->process_id, $metadata->login_id, $metadata->event_id)) { $eventData = $stripePayment->getEventDetails($metadata->event_id, $booking); //$metadata->event_id if($booking->workshop_session == 'ENLIGNE' || ($booking->workshop_session == 'DISTANCE-PRESENTIEL' && $booking->session_type == 'soir-distance') || $booking->workshop_session == 'DISTANCE'){ //if(is_null($eventData->reservation_start_date) || is_null($eventData->reservation_end_date)) { $d = date("Y-m-d H:i:s"); $eventData->reservation_start_date = $d; $eventData->reservation_end_date = date('+1 year', strtotime($d)); //} } $paymentFormData = json_decode($metadata->formData); $emailTemplate = $stripePayment->getReservationEmailTemplate($metadata->event_id, $booking); $registration_id = null; $registration = $this->validate($booking, $metadata->user_id, $metadata->login_id); if($registration) { $registration_id = $registration; } $stripePayment->handleSuccessfulPaymentIntent($paymentIntent, $registration_id); // Send success email $formattedEventData = $stripePayment->formatVariables($eventData, $paymentIntent, $paymentFormData, $booking); $this->load->library("mailjet_libr"); $responseStatus = $this->mailjet_libr->send_success_email($formattedEventData, $paymentFormData, $emailTemplate); } if($responseStatus == 200) { header("HTTP/1.1 200 OK"); output_to_json($this, array( "message" => 'Successful payment intent recognized', )); } header("HTTP/1.1 500 Internal Server Error"); output_to_json($this, array( "message" => 'Email not sent'//json_encode($responseStatus), )); break; // ... handle other event types default: output_to_json($this, array( "message" => 'Received unknown event type ' . $event->type )); } http_response_code(200); } private function checkProcessExists($process_id, $login_id, $event_id) { return $this->event_concurrent_process_model->check_process_exists($process_id, $login_id, $event_id); } private function validate($booking, $user_id, $login_id){ $eventCategory = array_keys(EVENT_CATEGORY); // Input is not empty and category is valid if(in_array($booking->event_category, $eventCategory)) { //check if process_id exists : bug fixed for #24568 if(!$this->isPaidEvent($booking) && $booking->process_id) { //close previous process $rest = $this->event_concurrent_process_model->unlock_action_by_process_id($login_id, $booking->process_type, (int)$booking->process_id); //unset($_POST['process_id']); } // Check if event is an online event! if( $this->event_schedule_model->is_online_event((int)$booking->event_id) ) { return false; } if($booking->action == "register" || $booking->action == "modify") { return $this->check_before_register_or_modify($booking, $user_id, $login_id); } else { return false; } } else { return false; } } private function isPaidEvent($booking) { $process_types = [1, 2, 6]; // register, cancel registration return $booking->event_category && $booking->event_category == 'PAID_EVENT' && in_array((int) $booking->process_type, $process_types); } private function check_before_register_or_modify($booking, $user_id, $login_id) { if(!is_null($booking) && ($booking->action == "register" || $booking->action == "modify" ) && ($booking->process_type == 1 || $booking->process_type == 3 || $booking->process_type == 6 || $booking->process_type == 7)) { // We do not appply button lock on paid_event $is_locked = $this->event_concurrent_process_model->has_activity($user_id, $login_id, $booking->process_type, $booking->event_id); /* if cancellation process is being done at the same time, on the same account with different login session */ if($is_locked) { return false; } else {//locked action when not locked //check if process_id is still valid $this->check_process_id_validity($booking, $login_id); //check if user is allowed to book for more than 1 date per event if($this->event_schedule_model->continue_registration($booking->event_id, $user_id, $booking->action, $booking->reg_type)) { //check if can still reserved $can_still_reserved = $this->event_model->check_seats($booking->event_id, $booking->reg_type, $this->checkIfReservationCanBeByPassed($booking), $booking->session_type); if($can_still_reserved) { //get event details seats_reserved_orig //$event_sched_details = $this->event_schedule_model->event_schedule_details($booking->event_id'), $booking->event_schedule_id'), $booking->request_type')); $event_sched_details = $this->event_schedule_model->event_schedule_details($booking->event_id, $booking->request_type); //get reservation information $reservation_details = $this->get_reservation_details($booking->action, $booking->reg_type, $booking->event_id, $user_id); /* check if event exists */ if(countVal($event_sched_details) > 0 || $booking->workshop_session=='ENLIGNE' || $booking->workshop_session=='DISTANCE-PRESENTIEL') { //check if event arent locked, closed, terminated, archived or deleted if( $event_sched_details->back_office_status >= 3 || ($event_sched_details->event_status == 'FULL' && $event_sched_details->remaining_seat >=0 && $booking->process_type == 1) || ($event_sched_details->event_status == 'FULL' && $booking->process_type == 3 && $booking->workshop_session !=='ENLIGNE' && $booking->workshop_session !=='DISTANCE' && $booking->workshop_session !=='DISTANCE-PRESENTIEL') ){ return false; } else { if($booking->seats_reserved && $booking->seats_reserved > 0) { //check subscription //$subscribed = $this->check_subscription($booking->event_id, $booking->event_schedule_id, $booking->check_subscription, 0); if($booking->action == "register"){ //continue with the reservation if($booking->reg_type == 1 || $booking->reg_type == 2){ //determine action type //$this->determine_action_type($booking->event_id, $booking->process_type); //finally, got to reserve return $this->register($booking, $user_id, $login_id); } else{ return false; } } else { return false; } } else{ //locked action when not locked $check_process = $this->event_concurrent_process_model->lock_or_add_process($user_id, $login_id, $booking->process_type, $booking->event_id); if($check_process['status']){ //determine action type //$this->determine_action_type($booking->event_id, $booking->process_type); return true; } else { return false; } } } //event is not closed } else{ return false; } //end of else event exists } else { //subscriber cannot reserved due to no available seats return false; } } else { return false; } }//end of else not locked } else { return false; } } private function check_process_id_validity($booking, $login_id){ if(isset($booking->process_id) && !empty($booking->process_id)){ //check if process_id is still active; $check = $this->event_concurrent_process_model->check_process_id_validity($login_id, $booking->process_id, $booking->process_type, $booking->event_id); if($check<=0){ return false; } } return true; } private function checkIfReservationCanBeByPassed($booking) { if($booking->bp === "true") { //by pass validation, so user can reserve in wl in advanced! return true; } return false; } private function get_reservation_details($action=false, $reg_type=false, $event_id, $user_id){ $this->load->model('event_wait_list_model'); $this->load->model('event_registration_model'); if($action && $reg_type){ if($reg_type == 1 && $action == "modify") { return $this->event_registration_model->get_registration_details($user_id, $event_id); } else if($reg_type == 2 && $action == "modify"){ return $this->event_wait_list_model->get_waitlist_registration_details($user_id, $event_id); } } return false; } private function revalidate_reservation($event_id, $event_schedule_id, $seats_reserved, $reg_type, $byPassRegularReservation){ $availability = $this->event_model->check_availability($event_id, $event_schedule_id, $seats_reserved, $reg_type, $byPassRegularReservation); if($availability == 4){ return false; } else if($availability == 5) { return false; } else if($availability == $reg_type){ return true; } else if($availability == 3) { return false; } else if($availability == 6){ return false; } else { return false; } } private function register($booking, $user_id, $login_id) { if( $this->event_schedule_model->is_paid_event($booking->event_id) && $this->isPaidEvent($booking)) { return false; } //$this->set_user_data(); $registration = array( "event_id" => $booking->event_id, "process_type" => $booking->process_type, "process_id" => $booking->process_id, "seat_feature" => $booking->seat_feature, "action" => $booking->action, "reg_type" => $booking->reg_type, "user_id" => $user_id, "login_id" => $login_id, "seats_reserved" => $booking->seats_reserved, "guest_emails" => $booking->guest_emails ?? '', "user_agent" => NULL,//$agent, "is_user_moderated" => $booking->is_user_moderated?? 0, 'workshop_session' => $booking->workshop_session, 'registration_type' => $booking->session_type ); if($booking->reg_type == 1){ if($registration['action'] == "register"){ return $this->email_registered($registration, $booking->workshop_session); } return false; } } private function email_registered($registration, $workshop_session) { $ws = false; if($workshop_session == 'ENLIGNE' || $workshop_session == 'DISTANCE-PRESENTIEL') { $ws = true; } $this->load->model("user_subscriber_model"); $this->load->model("event_registration_model"); $this->load->model('event_email_template_model'); $this->load->model('event_email_recipient_model'); $event_info = $this->event_model->event_details_email($registration['event_id'], $ws); $user_info = $this->user_subscriber_model->email_registered($registration['user_id']); if(countVal($user_info) > 0 && countVal($event_info) >0) { $registered = $this->event_registration_model->register($registration, $ws); //send email when reservation is successfull if($registered){ return $registered; } else { //unlock process $this->unlock_process($registration); return false; } return false; } else { //unlock process $this->unlock_process($registration); return false; } } private function unlock_process($data){ $this->event_concurrent_process_model->unlock_action($data['user_id'], $data['login_id'], $data['event_id'], $data['process_type'], $data['process_id']); } private function set_user_data(){ // User Agent if ($this->agent->is_browser()){ $this->data['agent'] = $this->agent->browser().' '.$this->agent->version(); } elseif ($this->agent->is_robot()){ $this->data['agent'] = $this->agent->robot(); } elseif ($this->agent->is_mobile()){ $this->data['agent'] = $this->agent->mobile(); } else { $this->data['agent'] = 'Unidentified User Agent'; } } }