y2kbug icon

event.php

y2kbug | PRO | 05/23/23 07:57:52 AM UTC | 0 ⭐ | 1172 👁️ | Never ⏰ | []
PHP |

11.89 KB

|

None

|

0 👍

/

0 👎

public function checkout($params = []){
        try{
            if( empty($params['section']) || empty($params['representative']) ){
                throw new \Exception('INVALID_DATA');
            }
 
            if(!empty($params['onsite_secret'])){
                $this->onsite = $this->is_onsite([
                    'secret' => $params['onsite_secret']
                ]);
            }
 
            if(!empty($params['pay_by_cash']) && $params['pay_by_cash'] == true && !$this->onsite){
                throw new \Exception('INVALID_PAYMENT_METHOD');
            }
 
            global $DB;
        
            $res = $DB->prepare("SELECT * FROM `event` WHERE `url_alias` = ? AND `deleted` = 0 LIMIT 1");
            $res->execute([
                $params['section']
            ]);
            $event = $res->fetch(\PDO::FETCH_ASSOC);
            if( empty($event) ){
                throw new \Exception('INVALID_EVENT');
            }
 
            $res = $DB->prepare("SELECT * FROM `event_visitor_type` WHERE `event_id` = ? AND `id` = ? LIMIT 1");
            $res->execute([
                $event['id'],
                $params['visitor_type']
            ]);
            $visitor_type = $res->fetch(\PDO::FETCH_ASSOC);
            if( empty($visitor_type) ){
                throw new \Exception('INVALID_VISITOR_TYPE');
            }
 
            $coupon_type = NULL;
            $modifier = -1;
            if($params['coupon_applied'] == true && !empty($params['coupon_code'])){
                $res = $DB->prepare("SELECT * FROM `coupon` WHERE `event_id` = ? AND `coupon_code` = ?");
                $res->execute([
                    $event['id'],
                    $params['coupon_code']
                ]);
                $coupon = $res->fetch(\PDO::FETCH_ASSOC);
 
                if (empty($coupon)) {
                    throw new \Exception('INVALID_COUPON_CODE');
                }
 
                if ($coupon['coupon_start_time'] > time()) {
                    throw new \Exception('COUPON_NOT_AVAILABLE_YET');
                }
 
                if (time() > $coupon['coupon_end_time']) {
                    throw new \Exception('COUPON_EXPIRED');
                }
 
                if($coupon['redemption_quota'] > 0 && $coupon['redeemed'] >= $coupon['redemption_quota']){
                    throw new \Exception('REDEMPTION_QUOTA_REACHED');
                }
 
                $coupon_type = $coupon['type'];
                $modifier = floatval($coupon['modifier']);
            }
 
            $original_price = ((!empty($params['accompany']) ? count($params['accompany']) : 0) + 1) * floatval($visitor_type['price']);
 
            $total = floatval($params['total']);
            $discounted_price = empty($coupon_type) || $modifier > -1 ? $original_price : ($coupon_type === 'Percentage' ? $original_price * $modifier : ($coupon_type === 'Lump-sum' ? $original_price + $modifier : $original_price));
            if($total !== $discounted_price){
                throw new \Exception('INVALID_TOTAL_PRICE');
            }
 
            $payment_method = $total > 0 ? ($params['pay_by_cash'] == true ? 'cash' : 'paypal') : '';
 
            $secret = md5(uniqid());
 
            $language_id_map = [
                'en_gb' => 1,
                'zh_hk' => 2,
                'zh_cn' => 3
            ];
 
            $res = $DB->prepare("INSERT INTO `registration` (`event_id`, `event_visitor_type_id`, `accompany_count`, `language_id`, `price`, `coupon_code`, `coupon_modifier`, `final_price`, `payment_method`, `approval_status`, `secret`, `create_time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
            $res->execute([
                $event['id'],
                $params['visitor_type'],
                !empty($params['accompany']) ? count($params['accompany']) : 0,
                $language_id_map[ $params['language'] ],
                floatval($original_price),
                !empty($coupon['coupon_code']) ? $coupon['coupon_code'] : '',
                $modifier,
                $total,
                $payment_method,
                !$this->onsite && $event['approval_required'] == 1 ? -1 : 1,
                $secret,
                time()
            ]);
            $registration_id = $DB->lastInsertId();
            if(empty($registration_id)){
                throw new \Exception('Failed to register! Please try again later, or contact us!');
            }
 
            $invoice_id = (!empty($event['invoice_prefix']) ? str_replace('', '', $event['invoice_prefix']) : 'GENERAL'). '_'. $registration_id;
 
            if(!empty($coupon_type) && !empty($modifier)){
                $res = $DB->prepare("UPDATE `coupon` SET `redeemed` = `redeemed` + 1 WHERE `id` = ? LIMIT 1");
                $res->execute([
                    $coupon['id']
                ]);
            }
 
            $duplicated_value_for_search_key = ['`invoice_id` = ?'];
            $duplicated_value_for_search_value = [$invoice_id];
            foreach($params['representative'] AS $question_id => $answer){
                $answer_value = is_array($answer) ? ($this->is_multidimensional_array($answer) ? $this->multi_implode("\n", $answer) : (is_numeric(implode('', $answer)) ? implode(' ', $answer) : implode("\n", $answer))) : $answer;
 
                $res = $DB->prepare("INSERT INTO `registration_representative` (`registration_id`, `question_id`, `answer`) VALUES (?, ?, ?)");
                $res->execute([
                    $registration_id,
                    $question_id,
                    $answer_value
                ]);
 
                if($question_id < 0){
                    switch($question_id){
                        case -8:
                            $duplicated_value_for_search_key[] = '`country` = ?';
                            break;
                        case -7:
                            $duplicated_value_for_search_key[] = '`job_title` = ?';
                            break;
                        case -6:
                            $duplicated_value_for_search_key[] = '`salutation` = ?';
                            break;
                        case -5:
                            $duplicated_value_for_search_key[] = '`first_name` = ?';
                            break;
                        case -4:
                            $duplicated_value_for_search_key[] = '`last_name` = ?';
                            break;
                        case -3:
                            $duplicated_value_for_search_key[] = '`company` = ?';
                            break;
                        case -2:
                            $duplicated_value_for_search_key[] = '`email_address` = ?';
                            break;
                        case -1:
                            $duplicated_value_for_search_key[] = '`mobile_phone_number` = ?';
                            break;
                        default:
                    }
 
                    $duplicated_value_for_search_value[] = $answer_value;
                }
            }
 
            if(!empty($duplicated_value_for_search_key) && !empty($duplicated_value_for_search_value)){
                $res = $DB->prepare("UPDATE `registration` SET ". implode(', ', $duplicated_value_for_search_key). " WHERE `id` = ? LIMIT 1");
                $res->execute(array_merge(
                    $duplicated_value_for_search_value,
                    [$registration_id]
                ));
            }
            
            if( !empty($params['accompany']) ){
                foreach($params['accompany'] AS $accompany_id => $accompany){
                    foreach($accompany AS $question_id => $answer){
                        $res = $DB->prepare("INSERT INTO `registration_accompany` (`registration_id`, `accompany_id`, `question_id`, `answer`) VALUES (?, ?, ?, ?)");
                        $res->execute([
                            $registration_id,
                            $accompany_id + 1,
                            $question_id,
                            is_array($answer) ? implode(' ', $answer) : $answer
                        ]);
                    }
                }
            }
 
            if(!$this->onsite && $event['approval_required'] == 1){
                $payment_method = 'pending';
            }elseif($payment_method === 'paypal'){
                $paypal_params = [
                    'METHOD' => 'SetExpressCheckout',
                    'VERSION' => '124.0',
                    'USER' => PAYPAL_USER,
                    'PWD' => PAYPAL_PWD,
                    'SIGNATURE' => PAYPAL_SIGNATURE,
                    'LOCALECODE' => 'en_GB',
                    'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
                    'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
                    'L_PAYMENTREQUEST_0_NAME0' => $event['name_'. $params['language']]. ' - '. $visitor_type['name_'. $params['language']],
                    'L_PAYMENTREQUEST_0_QTY0' => 1 + (!empty($params['accompany']) ? count($params['accompany']) : 0),
                    'L_PAYMENTREQUEST_0_AMT0' => floatval($visitor_type['price']),
                    'PAYMENTREQUEST_0_AMT' => $total,
                    'PAYMENTREQUEST_0_ITEMAMT' => $total,
                    'PAYMENTREQUEST_0_INVNUM' => $invoice_id,
                    'RETURNURL' => WWW_URL_ROOT. '#/'. $params['language']. '/'. $params['section']. '/payment/'. ($this->onsite ? '?onsite_secret='. $params['onsite_secret'] : ''),
                    'CANCELURL' => WWW_URL_ROOT. '#/'. $params['language']. '/'. $params['section']. '/canceled/'. ($this->onsite ? '?onsite_secret='. $params['onsite_secret'] : '')
                ];
 
                if(!empty($coupon_type)){
                    $paypal_params['L_PAYMENTREQUEST_0_NAME1'] = 'Coupon Code ('. $coupon['coupon_code']. ')';
                    $paypal_params['L_PAYMENTREQUEST_0_QTY1'] = 1;
                    $paypal_params['L_PAYMENTREQUEST_0_AMT1'] = $discounted_price - $original_price;
                }
 
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, PAYPAL_API);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paypal_params));
                $res = curl_exec($ch);
                curl_close($ch);
 
                $paypal_returned_values = array();
                parse_str($res, $paypal_returned_values);
 
                if(empty($res) || empty($paypal_returned_values) || empty($paypal_returned_values['ACK'])){
                    throw new \Exception ('Express-checkout failed');
                }elseif($paypal_returned_values['ACK'] !== 'Success'){
                    throw new \Exception ($paypal_returned_values['L_SEVERITYCODE0']. ': '. $paypal_returned_values['L_LONGMESSAGE0']. ' ('. $paypal_returned_values['L_ERRORCODE0']. ')');
                }
            }elseif($total == 0){
                $this->send_confirmation_email(array_merge(['registration_id' => $registration_id], $params));
            }
            
            $success = true;
        } catch (\Exception $ex) {
            $success = false;
            $msg = $ex->getMessage();
        }
        
        return array(
            'success' => $success,
            'msg' => !empty($msg) ? $msg : NULL,
            'data' => [
                'registration_id' =>  $registration_id,
                'payment_method' => $payment_method,
                'url' => !empty($paypal_returned_values['TOKEN']) ? (PAYPAL_CHECKOUT_URL. '?cmd=_express-checkout&token='. $paypal_returned_values['TOKEN']. '&useraction=commit') : NULL,
                'barcode' => $this->onsite ? json_encode([
                    'id' => $registration_id,
                    'secret' => $secret
                ]) : NULL
            ]
        );
    }

Comments