From d86b994222a2469b6a8ca30c582b257f957153fb Mon Sep 17 00:00:00 2001 From: ignaciosantise <25931366+ignaciosantise@users.noreply.github.com> Date: Thu, 26 Feb 2026 16:33:18 -0300 Subject: [PATCH 1/2] fix(pos-app): rename partner API key to customer API key --- dapps/pos-app/.env.example | 2 +- dapps/pos-app/AGENTS.md | 6 +- .../hooks/use-url-credentials.test.ts | 20 +-- .../__tests__/services/payment.test.ts | 12 +- .../__tests__/store/useSettingsStore.test.ts | 40 ++--- .../__tests__/utils/secure-storage.test.ts | 137 +++++++++++++----- .../pos-app/__tests__/utils/store-helpers.ts | 10 +- dapps/pos-app/app.json | 2 +- dapps/pos-app/app/index.tsx | 4 +- dapps/pos-app/app/settings.tsx | 60 ++++---- dapps/pos-app/hooks/use-merchant-flow.ts | 67 +++++---- dapps/pos-app/hooks/use-url-credentials.ts | 20 +-- dapps/pos-app/services/payment.ts | 10 +- dapps/pos-app/services/payment.web.ts | 4 +- dapps/pos-app/store/useSettingsStore.ts | 65 +++++---- dapps/pos-app/utils/merchant-config.ts | 8 +- dapps/pos-app/utils/secure-storage.ts | 41 ++++-- dapps/pos-app/utils/secure-storage.web.ts | 35 +++-- 18 files changed, 320 insertions(+), 223 deletions(-) diff --git a/dapps/pos-app/.env.example b/dapps/pos-app/.env.example index 2c0295ae..bb5b4c00 100644 --- a/dapps/pos-app/.env.example +++ b/dapps/pos-app/.env.example @@ -4,6 +4,6 @@ SENTRY_AUTH_TOKEN="" EXPO_PUBLIC_API_URL="" EXPO_PUBLIC_GATEWAY_URL="" EXPO_PUBLIC_DEFAULT_MERCHANT_ID="" -EXPO_PUBLIC_DEFAULT_PARTNER_API_KEY="" +EXPO_PUBLIC_DEFAULT_CUSTOMER_API_KEY="" EXPO_PUBLIC_MERCHANT_API_URL="" EXPO_PUBLIC_MERCHANT_PORTAL_API_KEY="" \ No newline at end of file diff --git a/dapps/pos-app/AGENTS.md b/dapps/pos-app/AGENTS.md index 11c9f829..259dd3b1 100644 --- a/dapps/pos-app/AGENTS.md +++ b/dapps/pos-app/AGENTS.md @@ -258,7 +258,7 @@ SENTRY_AUTH_TOKEN="" # Sentry authentication token EXPO_PUBLIC_API_URL="" # Payment API base URL EXPO_PUBLIC_GATEWAY_URL="" # WalletConnect gateway URL EXPO_PUBLIC_DEFAULT_MERCHANT_ID="" # Default merchant ID (optional) -EXPO_PUBLIC_DEFAULT_PARTNER_API_KEY="" # Default partner API key (optional) +EXPO_PUBLIC_DEFAULT_CUSTOMER_API_KEY="" # Default customer API key (optional) EXPO_PUBLIC_MERCHANT_API_URL="" # Merchant Portal API base URL EXPO_PUBLIC_MERCHANT_PORTAL_API_KEY="" # Merchant Portal API key (for Activity screen) ``` @@ -678,10 +678,10 @@ const { data, isLoading, error } = usePaymentStatus(paymentId, { import { secureStorage, SECURE_STORAGE_KEYS } from "@/utils/secure-storage"; // Store -await secureStorage.setItem(SECURE_STORAGE_KEYS.PARTNER_API_KEY, apiKey); +await secureStorage.setItem(SECURE_STORAGE_KEYS.CUSTOMER_API_KEY, apiKey); // Retrieve -const apiKey = await secureStorage.getItem(SECURE_STORAGE_KEYS.PARTNER_API_KEY); +const apiKey = await secureStorage.getItem(SECURE_STORAGE_KEYS.CUSTOMER_API_KEY); ``` ## Code Quality Guidelines diff --git a/dapps/pos-app/__tests__/hooks/use-url-credentials.test.ts b/dapps/pos-app/__tests__/hooks/use-url-credentials.test.ts index f8f8e039..88634721 100644 --- a/dapps/pos-app/__tests__/hooks/use-url-credentials.test.ts +++ b/dapps/pos-app/__tests__/hooks/use-url-credentials.test.ts @@ -36,11 +36,11 @@ afterEach(() => { }); describe("useUrlCredentials", () => { - it("applies both merchantId and partnerApiKey from base64-encoded URL params", async () => { + it("applies both merchantId and customerApiKey from base64-encoded URL params", async () => { const merchantId = "test-merchant-123"; const apiKey = "test-api-key-456"; setWindowLocation( - `?merchantId=${toBase64(merchantId)}&partnerApiKey=${toBase64(apiKey)}`, + `?merchantId=${toBase64(merchantId)}&customerApiKey=${toBase64(apiKey)}`, ); useSettingsStore.setState({ _hasHydrated: true }); @@ -50,11 +50,11 @@ describe("useUrlCredentials", () => { const state = useSettingsStore.getState(); expect(state.merchantId).toBe(merchantId); - expect(state.isPartnerApiKeySet).toBe(true); + expect(state.isCustomerApiKeySet).toBe(true); expect(router.replace).toHaveBeenCalledWith("/"); }); - it("applies only merchantId when partnerApiKey is absent", async () => { + it("applies only merchantId when customerApiKey is absent", async () => { const merchantId = "only-merchant"; setWindowLocation(`?merchantId=${toBase64(merchantId)}`); @@ -65,12 +65,12 @@ describe("useUrlCredentials", () => { const state = useSettingsStore.getState(); expect(state.merchantId).toBe(merchantId); - expect(state.isPartnerApiKeySet).toBe(false); + expect(state.isCustomerApiKeySet).toBe(false); }); - it("applies only partnerApiKey when merchantId is absent", async () => { + it("applies only customerApiKey when merchantId is absent", async () => { const apiKey = "only-api-key"; - setWindowLocation(`?partnerApiKey=${toBase64(apiKey)}`); + setWindowLocation(`?customerApiKey=${toBase64(apiKey)}`); useSettingsStore.setState({ _hasHydrated: true, merchantId: null }); @@ -79,7 +79,7 @@ describe("useUrlCredentials", () => { const state = useSettingsStore.getState(); expect(state.merchantId).toBeNull(); - expect(state.isPartnerApiKeySet).toBe(true); + expect(state.isCustomerApiKeySet).toBe(true); }); it("does nothing when no URL params are present", async () => { @@ -132,7 +132,7 @@ describe("useUrlCredentials", () => { it("logs actions when credentials are applied", async () => { setWindowLocation( - `?merchantId=${toBase64("log-test")}&partnerApiKey=${toBase64("log-key")}`, + `?merchantId=${toBase64("log-test")}&customerApiKey=${toBase64("log-key")}`, ); useSettingsStore.setState({ _hasHydrated: true }); @@ -144,6 +144,6 @@ describe("useUrlCredentials", () => { const infoLogs = logs.filter((l) => l.level === "info"); expect(infoLogs).toHaveLength(2); expect(infoLogs[0].message).toContain("Merchant ID set from URL"); - expect(infoLogs[1].message).toContain("Partner API key set from URL"); + expect(infoLogs[1].message).toContain("Customer API key set from URL"); }); }); diff --git a/dapps/pos-app/__tests__/services/payment.test.ts b/dapps/pos-app/__tests__/services/payment.test.ts index a3506101..ec55523b 100644 --- a/dapps/pos-app/__tests__/services/payment.test.ts +++ b/dapps/pos-app/__tests__/services/payment.test.ts @@ -42,10 +42,10 @@ describe("Payment Service", () => { describe("getApiHeaders (via startPayment/getPaymentStatus)", () => { it("should throw error when merchant ID is not configured", async () => { // Set API key but not merchant ID - await SecureStore.setItemAsync("partner_api_key", "test-api-key"); + await SecureStore.setItemAsync("customer_api_key", "test-api-key"); useSettingsStore.setState({ merchantId: null, - isPartnerApiKeySet: true, + isCustomerApiKeySet: true, }); await expect( @@ -57,10 +57,10 @@ describe("Payment Service", () => { }); it("should throw error when merchant ID is empty string", async () => { - await SecureStore.setItemAsync("partner_api_key", "test-api-key"); + await SecureStore.setItemAsync("customer_api_key", "test-api-key"); useSettingsStore.setState({ merchantId: " ", // whitespace only - isPartnerApiKeySet: true, + isCustomerApiKeySet: true, }); await expect( @@ -74,7 +74,7 @@ describe("Payment Service", () => { it("should throw error when API key is not configured", async () => { useSettingsStore.setState({ merchantId: "merchant-123", - isPartnerApiKeySet: false, + isCustomerApiKeySet: false, }); // Don't set the API key in secure storage @@ -83,7 +83,7 @@ describe("Payment Service", () => { referenceId: "ref-123", amount: { value: "1000", unit: "cents" }, }), - ).rejects.toThrow("Partner API key is not configured"); + ).rejects.toThrow("Customer API key is not configured"); }); it("should include correct headers when merchant is configured", async () => { diff --git a/dapps/pos-app/__tests__/store/useSettingsStore.test.ts b/dapps/pos-app/__tests__/store/useSettingsStore.test.ts index 0f1a34c7..ddf39622 100644 --- a/dapps/pos-app/__tests__/store/useSettingsStore.test.ts +++ b/dapps/pos-app/__tests__/store/useSettingsStore.test.ts @@ -34,9 +34,9 @@ describe("useSettingsStore", () => { expect(merchantId).toBeNull(); }); - it("should have isPartnerApiKeySet as false", () => { - const { isPartnerApiKeySet } = useSettingsStore.getState(); - expect(isPartnerApiKeySet).toBe(false); + it("should have isCustomerApiKeySet as false", () => { + const { isCustomerApiKeySet } = useSettingsStore.getState(); + expect(isCustomerApiKeySet).toBe(false); }); it("should have zero failed PIN attempts", () => { @@ -155,57 +155,57 @@ describe("useSettingsStore", () => { }); }); - describe("setPartnerApiKey / clearPartnerApiKey / getPartnerApiKey", () => { + describe("setCustomerApiKey / clearCustomerApiKey / getCustomerApiKey", () => { it("should store API key in secure storage", async () => { - const { setPartnerApiKey } = useSettingsStore.getState(); + const { setCustomerApiKey } = useSettingsStore.getState(); - await setPartnerApiKey("api-key-123"); + await setCustomerApiKey("api-key-123"); - expect(useSettingsStore.getState().isPartnerApiKeySet).toBe(true); + expect(useSettingsStore.getState().isCustomerApiKeySet).toBe(true); expect(SecureStore.setItemAsync).toHaveBeenCalledWith( - "partner_api_key", + "customer_api_key", "api-key-123", ); }); it("should retrieve API key from secure storage", async () => { // First store the key - await useSettingsStore.getState().setPartnerApiKey("api-key-456"); + await useSettingsStore.getState().setCustomerApiKey("api-key-456"); // Then retrieve it - const apiKey = await useSettingsStore.getState().getPartnerApiKey(); + const apiKey = await useSettingsStore.getState().getCustomerApiKey(); expect(apiKey).toBe("api-key-456"); }); it("should clear API key from secure storage", async () => { // First store a key - await useSettingsStore.getState().setPartnerApiKey("api-key-789"); - expect(useSettingsStore.getState().isPartnerApiKeySet).toBe(true); + await useSettingsStore.getState().setCustomerApiKey("api-key-789"); + expect(useSettingsStore.getState().isCustomerApiKeySet).toBe(true); // Clear it - await useSettingsStore.getState().clearPartnerApiKey(); + await useSettingsStore.getState().clearCustomerApiKey(); - expect(useSettingsStore.getState().isPartnerApiKeySet).toBe(false); + expect(useSettingsStore.getState().isCustomerApiKeySet).toBe(false); expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( - "partner_api_key", + "customer_api_key", ); }); it("should remove API key when setting null", async () => { // First store a key - await useSettingsStore.getState().setPartnerApiKey("api-key-to-remove"); + await useSettingsStore.getState().setCustomerApiKey("api-key-to-remove"); // Set to null - await useSettingsStore.getState().setPartnerApiKey(null); + await useSettingsStore.getState().setCustomerApiKey(null); expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( - "partner_api_key", + "customer_api_key", ); }); it("should return null when no API key is stored", async () => { - const apiKey = await useSettingsStore.getState().getPartnerApiKey(); + const apiKey = await useSettingsStore.getState().getCustomerApiKey(); expect(apiKey).toBeNull(); }); }); @@ -579,7 +579,7 @@ describe("useSettingsStore", () => { // Check persist name and version are set (for storage key) expect(persistOptions?.name).toBe("settings"); - expect(persistOptions?.version).toBe(12); + expect(persistOptions?.version).toBe(13); // Verify storage is configured (MMKV in production, mock in tests) expect(persistOptions?.storage).toBeDefined(); diff --git a/dapps/pos-app/__tests__/utils/secure-storage.test.ts b/dapps/pos-app/__tests__/utils/secure-storage.test.ts index 8edc6fce..9d5d2b0a 100644 --- a/dapps/pos-app/__tests__/utils/secure-storage.test.ts +++ b/dapps/pos-app/__tests__/utils/secure-storage.test.ts @@ -4,31 +4,34 @@ * Tests for the secure storage migration function. */ -import { migratePartnerApiKey } from "@/utils/secure-storage"; +import { + clearStaleSecureStorage, + migrateCustomerApiKey, +} from "@/utils/secure-storage"; import { storage } from "@/utils/storage"; // Get the mocked secure store const SecureStore = require("expo-secure-store"); -describe("migratePartnerApiKey", () => { +describe("migrateCustomerApiKey", () => { beforeEach(() => { // Clear secure storage mock between tests if (SecureStore.__clearMockStorage) { SecureStore.__clearMockStorage(); } // Clear the migration completed flag - storage.removeItem("migration_partner_api_key_completed"); + storage.removeItem("migration_customer_api_key_completed"); + storage.removeItem("app_has_launched"); }); - it("should migrate from old key to new key when old key exists", async () => { - // Set up old key + it("should migrate from old merchant key to new customer key", async () => { await SecureStore.setItemAsync("merchant_api_key", "test-api-key-123"); - const migrated = await migratePartnerApiKey(); + const migrated = await migrateCustomerApiKey(); expect(migrated).toBe(true); expect(SecureStore.setItemAsync).toHaveBeenCalledWith( - "partner_api_key", + "customer_api_key", "test-api-key-123", ); expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( @@ -36,76 +39,140 @@ describe("migratePartnerApiKey", () => { ); }); - it("should not overwrite existing new key", async () => { - // Set up both old and new keys - await SecureStore.setItemAsync("merchant_api_key", "old-api-key"); - await SecureStore.setItemAsync("partner_api_key", "existing-new-key"); + it("should migrate from old partner key to new customer key", async () => { + await SecureStore.setItemAsync("partner_api_key", "partner-key-456"); + + const migrated = await migrateCustomerApiKey(); + + expect(migrated).toBe(true); + expect(SecureStore.setItemAsync).toHaveBeenCalledWith( + "customer_api_key", + "partner-key-456", + ); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( + "partner_api_key", + ); + }); + + it("should migrate from merchant key when both old keys exist", async () => { + await SecureStore.setItemAsync("merchant_api_key", "merchant-value"); + await SecureStore.setItemAsync("partner_api_key", "partner-value"); - // Clear mock calls from setup jest.clearAllMocks(); - const migrated = await migratePartnerApiKey(); + const migrated = await migrateCustomerApiKey(); - // Should still delete old key but not set new key (existing value preserved) - expect(migrated).toBe(false); - expect(SecureStore.setItemAsync).not.toHaveBeenCalledWith( - "partner_api_key", - expect.anything(), + expect(migrated).toBe(true); + expect(SecureStore.setItemAsync).toHaveBeenCalledWith( + "customer_api_key", + "merchant-value", ); expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( "merchant_api_key", ); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( + "partner_api_key", + ); }); - it("should do nothing when old key does not exist", async () => { - // No keys set up + it("should not overwrite existing customer key", async () => { + await SecureStore.setItemAsync("partner_api_key", "old-value"); + await SecureStore.setItemAsync("customer_api_key", "existing-value"); + + jest.clearAllMocks(); - const migrated = await migratePartnerApiKey(); + const migrated = await migrateCustomerApiKey(); expect(migrated).toBe(false); expect(SecureStore.setItemAsync).not.toHaveBeenCalledWith( + "customer_api_key", + expect.anything(), + ); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith( "partner_api_key", + ); + }); + + it("should do nothing when no old keys exist", async () => { + const migrated = await migrateCustomerApiKey(); + + expect(migrated).toBe(false); + expect(SecureStore.setItemAsync).not.toHaveBeenCalledWith( + "customer_api_key", expect.anything(), ); expect(SecureStore.deleteItemAsync).not.toHaveBeenCalled(); }); it("should track migration completion and skip on subsequent calls", async () => { - // Set up old key await SecureStore.setItemAsync("merchant_api_key", "test-api-key"); - // First call should perform migration - const firstResult = await migratePartnerApiKey(); + const firstResult = await migrateCustomerApiKey(); expect(firstResult).toBe(true); - // Clear mocks but keep storage state jest.clearAllMocks(); - // Set up old key again to simulate what would happen if migration ran again await SecureStore.setItemAsync("merchant_api_key", "another-key"); - // Second call should skip due to completion flag - const secondResult = await migratePartnerApiKey(); + const secondResult = await migrateCustomerApiKey(); expect(secondResult).toBe(false); - // Should not have attempted to read/write secure storage for migration - // (only the setup call above) expect(SecureStore.getItemAsync).not.toHaveBeenCalledWith( "merchant_api_key", ); }); - it("should properly clean up old key after migration", async () => { + it("should properly clean up old keys after migration", async () => { await SecureStore.setItemAsync("merchant_api_key", "api-key-to-migrate"); - await migratePartnerApiKey(); + await migrateCustomerApiKey(); - // Verify old key was deleted const oldValue = await SecureStore.getItemAsync("merchant_api_key"); expect(oldValue).toBeNull(); - // Verify new key has the value - const newValue = await SecureStore.getItemAsync("partner_api_key"); + const newValue = await SecureStore.getItemAsync("customer_api_key"); expect(newValue).toBe("api-key-to-migrate"); }); }); + +describe("clearStaleSecureStorage", () => { + beforeEach(() => { + if (SecureStore.__clearMockStorage) { + SecureStore.__clearMockStorage(); + } + storage.removeItem("app_has_launched"); + }); + + it("should clear current and legacy API keys on fresh install", async () => { + await SecureStore.setItemAsync("customer_api_key", "new-key"); + await SecureStore.setItemAsync("merchant_api_key", "merchant-key"); + await SecureStore.setItemAsync("partner_api_key", "partner-key"); + await SecureStore.setItemAsync("pin_hash", "pin-hash"); + + jest.clearAllMocks(); + + await clearStaleSecureStorage(); + + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith("customer_api_key"); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith("merchant_api_key"); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith("partner_api_key"); + expect(SecureStore.deleteItemAsync).toHaveBeenCalledWith("pin_hash"); + expect(await SecureStore.getItemAsync("customer_api_key")).toBeNull(); + expect(await SecureStore.getItemAsync("merchant_api_key")).toBeNull(); + expect(await SecureStore.getItemAsync("partner_api_key")).toBeNull(); + expect(await SecureStore.getItemAsync("pin_hash")).toBeNull(); + expect(storage.getItem("app_has_launched")).toBe(true); + }); + + it("should not clear keys after first launch", async () => { + storage.setItem("app_has_launched", true); + await SecureStore.setItemAsync("partner_api_key", "partner-key"); + + jest.clearAllMocks(); + + await clearStaleSecureStorage(); + + expect(SecureStore.deleteItemAsync).not.toHaveBeenCalled(); + expect(await SecureStore.getItemAsync("partner_api_key")).toBe("partner-key"); + }); +}); diff --git a/dapps/pos-app/__tests__/utils/store-helpers.ts b/dapps/pos-app/__tests__/utils/store-helpers.ts index e4d5f0f1..df3496bd 100644 --- a/dapps/pos-app/__tests__/utils/store-helpers.ts +++ b/dapps/pos-app/__tests__/utils/store-helpers.ts @@ -16,7 +16,7 @@ export function resetSettingsStore() { variant: "default", _hasHydrated: false, merchantId: null, - isPartnerApiKeySet: false, + isCustomerApiKeySet: false, pinFailedAttempts: 0, pinLockoutUntil: null, biometricEnabled: false, @@ -51,11 +51,11 @@ export async function setupTestMerchant( ): Promise<() => Promise> { // eslint-disable-next-line @typescript-eslint/no-require-imports const SecureStore = require("expo-secure-store"); - await SecureStore.setItemAsync("partner_api_key", apiKey); + await SecureStore.setItemAsync("customer_api_key", apiKey); useSettingsStore.setState({ merchantId, - isPartnerApiKeySet: true, + isCustomerApiKeySet: true, }); // Return cleanup function for use in afterEach or manual cleanup @@ -68,10 +68,10 @@ export async function setupTestMerchant( export async function clearTestMerchant() { // eslint-disable-next-line @typescript-eslint/no-require-imports const SecureStore = require("expo-secure-store"); - await SecureStore.deleteItemAsync("partner_api_key"); + await SecureStore.deleteItemAsync("customer_api_key"); useSettingsStore.setState({ merchantId: null, - isPartnerApiKeySet: false, + isCustomerApiKeySet: false, }); } diff --git a/dapps/pos-app/app.json b/dapps/pos-app/app.json index 5dad4fdf..284f3e26 100644 --- a/dapps/pos-app/app.json +++ b/dapps/pos-app/app.json @@ -43,7 +43,7 @@ "android.permission.BLUETOOTH_ADVERTISE", "android.permission.USB_PERMISSION" ], - "versionCode": 17 + "versionCode": 18 }, "web": { "output": "static", diff --git a/dapps/pos-app/app/index.tsx b/dapps/pos-app/app/index.tsx index 33677607..ea3895e6 100644 --- a/dapps/pos-app/app/index.tsx +++ b/dapps/pos-app/app/index.tsx @@ -17,10 +17,10 @@ export default function HomeScreen() { ]); const Theme = useTheme(); - const { merchantId, isPartnerApiKeySet } = useSettingsStore(); + const { merchantId, isCustomerApiKeySet } = useSettingsStore(); const handleStartPayment = () => { - if (!merchantId || !isPartnerApiKeySet) { + if (!merchantId || !isCustomerApiKeySet) { router.push("/settings"); showErrorToast("Merchant information not configured"); return; diff --git a/dapps/pos-app/app/settings.tsx b/dapps/pos-app/app/settings.tsx index 302b843d..e3d29e70 100644 --- a/dapps/pos-app/app/settings.tsx +++ b/dapps/pos-app/app/settings.tsx @@ -37,7 +37,7 @@ type ActiveSheet = | "walletTheme" | "currency" | "merchantId" - | "partnerApiKey" + | "customerApiKey" | null; const THEME_OPTIONS: RadioOption[] = [ @@ -78,7 +78,7 @@ export default function SettingsScreen() { const theme = useTheme(); const [activeSheet, setActiveSheet] = useState(null); - const [isEditingPartnerKey, setIsEditingPartnerKey] = useState(false); + const [isEditingCustomerKey, setIsEditingCustomerKey] = useState(false); // Custom hooks for biometrics and merchant flow const { @@ -93,17 +93,17 @@ export default function SettingsScreen() { const { merchantIdInput, - partnerApiKeyInput, + customerApiKeyInput, activeModal, pinError, isMerchantIdConfirmDisabled, - isPartnerApiKeyConfirmDisabled, - hasStoredPartnerApiKey, + isCustomerApiKeyConfirmDisabled, + hasStoredCustomerApiKey, handleMerchantIdInputChange, - handlePartnerApiKeyInputChange, - resetPartnerApiKeyInput, + handleCustomerApiKeyInputChange, + resetCustomerApiKeyInput, handleMerchantIdConfirm, - handlePartnerApiKeyConfirm, + handleCustomerApiKeyConfirm, handlePinVerifyComplete, handleBiometricAuthSuccess, handleBiometricAuthFailure, @@ -141,11 +141,11 @@ export default function SettingsScreen() { const currentCurrency = getCurrency(currency); const closeSheet = () => { - if (activeSheet === "partnerApiKey") { - resetPartnerApiKeyInput(); + if (activeSheet === "customerApiKey") { + resetCustomerApiKeyInput(); } setActiveSheet(null); - setIsEditingPartnerKey(false); + setIsEditingCustomerKey(false); }; const handleThemeModeChange = (value: ThemeMode) => { @@ -168,16 +168,16 @@ export default function SettingsScreen() { closeSheet(); }; - const handlePartnerApiKeySave = async () => { - await handlePartnerApiKeyConfirm(); + const handleCustomerApiKeySave = async () => { + await handleCustomerApiKeyConfirm(); closeSheet(); }; - const handlePartnerKeyChange = (value: string) => { - if (!isEditingPartnerKey) { - setIsEditingPartnerKey(true); + const handleCustomerKeyChange = (value: string) => { + if (!isEditingCustomerKey) { + setIsEditingCustomerKey(true); } - handlePartnerApiKeyInputChange(value); + handleCustomerApiKeyInputChange(value); }; const handleTestPrinterPress = async () => { @@ -267,9 +267,9 @@ export default function SettingsScreen() { /> setActiveSheet("partnerApiKey")} + onPress={() => setActiveSheet("customerApiKey")} /> {/* Biometric toggle - only show if PIN is set and biometrics available */} @@ -406,23 +406,23 @@ export default function SettingsScreen() { - {/* Partner API Key Bottom Sheet */} + {/* Customer API Key Bottom Sheet */}