mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-06 01:08:21 +01:00
payzen keys configuration form
This commit is contained in:
parent
1d42fa8781
commit
54c1a3cfd9
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Next release
|
## Next release
|
||||||
- [TODO DEPLOY] `rails fablab:stripe:set_gateway`
|
- [TODO DEPLOY] `rails fablab:stripe:set_gateway`
|
||||||
|
- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet`
|
||||||
|
|
||||||
## v4.7.7 (pending)
|
## v4.7.7 (pending)
|
||||||
- Enforced validation on required input fields
|
- Enforced validation on required input fields
|
||||||
|
@ -27,7 +27,9 @@ export const FabInput: React.FC<FabInputProps> = ({ id, onChange, value, icon, c
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInputValue(value);
|
setInputValue(value);
|
||||||
onChange(value);
|
if (value) {
|
||||||
|
onChange(value);
|
||||||
|
}
|
||||||
}, [value]);
|
}, [value]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
159
app/frontend/src/javascript/components/payzen-keys-form.tsx
Normal file
159
app/frontend/src/javascript/components/payzen-keys-form.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
@ -14,6 +14,7 @@ import { Gateway } from '../models/gateway';
|
|||||||
import { StripeKeysForm } from './stripe-keys-form';
|
import { StripeKeysForm } from './stripe-keys-form';
|
||||||
import { SettingBulkResult, SettingName } from '../models/setting';
|
import { SettingBulkResult, SettingName } from '../models/setting';
|
||||||
import SettingAPI from '../api/setting';
|
import SettingAPI from '../api/setting';
|
||||||
|
import { PayZenKeysForm } from './payzen-keys-form';
|
||||||
|
|
||||||
|
|
||||||
declare var Application: IApplication;
|
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>
|
<option value={Gateway.PayZen}>{t('app.admin.invoices.payment.gateway_modal.payzen')}</option>
|
||||||
</select>
|
</select>
|
||||||
{selectedGateway === Gateway.Stripe && <StripeKeysForm onValidKeys={handleValidStripeKeys} />}
|
{selectedGateway === Gateway.Stripe && <StripeKeysForm onValidKeys={handleValidStripeKeys} />}
|
||||||
|
{selectedGateway === Gateway.PayZen && <PayZenKeysForm onValidKeys={handleValidStripeKeys} />}
|
||||||
</FabModal>
|
</FabModal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Form to set the stripe's public and private keys
|
* 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 { Loader } from './loader';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import SettingAPI from '../api/setting';
|
import SettingAPI from '../api/setting';
|
||||||
|
@ -102,7 +102,12 @@ export enum SettingName {
|
|||||||
PaymentSchedulePrefix = 'payment_schedule_prefix',
|
PaymentSchedulePrefix = 'payment_schedule_prefix',
|
||||||
TrainingsModule = 'trainings_module',
|
TrainingsModule = 'trainings_module',
|
||||||
AddressRequired = 'address_required',
|
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 {
|
export interface Setting {
|
||||||
|
@ -36,5 +36,6 @@
|
|||||||
@import "modules/plan-card";
|
@import "modules/plan-card";
|
||||||
@import "modules/select-gateway-modal";
|
@import "modules/select-gateway-modal";
|
||||||
@import "modules/stripe-keys-form";
|
@import "modules/stripe-keys-form";
|
||||||
|
@import "modules/payzen-keys-form";
|
||||||
|
|
||||||
@import "app.responsive";
|
@import "app.responsive";
|
||||||
|
55
app/frontend/src/stylesheets/modules/payzen-keys-form.scss
Normal file
55
app/frontend/src/stylesheets/modules/payzen-keys-form.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,12 @@ class Setting < ApplicationRecord
|
|||||||
payment_schedule_prefix
|
payment_schedule_prefix
|
||||||
trainings_module
|
trainings_module
|
||||||
address_required
|
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
|
# WARNING: when adding a new key, you may also want to add it in app/policies/setting_policy.rb#public_whitelist
|
||||||
|
|
||||||
def value
|
def value
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -638,6 +638,13 @@ en:
|
|||||||
error_check_keys: "Error: please check your Stripe keys."
|
error_check_keys: "Error: please check your Stripe keys."
|
||||||
stripe_keys_saved: "Stripe keys successfully saved."
|
stripe_keys_saved: "Stripe keys successfully saved."
|
||||||
error_saving_stripe_keys: "Unable to save the Stripe keys. Please try again later."
|
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"
|
edit_keys: "Edit keys"
|
||||||
currency: "Currency"
|
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>."
|
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>."
|
||||||
|
@ -638,6 +638,13 @@ fr:
|
|||||||
error_check_keys: "Erreur : veuillez vérifier vos clefs Stripe."
|
error_check_keys: "Erreur : veuillez vérifier vos clefs Stripe."
|
||||||
stripe_keys_saved: "Les clefs Stripe ont bien été enregistrées."
|
stripe_keys_saved: "Les clefs Stripe ont bien été enregistrées."
|
||||||
error_saving_stripe_keys: "Impossible d’enregistrer les clefs Stripe. Veuillez réessayer ultérieurement."
|
error_saving_stripe_keys: "Impossible d’enregistrer 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"
|
edit_keys: "Modifier les clefs"
|
||||||
currency: "Devise"
|
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>."
|
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>."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user