show simple order creation unless advance mode is selected
This commit is contained in:
parent
ef148b1501
commit
7d53aa2755
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2021-2023 Taler Systems S.A.
|
||||||
|
|
||||||
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sebastian Javier Marchano (sebasjm)
|
||||||
|
*/
|
||||||
|
import { h, VNode } from "preact";
|
||||||
|
import { InputProps, useField } from "./useField.js";
|
||||||
|
|
||||||
|
interface Props<T> extends InputProps<T> {
|
||||||
|
name: T;
|
||||||
|
readonly?: boolean;
|
||||||
|
expand?: boolean;
|
||||||
|
threeState?: boolean;
|
||||||
|
toBoolean?: (v?: any) => boolean | undefined;
|
||||||
|
fromBoolean?: (s: boolean | undefined) => any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultToBoolean = (f?: any): boolean | undefined => f || "";
|
||||||
|
const defaultFromBoolean = (v: boolean | undefined): any => v as any;
|
||||||
|
|
||||||
|
export function InputToggle<T>({
|
||||||
|
name,
|
||||||
|
readonly,
|
||||||
|
placeholder,
|
||||||
|
tooltip,
|
||||||
|
label,
|
||||||
|
help,
|
||||||
|
threeState,
|
||||||
|
expand,
|
||||||
|
fromBoolean = defaultFromBoolean,
|
||||||
|
toBoolean = defaultToBoolean,
|
||||||
|
}: Props<keyof T>): VNode {
|
||||||
|
const { error, value, onChange } = useField<T>(name);
|
||||||
|
|
||||||
|
const onCheckboxClick = (): void => {
|
||||||
|
const c = toBoolean(value);
|
||||||
|
if (c === false && threeState) return onChange(undefined as any);
|
||||||
|
return onChange(fromBoolean(!c));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label is-normal">
|
||||||
|
<label class="label" style={{ width: 200 }}>
|
||||||
|
{label}
|
||||||
|
{tooltip && (
|
||||||
|
<span class="icon has-tooltip-right" data-tooltip={tooltip}>
|
||||||
|
<i class="mdi mdi-information" />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body is-flex-grow-1">
|
||||||
|
<div class="field">
|
||||||
|
<p class={expand ? "control is-expanded" : "control"}>
|
||||||
|
<label class="toggle" style={{ marginLeft: 4, marginTop: 0 }}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class={toBoolean(value) === undefined ? "is-indeterminate" : "toggle-checkbox"}
|
||||||
|
checked={toBoolean(value)}
|
||||||
|
placeholder={placeholder}
|
||||||
|
readonly={readonly}
|
||||||
|
name={String(name)}
|
||||||
|
disabled={readonly}
|
||||||
|
onChange={onCheckboxClick}
|
||||||
|
/>
|
||||||
|
<div class="toggle-switch"></div>
|
||||||
|
</label>
|
||||||
|
{help}
|
||||||
|
</p>
|
||||||
|
{error && <p class="help is-danger">{error}</p>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -53,15 +53,17 @@ export function useBackendURL(
|
|||||||
|
|
||||||
export function useBackendDefaultToken(
|
export function useBackendDefaultToken(
|
||||||
initialValue?: string,
|
initialValue?: string,
|
||||||
): [string | undefined, ((d:string | undefined) => void)] {
|
): [string | undefined, ((d: string | undefined) => void)] {
|
||||||
const {update, value} = useMemoryStorage(`backend-token`, initialValue)
|
// uncomment for testing
|
||||||
|
initialValue = "secret-token:secret" as string | undefined
|
||||||
|
const { update, value } = useMemoryStorage(`backend-token`, initialValue)
|
||||||
return [value, update];
|
return [value, update];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useBackendInstanceToken(
|
export function useBackendInstanceToken(
|
||||||
id: string,
|
id: string,
|
||||||
): [string | undefined, ((d:string | undefined) => void)] {
|
): [string | undefined, ((d: string | undefined) => void)] {
|
||||||
const {update:setToken, value:token, reset} = useMemoryStorage(`backend-token-${id}`)
|
const { update: setToken, value: token, reset } = useMemoryStorage(`backend-token-${id}`)
|
||||||
const [defaultToken, defaultSetToken] = useBackendDefaultToken();
|
const [defaultToken, defaultSetToken] = useBackendDefaultToken();
|
||||||
|
|
||||||
// instance named 'default' use the default token
|
// instance named 'default' use the default token
|
||||||
|
59
packages/merchant-backoffice-ui/src/hooks/useSettings.ts
Normal file
59
packages/merchant-backoffice-ui/src/hooks/useSettings.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
This file is part of GNU Taler
|
||||||
|
(C) 2022 Taler Systems S.A.
|
||||||
|
|
||||||
|
GNU Taler is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
|
||||||
|
import {
|
||||||
|
Codec,
|
||||||
|
buildCodecForObject,
|
||||||
|
codecForBoolean,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
|
function parse_json_or_undefined<T>(str: string | undefined): T | undefined {
|
||||||
|
if (str === undefined) return undefined;
|
||||||
|
try {
|
||||||
|
return JSON.parse(str);
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Settings {
|
||||||
|
advanceOrderMode: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultSettings: Settings = {
|
||||||
|
advanceOrderMode: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const codecForSettings = (): Codec<Settings> =>
|
||||||
|
buildCodecForObject<Settings>()
|
||||||
|
.property("advanceOrderMode", codecForBoolean())
|
||||||
|
.build("Settings");
|
||||||
|
|
||||||
|
const SETTINGS_KEY = buildStorageKey("merchant-settings", codecForSettings());
|
||||||
|
|
||||||
|
export function useSettings(): [
|
||||||
|
Readonly<Settings>,
|
||||||
|
<T extends keyof Settings>(key: T, value: Settings[T]) => void,
|
||||||
|
] {
|
||||||
|
const { value, update } = useLocalStorage(SETTINGS_KEY);
|
||||||
|
|
||||||
|
const parsed: Settings = value ?? defaultSettings;
|
||||||
|
function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
|
||||||
|
update({ ...parsed, [k]: v });
|
||||||
|
}
|
||||||
|
return [parsed, updateField];
|
||||||
|
}
|
@ -43,6 +43,7 @@ import { Duration, MerchantBackend, WithId } from "../../../../declaration.js";
|
|||||||
import { OrderCreateSchema as schema } from "../../../../schemas/index.js";
|
import { OrderCreateSchema as schema } from "../../../../schemas/index.js";
|
||||||
import { rate } from "../../../../utils/amount.js";
|
import { rate } from "../../../../utils/amount.js";
|
||||||
import { undefinedIfEmpty } from "../../../../utils/table.js";
|
import { undefinedIfEmpty } from "../../../../utils/table.js";
|
||||||
|
import { useSettings } from "../../../../hooks/useSettings.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
|
onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
|
||||||
@ -62,8 +63,8 @@ function with_defaults(config: InstanceConfig): Partial<Entity> {
|
|||||||
!config.default_pay_delay || config.default_pay_delay.d_us === "forever"
|
!config.default_pay_delay || config.default_pay_delay.d_us === "forever"
|
||||||
? undefined
|
? undefined
|
||||||
: add(new Date(), {
|
: add(new Date(), {
|
||||||
seconds: config.default_pay_delay.d_us / (1000 * 1000),
|
seconds: config.default_pay_delay.d_us / (1000 * 1000),
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
inventoryProducts: {},
|
inventoryProducts: {},
|
||||||
@ -138,7 +139,7 @@ export function CreatePage({
|
|||||||
const [value, valueHandler] = useState(with_defaults(instanceConfig));
|
const [value, valueHandler] = useState(with_defaults(instanceConfig));
|
||||||
const config = useConfigContext();
|
const config = useConfigContext();
|
||||||
const zero = Amounts.zeroOfCurrency(config.currency);
|
const zero = Amounts.zeroOfCurrency(config.currency);
|
||||||
|
const [settings] = useSettings()
|
||||||
const inventoryList = Object.values(value.inventoryProducts || {});
|
const inventoryList = Object.values(value.inventoryProducts || {});
|
||||||
const productList = Object.values(value.products || {});
|
const productList = Object.values(value.products || {});
|
||||||
|
|
||||||
@ -154,10 +155,10 @@ export function CreatePage({
|
|||||||
order_price: !value.pricing?.order_price
|
order_price: !value.pricing?.order_price
|
||||||
? i18n.str`required`
|
? i18n.str`required`
|
||||||
: !parsedPrice
|
: !parsedPrice
|
||||||
? i18n.str`not valid`
|
? i18n.str`not valid`
|
||||||
: Amounts.isZero(parsedPrice)
|
: Amounts.isZero(parsedPrice)
|
||||||
? i18n.str`must be greater than 0`
|
? i18n.str`must be greater than 0`
|
||||||
: undefined,
|
: undefined,
|
||||||
}),
|
}),
|
||||||
extra:
|
extra:
|
||||||
value.extra && !stringIsValidJSON(value.extra)
|
value.extra && !stringIsValidJSON(value.extra)
|
||||||
@ -167,47 +168,47 @@ export function CreatePage({
|
|||||||
refund_deadline: !value.payments?.refund_deadline
|
refund_deadline: !value.payments?.refund_deadline
|
||||||
? undefined
|
? undefined
|
||||||
: !isFuture(value.payments.refund_deadline)
|
: !isFuture(value.payments.refund_deadline)
|
||||||
? i18n.str`should be in the future`
|
? i18n.str`should be in the future`
|
||||||
: value.payments.pay_deadline &&
|
: value.payments.pay_deadline &&
|
||||||
isBefore(value.payments.refund_deadline, value.payments.pay_deadline)
|
isBefore(value.payments.refund_deadline, value.payments.pay_deadline)
|
||||||
? i18n.str`refund deadline cannot be before pay deadline`
|
? i18n.str`refund deadline cannot be before pay deadline`
|
||||||
: value.payments.wire_transfer_deadline &&
|
: value.payments.wire_transfer_deadline &&
|
||||||
isBefore(
|
isBefore(
|
||||||
value.payments.wire_transfer_deadline,
|
value.payments.wire_transfer_deadline,
|
||||||
value.payments.refund_deadline,
|
value.payments.refund_deadline,
|
||||||
)
|
)
|
||||||
? i18n.str`wire transfer deadline cannot be before refund deadline`
|
? i18n.str`wire transfer deadline cannot be before refund deadline`
|
||||||
: undefined,
|
: undefined,
|
||||||
pay_deadline: !value.payments?.pay_deadline
|
pay_deadline: !value.payments?.pay_deadline
|
||||||
? undefined
|
? undefined
|
||||||
: !isFuture(value.payments.pay_deadline)
|
: !isFuture(value.payments.pay_deadline)
|
||||||
? i18n.str`should be in the future`
|
? i18n.str`should be in the future`
|
||||||
: value.payments.wire_transfer_deadline &&
|
: value.payments.wire_transfer_deadline &&
|
||||||
isBefore(
|
isBefore(
|
||||||
value.payments.wire_transfer_deadline,
|
value.payments.wire_transfer_deadline,
|
||||||
value.payments.pay_deadline,
|
value.payments.pay_deadline,
|
||||||
)
|
)
|
||||||
? i18n.str`wire transfer deadline cannot be before pay deadline`
|
? i18n.str`wire transfer deadline cannot be before pay deadline`
|
||||||
: undefined,
|
: undefined,
|
||||||
auto_refund_deadline: !value.payments?.auto_refund_deadline
|
auto_refund_deadline: !value.payments?.auto_refund_deadline
|
||||||
? undefined
|
? undefined
|
||||||
: !isFuture(value.payments.auto_refund_deadline)
|
: !isFuture(value.payments.auto_refund_deadline)
|
||||||
? i18n.str`should be in the future`
|
? i18n.str`should be in the future`
|
||||||
: !value.payments?.refund_deadline
|
: !value.payments?.refund_deadline
|
||||||
? i18n.str`should have a refund deadline`
|
? i18n.str`should have a refund deadline`
|
||||||
: !isAfter(
|
: !isAfter(
|
||||||
value.payments.refund_deadline,
|
value.payments.refund_deadline,
|
||||||
value.payments.auto_refund_deadline,
|
value.payments.auto_refund_deadline,
|
||||||
)
|
)
|
||||||
? i18n.str`auto refund cannot be after refund deadline`
|
? i18n.str`auto refund cannot be after refund deadline`
|
||||||
: undefined,
|
: undefined,
|
||||||
}),
|
}),
|
||||||
shipping: undefinedIfEmpty({
|
shipping: undefinedIfEmpty({
|
||||||
delivery_date: !value.shipping?.delivery_date
|
delivery_date: !value.shipping?.delivery_date
|
||||||
? undefined
|
? undefined
|
||||||
: !isFuture(value.shipping.delivery_date)
|
: !isFuture(value.shipping.delivery_date)
|
||||||
? i18n.str`should be in the future`
|
? i18n.str`should be in the future`
|
||||||
: undefined,
|
: undefined,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
const hasErrors = Object.keys(errors).some(
|
const hasErrors = Object.keys(errors).some(
|
||||||
@ -227,27 +228,27 @@ export function CreatePage({
|
|||||||
extra: value.extra,
|
extra: value.extra,
|
||||||
pay_deadline: value.payments.pay_deadline
|
pay_deadline: value.payments.pay_deadline
|
||||||
? {
|
? {
|
||||||
t_s: Math.floor(value.payments.pay_deadline.getTime() / 1000),
|
t_s: Math.floor(value.payments.pay_deadline.getTime() / 1000),
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
wire_transfer_deadline: value.payments.wire_transfer_deadline
|
wire_transfer_deadline: value.payments.wire_transfer_deadline
|
||||||
? {
|
? {
|
||||||
t_s: Math.floor(
|
t_s: Math.floor(
|
||||||
value.payments.wire_transfer_deadline.getTime() / 1000,
|
value.payments.wire_transfer_deadline.getTime() / 1000,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
refund_deadline: value.payments.refund_deadline
|
refund_deadline: value.payments.refund_deadline
|
||||||
? {
|
? {
|
||||||
t_s: Math.floor(value.payments.refund_deadline.getTime() / 1000),
|
t_s: Math.floor(value.payments.refund_deadline.getTime() / 1000),
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
auto_refund: value.payments.auto_refund_deadline
|
auto_refund: value.payments.auto_refund_deadline
|
||||||
? {
|
? {
|
||||||
d_us: Math.floor(
|
d_us: Math.floor(
|
||||||
value.payments.auto_refund_deadline.getTime() * 1000,
|
value.payments.auto_refund_deadline.getTime() * 1000,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
wire_fee_amortization: value.payments.wire_fee_amortization as number,
|
wire_fee_amortization: value.payments.wire_fee_amortization as number,
|
||||||
max_fee: value.payments.max_fee as string,
|
max_fee: value.payments.max_fee as string,
|
||||||
@ -374,13 +375,15 @@ export function CreatePage({
|
|||||||
inventory={instanceInventory}
|
inventory={instanceInventory}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<NonInventoryProductFrom
|
{settings.advanceOrderMode &&
|
||||||
productToEdit={editingProduct}
|
<NonInventoryProductFrom
|
||||||
onAddProduct={(p) => {
|
productToEdit={editingProduct}
|
||||||
setEditingProduct(undefined);
|
onAddProduct={(p) => {
|
||||||
return addNewProduct(p);
|
setEditingProduct(undefined);
|
||||||
}}
|
return addNewProduct(p);
|
||||||
/>
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
{allProducts.length > 0 && (
|
{allProducts.length > 0 && (
|
||||||
<ProductList
|
<ProductList
|
||||||
@ -423,8 +426,8 @@ export function CreatePage({
|
|||||||
discountOrRise > 0 &&
|
discountOrRise > 0 &&
|
||||||
(discountOrRise < 1
|
(discountOrRise < 1
|
||||||
? `discount of %${Math.round(
|
? `discount of %${Math.round(
|
||||||
(1 - discountOrRise) * 100,
|
(1 - discountOrRise) * 100,
|
||||||
)}`
|
)}`
|
||||||
: `rise of %${Math.round((discountOrRise - 1) * 100)}`)
|
: `rise of %${Math.round((discountOrRise - 1) * 100)}`)
|
||||||
}
|
}
|
||||||
tooltip={i18n.str`Amount to be paid by the customer`}
|
tooltip={i18n.str`Amount to be paid by the customer`}
|
||||||
@ -445,102 +448,108 @@ export function CreatePage({
|
|||||||
tooltip={i18n.str`Title of the order to be shown to the customer`}
|
tooltip={i18n.str`Title of the order to be shown to the customer`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InputGroup
|
{settings.advanceOrderMode &&
|
||||||
name="shipping"
|
<InputGroup
|
||||||
label={i18n.str`Shipping and Fulfillment`}
|
name="shipping"
|
||||||
initialActive
|
label={i18n.str`Shipping and Fulfillment`}
|
||||||
>
|
initialActive
|
||||||
<InputDate
|
>
|
||||||
name="shipping.delivery_date"
|
<InputDate
|
||||||
label={i18n.str`Delivery date`}
|
name="shipping.delivery_date"
|
||||||
tooltip={i18n.str`Deadline for physical delivery assured by the merchant.`}
|
label={i18n.str`Delivery date`}
|
||||||
/>
|
tooltip={i18n.str`Deadline for physical delivery assured by the merchant.`}
|
||||||
{value.shipping?.delivery_date && (
|
/>
|
||||||
<InputGroup
|
{value.shipping?.delivery_date && (
|
||||||
name="shipping.delivery_location"
|
<InputGroup
|
||||||
label={i18n.str`Location`}
|
name="shipping.delivery_location"
|
||||||
tooltip={i18n.str`address where the products will be delivered`}
|
label={i18n.str`Location`}
|
||||||
>
|
tooltip={i18n.str`address where the products will be delivered`}
|
||||||
<InputLocation name="shipping.delivery_location" />
|
>
|
||||||
</InputGroup>
|
<InputLocation name="shipping.delivery_location" />
|
||||||
)}
|
</InputGroup>
|
||||||
<Input
|
)}
|
||||||
name="shipping.fullfilment_url"
|
<Input
|
||||||
label={i18n.str`Fulfillment URL`}
|
name="shipping.fullfilment_url"
|
||||||
tooltip={i18n.str`URL to which the user will be redirected after successful payment.`}
|
label={i18n.str`Fulfillment URL`}
|
||||||
/>
|
tooltip={i18n.str`URL to which the user will be redirected after successful payment.`}
|
||||||
</InputGroup>
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
}
|
||||||
|
|
||||||
<InputGroup
|
{settings.advanceOrderMode &&
|
||||||
name="payments"
|
<InputGroup
|
||||||
label={i18n.str`Taler payment options`}
|
name="payments"
|
||||||
tooltip={i18n.str`Override default Taler payment settings for this order`}
|
label={i18n.str`Taler payment options`}
|
||||||
>
|
tooltip={i18n.str`Override default Taler payment settings for this order`}
|
||||||
<InputDate
|
>
|
||||||
name="payments.pay_deadline"
|
<InputDate
|
||||||
label={i18n.str`Payment deadline`}
|
name="payments.pay_deadline"
|
||||||
tooltip={i18n.str`Deadline for the customer to pay for the offer before it expires. Inventory products will be reserved until this deadline.`}
|
label={i18n.str`Payment deadline`}
|
||||||
/>
|
tooltip={i18n.str`Deadline for the customer to pay for the offer before it expires. Inventory products will be reserved until this deadline.`}
|
||||||
<InputDate
|
/>
|
||||||
name="payments.refund_deadline"
|
<InputDate
|
||||||
label={i18n.str`Refund deadline`}
|
name="payments.refund_deadline"
|
||||||
tooltip={i18n.str`Time until which the order can be refunded by the merchant.`}
|
label={i18n.str`Refund deadline`}
|
||||||
/>
|
tooltip={i18n.str`Time until which the order can be refunded by the merchant.`}
|
||||||
<InputDate
|
/>
|
||||||
name="payments.wire_transfer_deadline"
|
<InputDate
|
||||||
label={i18n.str`Wire transfer deadline`}
|
name="payments.wire_transfer_deadline"
|
||||||
tooltip={i18n.str`Deadline for the exchange to make the wire transfer.`}
|
label={i18n.str`Wire transfer deadline`}
|
||||||
/>
|
tooltip={i18n.str`Deadline for the exchange to make the wire transfer.`}
|
||||||
<InputDate
|
/>
|
||||||
name="payments.auto_refund_deadline"
|
<InputDate
|
||||||
label={i18n.str`Auto-refund deadline`}
|
name="payments.auto_refund_deadline"
|
||||||
tooltip={i18n.str`Time until which the wallet will automatically check for refunds without user interaction.`}
|
label={i18n.str`Auto-refund deadline`}
|
||||||
/>
|
tooltip={i18n.str`Time until which the wallet will automatically check for refunds without user interaction.`}
|
||||||
|
/>
|
||||||
|
|
||||||
<InputCurrency
|
<InputCurrency
|
||||||
name="payments.max_fee"
|
name="payments.max_fee"
|
||||||
label={i18n.str`Maximum deposit fee`}
|
label={i18n.str`Maximum deposit fee`}
|
||||||
tooltip={i18n.str`Maximum deposit fees the merchant is willing to cover for this order. Higher deposit fees must be covered in full by the consumer.`}
|
tooltip={i18n.str`Maximum deposit fees the merchant is willing to cover for this order. Higher deposit fees must be covered in full by the consumer.`}
|
||||||
/>
|
/>
|
||||||
<InputCurrency
|
<InputCurrency
|
||||||
name="payments.max_wire_fee"
|
name="payments.max_wire_fee"
|
||||||
label={i18n.str`Maximum wire fee`}
|
label={i18n.str`Maximum wire fee`}
|
||||||
tooltip={i18n.str`Maximum aggregate wire fees the merchant is willing to cover for this order. Wire fees exceeding this amount are to be covered by the customers.`}
|
tooltip={i18n.str`Maximum aggregate wire fees the merchant is willing to cover for this order. Wire fees exceeding this amount are to be covered by the customers.`}
|
||||||
/>
|
/>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
name="payments.wire_fee_amortization"
|
name="payments.wire_fee_amortization"
|
||||||
label={i18n.str`Wire fee amortization`}
|
label={i18n.str`Wire fee amortization`}
|
||||||
tooltip={i18n.str`Factor by which wire fees exceeding the above threshold are divided to determine the share of excess wire fees to be paid explicitly by the consumer.`}
|
tooltip={i18n.str`Factor by which wire fees exceeding the above threshold are divided to determine the share of excess wire fees to be paid explicitly by the consumer.`}
|
||||||
/>
|
/>
|
||||||
<InputBoolean
|
<InputBoolean
|
||||||
name="payments.createToken"
|
name="payments.createToken"
|
||||||
label={i18n.str`Create token`}
|
label={i18n.str`Create token`}
|
||||||
tooltip={i18n.str`Uncheck this option if the merchant backend generated an order ID with enough entropy to prevent adversarial claims.`}
|
tooltip={i18n.str`Uncheck this option if the merchant backend generated an order ID with enough entropy to prevent adversarial claims.`}
|
||||||
/>
|
/>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
name="payments.minimum_age"
|
name="payments.minimum_age"
|
||||||
label={i18n.str`Minimum age required`}
|
label={i18n.str`Minimum age required`}
|
||||||
tooltip={i18n.str`Any value greater than 0 will limit the coins able be used to pay this contract. If empty the age restriction will be defined by the products`}
|
tooltip={i18n.str`Any value greater than 0 will limit the coins able be used to pay this contract. If empty the age restriction will be defined by the products`}
|
||||||
help={
|
help={
|
||||||
minAgeByProducts > 0
|
minAgeByProducts > 0
|
||||||
? i18n.str`Min age defined by the producs is ${minAgeByProducts}`
|
? i18n.str`Min age defined by the producs is ${minAgeByProducts}`
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
}
|
||||||
|
|
||||||
<InputGroup
|
{settings.advanceOrderMode &&
|
||||||
name="extra"
|
<InputGroup
|
||||||
label={i18n.str`Additional information`}
|
|
||||||
tooltip={i18n.str`Custom information to be included in the contract for this order.`}
|
|
||||||
>
|
|
||||||
<Input
|
|
||||||
name="extra"
|
name="extra"
|
||||||
inputType="multiline"
|
label={i18n.str`Additional information`}
|
||||||
label={`Value`}
|
tooltip={i18n.str`Custom information to be included in the contract for this order.`}
|
||||||
tooltip={i18n.str`You must enter a value in JavaScript Object Notation (JSON).`}
|
>
|
||||||
/>
|
<Input
|
||||||
</InputGroup>
|
name="extra"
|
||||||
|
inputType="multiline"
|
||||||
|
label={`Value`}
|
||||||
|
tooltip={i18n.str`You must enter a value in JavaScript Object Notation (JSON).`}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
}
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
|
|
||||||
<div class="buttons is-right mt-5">
|
<div class="buttons is-right mt-5">
|
||||||
|
Loading…
Reference in New Issue
Block a user