You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
7.8 KiB
237 lines
7.8 KiB
<?php
|
|
namespace app\libraries;
|
|
|
|
class StripePayment {
|
|
|
|
private $stripePublicKey = '';
|
|
private $stripeSecretKey = '';
|
|
private $stripe = null;
|
|
protected $ci;
|
|
function __construct () {
|
|
$stripeKeys = json_decode(file_get_contents(APPPATH . 'config/stripe/stripe-api-keys.json'), true);
|
|
$this->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;
|
|
}
|
|
|
|
}
|