From b9355f051c37bb48ffecd53272ab1866ede1400a Mon Sep 17 00:00:00 2001 From: thisgun Date: Tue, 7 Jul 2026 16:38:15 +0900 Subject: [PATCH] =?UTF-8?q?fix(kginicis):=20=EC=A3=BC=EB=AC=B8=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EA=B2=B0=EC=A0=9C=20?= =?UTF-8?q?=EA=B2=BD=EA=B3=A0=20=ED=91=9C=EC=8B=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CHANGELOG.md | 6 + .../frontend/ja.json | 5 + .../sirsoft-pay_kginicis/CHANGELOG.md | 6 + .../resources/lang/en.json | 5 + .../resources/lang/ko.json | 5 + .../AdminSettingsStatusController.php | 28 +++ ...tEcommercePaymentMethodsLayoutListener.php | 234 +++++++++++++++++- .../sirsoft-pay_kginicis/src/routes/api.php | 5 + .../AdminSettingsStatusControllerTest.php | 33 +++ ...mmercePaymentMethodsLayoutListenerTest.php | 39 +++ 10 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 plugins/_bundled/sirsoft-pay_kginicis/src/Controllers/AdminSettingsStatusController.php create mode 100644 plugins/_bundled/sirsoft-pay_kginicis/tests/Feature/Controllers/AdminSettingsStatusControllerTest.php diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/CHANGELOG.md b/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/CHANGELOG.md index b3ce82a0..25ed116e 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/CHANGELOG.md +++ b/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/CHANGELOG.md @@ -4,6 +4,12 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [Unreleased] + +### Added + +- 주문 설정 화면의 KG 이니시스 테스트모드 경고(`kginicis_test_mode_status`, `test_mode_settings_warning_*`) 일본어 번역 추가 — 테스트결제 상태 안내와 실결제 설정 이동 버튼이 일본어 로케일에서 자연스럽게 표시됩니다. + ## [1.0.0] - 2026-07-01 ### Added diff --git a/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/frontend/ja.json b/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/frontend/ja.json index 50ceec99..d04eaa3d 100644 --- a/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/frontend/ja.json +++ b/lang-packs/_bundled/g7-plugin-sirsoft-pay_kginicis-ja/frontend/ja.json @@ -4,6 +4,7 @@ "kginicis_cbt_reconciliation": "海外決済精算", "kginicis_escrow_delivery": "エスクロー配送", "kginicis_status": "決済ステータス", + "kginicis_test_mode_status": "テストモード状態", "kginicis_test_map": "テスト決済マップ", "settings": "決済設定", "vbank_info": "仮想口座情報" @@ -74,6 +75,10 @@ "test_mode_badge": "テスト決済", "test_mode_warning_badge": "テスト決済注意事項", "test_mode_order_notice": "この注文はテスト決済として処理されました。実際のカード承認・出金通知が発生する可能性がありますが、KGイニシスのテスト取引は毎日23:00~23:50の間に自動キャンセルされる可能性があります。絶対に配送しないでください。", + "test_mode_settings_warning_plugin": "KGイニシス", + "test_mode_settings_warning_title": "(注意)KGイニシス決済設定が現在テスト決済になっています。", + "test_mode_settings_warning_body": "テスト決済では実際の決済は発生しません。ショップ運営中の場合は必ず実決済に設定して運営してください。", + "test_mode_settings_warning_action": "実決済に設定", "order_verify_title": "KGイニシス決済検証", "order_verify_description": "KGイニシスサーバーからリアルタイムで決済ステータスを照会します。", "order_verify_button": "決済照会", diff --git a/plugins/_bundled/sirsoft-pay_kginicis/CHANGELOG.md b/plugins/_bundled/sirsoft-pay_kginicis/CHANGELOG.md index 8acfc2f9..9d135ab4 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/CHANGELOG.md +++ b/plugins/_bundled/sirsoft-pay_kginicis/CHANGELOG.md @@ -4,6 +4,12 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. +## [Unreleased] + +### Fixed + +- 이커머스 주문설정 화면에서 KG 이니시스 플러그인이 테스트 모드일 때 운영 전환 경고와 설정 이동 버튼을 표시하도록 보강했습니다. + ## [1.0.0] - 2026-07-01 ### Added diff --git a/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/en.json b/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/en.json index 79853876..12d265df 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/en.json +++ b/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/en.json @@ -4,6 +4,7 @@ "kginicis_cbt_reconciliation": "Cross-border Reconciliation", "kginicis_escrow_delivery": "Escrow Delivery", "kginicis_status": "Payment Status", + "kginicis_test_mode_status": "Test Mode Status", "kginicis_test_map": "Test Payment Map", "settings": "Payment Settings", "vbank_info": "Virtual Account Info" @@ -74,6 +75,10 @@ "test_mode_badge": "Test Payment", "test_mode_warning_badge": "Test Payment WARNING)", "test_mode_order_notice": "This order was processed in test mode. Real card authorization/withdrawal notifications may occur, but KG Inicis test transactions may be automatically cancelled daily between 23:00 and 23:50. DO NOT ship this order.", + "test_mode_settings_warning_plugin": "KG Inicis", + "test_mode_settings_warning_title": "Warning: KG Inicis payments are currently set to test mode.", + "test_mode_settings_warning_body": "Test payments do not create real payments. If the shop is live, switch this plugin to live payment mode before operating.", + "test_mode_settings_warning_action": "Switch to live mode", "order_verify_title": "KG Inicis Payment Verification", "order_verify_description": "Query real-time payment status from KG Inicis servers.", "order_verify_button": "Query Payment", diff --git a/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/ko.json b/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/ko.json index 5f4ba04a..006fa5a4 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/ko.json +++ b/plugins/_bundled/sirsoft-pay_kginicis/resources/lang/ko.json @@ -4,6 +4,7 @@ "kginicis_cbt_reconciliation": "해외결제 정산", "kginicis_escrow_delivery": "에스크로 배송", "kginicis_status": "결제 상태", + "kginicis_test_mode_status": "테스트 모드 상태", "kginicis_test_map": "테스트 결제 맵", "settings": "결제 설정", "vbank_info": "가상계좌 정보" @@ -74,6 +75,10 @@ "test_mode_badge": "테스트 결제", "test_mode_warning_badge": "테스트 결제 주의)", "test_mode_order_notice": "이 주문은 테스트 결제로 처리되었습니다. 실제 카드 승인/출금 알림이 발생할 수 있으나, KG 이니시스 테스트 거래는 매일 23:00~23:50 사이 자동 취소될 수 있습니다. 절대 배송하지 마세요.", + "test_mode_settings_warning_plugin": "KG 이니시스", + "test_mode_settings_warning_title": "(주의!) KG 이니시스 결제 설정이 현재 테스트결제로 되어 있습니다.", + "test_mode_settings_warning_body": "테스트결제 시 실제 결제가 되지 않으므로, 쇼핑몰 운영 중이면 반드시 실결제로 설정하여 운영하세요.", + "test_mode_settings_warning_action": "실결제로 설정", "order_verify_title": "KG 이니시스 결제 검증", "order_verify_description": "KG 이니시스 서버에서 실시간으로 결제 상태를 조회합니다.", "order_verify_button": "결제 조회", diff --git a/plugins/_bundled/sirsoft-pay_kginicis/src/Controllers/AdminSettingsStatusController.php b/plugins/_bundled/sirsoft-pay_kginicis/src/Controllers/AdminSettingsStatusController.php new file mode 100644 index 00000000..a9cd5f4b --- /dev/null +++ b/plugins/_bundled/sirsoft-pay_kginicis/src/Controllers/AdminSettingsStatusController.php @@ -0,0 +1,28 @@ + (bool) $this->settingsService->get(self::PLUGIN_IDENTIFIER, 'is_test_mode', true), + ]); + } +} diff --git a/plugins/_bundled/sirsoft-pay_kginicis/src/Listeners/AdjustEcommercePaymentMethodsLayoutListener.php b/plugins/_bundled/sirsoft-pay_kginicis/src/Listeners/AdjustEcommercePaymentMethodsLayoutListener.php index 50f72e2a..0be14dd7 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/src/Listeners/AdjustEcommercePaymentMethodsLayoutListener.php +++ b/plugins/_bundled/sirsoft-pay_kginicis/src/Listeners/AdjustEcommercePaymentMethodsLayoutListener.php @@ -13,10 +13,21 @@ class AdjustEcommercePaymentMethodsLayoutListener implements HookListenerInterfa { private const TARGET_LAYOUT = 'admin_ecommerce_settings'; + private const TEST_MODE_DATA_SOURCE_ID = 'kginicis_test_mode_status'; + + private const TEST_MODE_NOTICE_ID = 'payment_test_mode_order_settings_notice'; + + private const TEST_MODE_NOTICE_ROW_ID = 'kginicis_test_mode_order_settings_notice'; + + private const TEST_MODE_CONDITION = 'kginicis_test_mode_status.data?.is_test_mode === true'; + private const CORE_NO_PG_METHODS = "['point','deposit','free','dbank']"; private const KGINICIS_NO_PG_METHODS = "['point','deposit','free','dbank','kginicis_samsung_pay','kginicis_naverpay','kginicis_lpay','kginicis_kakaopay','kginicis_japan_paypay','kginicis_japan_cvs']"; + /** + * @return array> + */ public static function getSubscribedHooks(): array { return [ @@ -37,6 +48,7 @@ class AdjustEcommercePaymentMethodsLayoutListener implements HookListenerInterfa /** * @param array $layout + * @param int $templateId * @return array */ public function markEasyPayMethodsAsPgNotRequired(array $layout, int $templateId): array @@ -45,7 +57,9 @@ class AdjustEcommercePaymentMethodsLayoutListener implements HookListenerInterfa return $layout; } - return $this->replaceNoPgMethodExpressions($layout); + $layout = $this->replaceNoPgMethodExpressions($layout); + + return $this->ensureTestModeWarning($layout); } /** @@ -71,4 +85,222 @@ class AdjustEcommercePaymentMethodsLayoutListener implements HookListenerInterfa return $node; } + + /** + * @param array $layout + * @return array + */ + private function ensureTestModeWarning(array $layout): array + { + $layout = $this->ensureTestModeDataSource($layout); + + return $this->insertTestModeNotice($layout); + } + + /** + * @param array $layout + * @return array + */ + private function ensureTestModeDataSource(array $layout): array + { + $dataSources = is_array($layout['data_sources'] ?? null) ? $layout['data_sources'] : []; + + foreach ($dataSources as $source) { + if (is_array($source) && ($source['id'] ?? null) === self::TEST_MODE_DATA_SOURCE_ID) { + $layout['data_sources'] = $dataSources; + + return $layout; + } + } + + $dataSources[] = [ + 'id' => self::TEST_MODE_DATA_SOURCE_ID, + 'label_key' => '$t:sirsoft-pay_kginicis.editor.data_source.kginicis_test_mode_status', + 'type' => 'api', + 'endpoint' => '/api/plugins/sirsoft-pay_kginicis/admin/settings/test-mode-status', + 'method' => 'GET', + 'auto_fetch' => true, + 'auth_required' => true, + ]; + + $layout['data_sources'] = $dataSources; + + return $layout; + } + + /** + * @param array $node + * @return array + */ + private function insertTestModeNotice(array $node): array + { + if (($node['id'] ?? null) === 'tab_content_order_settings' && is_array($node['children'] ?? null)) { + $noticeIndex = $this->findChildIndexById($node['children'], self::TEST_MODE_NOTICE_ID); + + if ($noticeIndex === null) { + $insertAt = $this->findChildIndexById($node['children'], 'payment_methods_card') ?? count($node['children']); + array_splice($node['children'], $insertAt, 0, [$this->testModeNoticeContainerNode()]); + $noticeIndex = $insertAt; + } + + if (is_array($node['children'][$noticeIndex] ?? null)) { + $notice = $node['children'][$noticeIndex]; + $notice['if'] = $this->mergeTestModeCondition((string) ($notice['if'] ?? '')); + $node['children'][$noticeIndex] = $this->appendTestModeNoticeRow($notice); + } + + return $node; + } + + foreach ($node as $key => $value) { + if (is_array($value)) { + $node[$key] = $this->insertTestModeNotice($value); + } + } + + return $node; + } + + /** + * @param array $children + */ + private function findChildIndexById(array $children, string $id): ?int + { + foreach ($children as $index => $child) { + if (is_array($child) && ($child['id'] ?? null) === $id) { + return $index; + } + } + + return null; + } + + /** + * @param array $children + */ + private function hasChildWithId(array $children, string $id): bool + { + return $this->findChildIndexById($children, $id) !== null; + } + + private function mergeTestModeCondition(string $condition): string + { + if (str_contains($condition, self::TEST_MODE_CONDITION)) { + return $condition !== '' ? $condition : '{{' . self::TEST_MODE_CONDITION . '}}'; + } + + $inner = trim($condition); + if (str_starts_with($inner, '{{') && str_ends_with($inner, '}}')) { + $inner = trim(substr($inner, 2, -2)); + } + + if ($inner === '') { + return '{{' . self::TEST_MODE_CONDITION . '}}'; + } + + return '{{' . $inner . ' || ' . self::TEST_MODE_CONDITION . '}}'; + } + + /** + * @param array $notice + * @return array + */ + private function appendTestModeNoticeRow(array $notice): array + { + $children = is_array($notice['children'] ?? null) ? $notice['children'] : []; + + if (! $this->hasChildWithId($children, self::TEST_MODE_NOTICE_ROW_ID)) { + $children[] = $this->testModeNoticeRowNode(); + } + + $notice['children'] = $children; + + return $notice; + } + + /** + * @return array + */ + private function testModeNoticeContainerNode(): array + { + return [ + 'id' => self::TEST_MODE_NOTICE_ID, + 'type' => 'basic', + 'name' => 'Div', + 'if' => '{{' . self::TEST_MODE_CONDITION . '}}', + 'props' => [ + 'className' => 'mb-4 space-y-3 rounded-lg border border-orange-200 bg-orange-50 p-4 dark:border-orange-700 dark:bg-orange-900/20', + ], + 'children' => [ + $this->testModeNoticeRowNode(), + ], + ]; + } + + /** + * @return array + */ + private function testModeNoticeRowNode(): array + { + return [ + 'id' => self::TEST_MODE_NOTICE_ROW_ID, + 'type' => 'basic', + 'name' => 'Div', + 'if' => '{{' . self::TEST_MODE_CONDITION . '}}', + 'props' => [ + 'className' => 'flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between', + ], + 'children' => [ + [ + 'type' => 'basic', + 'name' => 'Div', + 'props' => [ + 'className' => 'min-w-0', + ], + 'children' => [ + [ + 'type' => 'basic', + 'name' => 'Div', + 'props' => [ + 'className' => 'text-sm font-medium text-orange-950 dark:text-orange-50', + ], + 'text' => '$t:sirsoft-pay_kginicis.admin.test_mode_settings_warning_plugin', + ], + [ + 'type' => 'basic', + 'name' => 'P', + 'props' => [ + 'className' => 'mt-0.5 text-sm leading-6 text-orange-800 dark:text-orange-200', + ], + 'text' => '$t:sirsoft-pay_kginicis.admin.test_mode_settings_warning_body', + ], + ], + ], + [ + 'type' => 'basic', + 'name' => 'Button', + 'props' => [ + 'type' => 'button', + 'className' => 'btn btn-outline btn-sm w-full flex-shrink-0 border-orange-300 text-orange-900 hover:bg-orange-100 sm:w-auto dark:border-orange-600 dark:text-orange-100 dark:hover:bg-orange-900/40', + ], + 'actions' => [ + [ + 'type' => 'click', + 'handler' => 'navigate', + 'params' => [ + 'path' => '/admin/plugins/sirsoft-pay_kginicis/settings', + ], + ], + ], + 'children' => [ + [ + 'type' => 'basic', + 'name' => 'Span', + 'text' => '$t:sirsoft-pay_kginicis.admin.test_mode_settings_warning_action', + ], + ], + ], + ], + ]; + } } diff --git a/plugins/_bundled/sirsoft-pay_kginicis/src/routes/api.php b/plugins/_bundled/sirsoft-pay_kginicis/src/routes/api.php index 5b3a9b6a..8b9cdaaa 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/src/routes/api.php +++ b/plugins/_bundled/sirsoft-pay_kginicis/src/routes/api.php @@ -9,6 +9,7 @@ use Plugins\Sirsoft\PayKginicis\Controllers\AdminCbtTestProductController; use Plugins\Sirsoft\PayKginicis\Controllers\AdminEscrowDeliveryController; use Plugins\Sirsoft\PayKginicis\Controllers\AdminEscrowDenyConfirmController; use Plugins\Sirsoft\PayKginicis\Controllers\AdminOrderListController; +use Plugins\Sirsoft\PayKginicis\Controllers\AdminSettingsStatusController; use Plugins\Sirsoft\PayKginicis\Controllers\AdminTransactionController; use Plugins\Sirsoft\PayKginicis\Controllers\CbtCheckoutTokenController; use Plugins\Sirsoft\PayKginicis\Controllers\CbtHashDataController; @@ -66,6 +67,10 @@ Route::prefix('admin')->name('admin.')->middleware(['auth:sanctum', 'admin'])->g })->middleware('permission:admin,sirsoft-ecommerce.settings.read') ->name('vbank.notify.url'); + Route::get('/settings/test-mode-status', [AdminSettingsStatusController::class, 'testMode']) + ->middleware('permission:admin,sirsoft-ecommerce.settings.read') + ->name('settings.test-mode-status'); + // 어드민 주문 목록의 테스트 결제 배지 표시용 맵 (auto_fetch) Route::get('/orders/test-mode-map', [AdminOrderListController::class, 'testModeMap']) ->middleware('permission:admin,sirsoft-ecommerce.orders.read') diff --git a/plugins/_bundled/sirsoft-pay_kginicis/tests/Feature/Controllers/AdminSettingsStatusControllerTest.php b/plugins/_bundled/sirsoft-pay_kginicis/tests/Feature/Controllers/AdminSettingsStatusControllerTest.php new file mode 100644 index 00000000..edc48e32 --- /dev/null +++ b/plugins/_bundled/sirsoft-pay_kginicis/tests/Feature/Controllers/AdminSettingsStatusControllerTest.php @@ -0,0 +1,33 @@ +createMock(PluginSettingsService::class); + $settings->expects($this->once()) + ->method('get') + ->with('sirsoft-pay_kginicis', 'is_test_mode', true) + ->willReturn(true); + $this->app->instance(PluginSettingsService::class, $settings); + + $admin = $this->createAdminUser(['sirsoft-ecommerce.settings.read']); + + $response = $this->actingAs($admin) + ->getJson('/api/plugins/sirsoft-pay_kginicis/admin/settings/test-mode-status'); + + $response->assertOk() + ->assertJsonPath('data.is_test_mode', true); + + $data = $response->json('data'); + $this->assertArrayNotHasKey('test_mid', $data); + $this->assertArrayNotHasKey('live_mid', $data); + } +} diff --git a/plugins/_bundled/sirsoft-pay_kginicis/tests/Unit/Listeners/AdjustEcommercePaymentMethodsLayoutListenerTest.php b/plugins/_bundled/sirsoft-pay_kginicis/tests/Unit/Listeners/AdjustEcommercePaymentMethodsLayoutListenerTest.php index 05ef775c..e295d388 100644 --- a/plugins/_bundled/sirsoft-pay_kginicis/tests/Unit/Listeners/AdjustEcommercePaymentMethodsLayoutListenerTest.php +++ b/plugins/_bundled/sirsoft-pay_kginicis/tests/Unit/Listeners/AdjustEcommercePaymentMethodsLayoutListenerTest.php @@ -58,6 +58,45 @@ class AdjustEcommercePaymentMethodsLayoutListenerTest extends TestCase $this->assertStringNotContainsString("['point','deposit','free','dbank'].includes", $json); } + public function test_adds_test_mode_warning_to_order_settings_tab(): void + { + $listener = new AdjustEcommercePaymentMethodsLayoutListener(); + + $layout = [ + 'layout_name' => 'admin_ecommerce_settings', + 'children' => [ + [ + 'id' => 'tab_content_order_settings', + 'children' => [ + ['id' => 'default_pg_card'], + ['id' => 'payment_methods_card'], + ], + ], + ], + ]; + + $result = $listener->markEasyPayMethodsAsPgNotRequired($layout, 1); + $result = $listener->markEasyPayMethodsAsPgNotRequired($result, 1); + $json = json_encode($result, JSON_UNESCAPED_SLASHES); + + $this->assertIsString($json); + $this->assertStringContainsString('kginicis_test_mode_status', $json); + $this->assertStringContainsString('/api/plugins/sirsoft-pay_kginicis/admin/settings/test-mode-status', $json); + $this->assertStringContainsString('payment_test_mode_order_settings_notice', $json); + $this->assertStringContainsString('kginicis_test_mode_order_settings_notice', $json); + $this->assertStringNotContainsString('sirsoft-pay_kginicis.admin.test_mode_settings_summary_title', $json); + $this->assertStringNotContainsString('sirsoft-pay_kginicis.admin.test_mode_settings_summary_body', $json); + $this->assertStringContainsString('sirsoft-pay_kginicis.admin.test_mode_settings_warning_plugin', $json); + $this->assertStringContainsString('sirsoft-pay_kginicis.admin.test_mode_settings_warning_body', $json); + $this->assertStringContainsString('/admin/plugins/sirsoft-pay_kginicis/settings', $json); + $this->assertSame(1, substr_count($json, 'payment_test_mode_order_settings_notice')); + $this->assertSame(1, substr_count($json, 'kginicis_test_mode_order_settings_notice')); + $this->assertLessThan( + strpos($json, 'payment_methods_card'), + strpos($json, 'payment_test_mode_order_settings_notice') + ); + } + public function test_leaves_other_layouts_unchanged(): void { $listener = new AdjustEcommercePaymentMethodsLayoutListener();