member = $member; } // ============================================================================== // 1. 결제 정보 생성 및 조회 // ============================================================================== /** * 새로운 결제 정보를 생성합니다. * @param array $data 결제 데이터 (total_amount, payment_method 등) * 'order_type', 'order_id' 등 연동 서비스의 정보를 추가할 수 있습니다. * @return int|bool payment_id 또는 실패 시 false */ public function createPayment(array $data) { $data['payment_status'] = 'pending'; // 초기 상태는 'pending' return $this->create($this->payment_table, $data); } /** * payment_id로 결제 정보를 조회합니다. * @param int $payment_id * @return array|null */ public function getPaymentById(int $payment_id) { return sql_fetch("SELECT * FROM {$this->payment_table} WHERE id = '{$payment_id}' AND is_deleted = 0"); } /** * 특정 주문 ID (예: estimate_id)에 연결된 가장 최근의 pending 상태 결제 정보를 조회합니다. * @param string $order_type 주문 타입 (예: 'estimate') * @param int $order_id 주문 ID (예: estimate_id) * @return array|null */ public function getLatestPendingPaymentByOrderId(string $order_type, int $order_id) { // 이 메서드는 payment 테이블에 order_type, order_id 컬럼이 추가되어야 동작합니다. // 현재는 estimate_id 컬럼이 있으므로, estimate_id를 order_id로 간주합니다. return sql_fetch("SELECT * FROM {$this->payment_table} WHERE estimate_id = '{$order_id}' AND payment_status = 'pending' AND is_deleted = 0 ORDER BY created_at DESC LIMIT 1"); } // ============================================================================== // 2. 결제 상태 업데이트 및 로그 기록 // ============================================================================== /** * 결제 상태를 업데이트하고 로그를 남깁니다. * @param int $payment_id * @param string $new_status * @param string $memo * @return bool */ public function updatePaymentStatus(int $payment_id, string $new_status, string $memo = '') { $old = sql_fetch("SELECT payment_status FROM {$this->payment_table} WHERE id = '{$payment_id}'"); if (!$old) return false; $result = $this->update($this->payment_table, $payment_id, ["payment_status = '{$new_status}'"]); if ($result) { $this->logPaymentStatus($payment_id, $old['payment_status'], $new_status, $memo); } return $result; } /** * PG사 전문(payload)을 기록합니다. * @param int $payment_id * @param string $type 'request', 'response', 'webhook' 등 * @param string $payload 원본 데이터 * @return int|bool payload_id 또는 실패 시 false */ public function logPaymentPayload(int $payment_id, string $type, string $payload) { $data = [ 'payment_id' => $payment_id, 'payload_type' => $type, 'payload' => $payload ]; return $this->create($this->payment_payload_table, $data); } // ============================================================================== // Private Helper Functions (공통 CRUD 및 로깅) // ============================================================================== private function create(string $table, array $data) : int|bool { $mb_id = $this->member['mb_id'] ?? 'system'; $data['created_by'] = $mb_id; $data['created_at'] = G5_TIME_YMDHIS; $data['is_used'] = $data['is_used'] ?? 1; $data['is_deleted'] = $data['is_deleted'] ?? 0; $fields = []; $values = []; foreach ($data as $key => $value) { $fields[] = "`{$key}`"; $values[] = "'" . sql_real_escape_string($value) . "'"; } $sql = "INSERT INTO {$table} (" . implode(', ', $fields) . ") VALUES (" . implode(', ', $values) . ")"; sql_query($sql); return sql_insert_id(); } private function update(string $table, int $id, array $set_clauses) : bool { $mb_id = $this->member['mb_id'] ?? 'system'; $set_clauses[] = "updated_at = '" . G5_TIME_YMDHIS . "'"; $set_clauses[] = "updated_by = '{$mb_id}'"; $sql = "UPDATE {$table} SET " . implode(', ', $set_clauses) . " WHERE id = '{$id}'"; return (bool)sql_query($sql); } private function logPaymentStatus(int $payment_id, string $old_status, string $new_status, string $memo) : int|bool { $data = [ 'payment_id' => $payment_id, 'estimate_id' => sql_fetch("SELECT estimate_id FROM {$this->payment_table} WHERE id = '{$payment_id}'")['estimate_id'], // 연동을 위해 estimate_id도 저장 'previous_status' => $old_status, 'new_status' => $new_status, 'memo' => $memo, ]; return $this->create($this->payment_log_table, $data); } }