지난번 글대로 pg사 승인이 났고, 카드사 승인도 모두 완료되어서 간단하게 허접하게나마 수정해서 사용하고 있는 코드를 업데이트 해봅니다. (개인적으로는 차후에 정식 적용이 되면 정말 좋을 것 같습니다. 정말 깔끔하고 완벽한 라이믹스 결제모듈입니다.)

 

 

이 코드를 적용하면 위 처럼 상품 등록시 부여할 포인트를 입력하는 창이 나타나고 결제 완료시 포인트가 부여됩니다. 포인트 제공을 하지 않을 경우는 0을 입력하시면 됩니다.

 

 

수정 파일과 추가한 코드들입니다. hotopay 최신 1.4.4 코드 기준입니다.

 

 


queries\updateProduct.xml


<query id="updateProduct" action="update">
    <tables>
        <table name="hotopay_product" />
    </tables>
    <columns>
        <column name="product_name" var="product_name" />
        <column name="product_des" var="product_des" />
        <column name="product_status" var="product_status" />
        <column name="product_pic_src" var="product_pic_src" />
        <column name="product_pic_srl" var="product_pic_srl" />
        <column name="product_sale_price" var="product_sale_price" />
        <column name="product_original_price" var="product_original_price" />
        <column name="product_option" var="product_option" />
        <column name="product_buyer_group" var="product_buyer_group" />
        <column name="product_buyer_point" var="product_buyer_point" />
        <column name="extra_vars" var="extra_vars" />
        <column name="document_srl" var="document_srl" />
        <column name="tax_rate" var="tax_rate" />
        <column name="is_adult" var="is_adult" />
        <column name="is_billing" var="is_billing" />
        <column name="allow_use_point" var="allow_use_point" />
        <column name="regdate" var="regdate" />
    </columns>
    <conditions>
        <condition operation="equal" column="product_srl" var="product_srl" notnull="notnull" />
    </conditions>
</query>

 

 

 

 


schemas\hotopay_product.xml


<table name="hotopay_product">
    <column name="product_srl" type="number" size="10" notnull="notnull" primary_key="primary_key" />
    <column name="product_name" type="varchar" size="100" notnull="notnull" />
    <column name="product_des" type="varchar" size="500" default="" />
    <column name="product_status" type="varchar" size="20" default="selling" />
    <column name="product_pic_src" type="varchar" size="500" default="" />
    <column name="product_pic_srl" type="number" size="10" default="0" />
    <column name="product_sale_price" type="number" size="10" default="0" />
    <column name="product_original_price" type="number" size="10" default="0" />
    <column name="product_option" type="varchar" size="1000" default="{}" />
    <column name="product_buyer_group" type="number" size="10" default="0" />
    <column name="product_buyer_point" type="number" size="10" default="0" />
    <column name="member_srl" type="number" size="10" notnull="notnull" index="idx_member_srl" />
    <column name="market_srl" type="number" size="20" default="0" index="idx_market_srl" />
    <column name="document_srl" type="number" size="10" default="0" index="idx_document_srl" />
    <column name="tax_rate" type="double" default="0" />
    <column name="is_adult" type="char" size="1" default="N" />
    <column name="is_billing" type="char" size="1" default="N" />
    <column name="allow_use_point" type="char" size="1" default="Y" />
    <column name="extra_vars" type="text" />
    <column name="regdate" type="number" size="10" notnull="notnull" index="idx_regdate" />
</table>

 

 

 


tpl\insert_product.html


    <div class="x_control-group">
        <label class="x_control-label" for="product_buyer_group">구매시 부여할 그룹</label>
        <div class="x_controls">
            <label><input type="radio" name="product_buyer_group" value="0" checked="checked">&nbsp;부여 안함</label>
            <!--@foreach($groups as $group)-->
            <label><input type="radio" name="product_buyer_group" value="{$group->group_srl}">&nbsp;{$group->title}</label>
            <!--@endforeach-->
        </div>
    </div>
    
    <div class="x_control-group">
      <label class="x_control-label" for="product_buyer_point">구매시 부여할 포인트</label>
        <div class="x_controls">
            <input type="number" name="product_buyer_point" id="product_buyer_point" value="{$product->product_buyer_point}" required><br>
            부여할 포인트입니다.
        </div>
    </div>

    

    <div class="btnArea x_clearfix">
        <button type="submit" class="x_btn x_btn-primary x_pull-right">{$lang->cmd_registration}</button>
    </div>
</form>

 

 

 

 


tpl\modify_product.html


    <div class="x_control-group">
        <label class="x_control-label" for="product_buyer_group">구매시 부여할 그룹</label>
        <div class="x_controls">
            <label><input type="radio" name="product_buyer_group" value="0" checked="checked"|cond="$product->product_buyer_group == 0">&nbsp;부여 안함</label>
            <!--@foreach($groups as $group)-->
            <label><input type="radio" name="product_buyer_group" value="{$group->group_srl}" checked="checked"|cond="$product->product_buyer_group == $group->group_srl">&nbsp;{$group->title}</label>
            <!--@endforeach-->
            <p class="x_help-block">구매시 부여할 그룹을 선택합니다. 정기결제 상품은 구매 후 다음 만료일 전까지 해당 그룹이 유효하며 기한 만료 혹은 결재 실패시 회수됩니다.</p>
        </div>
    </div>
    
    <div class="x_control-group">
      <label class="x_control-label" for="product_buyer_point">구매시 부여할 포인트</label>
        <div class="x_controls">
            <input type="number" name="product_buyer_point" id="product_buyer_point" value="{$product->product_buyer_point}" required><br>
            부여할 포인트입니다.
        </div>
    </div>


    <div class="btnArea x_clearfix">
        <button type="submit" class="x_btn x_btn-primary x_pull-right">수정</button>
    </div>
</form>

 

 

 


hotopay.admin.controller.php // 추가 부분 2군데 있음


 

   // \n을 <br>로 변환하는 함수
        // $contents = nl2br($vars->product_option);
        $args->product_option = ''; // 사용 안함
        $args->product_buyer_group = $vars->product_buyer_group;
        $args->product_buyer_point = $vars->product_buyer_point;
        $args->extra_vars = serialize($vars->extra_vars ?? new stdClass());
        $args->regdate = time();

        executeQuery("hotopay.insertProduct", $args);

 


 

    // \n을 <br>로 변환하는 함수
        // $contents = nl2br($vars->product_option);
        $args->product_option = ''; // 사용 안함
        $args->product_buyer_group = $vars->product_buyer_group ?: 0;
        $args->product_buyer_point = $vars->product_buyer_point ?: 0;
        $args->regdate = time();

        $output = executeQuery("hotopay.updateProduct", $args);
        if(!$output->toBool()) return $output;

 

 

 


hotopay.class.php // 세군데 추가


 

    if (self::$_config_cache === null)
        {
            $oModuleModel = getModel('module');
            self::$_config_cache = $oModuleModel->getModuleConfig('hotopay') ?: new stdClass;
            if(!isset(self::$_config_cache->hotopay_purchase_enabled)) self::$_config_cache->hotopay_purchase_enabled = 'Y'; // Hotopay 결제 활성화
            if(!isset(self::$_config_cache->shop_name)) self::$_config_cache->shop_name = 'HotoPay'; // 쇼핑몰 이름
            if(!isset(self::$_config_cache->board_module_srl)) self::$_config_cache->board_module_srl = array(); // 선택한 게시판 mid
            if(!isset(self::$_config_cache->point_discount)) self::$_config_cache->point_discount = 'N'; // 포인트 할인 활성화
            if(!isset(self::$_config_cache->cart_item_limit)) self::$_config_cache->cart_item_limit = 50; // 카트에 담을 수 있는 최대 상품 개수
            if(!isset(self::$_config_cache->min_product_price)) self::$_config_cache->min_product_price = 0; // 등록할 수 있는 최소 가격
            if(!isset(self::$_config_cache->change_group_to_regular_when_pay)) self::$_config_cache->change_group_to_regular_when_pay = 'N'; // 결제시에 회원 그룹을 정회원으로 변경
            if(!isset(self::$_config_cache->associate_group_srl)) self::$_config_cache->associate_group_srl = 2; // 준회원 그룹 srl
            if(!isset(self::$_config_cache->regular_group_srl)) self::$_config_cache->regular_group_srl = 3; // 정회원 그룹 srl
            if(!isset(self::$_config_cache->product_buyer_point)) self::$_config_cache->product_buyer_point = 0; // 구입 포인트
            if(!isset(self::$_config_cache->hotopay_license_key)) self::$_config_cache->hotopay_license_key = ''; // Hotopay 라이선스 키
            if(!isset(self::$_config_cache->hotopay_last_license_expire_alert_date)) self::$_config_cache->hotopay_last_license_expire_alert_date = 0; // 라이선스 만료 경고 마지막 날짜

            if(!isset(self::$_config_cache->hotopay_currency_renew_api_type)) self::$_config_cache->hotopay_currency_renew_api_type = 'exchangeratehost'; // 환율 갱신 API 타입 (none/fixerio/exchangeratehost)
            if(!isset(self::$_config_cache->fixer_io_api_key)) self::$_config_cache->fixer_io_api_key = ''; // Fixer.io API Key
            if(!isset(self::$_config_cache->hotopay_currency_renew_time)) self::$_config_cache->hotopay_currency_renew_time = 0; // 환율 갱신 API 마지막 시각

 

 


 

    public function checkUpdate()
    {
        $oModule = getModel('module');
        $module_info = $oModule->getModuleInfoByMid('hotopay');
        if($module_info->module_srl)
        {
            if($module_info->module != 'hotopay')
            {
                return true;
            }
        }else return true;

        $oDB = DB::getInstance();
        if(!$oDB->isColumnExists("hotopay_product","extra_vars")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase","extra_vars")) return true;
        if(!$oDB->isColumnExists("hotopay_product_option","infinity_stock")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase_item","option_name")) return true;
        if(!$oDB->isColumnExists("hotopay_product","member_srl")) return true;
        if(!$oDB->isIndexExists("hotopay_product","idx_member_srl")) return true;
        if(!$oDB->isColumnExists("hotopay_product","product_status")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase","iamport_uid")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase","receipt_url")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase","title")) return true;
        if(!$oDB->isColumnExists("hotopay_product","tax_rate")) return true;
        if(!$oDB->isColumnExists("hotopay_product","market_srl")) return true;
        if(!$oDB->isIndexExists("hotopay_product","idx_market_srl")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase_item","quantity")) return true;
        if(!$oDB->isColumnExists("hotopay_product","is_adult")) return true;
        if(!$oDB->isColumnExists("hotopay_product","product_buyer_point")) return true;
        if(!$oDB->isColumnExists("hotopay_product","is_billing")) return true;
        if(!$oDB->isColumnExists("hotopay_product_option","billing_period_date")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase","is_billing")) return true;
        if(!$oDB->isColumnExists("hotopay_product_option","billing_infinity_stock")) return true;
        if(!$oDB->isColumnExists("hotopay_product","allow_use_point")) return true;
        if(!$oDB->isColumnExists("hotopay_purchase_item","subscription_srl")) return true;
        if(!$oDB->isIndexExists("hotopay_purchase_item","idx_subscription_srl")) return true;

        $config = $this->getConfig();
        if (self::HOTOPAY_NEEDED_DB_VERSION > $config->hotopay_db_version)
        {
            return true;
        }

        return $this->checkTriggers();
    }

 

 


 

 

    if(!$oDB->isColumnExists("hotopay_purchase_item","option_name"))
        {
            $oDB->addColumn('hotopay_purchase_item',"option_name","varchar",500,null,true,"option_srl");
        }

        if(!$oDB->isColumnExists("hotopay_product","member_srl"))
        {
            $oDB->addColumn('hotopay_product',"member_srl","number",20,null,true,"product_buyer_group");
        }
        
        if(!$oDB->isColumnExists("hotopay_product","product_buyer_point"))
        {
            $oDB->addColumn('hotopay_product',"product_buyer_point","number",10,0,false,"member_srl");
        }

        
        if(!$oDB->isIndexExists("hotopay_product","idx_member_srl"))
        {
            $oDB->addIndex('hotopay_product',"idx_member_srl","member_srl");
        }

        if(!$oDB->isColumnExists("hotopay_product","product_status"))
        {
            $oDB->addColumn('hotopay_product',"product_status","varchar",20,"selling",false,"product_des");
        }

        if(!$oDB->isColumnExists("hotopay_product","document_srl"))
        {
            $oDB->addColumn('hotopay_product',"document_srl","number",20,null,false,"member_srl");
        }
 

 

 


\hotopay.controller.php  // 세군데 추가


 

public function _ActivePurchase($purchase_srl, $member_srl = -1)
    {
        $logged_info = Context::get('logged_info');
        if($member_srl == -1) $member_srl = $logged_info->member_srl;

        $oHotopayModel = getModel('hotopay');
        $purchase = $oHotopayModel->getPurchase($purchase_srl);

        $trigger_obj = new stdClass();
        $trigger_obj->member_srl = $member_srl;
        $trigger_obj->purchase_srl = $purchase_srl;
        $output = ModuleHandler::triggerCall('hotopay.activePurchase', 'before', $trigger_obj);
        if(!$output->toBool()) return $output;

        $args = new stdClass();
        $args->purchase_srl = $purchase_srl;
        $args->pay_status = "DONE";
        executeQuery('hotopay.updatePurchaseStatus', $args);

        $this->_MessageMailer("DONE", $purchase);
        $this->_AdminMailer("DONE", $purchase);
        $this->clearPurchasedCartItem($purchase);

        $products = $oHotopayModel->getProductsByPurchaseSrl($purchase_srl);

        $group_srls = array();
        $oMemberController = getController('member');
        $oPointController = getController('point'); // 포인트 컨트롤러 추가
        foreach($products as $product)
        {
            $group_srl = $product->product_buyer_group;
            if($group_srl != 0)
            {
                $group_srls[] = $group_srl;
                $oMemberController->addMemberToGroup($member_srl, $group_srl);
            }
 
             // 포인트 부여 코드 추가
            $product_info = $oHotopayModel->getProduct($product->product_srl); // 상품 정보 가져오기
            $points_to_add = $product_info->product_buyer_point; // 상품 정보에서 포인트 값을 가져옴
            $current_points = getModel('point')->getPoint($member_srl, true); // 현재 포인트
            $new_points = $current_points + $points_to_add; // 새로운 포인트
            $oPointController->setPoint($member_srl, $new_points); // 포인트 설정

        }

        $config = $this->getConfig();
        if ($config->change_group_to_regular_when_pay == 'Y')
        {
            if ($config->regular_group_srl != 0)
            {
                $oMemberController->addMemberToGroup($member_srl, $config->regular_group_srl);
            }

            if ($config->associate_group_srl != 0)
            {
                $args = new stdClass();
                $args->member_srl = $member_srl;
                $args->group_srl = $config->associate_group_srl;
                $output = executeQuery('member.deleteMemberGroupMember', $args); // 그룹제거
            }
        }

        $trigger_obj->group_srls = $group_srls;
        ModuleHandler::triggerCall('hotopay.activePurchase', 'after', $trigger_obj);
    }

 

 


 

 

 

    public function triggerAfterInsertDocument($obj)
    {
        $config = $this->getConfig();
        $mid = $obj->mid;

        $oModuleModel = getModel('module');
        $module_info = $oModuleModel->getModuleInfoByMid($mid);
        if(in_array($module_info->module_srl, $config->board_module_srl))
        {
            if(!isset($obj->sale_option)) return;

            $lowest_price = -1;
            foreach($obj->sale_option as &$options)
            {
                $options = (object) $options;
                $options->price = preg_replace("/[^\d]/", "", $options->price) ?: 0;
                if($lowest_price == -1 || $options->price < $lowest_price)
                {
                    $lowest_price = $options->price;
                }
            }

            $sale_price = $lowest_price;
            $extra_vars = (object) $obj->extra_vars ?: new \stdClass();
            $product_option = '';

            Context::set('product_name', $obj->title, true);
            Context::set('product_des', $obj->sub_title, true);
            Context::set('product_sale_price', $sale_price, true);
            Context::set('product_original_price', $sale_price, true);
            Context::set('product_option', $product_option, true);
            Context::set('product_buyer_group', 0, true);
            Context::set('product_buyer_point', 0, true);
            Context::set('extra_vars', $extra_vars, true);
            Context::set('document_srl', $obj->document_srl, true);

            $oHotopayAdminController = getAdminController('hotopay');
            $output = $oHotopayAdminController->procHotopayAdminInsertProduct();
        }
    }

 


 

    public function triggerAfterUpdateDocument($obj)
    {
        $config = $this->getConfig();
        $mid = $obj->mid;

        $oModuleModel = getModel('module');
        $module_info = $oModuleModel->getModuleInfoByMid($mid);
        if(in_array($module_info->module_srl, $config->board_module_srl))
        {
            if(!isset($obj->sale_option)) return;

            $lowest_price = -1;
            foreach($obj->sale_option as &$options)
            {
                $options = (object) $options;
                $options->price = preg_replace("/[^\d]/", "", $options->price);
                if($lowest_price == -1 || $options->price < $lowest_price)
                {
                    $lowest_price = $options->price;
                }
            }
            $logged_info = Context::get('logged_info');

            $sale_price = $lowest_price;

            $extra_vars = $obj->extra_vars ?? new stdClass();
            if(!($extra_vars instanceof stdClass))
            {
                $extra_vars = (object) $extra_vars ?? new stdClass();
            }
            $extra_vars->option_description = [];

            $product_option = '';

            Context::set('product_srl', $obj->hotopay_product_srl, true);
            Context::set('product_name', $obj->title, true);
            Context::set('product_des', $obj->sub_title, true);
            Context::set('product_sale_price', $sale_price, true);
            Context::set('product_original_price', $sale_price, true);
            Context::set('product_option', $product_option, true);
            Context::set('product_buyer_group', 0, true);
            Context::set('product_buyer_point', 0, true);
            Context::set('extra_vars', $extra_vars, true);
            $oHotopayAdminController = getAdminController('hotopay');
            $output = $oHotopayAdminController->procHotopayAdminModifyProduct();
        }
    }
 

 


 

 

이상입니다. 환불시 포인트 회수 코드는 들어있지 않고, 수동으로 포인트 삭제 처리 해주셔야 합니다. ^^ 허접한 팁이지만 도움이 되시는 분들이 계시길... 다시한번 hotopay 모듈을 제작해주신 리버스님께 감사드립니다. 

 

 

  • ?
    감사합니다. 빨간색 코드를 추가하라는걸까요? 제가 밖이라서 확인못해서 여쭈어봅니다.
  • ? profile
    네 맞습니다. ^^
  • profile ?
    감사합니다.
  • profile
    자세한 팁 감사합니다~
  • profile profile
    정말 잘 사용 중입니다. ^^ 감사합니다!