stripePublicKey = $stripeKeys['public']; $this->stripeSecretKey = $stripeKeys['secret']; $this->ci =& get_instance(); $this->stripe = new \Stripe\StripeClient($this->stripeSecretKey); } public function getPublicKey() { return $this->stripePublicKey; } public function getSecretKey() { return $this->stripeSecretKey; } /** * Create a stripe Payment Intent object * * @return Stripe\PaymentIntent|bool - returns false if failed */ public function createPaymentIntent(array $data) { try { return [ 'amount' => $data['amount'], 'currency' => $data['currency'] ?? 'eur', 'payment_method_options' => [ 'card' => [ 'request_three_d_secure' => 'any' ] ], 'payment_method_types' => ['card'], // 'confirmation_method' => 'manual', 'metadata' => $data['metadata'] ]; } catch(\Exception $e){ dd($e); return false; } } /** * Retrieves previously created Payment Intent object * * @param string $clientSecret - the publishable key from creating a payment intent */ public function retrievePaymentIntent(string $clientSecret) { $secret = explode('_secret_', $clientSecret)[0]; // Get the string before the `_secret_` substring only try { $pi = $this->stripe->paymentIntents->retrieve($secret); return $pi; } catch (\Stripe\Exception\CardException $e) { $error_code = $e->jsonBody['error']['code']; switch($error_code) { case 'resource_missing': // Display notice message if env is dev for debugging purposes if (ENVIRONMENT == 'development') $this->output->set_output('Notice: Payment Intent instance is recreated. Message: ' . $e->jsonBody['error']['message']); // Re-create a stripe Payment Intent return $this->createPaymentIntent([]); break; default: return $e->jsonBody['error']; break; } } } /** * Confirms a Payment Intent * * @param $clientSecret - the publishable key from creating a payment intent * @param $paymentMethod */ public function confirmPaymentIntent(string $clientSecret, string $paymentMethod) { $intent = $this->retrievePaymentIntent($clientSecret); return $intent->confirm([ 'payment_method' => $paymentMethod ]); } /** * Check if payment is successful * * @param $clientSecret - the publishable key from creating a payment intent * @return bool - returns true if payment is successful, * returns false if there's an error or if the stripe can't retrieve the paymentIntent */ public function handleSuccessfulPaymentIntent($paymentIntent, $registration_id) { // Get CodeIgniter instance //$CI =& get_instance(); if ($paymentIntent->status === 'succeeded') { // Do something with successful payment $this->ci->load->model('event_payment_model'); $this->ci->load->helper('number'); $metadata = $paymentIntent->metadata; $queryResult = $this->ci->event_payment_model->add([ 'event_id' => $metadata->event_id, 'user_id' => $metadata->user_id, 'login_id' => $metadata->login_id, 'stripe_client_secret' => $paymentIntent->client_secret, 'event_rate' => $metadata->event_rate, 'seats_reserved' => $metadata->seats_reserved, 'discount_percent' => $metadata->discount_percent, 'service_charge' => $metadata->service_charge, 'total_amount' => $metadata->total_amount, 'billing_details' => json_encode($paymentIntent->charges->data[0]->billing_details), 'vat' => number_format($this->getVatAmount($metadata->total_amount), 2,'.',''), 'registration_id' => $registration_id ]); // Clear cookie event data for payment //delete_cookie($this->ci->config->item('sess_cookie_name').'_event_data'); return $queryResult; } else { // Oops payment intent is not successful return false; } } /** * Get the email reservation template */ public function getReservationEmailTemplate($event_id, $ws) { //$ci = get_instance(); $email_type_id = 1; if($ws->workshop_session == 'ENLIGNE' || $ws->workshop_session == 'DISTANCE' || ($ws->workshop_session == 'DISTANCE-PRESENTIEL' && $ws->session_type == 'soir-distance')) { $email_type_id=7; } $this->ci->load->model('event_email_template_model'); return $this->ci->event_email_template_model->get_current_event_email_template($event_id, $email_type_id, 1); } public function getEventDetails($event_id, $ws) { //$ci = get_instance(); $is_video = false; if($ws->workshop_session == 'ENLIGNE' || $ws->workshop_session == 'DISTANCE' || ($ws->workshop_session == 'DISTANCE-PRESENTIEL' && $ws->session_type == 'soir-distance')) { $is_video = true; } $this->ci->load->model('event_model'); return $this->ci->event_model->event_details_reserved($event_id, $is_video); } public function getUserDetails($user_id) { //$ci = get_instance(); $this->ci->load->model('user_model'); return $this->ci->user_model->user_details($user_id); } private function getNoVatAmount($amount) { $rate = $this->getTaxRate(); $tax_rate = 1; if($rate) { $tax_rate = 1 + ($rate->tax_rate / 100); } return ($amount / $tax_rate); } private function getVatAmount($amount) { return ($amount - $this->getNoVatAmount($amount)); } private function getTaxRate() { $this->ci->load->model('event_payment_model'); return $this->ci->event_payment_model->get_tax_rate(); } public function formatVariables($eventData, $payment, $paymentFormData, $ws) { $this->ci->load->helper('number'); $metadata = $payment->metadata; $rate = $this->getTaxRate(); $video_link = ''; $url = str_replace("webhook", "", $_SERVER["HTTP_HOST"].dirname($_SERVER["REQUEST_URI"])); if($ws->workshop_session == 'ENLIGNE'){ $video_link = 'cours-en-ligne-achat/'.$eventData->event_id; } else if($ws->workshop_session == 'DISTANCE-PRESENTIEL' && $ws->session_type == 'soir-distance') { $video_link = 'atelier-a-distance/'.$eventData->event_id; } try { $data = array( 'order_number' => isset($payment->charges->data[0]->receipt_number) ? $payment->charges->data[0]->receipt_number: '', 'event_rate' => $metadata->event_rate, 'seats_reserved' => $metadata->seats_reserved, 'service_charge' => $metadata->service_charge, 'mode_of_payment' => 'card', 'order_date' => date('Y-m-d'), 'total_amount' => $metadata->total_amount, 'no_vat_amount' => number_format($this->getNoVatAmount($metadata->total_amount), 2,'.',''), 'vat' => $rate->tax_rate.'%',//number_format($this->getVatAmount($metadata->total_amount), 2,'.',''), 'subscriber_address' => $this->formatAddress($payment->charges->data[0]->billing_details->address), 'subscriber_first_name' => $paymentFormData->fname, 'subscriber_last_name' => $paymentFormData->name, 'video_link' => $video_link ); return (object) array_merge((array) $eventData, $data); } catch(Exception $e) { return $e; } } private function formatAddress($address) { $formattedAddress=""; if(isset($address)) { if(!empty($address->line1) && !is_null($address->line1)) $formattedAddress = $formattedAddress . $address->line1; if(!empty($address->line2) && !is_null($address->line2)) $formattedAddress = $formattedAddress . ', ' .$address->line2; if(!empty($address->city) && !is_null($address->city)) $formattedAddress = $formattedAddress .', '. $address->city; if(!empty($address->country) && !is_null($address->country)) $formattedAddress = $formattedAddress .', '. $address->country; if(!empty($address->postal_code) && !is_null($address->postal_code)) $formattedAddress = $formattedAddress .', '. $address->postal_code; } return $formattedAddress; } }