cashier/utils/merchant-context.ts

77 lines
2.3 KiB
TypeScript

import CryptoJS from 'crypto-js';
import { encryptedStorage } from '@/utils/storage';
export const ACTIVE_QR_URL_CACHE_KEY = 'cashier:property:active-url';
export const ACTIVE_QR_HASH_CACHE_KEY = 'cashier:property:active-url-hash';
const decodeOption = (value?: string) => {
if (!value) return '';
try {
return decodeURIComponent(value);
} catch (error) {
return value;
}
};
export const resolveMerchantUrlFromOptions = (options: Record<string, string>) => {
return decodeOption(options.url || options.qr_url || '');
};
const readQueryParam = (raw: string, key: string) => {
const match = raw.match(new RegExp(`[?&]${key}=([^&]+)`));
return match ? decodeOption(match[1]) : '';
};
export const resolveMerchantUrlFromScanResult = (raw: string) => {
const text = (raw || '').trim();
if (!text) return '';
if (/^https?:\/\//i.test(text)) {
return text;
}
const fromUrl = readQueryParam(text, 'url') || readQueryParam(text, 'qr_url');
if (fromUrl) return fromUrl;
const fromQ = readQueryParam(text, 'q');
if (fromQ) return resolveMerchantUrlFromScanResult(fromQ);
return '';
};
export const getMerchantUrlHash = (merchantUrl: string) => {
return CryptoJS.SHA256(merchantUrl).toString();
};
export const getPropertyBindingCacheKeyByHash = (hash: string) => {
// Hash key keeps cache key short/stable and avoids raw URL special characters.
return `cashier:property:binding:${hash}`;
};
export const getSupplierCacheKeyByHash = (hash: string) => {
return `cashier:supplier:detail:${hash}`;
};
export const getPropertyBindingCacheKey = (merchantUrl: string) => {
return getPropertyBindingCacheKeyByHash(getMerchantUrlHash(merchantUrl));
};
export const getSupplierCacheKey = (merchantUrl: string) => {
return getSupplierCacheKeyByHash(getMerchantUrlHash(merchantUrl));
};
export const syncActiveMerchantContext = (merchantUrl: string) => {
const currentHash = getMerchantUrlHash(merchantUrl);
const previousHash = encryptedStorage.get<string>(ACTIVE_QR_HASH_CACHE_KEY) || '';
encryptedStorage.set(ACTIVE_QR_URL_CACHE_KEY, merchantUrl);
encryptedStorage.set(ACTIVE_QR_HASH_CACHE_KEY, currentHash);
return {
currentHash,
previousHash,
switched: Boolean(previousHash && previousHash !== currentHash)
};
};
export const getActiveMerchantUrl = () => encryptedStorage.get<string>(ACTIVE_QR_URL_CACHE_KEY) || '';