1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-29 18:52:22 +01:00

payzen keys configuration form

This commit is contained in:
Sylvain 2021-03-31 16:03:51 +02:00
parent 1d42fa8781
commit 54c1a3cfd9
12 changed files with 255 additions and 4 deletions

View File

@ -2,6 +2,7 @@
## Next release
- [TODO DEPLOY] `rails fablab:stripe:set_gateway`
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
## v4.7.7 (pending)
- Enforced validation on required input fields

View File

@ -27,7 +27,9 @@ export const FabInput: React.FC<FabInputProps> = ({ id, onChange, value, icon, c
useEffect(() => {
setInputValue(value);
onChange(value);
if (value) {
onChange(value);
}
}, [value]);
/**

View File

@ -0,0 +1,159 @@
/**
* 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';
interface PayZenKeysFormProps {
onValidKeys: (payZenSettings: Map<SettingName, string>) => void
}
const payZenSettings = [SettingName.PayZenUsername, SettingName.PayZenPassword, SettingName.PayZenEndpoint, SettingName.PayZenHmacKey, SettingName.PayZenPublicKey];
const payZenKeys = SettingAPI.query(payZenSettings);
const PayZenKeysFormComponent: React.FC<PayZenKeysFormProps> = ({ onValidKeys }) => {
const { t } = useTranslation('admin');
const defaultSettings: [SettingName, string][] = payZenSettings.map(name => [name, '']);
const [settings, setSettings] = useState<Map<SettingName, string>>(new Map(defaultSettings));
const [restApiAddOn, setRestApiAddOn] = useState<ReactNode>(null);
const [restApiAddOnClassName, setRestApiAddOnClassName] = useState<string>('');
const [publicKeyAddOn, setPublicKeyAddOn] = useState<ReactNode>(null);
const [publicKeyAddOnClassName, setPublicKeyAddOnClassName] = useState<string>('');
useEffect(() => {
setSettings(payZenKeys.read());
}, []);
useEffect(() => {
const validClassName = 'key-valid';
if (publicKeyAddOnClassName === validClassName && restApiAddOnClassName === validClassName) {
onValidKeys(settings);
}
}, [publicKeyAddOnClassName, restApiAddOnClassName]);
/**
* Check if the inputted public key is valid and assign it to the settings if the key is valid
*/
const testPublicKey = (key: string) => {
if (!key.match(/^[0-9]+:/)) {
setPublicKeyAddOn(<i className="fa fa-times" />);
setPublicKeyAddOnClassName('key-invalid');
return;
}
setSettings(new Map(settings).set(SettingName.PayZenPublicKey, key));
setPublicKeyAddOn(<i className="fa fa-check" />);
setPublicKeyAddOnClassName('key-valid');
}
/**
* Send a test call to the payZen REST API to check if the inputted settings key are valid
*/
const testRestApi = (setting: SettingName.PayZenUsername | SettingName.PayZenPassword | SettingName.PayZenEndpoint | SettingName.PayZenHmacKey) => {
return (key: string) => {
// if (!key.match(/^sk_/)) {
setRestApiAddOn(<i className="fa fa-times" />);
setRestApiAddOnClassName('key-invalid');
return;
// }
// StripeAPI.listAllCharges(key).then(() => {
// setSecretKey(key);
// setSecretKeyAddOn(<i className="fa fa-check" />);
// setSecretKeyAddOnClassName('key-valid');
// }, reason => {
// if (reason.response.status === 401) {
// setSecretKeyAddOn(<i className="fa fa-times" />);
// setSecretKeyAddOnClassName('key-invalid');
// }
// });
};
}
/**
* Check if an add-on icon must be shown for the API settings
*/
const hasApiAddOn = () => {
return restApiAddOn !== null;
}
return (
<div className="payzen-keys-form">
<div className="payzen-keys-info" dangerouslySetInnerHTML={{__html: t('app.admin.invoices.payment.payzen_keys_info_html')}} />
<form name="payzenKeysForm">
<fieldset>
<legend>{t('app.admin.invoices.payment.client_keys')}</legend>
<div className="payzen-public-input">
<label htmlFor="payzen_public_key">{ t('app.admin.invoices.payment.public_key') } *</label>
<FabInput id="payzen_public_key"
icon={<i className="fas fa-info" />}
value={settings.get(SettingName.PayZenPublicKey)}
onChange={testPublicKey}
addOn={publicKeyAddOn}
addOnClassName={publicKeyAddOnClassName}
debounce={200}
required />
</div>
</fieldset>
<fieldset>
<legend className={hasApiAddOn() ? 'with-addon' : ''}>
<span>{t('app.admin.invoices.payment.api_keys')}</span>
{hasApiAddOn() && <span className={`fieldset-legend--addon ${restApiAddOnClassName ? restApiAddOnClassName : ''}`}>{restApiAddOn}</span>}
</legend>
<div className="payzen-api-user-input">
<label htmlFor="payzen_username">{ t('app.admin.invoices.payment.username') } *</label>
<FabInput id="payzen_username"
type="number"
icon={<i className="fas fa-user-alt" />}
value={settings.get(SettingName.PayZenUsername)}
onChange={testRestApi(SettingName.PayZenUsername)}
debounce={200}
required />
</div>
<div className="payzen-api-password-input">
<label htmlFor="payzen_password">{ t('app.admin.invoices.payment.password') } *</label>
<FabInput id="payzen_password"
icon={<i className="fas fa-key" />}
value={settings.get(SettingName.PayZenPassword)}
onChange={testRestApi(SettingName.PayZenPassword)}
debounce={200}
required />
</div>
<div className="payzen-api-endpoint-input">
<label htmlFor="payzen_endpoint">{ t('app.admin.invoices.payment.endpoint') } *</label>
<FabInput id="payzen_endpoint"
type="url"
icon={<i className="fas fa-anchor" />}
value={settings.get(SettingName.PayZenEndpoint)}
onChange={testRestApi(SettingName.PayZenEndpoint)}
debounce={200}
required />
</div>
<div className="payzen-api-hmac-input">
<label htmlFor="payzen_hmac">{ t('app.admin.invoices.payment.hmac') } *</label>
<FabInput id="payzen_hmac"
icon={<i className="fas fa-subscript" />}
value={settings.get(SettingName.PayZenHmacKey)}
onChange={testRestApi(SettingName.PayZenHmacKey)}
debounce={200}
required />
</div>
</fieldset>
</form>
</div>
);
}
export const PayZenKeysForm: React.FC<PayZenKeysFormProps> = ({ onValidKeys }) => {
return (
<Loader>
<PayZenKeysFormComponent onValidKeys={onValidKeys} />
</Loader>
);
}

View File

@ -14,6 +14,7 @@ import { Gateway } from '../models/gateway';
import { StripeKeysForm } from './stripe-keys-form';
import { SettingBulkResult, SettingName } from '../models/setting';
import SettingAPI from '../api/setting';
import { PayZenKeysForm } from './payzen-keys-form';
declare var Application: IApplication;
@ -116,6 +117,7 @@ const SelectGatewayModal: React.FC<SelectGatewayModalModalProps> = ({ isOpen, to
<option value={Gateway.PayZen}>{t('app.admin.invoices.payment.gateway_modal.payzen')}</option>
</select>
{selectedGateway === Gateway.Stripe && <StripeKeysForm onValidKeys={handleValidStripeKeys} />}
{selectedGateway === Gateway.PayZen && <PayZenKeysForm onValidKeys={handleValidStripeKeys} />}
</FabModal>
);
};

View File

@ -2,7 +2,7 @@
* Form to set the stripe's public and private keys
*/
import React, { BaseSyntheticEvent, ReactNode, useEffect, useState } from 'react';
import React, { ReactNode, useEffect, useState } from 'react';
import { Loader } from './loader';
import { useTranslation } from 'react-i18next';
import SettingAPI from '../api/setting';

View File

@ -102,7 +102,12 @@ export enum SettingName {
PaymentSchedulePrefix = 'payment_schedule_prefix',
TrainingsModule = 'trainings_module',
AddressRequired = 'address_required',
PaymentGateway = 'payment_gateway'
PaymentGateway = 'payment_gateway',
PayZenUsername = 'payzen_username',
PayZenPassword = 'payzen_password',
PayZenEndpoint = 'payzen_endpoint',
PayZenPublicKey = 'payzen_public_key',
PayZenHmacKey = 'payzen_hmac'
}
export interface Setting {

View File

@ -36,5 +36,6 @@
@import "modules/plan-card";
@import "modules/select-gateway-modal";
@import "modules/stripe-keys-form";
@import "modules/payzen-keys-form";
@import "app.responsive";

View File

@ -0,0 +1,55 @@
.payzen-keys-form {
& {
margin-top: 1em;
}
.payzen-keys-info {
border: 1px solid #bce8f1;
border-radius: 4px;
color: #31708f;
background-color: #d9edf7;
padding: 15px;
}
fieldset {
border: 1px solid #c4c4c4;
border-radius: 4px;
margin-top: 1em;
padding: 7px;
& > legend {
padding: 3px 6px;
width: fit-content;
font-size: 1em;
border-radius: 4px;
margin-left: 1em;
margin-bottom: 0;
position: relative;
&.with-addon {
border-radius: 4px 0 0 4px;;
}
}
.fieldset-legend--addon {
display: block;
position: absolute;
top: 0;
right: -35px;
font-size: 1em;
padding: 3px 12px;
font-weight: 400;
text-align: center;
border-radius: 0 4px 4px 0;
vertical-align: middle;
}
}
.key-valid {
background-color: #7bca38;
}
.key-invalid {
background-color: #d92227;
color: white;
}
}

View File

@ -110,7 +110,12 @@ class Setting < ApplicationRecord
payment_schedule_prefix
trainings_module
address_required
payment_gateway] }
payment_gateway
payzen_username
payzen_password
payzen_endpoint
payzen_public_key
payzen_hmac] }
# WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist
def value

View File

@ -349,3 +349,10 @@ section#cookies-modal div.cookies-consent .cookies-actions button.accept {
}
}
}
.payzen-keys-form {
fieldset > legend {
background-color: $secondary;
color: $secondary-text-color;
}
}

View File

@ -638,6 +638,13 @@ en:
error_check_keys: "Error: please check your Stripe keys."
stripe_keys_saved: "Stripe keys successfully saved."
error_saving_stripe_keys: "Unable to save the Stripe keys. Please try again later."
payzen_keys_info_html: "<p>To be able to collect online payments, you must configure the <a href='https://payzen.eu' target='_blank'>PayZen</a> identifiers and keys.</p><p>Retrieve them from <a href='https://secure.payzen.eu/vads-merchant/' target='_blank'>your merchant back office</a>.</p>"
client_keys: "Client keys"
api_keys: "API keys"
username: "User"
password: "Password"
endpoint: "REST API server name"
hmac: "HMAC-SHA-256 key"
edit_keys: "Edit keys"
currency: "Currency"
currency_info_html: "Please specify below the currency used for online payment. You should provide a three-letter ISO code, from the list of <a href='https://stripe.com/docs/currencies' target='_blank'>Stripe supported currencies</a>."

View File

@ -638,6 +638,13 @@ fr:
error_check_keys: "Erreur : veuillez vérifier vos clefs Stripe."
stripe_keys_saved: "Les clefs Stripe ont bien été enregistrées."
error_saving_stripe_keys: "Impossible denregistrer les clefs Stripe. Veuillez réessayer ultérieurement."
payzen_keys_info_html: "<p>Pour pouvoir encaisser des paiements en ligne, vous devez configurer les identifiants et les clefs <a href='https://payzen.eu' target='_blank'>PayZen</a>.</p><p>Retrouvez les dans <a href='https://secure.payzen.eu/vads-merchant/' target='_blank'>votre back office marchant</a>.</p>"
client_keys: "Clefs client"
api_keys: "Clefs d'API"
username: "Utilisateur"
password: "Mot de passe"
endpoint: "Nom du serveur de l'API REST"
hmac: "Clef HMAC-SHA-256"
edit_keys: "Modifier les clefs"
currency: "Devise"
currency_info_html: "Veuillez indiquer la devise à utiliser lors des paiements en ligne. Vous devez fournir un code ISO à trois lettres, issu de la liste des <a href='https://stripe.com/docs/currencies' target='_blank'>devises supportées par Stripe</a>."