[TIP] hotopay 결제 완료시 포인트 부여
지난번 글대로 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"> 부여 안함</label>
<!--@foreach($groups as $group)-->
<label><input type="radio" name="product_buyer_group" value="{$group->group_srl}"> {$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"> 부여 안함</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"> {$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 모듈을 제작해주신 리버스님께 감사드립니다.
댓글 5