Changeset 1888627
- Timestamp:
- 06/07/2018 08:39:32 AM (8 years ago)
- Location:
- woo-bootpay/trunk
- Files:
-
- 2 edited
-
bootpay-woocommerce.php (modified) (2 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
woo-bootpay/trunk/bootpay-woocommerce.php
r1858733 r1888627 4 4 * Plugin URI: https://www.bootpay.co.kr 5 5 * Description: 우커머스에 PG를 손쉽게 붙일 수 연동 플러그인 ( 이니시스 / 다날 / KCP / LGU+ 모두 쉽게 붙이는 Woo-bootpay ) 6 * Version: 1.1.1 06 * Version: 1.1.11 7 7 * Author: Gosomi 8 8 * Author URI: https://blog.areum.io … … 10 10 */ 11 11 12 require_once( 'bootpay-api.php' ); 13 14 add_action( 'init', function() { 15 register_post_status( 'wc-wating-bank', [ 16 'label' => __( '입금대기', 'bootpay-with-woocommerce' ), 17 'label_count' => _n_noop( '입금대기 <span class="count">(%s)</span>', '입금대기 <span class="count">(%s)</span>' ), 18 'show_in_admin_all_list' => true, 19 'public' => true, 20 'show_in_admin_status_list' => true, 21 'exclude_from_search' => false 22 ] ); 23 } ); 24 add_action( 'wc_order_statuses', function( $order_statuses ) { 25 $order_statuses['wc-wating-bank'] = __( '입금대기', 'bootpay-with-woocommerce' ); 26 27 return $order_statuses; 28 } ); 29 add_filter( 'woocommerce_payment_gateways', function() { 30 $methods[] = 'WC_Gateway_Bootpay'; 31 32 return $methods; 33 } ); 34 35 add_action( 'plugins_loaded', 'init_bootpay_plugin', 0 ); 36 load_plugin_textdomain( 'bootpay-with-woocommerce', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); 37 38 function init_bootpay_plugin() { 39 if( ! class_exists( 'WC_Payment_Gateway' ) || class_exists( 'WC_Gateway_Bootpay' ) ) { 40 return; 41 } 42 43 class WC_Gateway_Bootpay extends WC_Payment_Gateway { 44 45 const CURRENT_VERSION = '1.1.3'; 46 const BOOTPAY_WC_DOMAIN = 'bootpay-with-woocommerce'; 47 const SUPPORT_CURRENCY = ['KRW']; 48 const PAYMENT_SUBMIT = 'BOOTPAY_PAYMENT_SUBMIT'; 49 const VBANK_NOTIFICATION = 'BOOTPAY_VBANK_NOTI'; 50 51 static $loadActions = false; 52 53 public function __construct() { 54 $this->id = 'bootpay_gateway'; 55 $this->method_title = __( '부트페이', self::BOOTPAY_WC_DOMAIN ); 56 $this->method_description = __( '* 부트페이를 이용하여 결제를 할 수 있습니다.', self::BOOTPAY_WC_DOMAIN ); 57 $this->has_fields = true; 58 $this->supports = ['products', 'refunds']; 59 $this->enabled = $this->is_valid_currency(); 60 61 $this->init_form_fields(); 62 $this->init_settings(); 63 64 $this->title = $this->get_option( 'title' ); 65 $this->description = $this->get_option( 'description' ); 66 if( !static::$loadActions ) { 67 $this->load_actions(); 68 } 69 70 } 71 72 public function init_form_fields() { 73 $this->form_fields = [ 74 'enabled' => [ 75 'title' => __( 'Enable/Disable', 'woocommerce' ), 76 'type' => 'checkbox', 77 'label' => __( '부트페이 결제 활성화', self::BOOTPAY_WC_DOMAIN ), 78 'default' => 'yes' 79 ], 80 'title' => [ 81 'title' => __( 'Title', 'woocommerce' ), 82 'type' => 'text', 83 'description' => __( '결제 정보 수단 이름', self::BOOTPAY_WC_DOMAIN ), 84 'default' => __( '부트페이 [ 휴대폰 소액결제 / 카드 결제 ]', self::BOOTPAY_WC_DOMAIN ), 85 'desc_tip' => true 86 ], 87 'description' => [ 88 'title' => __( 'Customer Message', 'woocommerce' ), 89 'type' => 'textarea', 90 'description' => __( '구매 고객에게 결제 정보에 대한 설명을 보여줍니다.', self::BOOTPAY_WC_DOMAIN ), 91 'default' => __( '주문확정 버튼을 누르면 결제를 진행할 수 있습니다.', self::BOOTPAY_WC_DOMAIN ) 92 ], 93 'notification' => [ 94 'title' => __( '가상계좌 입금 통지 URL', self::BOOTPAY_WC_DOMAIN ), 95 'type' => 'text', 96 'custom_attributes' => ['readonly' => 'true'], 97 'description' => __( 'URL을 복사 한 후 부트페이 관리자에서 결제연동 > Private key관리 > 웹 ( FeedbackUrl )에 붙여넣기 한 후 저장해주세요.', self::BOOTPAY_WC_DOMAIN ), 98 'placeholder' => add_query_arg( 'wc-api', self::VBANK_NOTIFICATION, site_url() ), 99 'default' => add_query_arg( 'wc-api', self::VBANK_NOTIFICATION, site_url() ) 100 ], 101 'js_api_key' => [ 102 'title' => __( 'Javascript API KEY', self::BOOTPAY_WC_DOMAIN ), 103 'type' => 'text', 104 'description' => __( '부트페이 관리자에서 자바스크립트 API KEY를 복사한 후 붙여넣기 해주세요.', self::BOOTPAY_WC_DOMAIN ), 105 'placeholder' => __( '자바스크립트 API KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN ) 106 ], 107 'rest_api_key' => [ 108 'title' => __( 'REST API KEY', self::BOOTPAY_WC_DOMAIN ), 109 'type' => 'text', 110 'description' => __( '부트페이 관리자에서 REST API KEY를 복사한 후 붙여넣기 해주세요. 결제 취소 / 검증 시에 반드시 필요합니다.', self::BOOTPAY_WC_DOMAIN ), 111 'placeholder' => __( 'REST API KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN ) 112 ], 113 'private_key' => [ 114 'title' => __( 'PRIVATE KEY', self::BOOTPAY_WC_DOMAIN ), 115 'type' => 'text', 116 'description' => __( '서버 인증에 필요한 PRIVATE KEY를 관리자에서 복사한 후 붙여넣기 해주세요.', self::BOOTPAY_WC_DOMAIN ), 117 'placeholder' => __( 'PRIVATE KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN ) 118 ], 119 'agree_window' => [ 120 'title' => __( '동의창 보이기 여부', self::BOOTPAY_WC_DOMAIN ), 121 'type' => 'checkbox', 122 'description' => __( '부트페이 약관 동의창을 보이게 하려면 체크해주세요.', self::BOOTPAY_WC_DOMAIN ) 123 ] 124 ]; 125 } 126 127 /** 128 * 지원하는 결제 리스트 129 * @return bool 130 */ 131 public function is_valid_currency() { 132 if( ! in_array( get_woocommerce_currency(), self::SUPPORT_CURRENCY ) ) { 133 $this->msg = sprintf( "부트페이는 %s 화폐 결제를 지원하지 않습니다.", get_woocommerce_currency() ); 134 135 return false; 136 } 137 138 return true; 139 } 140 141 /** 142 * admin option 호출 143 * 관리자 환경설정에서 option 및 타이틀 기능을 커스텀 한다. 144 */ 145 public function admin_options() { 146 $this->renderFile( 'header.php', [ 147 'title' => __( '부트페이 설정', self::BOOTPAY_WC_DOMAIN ) 148 ] ); 149 } 150 151 /** 152 * Action Gateway를 호출하여 Override한다. 153 */ 154 public function load_actions() { 155 add_filter( 'login_redirect', [$this, 'bootpay_login_redirect'], 30, 3 ); 156 add_action( 'woocommerce_api_' . strtolower( self::PAYMENT_SUBMIT ), [$this, 'payment_validation'] ); 157 add_action( 'woocommerce_api_' . strtolower( self::VBANK_NOTIFICATION ), [$this, 'vbank_notification'] ); 158 add_action( 'woocommerce_order_details_after_order_table', [$this, 'bootpay_order_table'], 10, 1 ); 159 add_action( "woocommerce_update_options_payment_gateways_{$this->id}", [$this, 'process_admin_options'] ); 160 add_action( "wp_ajax_bootpay_payment_response", [$this, 'pre_bootpay_payment_response'] ); 161 add_action( "admin_enqueue_scripts", [$this, 'enqueue_inject_admin_bootpay_script'], 10000 ); 162 add_action( "wp_enqueue_scripts", [$this, 'enqueue_inject_bootpay_script'], 10000 ); 163 add_filter( 'wc_checkout_params', [$this, 'inject_checkout_params'] ); 164 add_action( 'wp_head', [$this, 'insert_meta_tag'] ); 165 wp_register_script( 'bootpay-script', plugins_url( '/assets/js/bootpay.js', plugin_basename( __FILE__ ) ) ); 166 wp_register_script( 'bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js" ); 167 wp_enqueue_script( 'jquery' ); 168 wp_enqueue_script( 'bootpay-script' ); 169 wp_enqueue_script( 'bootpay-cdn-script' ); 170 if( is_product() ) { 171 wp_register_script( 'bootpay-analystics-script', plugins_url( '/assets/js/bootpay-analystics.js', plugin_basename( __FILE__ ) ) ); 172 wp_enqueue_script( 'bootpay-analystics-script' ); 173 } 174 static::$loadActions = true; 175 } 176 177 public function insert_meta_tag() { 178 echo "\t<meta name='bootpay-application-id' content='{$this->get_option('js_api_key')}' />\n"; 179 } 180 181 public function bootpay_order_table( $order ) { 182 return $this->renderFile( 'order_detail.php', [ 183 'pg_name' => $order->get_meta( 'bootpay_pg_name' ), 184 'method_name' => $order->get_meta( 'bootpay_method_name' ), 185 'bankname' => $order->get_meta( 'bootpay_bankname' ), 186 'holder' => $order->get_meta( 'bootpay_holder' ), 187 'account' => $order->get_meta( 'bootpay_account' ), 188 'username' => $order->get_meta( 'bootpay_username' ), 189 'expire' => $order->get_meta( 'bootpay_expire' ), 190 'price' => number_format( (int) $order->get_total() ) 191 ] ); 192 } 193 194 public function pre_bootpay_payment_response() { 195 if( ! empty( $_POST['order_key'] ) ) { 196 $order_id = wc_get_order_id_by_order_key( $_POST['order_key'] ); 197 $this->renderJson( $this->bootpay_payment_response( $order_id ) ); 198 } else { 199 $this->renderJson( [ 200 'result' => 'failure', 201 'messages' => __( '해당되는 Order Key 정보를 찾지 못했습니다.', self::BOOTPAY_WC_DOMAIN ) 202 ] ); 203 } 204 } 205 206 /** 207 * Bootpay로 주문한 데이터 결과를 가져온다. 208 */ 209 public function bootpay_payment_response( $order_id ) { 210 $order = new WC_Order( $order_id ); 211 $checkout_url = $order->has_status( [ 212 'processing', 213 'completed' 214 ] ) ? $order->get_checkout_order_received_url() : $order->get_checkout_payment_url( false ); 215 $order_items = $order->get_items(); 216 if( is_array( $order_items ) ) { 217 $items = []; 218 foreach( $order_items as $item_id => $item ) { 219 $cats = []; 220 $terms = get_the_terms( $item['product_id'], 'product_cat' ); 221 foreach( $terms as $term ) { 222 $cats[] = $term->slug; 223 } 224 $line_price = wc_get_order_item_meta( $item_id, '_line_total', true ); 225 array_push( $items, [ 226 'item_name' => $item['name'], 227 'qty' => $item['qty'], 228 'unique' => (string) $item_id, 229 'price' => (int) ( $line_price / $item['qty'] ), 230 'cat1' => empty( $cats[0] ) ? '' : $cats[0], 231 'cat2' => empty( $cats[1] ) ? '' : $cats[1], 232 'cat3' => empty( $cats[2] ) ? '' : $cats[2], 233 ] ); 234 } 235 } 236 237 $order_data = [ 238 'name' => sizeof( $items ) > 1 ? sprintf( "%s 외 %s 개", $items[0]['item_name'], sizeof( $items ) - 1 ) : $items[0]['item_name'], 239 'price' => $order->get_total(), 240 'items' => $items, 241 'order_id' => $order_id, 242 'user_info' => [ 243 'username' => $order->billing_last_name . $order->billing_first_name, 244 'phone' => ( empty( $order->get_billing_phone() ) ? '010-0000-0000' : $order->get_billing_phone() ), 245 'email' => $order->billing_email, 246 'addr' => strip_tags( implode( ' ', [ 247 $order->get_billing_city(), 248 $order->get_billing_address_1(), 249 $order->get_billing_address_2() 250 ] ) ) 251 ] 252 ]; 253 254 return [ 255 'result' => 'success', 256 'order_key' => $order->order_key, 257 'order_id' => $order_id, 258 'order_data' => $order_data, 259 'checkout_url' => add_query_arg( [ 260 'wc-api' => self::PAYMENT_SUBMIT, 261 'order_id' => $order_id 262 ], $checkout_url ), 263 ]; 264 } 265 266 /** 267 * Bootpay Script 추가 268 */ 269 public function enqueue_inject_bootpay_script() { 270 wp_register_script( 'bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js" ); 271 wp_register_script( 'bootpay-script', plugins_url( '/assets/js/bootpay.js', plugin_basename( __FILE__ ) ) ); 272 wp_register_script( 'bootpay-order-script', plugins_url( '/assets/js/bootpay-order.js', plugin_basename( __FILE__ ) ) ); 273 // 일단 주석 checkout을 주석처리할 경우 woocommerce의 wc_checkout_params의 값을 사용 못함 12 require_once('bootpay-api.php'); 13 14 add_action('init', function () { 15 register_post_status('wc-wating-bank', [ 16 'label' => __('입금대기', 'bootpay-with-woocommerce'), 17 'label_count' => _n_noop('입금대기 <span class="count">(%s)</span>', '입금대기 <span class="count">(%s)</span>'), 18 'show_in_admin_all_list' => true, 19 'public' => true, 20 'show_in_admin_status_list' => true, 21 'exclude_from_search' => false 22 ]); 23 }); 24 add_action('wc_order_statuses', function ($order_statuses) { 25 $order_statuses['wc-wating-bank'] = __('입금대기', 'bootpay-with-woocommerce'); 26 27 return $order_statuses; 28 }); 29 add_filter('woocommerce_payment_gateways', function ($methods) { 30 $methods[] = 'WC_Gateway_Bootpay'; 31 return $methods; 32 }); 33 34 add_action('plugins_loaded', 'init_bootpay_plugin', 0); 35 load_plugin_textdomain('bootpay-with-woocommerce', false, dirname(plugin_basename(__FILE__)) . '/languages'); 36 37 function init_bootpay_plugin() 38 { 39 if (!class_exists('WC_Payment_Gateway') || class_exists('WC_Gateway_Bootpay')) { 40 return; 41 } 42 43 class WC_Gateway_Bootpay extends WC_Payment_Gateway 44 { 45 46 const CURRENT_VERSION = '2.0.6'; 47 const BOOTPAY_WC_DOMAIN = 'bootpay-with-woocommerce'; 48 const SUPPORT_CURRENCY = ['KRW']; 49 const PAYMENT_SUBMIT = 'BOOTPAY_PAYMENT_SUBMIT'; 50 const VBANK_NOTIFICATION = 'BOOTPAY_VBANK_NOTI'; 51 52 static $loadActions = false; 53 54 public function __construct() 55 { 56 $this->id = 'bootpay_gateway'; 57 $this->method_title = __('부트페이', self::BOOTPAY_WC_DOMAIN); 58 $this->method_description = __('* 부트페이를 이용하여 결제를 할 수 있습니다.', self::BOOTPAY_WC_DOMAIN); 59 $this->has_fields = true; 60 $this->supports = ['products', 'refunds']; 61 $this->enabled = $this->is_valid_currency(); 62 63 $this->init_form_fields(); 64 $this->init_settings(); 65 66 $this->title = $this->get_option('title'); 67 $this->description = $this->get_option('description'); 68 if (!static::$loadActions) { 69 $this->load_actions(); 70 } 71 72 } 73 74 public function init_form_fields() 75 { 76 $this->form_fields = [ 77 'enabled' => [ 78 'title' => __('Enable/Disable', 'woocommerce'), 79 'type' => 'checkbox', 80 'label' => __('부트페이 결제 활성화', self::BOOTPAY_WC_DOMAIN), 81 'default' => 'yes' 82 ], 83 'title' => [ 84 'title' => __('Title', 'woocommerce'), 85 'type' => 'text', 86 'description' => __('결제 정보 수단 이름', self::BOOTPAY_WC_DOMAIN), 87 'default' => __('부트페이 [ 휴대폰 소액결제 / 카드 결제 ]', self::BOOTPAY_WC_DOMAIN), 88 'desc_tip' => true 89 ], 90 'description' => [ 91 'title' => __('Customer Message', 'woocommerce'), 92 'type' => 'textarea', 93 'description' => __('구매 고객에게 결제 정보에 대한 설명을 보여줍니다.', self::BOOTPAY_WC_DOMAIN), 94 'default' => __('주문확정 버튼을 누르면 결제를 진행할 수 있습니다.', self::BOOTPAY_WC_DOMAIN) 95 ], 96 'notification' => [ 97 'title' => __('가상계좌 입금 통지 URL', self::BOOTPAY_WC_DOMAIN), 98 'type' => 'text', 99 'custom_attributes' => ['readonly' => 'true'], 100 'description' => __('URL을 복사 한 후 부트페이 관리자에서 결제연동 > Private key관리 > 웹 ( FeedbackUrl )에 붙여넣기 한 후 저장해주세요.', self::BOOTPAY_WC_DOMAIN), 101 'placeholder' => add_query_arg('wc-api', self::VBANK_NOTIFICATION, site_url()), 102 'default' => add_query_arg('wc-api', self::VBANK_NOTIFICATION, site_url()) 103 ], 104 'js_api_key' => [ 105 'title' => __('Javascript API KEY', self::BOOTPAY_WC_DOMAIN), 106 'type' => 'text', 107 'description' => __('부트페이 관리자에서 자바스크립트 API KEY를 복사한 후 붙여넣기 해주세요.', self::BOOTPAY_WC_DOMAIN), 108 'placeholder' => __('자바스크립트 API KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN) 109 ], 110 'rest_api_key' => [ 111 'title' => __('REST API KEY', self::BOOTPAY_WC_DOMAIN), 112 'type' => 'text', 113 'description' => __('부트페이 관리자에서 REST API KEY를 복사한 후 붙여넣기 해주세요. 결제 취소 / 검증 시에 반드시 필요합니다.', self::BOOTPAY_WC_DOMAIN), 114 'placeholder' => __('REST API KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN) 115 ], 116 'private_key' => [ 117 'title' => __('PRIVATE KEY', self::BOOTPAY_WC_DOMAIN), 118 'type' => 'text', 119 'description' => __('서버 인증에 필요한 PRIVATE KEY를 관리자에서 복사한 후 붙여넣기 해주세요.', self::BOOTPAY_WC_DOMAIN), 120 'placeholder' => __('PRIVATE KEY를 입력해주세요.', self::BOOTPAY_WC_DOMAIN) 121 ], 122 'agree_window' => [ 123 'title' => __('동의창 보이기 여부', self::BOOTPAY_WC_DOMAIN), 124 'type' => 'checkbox', 125 'description' => __('부트페이 약관 동의창을 보이게 하려면 체크해주세요.', self::BOOTPAY_WC_DOMAIN) 126 ] 127 ]; 128 } 129 130 /** 131 * 지원하는 결제 리스트 132 * @return bool 133 */ 134 public function is_valid_currency() 135 { 136 if (!in_array(get_woocommerce_currency(), self::SUPPORT_CURRENCY)) { 137 $this->msg = sprintf("부트페이는 %s 화폐 결제를 지원하지 않습니다.", get_woocommerce_currency()); 138 139 return false; 140 } 141 142 return true; 143 } 144 145 /** 146 * admin option 호출 147 * 관리자 환경설정에서 option 및 타이틀 기능을 커스텀 한다. 148 */ 149 public function admin_options() 150 { 151 $this->renderFile('header.php', [ 152 'title' => __('부트페이 설정', self::BOOTPAY_WC_DOMAIN) 153 ]); 154 } 155 156 /** 157 * Action Gateway를 호출하여 Override한다. 158 */ 159 public function load_actions() 160 { 161 add_filter('login_redirect', [$this, 'bootpay_login_redirect'], 30, 3); 162 add_action('woocommerce_api_' . strtolower(self::PAYMENT_SUBMIT), [$this, 'payment_validation']); 163 add_action('woocommerce_api_' . strtolower(self::VBANK_NOTIFICATION), [$this, 'vbank_notification']); 164 add_action('woocommerce_order_details_after_order_table', [$this, 'bootpay_order_table'], 10, 1); 165 add_action("woocommerce_update_options_payment_gateways_{$this->id}", [$this, 'process_admin_options']); 166 add_action("wp_ajax_bootpay_payment_response", [$this, 'pre_bootpay_payment_response']); 167 add_action("admin_enqueue_scripts", [$this, 'enqueue_inject_admin_bootpay_script'], 10000); 168 add_action("wp_enqueue_scripts", [$this, 'enqueue_inject_bootpay_script'], 10000); 169 add_filter('wc_checkout_params', [$this, 'inject_checkout_params']); 170 add_action('wp_head', [$this, 'insert_meta_tag']); 171 wp_register_script('bootpay-script', plugins_url('/assets/js/bootpay.js', plugin_basename(__FILE__))); 172 wp_register_script('bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js"); 173 wp_enqueue_script('jquery'); 174 wp_enqueue_script('bootpay-script'); 175 wp_enqueue_script('bootpay-cdn-script'); 176 if (is_product()) { 177 wp_register_script('bootpay-analystics-script', plugins_url('/assets/js/bootpay-analystics.js', plugin_basename(__FILE__))); 178 wp_enqueue_script('bootpay-analystics-script'); 179 } 180 static::$loadActions = true; 181 } 182 183 public function insert_meta_tag() 184 { 185 echo "\t<meta name='bootpay-application-id' content='{$this->get_option('js_api_key')}' />\n"; 186 } 187 188 public function bootpay_order_table($order) 189 { 190 return $this->renderFile('order_detail.php', [ 191 'pg_name' => $order->get_meta('bootpay_pg_name'), 192 'method_name' => $order->get_meta('bootpay_method_name'), 193 'bankname' => $order->get_meta('bootpay_bankname'), 194 'holder' => $order->get_meta('bootpay_holder'), 195 'account' => $order->get_meta('bootpay_account'), 196 'username' => $order->get_meta('bootpay_username'), 197 'expire' => $order->get_meta('bootpay_expire'), 198 'price' => number_format((int)$order->get_total()) 199 ]); 200 } 201 202 public function pre_bootpay_payment_response() 203 { 204 if (!empty($_POST['order_key'])) { 205 $order_id = wc_get_order_id_by_order_key($_POST['order_key']); 206 $this->renderJson($this->bootpay_payment_response($order_id)); 207 } else { 208 $this->renderJson([ 209 'result' => 'failure', 210 'messages' => __('해당되는 Order Key 정보를 찾지 못했습니다.', self::BOOTPAY_WC_DOMAIN) 211 ]); 212 } 213 } 214 215 /** 216 * Bootpay로 주문한 데이터 결과를 가져온다. 217 */ 218 public function bootpay_payment_response($order_id) 219 { 220 $order = new WC_Order($order_id); 221 $checkout_url = $order->has_status([ 222 'processing', 223 'completed' 224 ]) ? $order->get_checkout_order_received_url() : $order->get_checkout_payment_url(false); 225 $order_items = $order->get_items(); 226 if (is_array($order_items)) { 227 $items = []; 228 foreach ($order_items as $item_id => $item) { 229 $cats = []; 230 $terms = get_the_terms($item['product_id'], 'product_cat'); 231 foreach ($terms as $term) { 232 $cats[] = $term->slug; 233 } 234 $line_price = wc_get_order_item_meta($item_id, '_line_total', true); 235 array_push($items, [ 236 'item_name' => $item['name'], 237 'qty' => $item['qty'], 238 'unique' => (string)$item_id, 239 'price' => (int)($line_price / $item['qty']), 240 'cat1' => empty($cats[0]) ? '' : $cats[0], 241 'cat2' => empty($cats[1]) ? '' : $cats[1], 242 'cat3' => empty($cats[2]) ? '' : $cats[2], 243 ]); 244 } 245 } 246 247 $order_data = [ 248 'name' => sizeof($items) > 1 ? sprintf("%s 외 %s 개", $items[0]['item_name'], sizeof($items) - 1) : $items[0]['item_name'], 249 'price' => $order->get_total(), 250 'items' => $items, 251 'order_id' => $order_id, 252 'user_info' => [ 253 'username' => $order->billing_last_name . $order->billing_first_name, 254 'phone' => (empty($order->get_billing_phone()) ? '010-0000-0000' : $order->get_billing_phone()), 255 'email' => $order->billing_email, 256 'addr' => strip_tags(implode(' ', [ 257 $order->get_billing_city(), 258 $order->get_billing_address_1(), 259 $order->get_billing_address_2() 260 ])) 261 ] 262 ]; 263 264 return [ 265 'result' => 'success', 266 'order_key' => $order->order_key, 267 'order_id' => $order_id, 268 'order_data' => $order_data, 269 'checkout_url' => add_query_arg([ 270 'wc-api' => self::PAYMENT_SUBMIT, 271 'order_id' => $order_id 272 ], $checkout_url), 273 ]; 274 } 275 276 /** 277 * Bootpay Script 추가 278 */ 279 public function enqueue_inject_bootpay_script() 280 { 281 wp_register_script('bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js"); 282 wp_register_script('bootpay-script', plugins_url('/assets/js/bootpay.js', plugin_basename(__FILE__))); 283 wp_register_script('bootpay-order-script', plugins_url('/assets/js/bootpay-order.js', plugin_basename(__FILE__))); 284 // 일단 주석 checkout을 주석처리할 경우 woocommerce의 wc_checkout_params의 값을 사용 못함 274 285 // wp_dequeue_script( 'wc-checkout' ); 275 wp_enqueue_script( 'bootpay-script' ); 276 wp_enqueue_script( 'bootpay-order-script' ); 277 wp_enqueue_script( 'bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js", ['boot-app-id' => $this->get_option( 'js_app_key' )] ); 278 } 279 280 /** 281 * 282 */ 283 public function enqueue_inject_admin_bootpay_script() { 284 wp_register_script( 'bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js" ); 285 wp_register_script( 'bootpay-script', plugins_url( '/assets/js/bootpay.js', plugin_basename( __FILE__ ) ) ); 286 wp_register_script( 'bootpay-admin-script', plugins_url( '/assets/js/bootpay-admin.js', plugin_basename( __FILE__ ) ) ); 287 wp_enqueue_script( 'bootpay-script' ); 288 wp_enqueue_script( 'bootpay-admin-script' ); 289 wp_enqueue_script( 'bootpay-cdn-script' ); 290 } 291 292 /** 293 * 결제 요청시에 wc_checkout_params 값에 추가적인 field 294 * 295 * @param $params 296 * 297 * @return array 298 */ 299 public function inject_checkout_params( $params ) { 300 $params['js_api_key'] = $this->get_option( 'js_api_key' ); 301 $params['show_agree_window'] = $this->get_option( 'agree_window' ); 302 303 return $params; 304 } 305 306 public function process_payment( $order_id ) { 307 $order = new WC_Order( $order_id ); 308 $checkout_url = $order->has_status( [ 309 'processing', 310 'completed' 311 ] ) ? $order->get_checkout_order_received_url() : $order->get_checkout_payment_url( false ); 312 $order_items = $order->get_items(); 313 if( is_array( $order_items ) ) { 314 $items = []; 315 foreach( $order_items as $item_id => $item ) { 316 $cats = []; 317 $terms = get_the_terms( $item['product_id'], 'product_cat' ); 318 foreach( $terms as $term ) { 319 $cats[] = $term->slug; 320 } 321 $line_price = wc_get_order_item_meta( $item_id, '_line_total', true ); 322 array_push( $items, [ 323 'item_name' => $item['name'], 324 'qty' => $item['qty'], 325 'unique' => (string) $item_id, 326 'price' => (int) ( $line_price / $item['qty'] ), 327 'cat1' => empty( $cats[0] ) ? '' : $cats[0], 328 'cat2' => empty( $cats[1] ) ? '' : $cats[1], 329 'cat3' => empty( $cats[2] ) ? '' : $cats[2], 330 ] ); 331 } 332 } 333 $order_data = [ 334 'name' => sizeof( $items ) > 1 ? sprintf( "%s 외 %s 개", $items[0]['item_name'], sizeof( $items ) - 1 ) : $items[0]['item_name'], 335 'price' => $order->get_total(), 336 'items' => $items, 337 'order_id' => $order_id, 338 'user_info' => [ 339 'username' => $order->billing_last_name . $order->billing_first_name, 340 'phone' => ( empty( $order->get_billing_phone() ) ? '010-0000-0000' : $order->get_billing_phone() ), 341 'email' => $order->billing_email, 342 'addr' => strip_tags( implode( ' ', [ 343 $order->get_billing_city(), 344 $order->get_billing_address_1(), 345 $order->get_billing_address_2() 346 ] ) ) 347 ] 348 ]; 349 350 return [ 351 'result' => 'success', 352 'order_key' => $order->order_key, 353 'order_id' => $order_id, 354 'order_data' => $order_data, 355 'checkout_url' => add_query_arg( [ 356 'wc-api' => self::PAYMENT_SUBMIT, 357 'order_id' => $order_id 358 ], $checkout_url ), 359 ]; 360 } 361 362 public function bootpay_login_redirect( $redirect_to, $request, $user ) { 286 wp_enqueue_script('bootpay-script'); 287 wp_enqueue_script('bootpay-order-script'); 288 wp_enqueue_script('bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js", ['boot-app-id' => $this->get_option('js_app_key')]); 289 } 290 291 /** 292 * 293 */ 294 public function enqueue_inject_admin_bootpay_script() 295 { 296 wp_register_script('bootpay-cdn-script', "https://cdn.bootpay.co.kr/js/bootpay-{$this->currentVersion()}.min.js"); 297 wp_register_script('bootpay-script', plugins_url('/assets/js/bootpay.js', plugin_basename(__FILE__))); 298 wp_register_script('bootpay-admin-script', plugins_url('/assets/js/bootpay-admin.js', plugin_basename(__FILE__))); 299 wp_enqueue_script('bootpay-script'); 300 wp_enqueue_script('bootpay-admin-script'); 301 wp_enqueue_script('bootpay-cdn-script'); 302 } 303 304 /** 305 * 결제 요청시에 wc_checkout_params 값에 추가적인 field 306 * 307 * @param $params 308 * 309 * @return array 310 */ 311 public function inject_checkout_params($params) 312 { 313 $params['js_api_key'] = $this->get_option('js_api_key'); 314 $params['show_agree_window'] = $this->get_option('agree_window'); 315 316 return $params; 317 } 318 319 public function process_payment($order_id) 320 { 321 $order = new WC_Order($order_id); 322 $checkout_url = $order->has_status([ 323 'processing', 324 'completed' 325 ]) ? $order->get_checkout_order_received_url() : $order->get_checkout_payment_url(false); 326 $order_items = $order->get_items(); 327 if (is_array($order_items)) { 328 $items = []; 329 foreach ($order_items as $item_id => $item) { 330 $cats = []; 331 $terms = get_the_terms($item['product_id'], 'product_cat'); 332 foreach ($terms as $term) { 333 $cats[] = $term->slug; 334 } 335 $line_price = wc_get_order_item_meta($item_id, '_line_total', true); 336 array_push($items, [ 337 'item_name' => $item['name'], 338 'qty' => $item['qty'], 339 'unique' => (string)$item_id, 340 'price' => (int)($line_price / $item['qty']), 341 'cat1' => empty($cats[0]) ? '' : $cats[0], 342 'cat2' => empty($cats[1]) ? '' : $cats[1], 343 'cat3' => empty($cats[2]) ? '' : $cats[2], 344 ]); 345 } 346 } 347 $order_data = [ 348 'name' => sizeof($items) > 1 ? sprintf("%s 외 %s 개", $items[0]['item_name'], sizeof($items) - 1) : $items[0]['item_name'], 349 'price' => $order->get_total(), 350 'items' => $items, 351 'order_id' => $order_id, 352 'user_info' => [ 353 'username' => $order->billing_last_name . $order->billing_first_name, 354 'phone' => (empty($order->get_billing_phone()) ? '010-0000-0000' : $order->get_billing_phone()), 355 'email' => $order->billing_email, 356 'addr' => strip_tags(implode(' ', [ 357 $order->get_billing_city(), 358 $order->get_billing_address_1(), 359 $order->get_billing_address_2() 360 ])) 361 ] 362 ]; 363 364 return [ 365 'result' => 'success', 366 'order_key' => $order->order_key, 367 'order_id' => $order_id, 368 'order_data' => $order_data, 369 'checkout_url' => add_query_arg([ 370 'wc-api' => self::PAYMENT_SUBMIT, 371 'order_id' => $order_id 372 ], $checkout_url), 373 ]; 374 } 375 376 public function bootpay_login_redirect($redirect_to, $request, $user) 377 { 363 378 // exit; 364 return $redirect_to; 365 } 366 367 /** 368 * 결제 취소 관련 로직 369 * 부트페이 서버로 부터 결제가 취소가 실패한 경우엔 370 * alert으로 메세지를 보이도록 wp_error를 리턴한다. 371 * 372 * @param int $order_id 373 * @param null $amount 374 * @param string $reason 375 * 376 * @return bool|WP_Error 377 */ 378 379 public function process_refund( $order_id, $amount = null, $reason = '' ) { 380 $order = new WC_Order( $order_id ); 381 $receipt_id = $order->get_meta( 'bootpay_receipt_id' ); 382 BootpayApi::setConfig( $this->get_option( 'rest_api_key' ), $this->get_option( 'private_key' ) ); 383 $response = BootpayApi::cancel( [ 384 'receipt_id' => $receipt_id, 385 'name' => __( '판매자', self::BOOTPAY_WC_DOMAIN ), 386 'reason' => '판매자 취소', 387 'price' => $amount 388 ] ); 389 390 if( $response->status == 200 ) { 391 $result = $response->data; 392 // 모두 결제 취소가 된 경우 393 if( (int) $result->remain_price == 0 ) { 394 $order->add_order_note( sprintf( __( "%s원 모두 취소 됨", self::BOOTPAY_WC_DOMAIN ), number_format( (int) $amount ) ) ); 395 $order->update_status( 'refunded' ); 396 } else { 397 $order->add_order_note( sprintf( __( " %s원 부분 취소 됨", self::BOOTPAY_WC_DOMAIN ), number_format( (int) $amount ) ) ); 398 } 399 400 return true; 401 } else { 402 $message = sprintf( __( "결제 취소 실패 %s", self::BOOTPAY_WC_DOMAIN ), $response->message ); 403 $order->add_order_note( $message ); 404 405 return new WP_Error( 'error', $message ); 406 } 407 } 408 409 public function ajax_bootpay_payment_info() { 410 411 } 412 413 /** 414 * 결제 완료후 Validation을 한다. 415 * Bootpay Rest를 이용하여 결제 정보를 검증한다. 416 * @return WP_Error 417 */ 418 public function payment_validation() { 419 $receipt_id = $_GET['receipt_id']; 420 $order_id = $_GET['order_id']; 421 422 if( ! empty( $receipt_id ) && ! empty( $order_id ) ) { 423 $order = new WC_Order( $order_id ); 424 if( in_array( $order->get_status(), ['processing', 'completed'] ) ) { 425 $order->add_order_note( __( '이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN ) ); 426 427 return new WP_Error( 'error', __( '이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN ) ); 428 } 429 430 BootpayApi::setConfig( $this->get_option( 'rest_api_key' ), $this->get_option( 'private_key' ) ); 431 try { 432 $response = BootpayApi::confirm( [ 433 'receipt_id' => $receipt_id 434 ] ); 435 } catch( Exception $e ) { 436 $order->update_status( 'failed' ); 437 $order->add_order_note( __( '결제가 원활히 진행되지 못했습니다.', self::BOOTPAY_WC_DOMAIN ) ); 438 439 return new WP_Error( 'error', __( '결제가 원활히 진행되지 못했습니다.', self::BOOTPAY_WC_DOMAIN ) ); 440 } 441 $result = $response->data; 442 if( $response->status == 200 && $result ) { 443 if( $result->status == 1 || ( $result->method == 'vbank' && $result->status == 2 ) ) { 444 if( (int) $result->price != (int) $order->get_total() ) { 445 $order->add_order_note( __( '결제된 금액이 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN ) ); 446 447 return new WP_Error( 'error', __( '결제된 금액이 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN ) ); 448 } 449 if( $order_id != $result->order_id ) { 450 $order->add_order_note( __( '결제 정보가 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN ) ); 451 452 return new WP_Error( 'error', __( '결제 정보가 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN ) ); 453 } 454 $transaction_id = $order->get_transaction_id(); 455 if( $result->method == 'vbank' ) { 456 $order->update_status( 'wc-wating-bank', __( '입금대기', self::BOOTPAY_WC_DOMAIN ) ); 457 $order->set_payment_method( $this->id ); 458 $order->set_payment_method_title( $this->get_payment_method_title( $result ) ); 459 $order->add_order_note( $this->get_payment_method_title( $result ) . __( ' 입금대기', self::BOOTPAY_WC_DOMAIN ) ); 460 add_post_meta( $order_id, 'bootpay_receipt_id', $result->receipt_id ); 461 add_post_meta( $order_id, 'bootpay_pg_name', $result->pg_name ); 462 add_post_meta( $order_id, 'bootpay_method_name', $result->method_name ); 463 add_post_meta( $order_id, 'bootpay_pg', $result->pg ); 464 add_post_meta( $order_id, 'bootpay_method', $result->method ); 465 add_post_meta( $order_id, 'bootpay_bankname', $result->payment_data->bankname ); 466 add_post_meta( $order_id, 'bootpay_holder', $result->payment_data->accountholder ); 467 add_post_meta( $order_id, 'bootpay_account', $result->payment_data->account ); 468 add_post_meta( $order_id, 'bootpay_username', $result->payment_data->username ); 469 add_post_meta( $order_id, 'bootpay_expire', $result->payment_data->expiredate ); 470 } else { 471 // TODO: 나중에 Float형으로 변경해야 한다. 472 473 $order->payment_complete( $transaction_id ); 474 $order->set_payment_method( $this->id ); 475 $order->set_payment_method_title( $this->get_payment_method_title( $result ) ); 476 $order->add_order_note( $this->get_payment_method_title( $result ) . __( ' 로 지불됨', self::BOOTPAY_WC_DOMAIN ) ); 477 add_post_meta( $order_id, 'bootpay_receipt_id', $result->receipt_id ); 478 add_post_meta( $order_id, 'bootpay_pg_name', $result->pg_name ); 479 add_post_meta( $order_id, 'bootpay_method_name', $result->method_name ); 480 add_post_meta( $order_id, 'bootpay_pg', $result->pg ); 481 add_post_meta( $order_id, 'bootpay_method', $result->method ); 482 } 483 // 구매가 완료되었으므로 카트를 지운다. 484 wc_empty_cart(); 485 wp_redirect( $order->get_checkout_order_received_url() ); 486 } 487 } else { 488 $order->add_order_note( $result->message ); 489 490 return new WP_Error( 'error', $result->message ); 491 } 492 } else { 493 return new WP_Error( 'error', __( '잘못된 결제 접근 입니다.', self::BOOTPAY_WC_DOMAIN ) ); 494 } 495 } 496 497 /** 498 * 가상계좌 입금시 Notification 처리하는 곳 499 */ 500 public function vbank_notification() { 501 $receipt_id = $_POST['receipt_id']; 502 $order_id = $_POST['order_id']; 503 $price = (int) $_POST['price']; 504 $private_key = $_POST['private_key']; 505 // 가상 계좌만 처리하고 나머지는 처리하지 않는다. 506 // 서버에 질의하여 검증하는 로직이 있으므로 다른 결제는 유효성 검사를 하지 않는다. ( 중복 방지 ) 507 if( $_POST['method'] == 'vbank' ) { 508 $order = new WC_Order( $order_id ); 509 if( in_array( $order->get_status(), ['processing', 'completed'] ) ) { 510 $order->add_order_note( __( '이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN ) ); 511 echo 'error 1'; 512 exit; 513 } 514 if( $this->get_option( 'private_key' ) != $private_key ) { 515 $order->add_order_note( __( '결제 비밀키가 일치하지 않아 가상계좌 결제가 승인되지 않았습니다.', self::BOOTPAY_WC_DOMAIN ) ); 516 echo 'error 2'; 517 exit; 518 } 519 if( (int) $price != (int) $order->get_total() ) { 520 $order->add_order_note( __( '결제된 금액이 일치하지 않아 가상계좌 결제가 승인이 되지 않았습니다.', self::BOOTPAY_WC_DOMAIN ) ); 521 echo 'error 3'; 522 exit; 523 } 524 $transaction_id = $order->get_transaction_id(); 525 $order->payment_complete( $transaction_id ); 526 $order->update_status( 'processing' ); 527 $order->set_payment_method( $this->id ); 528 $order->set_payment_method_title( sprintf( "%s - %s", $_POST['pg_name'], $_POST['method_name'] ) ); 529 $order->add_order_note( sprintf( "%s - %s", $_POST['pg_name'], $_POST['method_name'] ) . __( ' 로 지불됨', self::BOOTPAY_WC_DOMAIN ) ); 530 add_post_meta( $order_id, 'bootpay_receipt_id', $receipt_id ); 531 add_post_meta( $order_id, 'bootpay_pg_name', $_POST['pg_name'] ); 532 add_post_meta( $order_id, 'bootpay_method_name', $_POST['method_name'] ); 533 add_post_meta( $order_id, 'bootpay_pg', $_POST['pg'] ); 534 add_post_meta( $order_id, 'bootpay_method', $_POST['method'] ); 535 } 536 echo 'OK'; 537 exit; 538 } 539 540 private function get_payment_method_title( $result ) { 541 return sprintf( "부트페이 [%s - %s]", $result->pg_name, $result->method_name ); 542 } 543 544 private function currentVersion() { 545 return self::CURRENT_VERSION; 546 } 547 548 /** 549 * @param $file - Template 파일명 550 * @param null $data - Template에서 사용할 Local Variable 551 * View Template 기본 엔진 기능 552 */ 553 private function renderFile( $file, $data = null ) { 554 $template_path = __DIR__ . '/templates/' . $file; 555 if( file_exists( $template_path ) ) { 556 if( ! is_null( $data ) && is_array( $data ) ) { 557 foreach( $data as $key => $value ) { 558 $$key = $value; 559 } 560 } 561 ob_start(); 562 include( $template_path ); 563 ob_end_flush(); 564 } else { 565 $this->renderError( __( "$template_path 파일이 없습니다.", self::BOOTPAY_WC_DOMAIN ) ); 566 } 567 568 return; 569 } 570 571 /** 572 * 에러가 났을 경우 에러를 뿌리고 바로 나간다. 573 * javascript console.error도 함께 출력한다. 574 * 575 * @param $msg 576 */ 577 private function renderError( $msg, $console = true ) { 578 $this->renderFile( 'error.php', [ 579 'errorMsg' => $msg, 580 'console' => $console 581 ] ); 582 exit; 583 } 584 585 private function renderJson( $response ) { 586 header( 'Content-type: application/json' ); 587 echo json_encode( $response ); 588 wp_die(); 589 } 590 } 591 592 new WC_Gateway_Bootpay(); 379 return $redirect_to; 380 } 381 382 /** 383 * 결제 취소 관련 로직 384 * 부트페이 서버로 부터 결제가 취소가 실패한 경우엔 385 * alert으로 메세지를 보이도록 wp_error를 리턴한다. 386 * 387 * @param int $order_id 388 * @param null $amount 389 * @param string $reason 390 * 391 * @return bool|WP_Error 392 */ 393 394 public function process_refund($order_id, $amount = null, $reason = '') 395 { 396 $order = new WC_Order($order_id); 397 $receipt_id = $order->get_meta('bootpay_receipt_id'); 398 BootpayApi::setConfig($this->get_option('rest_api_key'), $this->get_option('private_key')); 399 $response = BootpayApi::cancel([ 400 'receipt_id' => $receipt_id, 401 'name' => __('판매자', self::BOOTPAY_WC_DOMAIN), 402 'reason' => '판매자 취소', 403 'price' => $amount 404 ]); 405 406 if ($response->status == 200) { 407 $result = $response->data; 408 // 모두 결제 취소가 된 경우 409 if ((int)$result->remain_price == 0) { 410 $order->add_order_note(sprintf(__("%s원 모두 취소 됨", self::BOOTPAY_WC_DOMAIN), number_format((int)$amount))); 411 $order->update_status('refunded'); 412 } else { 413 $order->add_order_note(sprintf(__(" %s원 부분 취소 됨", self::BOOTPAY_WC_DOMAIN), number_format((int)$amount))); 414 } 415 416 return true; 417 } else { 418 $message = sprintf(__("결제 취소 실패 %s", self::BOOTPAY_WC_DOMAIN), $response->message); 419 $order->add_order_note($message); 420 421 return new WP_Error('error', $message); 422 } 423 } 424 425 public function ajax_bootpay_payment_info() 426 { 427 428 } 429 430 /** 431 * 결제 완료후 Validation을 한다. 432 * Bootpay Rest를 이용하여 결제 정보를 검증한다. 433 * @return WP_Error 434 */ 435 public function payment_validation() 436 { 437 $receipt_id = $_GET['receipt_id']; 438 $order_id = $_GET['order_id']; 439 440 if (!empty($receipt_id) && !empty($order_id)) { 441 $order = new WC_Order($order_id); 442 if (in_array($order->get_status(), ['processing', 'completed'])) { 443 $order->add_order_note(__('이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN)); 444 445 return new WP_Error('error', __('이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN)); 446 } 447 448 BootpayApi::setConfig($this->get_option('rest_api_key'), $this->get_option('private_key')); 449 try { 450 $response = BootpayApi::confirm([ 451 'receipt_id' => $receipt_id 452 ]); 453 } catch (Exception $e) { 454 $order->update_status('failed'); 455 $order->add_order_note(__('결제가 원활히 진행되지 못했습니다.', self::BOOTPAY_WC_DOMAIN)); 456 457 return new WP_Error('error', __('결제가 원활히 진행되지 못했습니다.', self::BOOTPAY_WC_DOMAIN)); 458 } 459 $result = $response->data; 460 if ($response->status == 200 && $result) { 461 if ($result->status == 1 || ($result->method == 'vbank' && $result->status == 2)) { 462 if ((int)$result->price != (int)$order->get_total()) { 463 $order->add_order_note(__('결제된 금액이 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN)); 464 465 return new WP_Error('error', __('결제된 금액이 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN)); 466 } 467 if ($order_id != $result->order_id) { 468 $order->add_order_note(__('결제 정보가 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN)); 469 470 return new WP_Error('error', __('결제 정보가 일치하지 않습니다.', self::BOOTPAY_WC_DOMAIN)); 471 } 472 $transaction_id = $order->get_transaction_id(); 473 if ($result->method == 'vbank') { 474 $order->update_status('wc-wating-bank', __('입금대기', self::BOOTPAY_WC_DOMAIN)); 475 $order->set_payment_method($this->id); 476 $order->set_payment_method_title($this->get_payment_method_title($result)); 477 $order->add_order_note($this->get_payment_method_title($result) . __(' 입금대기', self::BOOTPAY_WC_DOMAIN)); 478 add_post_meta($order_id, 'bootpay_receipt_id', $result->receipt_id); 479 add_post_meta($order_id, 'bootpay_pg_name', $result->pg_name); 480 add_post_meta($order_id, 'bootpay_method_name', $result->method_name); 481 add_post_meta($order_id, 'bootpay_pg', $result->pg); 482 add_post_meta($order_id, 'bootpay_method', $result->method); 483 add_post_meta($order_id, 'bootpay_bankname', $result->payment_data->bankname); 484 add_post_meta($order_id, 'bootpay_holder', $result->payment_data->accountholder); 485 add_post_meta($order_id, 'bootpay_account', $result->payment_data->account); 486 add_post_meta($order_id, 'bootpay_username', $result->payment_data->username); 487 add_post_meta($order_id, 'bootpay_expire', $result->payment_data->expiredate); 488 } else { 489 // TODO: 나중에 Float형으로 변경해야 한다. 490 491 $order->payment_complete($transaction_id); 492 $order->set_payment_method($this->id); 493 $order->set_payment_method_title($this->get_payment_method_title($result)); 494 $order->add_order_note($this->get_payment_method_title($result) . __(' 로 지불됨', self::BOOTPAY_WC_DOMAIN)); 495 add_post_meta($order_id, 'bootpay_receipt_id', $result->receipt_id); 496 add_post_meta($order_id, 'bootpay_pg_name', $result->pg_name); 497 add_post_meta($order_id, 'bootpay_method_name', $result->method_name); 498 add_post_meta($order_id, 'bootpay_pg', $result->pg); 499 add_post_meta($order_id, 'bootpay_method', $result->method); 500 } 501 // 구매가 완료되었으므로 카트를 지운다. 502 wc_empty_cart(); 503 wp_redirect($order->get_checkout_order_received_url()); 504 } 505 } else { 506 $order->add_order_note($result->message); 507 508 return new WP_Error('error', $result->message); 509 } 510 } else { 511 return new WP_Error('error', __('잘못된 결제 접근 입니다.', self::BOOTPAY_WC_DOMAIN)); 512 } 513 } 514 515 /** 516 * 가상계좌 입금시 Notification 처리하는 곳 517 */ 518 public function vbank_notification() 519 { 520 $receipt_id = $_POST['receipt_id']; 521 $order_id = $_POST['order_id']; 522 $price = (int)$_POST['price']; 523 $private_key = $_POST['private_key']; 524 // 가상 계좌만 처리하고 나머지는 처리하지 않는다. 525 // 서버에 질의하여 검증하는 로직이 있으므로 다른 결제는 유효성 검사를 하지 않는다. ( 중복 방지 ) 526 if ($_POST['method'] == 'vbank') { 527 $order = new WC_Order($order_id); 528 if (in_array($order->get_status(), ['processing', 'completed'])) { 529 $order->add_order_note(__('이미 결제 처리가 완료되었습니다.', self::BOOTPAY_WC_DOMAIN)); 530 echo 'error 1'; 531 exit; 532 } 533 if ($this->get_option('private_key') != $private_key) { 534 $order->add_order_note(__('결제 비밀키가 일치하지 않아 가상계좌 결제가 승인되지 않았습니다.', self::BOOTPAY_WC_DOMAIN)); 535 echo 'error 2'; 536 exit; 537 } 538 if ((int)$price != (int)$order->get_total()) { 539 $order->add_order_note(__('결제된 금액이 일치하지 않아 가상계좌 결제가 승인이 되지 않았습니다.', self::BOOTPAY_WC_DOMAIN)); 540 echo 'error 3'; 541 exit; 542 } 543 $transaction_id = $order->get_transaction_id(); 544 $order->payment_complete($transaction_id); 545 $order->update_status('processing'); 546 $order->set_payment_method($this->id); 547 $order->set_payment_method_title(sprintf("%s - %s", $_POST['pg_name'], $_POST['method_name'])); 548 $order->add_order_note(sprintf("%s - %s", $_POST['pg_name'], $_POST['method_name']) . __(' 로 지불됨', self::BOOTPAY_WC_DOMAIN)); 549 add_post_meta($order_id, 'bootpay_receipt_id', $receipt_id); 550 add_post_meta($order_id, 'bootpay_pg_name', $_POST['pg_name']); 551 add_post_meta($order_id, 'bootpay_method_name', $_POST['method_name']); 552 add_post_meta($order_id, 'bootpay_pg', $_POST['pg']); 553 add_post_meta($order_id, 'bootpay_method', $_POST['method']); 554 } 555 echo 'OK'; 556 exit; 557 } 558 559 private function get_payment_method_title($result) 560 { 561 return sprintf("부트페이 [%s - %s]", $result->pg_name, $result->method_name); 562 } 563 564 private function currentVersion() 565 { 566 return self::CURRENT_VERSION; 567 } 568 569 /** 570 * @param $file - Template 파일명 571 * @param null $data - Template에서 사용할 Local Variable 572 * View Template 기본 엔진 기능 573 */ 574 private function renderFile($file, $data = null) 575 { 576 $template_path = __DIR__ . '/templates/' . $file; 577 if (file_exists($template_path)) { 578 if (!is_null($data) && is_array($data)) { 579 foreach ($data as $key => $value) { 580 $$key = $value; 581 } 582 } 583 ob_start(); 584 include($template_path); 585 ob_end_flush(); 586 } else { 587 $this->renderError(__("$template_path 파일이 없습니다.", self::BOOTPAY_WC_DOMAIN)); 588 } 589 590 return; 591 } 592 593 /** 594 * 에러가 났을 경우 에러를 뿌리고 바로 나간다. 595 * javascript console.error도 함께 출력한다. 596 * 597 * @param $msg 598 */ 599 private function renderError($msg, $console = true) 600 { 601 $this->renderFile('error.php', [ 602 'errorMsg' => $msg, 603 'console' => $console 604 ]); 605 exit; 606 } 607 608 private function renderJson($response) 609 { 610 header('Content-type: application/json'); 611 echo json_encode($response); 612 wp_die(); 613 } 614 } 615 616 new WC_Gateway_Bootpay(); 593 617 } -
woo-bootpay/trunk/readme.txt
r1858733 r1888627 5 5 Requires at least: 3.6 6 6 Tested up to: 4.9.5 7 Stable tag: 1.1.1 07 Stable tag: 1.1.11 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 12 12 13 13 == Description == 14 15 버전 1.1.11 16 bootpay 2.0.6 버전 업데이트 17 다른 결제 수단 함께 사용 가능하도록 업데이트 18 14 19 버전 1.1.10 15 20 Gateway Action 중복 등록 관리 Singleton Semaphore 추가
Note: See TracChangeset
for help on using the changeset viewer.