commit d3a94fe629cb55bfa5b0e11a524e8a85635bf4f6
parent 710df80b93ed13e2c1c84dceb44ac0ce7e0ea7f7
Author: Sebastian <sebasjm@taler-systems.com>
Date: Wed, 10 Dec 2025 12:01:10 -0300
fix #9148
Diffstat:
6 files changed, 125 insertions(+), 97 deletions(-)
diff --git a/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx b/packages/merchant-backoffice-ui/src/components/instance/DefaultInstanceFormFields.tsx
@@ -117,10 +117,17 @@ export function DefaultInstanceFormFields({
/>
<InputDuration<Entity>
+ name="default_refund_delay"
+ label={i18n.str`Default refund delay`}
+ tooltip={i18n.str`Time merchants have to refund an order.`}
+ />
+
+ <InputDuration<Entity>
name="default_wire_transfer_delay"
label={i18n.str`Default wire transfer delay`}
tooltip={i18n.str`Maximum time an exchange is allowed to delay wiring funds to the merchant, enabling it to aggregate smaller payments into larger wire transfers and reducing wire fees.`}
/>
+
<InputSelector<Entity>
name="default_wire_transfer_rounding_interval"
label={i18n.str`Default wire transfer rounding interval`}
@@ -137,26 +144,26 @@ export function DefaultInstanceFormFields({
RoundingInterval.YEAR,
RoundingInterval.NONE,
]}
- toStr={(v:RoundingInterval) => {
- switch(v) {
+ toStr={(v: RoundingInterval) => {
+ switch (v) {
case RoundingInterval.NONE:
- return i18n.str`No rounding`
+ return i18n.str`No rounding`;
case RoundingInterval.SECOND:
- return i18n.str`To second`
+ return i18n.str`To second`;
case RoundingInterval.MINUTE:
- return i18n.str`To minute`
+ return i18n.str`To minute`;
case RoundingInterval.HOUR:
- return i18n.str`To hour`
+ return i18n.str`To hour`;
case RoundingInterval.DAY:
- return i18n.str`To day`
+ return i18n.str`To day`;
case RoundingInterval.WEEK:
- return i18n.str`To week`
+ return i18n.str`To week`;
case RoundingInterval.MONTH:
- return i18n.str`To month`
+ return i18n.str`To month`;
case RoundingInterval.QUARTER:
- return i18n.str`To quarter`
+ return i18n.str`To quarter`;
case RoundingInterval.YEAR:
- return i18n.str`To year`
+ return i18n.str`To year`;
}
}}
/>
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/admin/create/CreatePage.tsx
@@ -110,15 +110,19 @@ export function CreatePage({ onConfirm, onBack, forceId }: Props): VNode {
: undefined,
default_pay_delay: !value.default_pay_delay
? i18n.str`Required`
- : value.default_wire_transfer_delay !== undefined &&
- value.default_wire_transfer_delay.d_us !== "forever" &&
- value.default_pay_delay.d_us !== "forever" &&
- value.default_pay_delay.d_us > value.default_wire_transfer_delay.d_us
- ? i18n.str`Pay delay can't be greater than wire transfer delay`
+ : value.default_pay_delay.d_us === "forever"
+ ? i18n.str`Invalid value`
+ : undefined,
+ default_refund_delay: !value.default_refund_delay
+ ? i18n.str`Required`
+ : value.default_refund_delay.d_us === "forever"
+ ? i18n.str`Invalid value`
: undefined,
default_wire_transfer_delay: !value.default_wire_transfer_delay
? i18n.str`Required`
- : undefined,
+ : value.default_wire_transfer_delay.d_us === "forever"
+ ? i18n.str`Invalid value`
+ : undefined,
address: undefinedIfEmpty({
address_lines:
value.address?.address_lines && value.address?.address_lines.length > 7
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
@@ -45,6 +45,9 @@ export const Example = createExample(TestedComponent, {
default_pay_delay: {
d_us: 1000 * 1000 * 60 * 60, //one hour
},
+ default_refund_delay: {
+ d_us: 1000 * 1000 * 60 * 60, //one hour
+ },
default_wire_transfer_delay: {
d_us: 1000 * 1000 * 60 * 60, //one hour
},
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
@@ -73,6 +73,7 @@ export interface Props {
interface InstanceConfig {
use_stefan: boolean;
default_pay_delay: TalerProtocolDuration;
+ default_refund_delay: TalerProtocolDuration;
default_wire_transfer_delay: TalerProtocolDuration;
}
@@ -80,16 +81,15 @@ function with_defaults(
config: InstanceConfig,
_currency: string,
): Partial<Entity> {
- const defaultPayDeadline = Duration.fromTalerProtocolDuration(
+ const defaultPayDelay = Duration.fromTalerProtocolDuration(
config.default_pay_delay,
);
- const defaultWireDeadline = Duration.fromTalerProtocolDuration(
+ const defaultWireDelay = Duration.fromTalerProtocolDuration(
config.default_wire_transfer_delay,
);
- const defaultRefundDeadline = Duration.min(
- defaultWireDeadline,
- Duration.fromSpec({ days: 15 }),
- );
+ const defaultRefundDelay = Duration.fromTalerProtocolDuration(
+ config.default_refund_delay,
+ );;
return {
inventoryProducts: {},
@@ -98,9 +98,9 @@ function with_defaults(
payments: {
max_fee: undefined,
createToken: true,
- pay_deadline: defaultPayDeadline,
- refund_deadline: defaultRefundDeadline,
- wire_transfer_deadline: defaultWireDeadline,
+ pay_delay: defaultPayDelay,
+ refund_delay: defaultRefundDelay,
+ wire_transfer_delay: defaultWireDelay,
},
shipping: {},
extra: {},
@@ -127,10 +127,10 @@ interface Shipping extends TalerForm {
fulfillment_message?: string;
}
interface Payments extends TalerForm {
- refund_deadline: Duration;
- pay_deadline: Duration;
- wire_transfer_deadline: Duration;
- auto_refund_deadline?: Duration;
+ pay_delay: Duration;
+ refund_delay: Duration;
+ wire_transfer_delay: Duration;
+ auto_refund_delay?: Duration;
max_fee?: string;
createToken: boolean;
minimum_age?: number;
@@ -185,40 +185,28 @@ export function CreatePage({
: undefined,
}),
payments: undefinedIfEmpty({
- refund_deadline: !value.payments?.refund_deadline
- ? undefined
- : value.payments.pay_deadline &&
- Duration.cmp(
- value.payments.refund_deadline,
- value.payments.pay_deadline,
- ) === -1
- ? i18n.str`The refund deadline cannot be earlier than the payment deadline.`
- : value.payments.wire_transfer_deadline &&
- Duration.cmp(
- value.payments.wire_transfer_deadline,
- value.payments.refund_deadline,
- ) === -1
- ? i18n.str`Wire transfer deadline can't be before refund deadline`
- : undefined,
- pay_deadline: !value.payments?.pay_deadline
- ? i18n.str`Required`
- : value.payments.wire_transfer_deadline &&
- Duration.cmp(
- value.payments.wire_transfer_deadline,
- value.payments.pay_deadline,
- ) === -1
- ? i18n.str`Wire transfer deadline can't be before pay deadline`
- : undefined,
- wire_transfer_deadline: !value.payments?.wire_transfer_deadline
- ? i18n.str`Required`
- : undefined,
- auto_refund_deadline: !value.payments?.auto_refund_deadline
+ // refund_delay: !value.payments?.refund_delay
+ // ? undefined
+ // : undefined,
+ // pay_delay: !value.payments?.pay_delay
+ // ? i18n.str`Required`
+ // : value.payments.wire_transfer_delay &&
+ // Duration.cmp(
+ // value.payments.wire_transfer_delay,
+ // value.payments.pay_delay,
+ // ) === -1
+ // ? i18n.str`Wire transfer deadline can't be before pay deadline`
+ // : undefined,
+ // wire_transfer_delay: !value.payments?.wire_transfer_delay
+ // ? i18n.str`Required`
+ // : undefined,
+ auto_refund_delay: !value.payments?.auto_refund_delay
? undefined
- : !value.payments?.refund_deadline
+ : !value.payments?.refund_delay
? i18n.str`Must have a refund deadline`
: Duration.cmp(
- value.payments.refund_deadline,
- value.payments.auto_refund_deadline,
+ value.payments.refund_delay,
+ value.payments.auto_refund_delay,
) == -1
? i18n.str`Auto refund can't be after refund deadline`
: undefined,
@@ -268,24 +256,24 @@ export function CreatePage({
pay_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
- value.payments.pay_deadline!,
+ value.payments.pay_delay!,
),
),
wire_transfer_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
- value.payments.wire_transfer_deadline!,
+ value.payments.wire_transfer_delay!,
),
),
refund_deadline: AbsoluteTime.toProtocolTimestamp(
AbsoluteTime.addDuration(
AbsoluteTime.now(),
- value.payments.refund_deadline!,
+ value.payments.refund_delay!,
),
),
- auto_refund: value.payments.auto_refund_deadline
+ auto_refund: value.payments.auto_refund_delay
? Duration.toTalerProtocolDuration(
- value.payments.auto_refund_deadline,
+ value.payments.auto_refund_delay,
)
: undefined,
delivery_date: value.shipping.delivery_date
@@ -411,11 +399,11 @@ export function CreatePage({
// if there is no default pay deadline
const noDefault_payDeadline =
- !instance_default.payments || !instance_default.payments.pay_deadline;
+ !instance_default.payments || !instance_default.payments.pay_delay;
// and there is no default wire deadline
const noDefault_wireDeadline =
!instance_default.payments ||
- !instance_default.payments.wire_transfer_deadline;
+ !instance_default.payments.wire_transfer_delay;
// user required to set the taler options
const requiresSomeTalerOptions =
noDefault_payDeadline || noDefault_wireDeadline;
@@ -571,14 +559,14 @@ export function CreatePage({
point={UIElement.option_advanceOrderCreation}
showAnywayIf={
noDefault_payDeadline ||
- errors?.payments?.pay_deadline !== undefined
+ errors?.payments?.pay_delay !== undefined
}
>
<InputDuration
- name="payments.pay_deadline"
+ name="payments.pay_delay"
label={i18n.str`Payment time`}
help={
- <DeadlineHelp duration={value.payments?.pay_deadline} />
+ <DeadlineHelp duration={value.payments?.pay_delay} />
}
withForever
withoutClear
@@ -593,8 +581,8 @@ export function CreatePage({
...value,
payments: {
...(value.payments ?? {}),
- pay_deadline:
- instance_default.payments?.pay_deadline,
+ pay_delay:
+ instance_default.payments?.pay_delay,
},
};
valueHandler(c);
@@ -609,15 +597,15 @@ export function CreatePage({
<FragmentPersonaFlag
point={UIElement.option_advanceOrderCreation}
showAnywayIf={
- errors?.payments?.refund_deadline !== undefined
+ errors?.payments?.refund_delay !== undefined
}
>
<InputDuration
- name="payments.refund_deadline"
+ name="payments.refund_delay"
label={i18n.str`Refund time`}
help={
<DeadlineHelp
- duration={value.payments?.refund_deadline}
+ duration={value.payments?.refund_delay}
/>
}
withForever
@@ -633,8 +621,8 @@ export function CreatePage({
...value,
payments: {
...(value.payments ?? {}),
- refund_deadline:
- instance_default.payments?.refund_deadline,
+ refund_delay:
+ instance_default.payments?.refund_delay,
},
});
}}
@@ -650,15 +638,15 @@ export function CreatePage({
point={UIElement.option_advanceOrderCreation}
showAnywayIf={
noDefault_wireDeadline ||
- errors?.payments?.wire_transfer_deadline !== undefined
+ errors?.payments?.wire_transfer_delay !== undefined
}
>
<InputDuration
- name="payments.wire_transfer_deadline"
+ name="payments.wire_transfer_delay"
label={i18n.str`Wire transfer time`}
help={
<DeadlineHelp
- duration={value.payments?.wire_transfer_deadline}
+ duration={value.payments?.wire_transfer_delay}
/>
}
withoutClear
@@ -674,9 +662,9 @@ export function CreatePage({
...value,
payments: {
...(value.payments ?? {}),
- wire_transfer_deadline:
+ wire_transfer_delay:
instance_default.payments
- ?.wire_transfer_deadline,
+ ?.wire_transfer_delay,
},
});
}}
@@ -690,15 +678,15 @@ export function CreatePage({
<FragmentPersonaFlag
point={UIElement.option_advanceOrderCreation}
showAnywayIf={
- errors?.payments?.auto_refund_deadline !== undefined
+ errors?.payments?.auto_refund_delay !== undefined
}
>
<InputDuration
- name="payments.auto_refund_deadline"
+ name="payments.auto_refund_delay"
label={i18n.str`Auto-refund time`}
help={
<DeadlineHelp
- duration={value.payments?.auto_refund_deadline}
+ duration={value.payments?.auto_refund_delay}
/>
}
tooltip={i18n.str`Time until which the wallet will automatically check for refunds without user interaction.`}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
@@ -48,11 +48,15 @@ import { SolveMFAChallenges } from "../../../components/SolveMFA.js";
const TALER_SCREEN_ID = 75;
export type Entity = Omit<
- Omit<TalerMerchantApi.InstanceReconfigurationMessage, "default_pay_delay">,
- "default_wire_transfer_delay"
+ Omit<
+ Omit<TalerMerchantApi.InstanceReconfigurationMessage, "default_pay_delay">,
+ "default_wire_transfer_delay"
+ >,
+ "default_refund_delay"
> & {
default_pay_delay: Duration;
default_wire_transfer_delay: Duration;
+ default_refund_delay: Duration;
} & TalerForm;
export interface Props {
@@ -64,11 +68,18 @@ export interface Props {
}
function convert(from: TalerMerchantApi.QueryInstancesResponse): Entity {
- const { default_pay_delay, default_wire_transfer_delay, ...rest } = from;
-
- const defaults = {
+ const {
+ default_pay_delay,
+ default_wire_transfer_delay,
+ default_refund_delay,
+ ...rest
+ } = from;
+
+ const defaults: Partial<Entity> = {
use_stefan: false,
default_pay_delay: Duration.fromTalerProtocolDuration(default_pay_delay),
+ default_refund_delay:
+ Duration.fromTalerProtocolDuration(default_refund_delay),
default_wire_transfer_delay: Duration.fromTalerProtocolDuration(
default_wire_transfer_delay,
),
@@ -117,10 +128,16 @@ export function UpdatePage({
const hasErrors = errors !== undefined;
- const { default_pay_delay, default_wire_transfer_delay, ...rest } =
- value as Required<Entity>;
+ const {
+ default_pay_delay,
+ default_wire_transfer_delay,
+ default_refund_delay,
+ ...rest
+ } = value as Required<Entity>;
const result: TalerMerchantApi.InstanceReconfigurationMessage = {
default_pay_delay: Duration.toTalerProtocolDuration(default_pay_delay),
+ default_refund_delay:
+ Duration.toTalerProtocolDuration(default_refund_delay),
default_wire_transfer_delay: Duration.toTalerProtocolDuration(
default_wire_transfer_delay,
),
@@ -197,7 +214,8 @@ export function UpdatePage({
</FormProvider>
<div class="buttons is-right mt-4">
- <button type="button"
+ <button
+ type="button"
class="button"
onClick={onBack}
data-tooltip="cancel operation"
diff --git a/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx b/packages/merchant-backoffice-ui/src/paths/newAccount/index.tsx
@@ -59,6 +59,7 @@ export interface Account {
}
const twoHours = Duration.fromSpec({ hours: 2 });
+const oneDay = Duration.fromSpec({ days: 1 });
const twoDays = Duration.fromSpec({ days: 2 });
interface Props {
@@ -131,8 +132,13 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode {
method: MerchantAuthMethod.TOKEN,
password: value.password!,
},
- default_pay_delay: Duration.toTalerProtocolDuration(twoHours),
- default_wire_transfer_delay: Duration.toTalerProtocolDuration(twoDays),
+ default_pay_delay:
+ config.default_pay_delay ?? Duration.toTalerProtocolDuration(twoHours),
+ default_wire_transfer_delay:
+ config.default_wire_transfer_delay ??
+ Duration.toTalerProtocolDuration(oneDay),
+ default_refund_delay:
+ config.default_refund_delay ?? Duration.toTalerProtocolDuration(twoDays),
id: value.id!,
jurisdiction: {},
name: value.name!,
@@ -250,7 +256,9 @@ export function NewAccount({ onCancel, onCreated }: Props): VNode {
target="_blank"
referrerpolicy="no-referrer"
>
- <i18n.Translate>Accept the Terms of service</i18n.Translate>
+ <i18n.Translate>
+ Accept the Terms of service
+ </i18n.Translate>
</a>
</i18n.Translate>
}