/** * Form to set the PayZen's username, password and public key */ import React, { ReactNode, useEffect, useState } from 'react'; import { Loader } from './loader'; import { useTranslation } from 'react-i18next'; import SettingAPI from '../api/setting'; import { SettingName } from '../models/setting'; import { FabInput } from './fab-input'; import { enableMapSet } from 'immer'; import { useImmer } from 'use-immer'; import PayzenAPI from '../api/payzen'; enableMapSet(); interface PayZenKeysFormProps { onValidKeys: (payZenSettings: Map) => void } const payZenSettings: Array = [SettingName.PayZenUsername, SettingName.PayZenPassword, SettingName.PayZenEndpoint, SettingName.PayZenHmacKey, SettingName.PayZenPublicKey]; const restApiSettings: Array = [SettingName.PayZenUsername, SettingName.PayZenPassword, SettingName.PayZenEndpoint, SettingName.PayZenHmacKey]; const payZenKeys = SettingAPI.query(payZenSettings); // Prevent multiples call to the payzen keys validation endpoint. // this cannot be handled by a React state because of their asynchronous nature let pendingKeysValidation = false; const PayZenKeysFormComponent: React.FC = ({ onValidKeys }) => { const { t } = useTranslation('admin'); const [settings, updateSettings] = useImmer>(new Map(payZenSettings.map(name => [name, '']))); const [restApiAddOn, setRestApiAddOn] = useState(null); const [restApiAddOnClassName, setRestApiAddOnClassName] = useState(''); const [publicKeyAddOn, setPublicKeyAddOn] = useState(null); const [publicKeyAddOnClassName, setPublicKeyAddOnClassName] = useState(''); useEffect(() => { updateSettings(payZenKeys.read()); }, []); useEffect(() => { const validClassName = 'key-valid'; if (publicKeyAddOnClassName === validClassName && restApiAddOnClassName === validClassName) { onValidKeys(settings); } }, [publicKeyAddOnClassName, restApiAddOnClassName, settings]); useEffect(() => { testRestApi(); }, [settings]) /** * Assign the inputted key to the settings and check if it is valid. * Depending on the test result, assign an add-on icon and a style to notify the user. */ const testPublicKey = (key: string) => { if (!key.match(/^[0-9]+:/)) { setPublicKeyAddOn(); setPublicKeyAddOnClassName('key-invalid'); return; } updateSettings(draft => draft.set(SettingName.PayZenPublicKey, key)); setPublicKeyAddOn(); setPublicKeyAddOnClassName('key-valid'); } /** * Send a test call to the payZen REST API to check if the inputted settings key are valid. * Depending on the test result, assign an add-on icon and a style to notify the user. */ const testRestApi = () => { let valid: boolean = restApiSettings.map(s => !!settings.get(s)) .reduce((acc, val) => acc && val, true); if (valid && !pendingKeysValidation) { pendingKeysValidation = true; PayzenAPI.chargeSDKTest( settings.get(SettingName.PayZenEndpoint), settings.get(SettingName.PayZenUsername), settings.get(SettingName.PayZenPassword) ).then(result => { pendingKeysValidation = false; if (result.success) { setRestApiAddOn(); setRestApiAddOnClassName('key-valid'); } else { setRestApiAddOn(); setRestApiAddOnClassName('key-invalid'); } }, () => { pendingKeysValidation = false; setRestApiAddOn(); setRestApiAddOnClassName('key-invalid'); }); } } /** * Assign the inputted key to the given settings */ const setApiKey = (setting: SettingName.PayZenUsername | SettingName.PayZenPassword | SettingName.PayZenEndpoint | SettingName.PayZenHmacKey) => { return (key: string) => { updateSettings(draft => draft.set(setting, key)); } } /** * Check if an add-on icon must be shown for the API settings */ const hasApiAddOn = () => { return restApiAddOn !== null; } return (
{t('app.admin.invoices.payment.client_keys')}
} value={settings.get(SettingName.PayZenPublicKey)} onChange={testPublicKey} addOn={publicKeyAddOn} addOnClassName={publicKeyAddOnClassName} debounce={200} required />
{t('app.admin.invoices.payment.api_keys')} {hasApiAddOn() && {restApiAddOn}}
} value={settings.get(SettingName.PayZenUsername)} onChange={setApiKey(SettingName.PayZenUsername)} debounce={200} required />
} value={settings.get(SettingName.PayZenPassword)} onChange={setApiKey(SettingName.PayZenPassword)} debounce={200} required />
} value={settings.get(SettingName.PayZenEndpoint)} onChange={setApiKey(SettingName.PayZenEndpoint)} debounce={200} required />
} value={settings.get(SettingName.PayZenHmacKey)} onChange={setApiKey(SettingName.PayZenHmacKey)} debounce={200} required />
); } export const PayZenKeysForm: React.FC = ({ onValidKeys }) => { return ( ); }