more no enough balance description
This commit is contained in:
parent
378cc9125d
commit
6f24b5a05e
@ -17,6 +17,7 @@
|
||||
import {
|
||||
AmountJson,
|
||||
Amounts,
|
||||
PayMerchantInsufficientBalanceDetails,
|
||||
PreparePayResult,
|
||||
PreparePayResultType,
|
||||
TranslatedString,
|
||||
@ -35,7 +36,6 @@ import { assertUnreachable } from "../utils/index.js";
|
||||
interface Props {
|
||||
payStatus: PreparePayResult;
|
||||
payHandler: ButtonHandler | undefined;
|
||||
balance: AmountJson | undefined;
|
||||
uri: string;
|
||||
amount: AmountJson;
|
||||
goToWalletManualWithdraw: (currency: string) => Promise<void>;
|
||||
@ -45,7 +45,6 @@ export function PaymentButtons({
|
||||
payStatus,
|
||||
uri,
|
||||
payHandler,
|
||||
balance,
|
||||
amount,
|
||||
goToWalletManualWithdraw,
|
||||
}: Props): VNode {
|
||||
@ -73,16 +72,58 @@ export function PaymentButtons({
|
||||
}
|
||||
|
||||
if (payStatus.status === PreparePayResultType.InsufficientBalance) {
|
||||
const reason = getReason(payStatus.balanceDetails);
|
||||
|
||||
let BalanceMessage = "";
|
||||
if (!balance) {
|
||||
BalanceMessage = i18n.str`You have no balance for this currency. Withdraw digital cash first.`;
|
||||
} else {
|
||||
const balanceShouldBeEnough = Amounts.cmp(balance, amount) !== -1;
|
||||
if (balanceShouldBeEnough) {
|
||||
BalanceMessage = i18n.str`Could not find enough coins to pay. Even if you have enough ${balance.currency} some restriction may apply.`;
|
||||
} else {
|
||||
BalanceMessage = i18n.str`Your current balance is not enough.`;
|
||||
switch (reason) {
|
||||
case "age-acceptable": {
|
||||
BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.balanceAgeAcceptable,
|
||||
)} ${amount.currency} to pay for contracts restricted for age above ${
|
||||
payStatus.contractTerms.minimum_age
|
||||
} years old`;
|
||||
break;
|
||||
}
|
||||
case "available": {
|
||||
BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.balanceAvailable,
|
||||
)} ${amount.currency} available.`;
|
||||
break;
|
||||
}
|
||||
case "merchant-acceptable": {
|
||||
BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.balanceMerchantAcceptable,
|
||||
)} ${
|
||||
amount.currency
|
||||
} . To know more you can check which exchange and auditors the merchant trust.`;
|
||||
break;
|
||||
}
|
||||
case "merchant-depositable": {
|
||||
BalanceMessage = i18n.str`Balance is not enough because merchant will just accept ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.balanceMerchantDepositable,
|
||||
)} ${
|
||||
amount.currency
|
||||
} . To know more you can check which wire methods the merchant accepts.`;
|
||||
break;
|
||||
}
|
||||
case "material": {
|
||||
BalanceMessage = i18n.str`Balance is not enough because you have ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.balanceMaterial,
|
||||
)} ${
|
||||
amount.currency
|
||||
} to spend right know. There are some coins that need to be refreshed.`;
|
||||
break;
|
||||
}
|
||||
case "fee-gap": {
|
||||
BalanceMessage = i18n.str`Balance looks like it should be enough, but doesn't cover all fees requested by the merchant and payment processor. Please ensure there is at least ${Amounts.stringifyValue(
|
||||
payStatus.balanceDetails.feeGapEstimate,
|
||||
)} ${
|
||||
amount.currency
|
||||
} more balance in your wallet or ask your merchant to cover more of the fees.`;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assertUnreachable(reason);
|
||||
}
|
||||
const uriPrivate = `${uri}&n=${payStatus.noncePriv}`;
|
||||
|
||||
@ -150,3 +191,32 @@ function PayWithMobile({ uri }: { uri: string }): VNode {
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
type NoEnoughBalanceReason =
|
||||
| "available"
|
||||
| "material"
|
||||
| "age-acceptable"
|
||||
| "merchant-acceptable"
|
||||
| "merchant-depositable"
|
||||
| "fee-gap";
|
||||
|
||||
function getReason(
|
||||
info: PayMerchantInsufficientBalanceDetails,
|
||||
): NoEnoughBalanceReason {
|
||||
if (Amounts.cmp(info.amountRequested, info.balanceAvailable)) {
|
||||
return "available";
|
||||
}
|
||||
if (Amounts.cmp(info.amountRequested, info.balanceMaterial)) {
|
||||
return "material";
|
||||
}
|
||||
if (Amounts.cmp(info.amountRequested, info.balanceAgeAcceptable)) {
|
||||
return "age-acceptable";
|
||||
}
|
||||
if (Amounts.cmp(info.amountRequested, info.balanceMerchantAcceptable)) {
|
||||
return "merchant-acceptable";
|
||||
}
|
||||
if (Amounts.cmp(info.amountRequested, info.balanceMerchantDepositable)) {
|
||||
return "merchant-depositable";
|
||||
}
|
||||
return "fee-gap";
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ export function ReadyView(
|
||||
state: State.Ready | State.NoBalanceForCurrency | State.NoEnoughBalance,
|
||||
): VNode {
|
||||
const { i18n } = useTranslationContext();
|
||||
const { summary, amount, expiration, uri, status, balance, payStatus } =
|
||||
state;
|
||||
const { summary, amount, expiration, uri, status, payStatus } = state;
|
||||
return (
|
||||
<WalletAction>
|
||||
<LogoHeader />
|
||||
@ -47,7 +46,6 @@ export function ReadyView(
|
||||
</section>
|
||||
<PaymentButtons
|
||||
amount={amount}
|
||||
balance={balance}
|
||||
payStatus={payStatus}
|
||||
uri={uri}
|
||||
payHandler={status === "ready" ? state.accept : undefined}
|
||||
|
@ -36,16 +36,28 @@ export default {
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
export const NoBalance = tests.createExample(BaseView, {
|
||||
status: "no-balance-for-currency",
|
||||
export const NoEnoughBalanceAvailable = tests.createExample(BaseView, {
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: undefined,
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {} as any,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:9",
|
||||
balanceMaterial: "USD:9",
|
||||
balanceAgeAcceptable: "USD:9",
|
||||
balanceMerchantAcceptable: "USD:9",
|
||||
balanceMerchantDepositable: "USD:9",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
@ -63,20 +75,28 @@ export const NoBalance = tests.createExample(BaseView, {
|
||||
},
|
||||
});
|
||||
|
||||
export const NoEnoughBalance = tests.createExample(BaseView, {
|
||||
export const NoEnoughBalanceMaterial = tests.createExample(BaseView, {
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 9,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {} as any,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:10",
|
||||
balanceMaterial: "USD:9",
|
||||
balanceAgeAcceptable: "USD:9",
|
||||
balanceMerchantAcceptable: "USD:9",
|
||||
balanceMerchantDepositable: "USD:0",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
@ -94,20 +114,28 @@ export const NoEnoughBalance = tests.createExample(BaseView, {
|
||||
},
|
||||
});
|
||||
|
||||
export const EnoughBalanceButRestricted = tests.createExample(BaseView, {
|
||||
export const NoEnoughBalanceAgeAcceptable = tests.createExample(BaseView, {
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 19,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {} as any,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:10",
|
||||
balanceMaterial: "USD:10",
|
||||
balanceAgeAcceptable: "USD:9",
|
||||
balanceMerchantAcceptable: "USD:9",
|
||||
balanceMerchantDepositable: "USD:9",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
@ -118,6 +146,128 @@ export const EnoughBalanceButRestricted = tests.createExample(BaseView, {
|
||||
website: "https://www.themerchant.taler",
|
||||
email: "contact@merchant.taler",
|
||||
},
|
||||
minimum_age: 18,
|
||||
summary: "some beers",
|
||||
amount: "USD:10",
|
||||
} as Partial<ContractTerms> as any,
|
||||
amountRaw: "USD:10",
|
||||
},
|
||||
});
|
||||
|
||||
export const NoEnoughBalanceMerchantAcceptable = tests.createExample(BaseView, {
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:10",
|
||||
balanceMaterial: "USD:10",
|
||||
balanceAgeAcceptable: "USD:10",
|
||||
balanceMerchantAcceptable: "USD:9",
|
||||
balanceMerchantDepositable: "USD:9",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
contractTerms: {
|
||||
merchant: {
|
||||
name: "the merchant",
|
||||
logo: merchantIcon,
|
||||
website: "https://www.themerchant.taler",
|
||||
email: "contact@merchant.taler",
|
||||
},
|
||||
summary: "some beers",
|
||||
amount: "USD:10",
|
||||
} as Partial<ContractTerms> as any,
|
||||
amountRaw: "USD:10",
|
||||
},
|
||||
});
|
||||
|
||||
export const NoEnoughBalanceMerchantDepositable = tests.createExample(
|
||||
BaseView,
|
||||
{
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:10",
|
||||
balanceMaterial: "USD:10",
|
||||
balanceAgeAcceptable: "USD:10",
|
||||
balanceMerchantAcceptable: "USD:10",
|
||||
balanceMerchantDepositable: "USD:9",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
contractTerms: {
|
||||
merchant: {
|
||||
name: "the merchant",
|
||||
logo: merchantIcon,
|
||||
website: "https://www.themerchant.taler",
|
||||
email: "contact@merchant.taler",
|
||||
},
|
||||
summary: "some beers",
|
||||
amount: "USD:10",
|
||||
} as Partial<ContractTerms> as any,
|
||||
amountRaw: "USD:10",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export const NoEnoughBalanceFeeGap = tests.createExample(BaseView, {
|
||||
status: "no-enough-balance",
|
||||
error: undefined,
|
||||
amount: Amounts.parseOrThrow("USD:10"),
|
||||
balance: {
|
||||
currency: "USD",
|
||||
fraction: 40000000,
|
||||
value: 12,
|
||||
},
|
||||
|
||||
uri: "",
|
||||
payStatus: {
|
||||
status: PreparePayResultType.InsufficientBalance,
|
||||
balanceDetails: {
|
||||
amountRequested: "USD:10",
|
||||
balanceAvailable: "USD:10",
|
||||
balanceMaterial: "USD:10",
|
||||
balanceAgeAcceptable: "USD:10",
|
||||
balanceMerchantAcceptable: "USD:10",
|
||||
balanceMerchantDepositable: "USD:10",
|
||||
feeGapEstimate: "USD:1",
|
||||
},
|
||||
talerUri: "taler://pay/..",
|
||||
noncePriv: "",
|
||||
proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0",
|
||||
contractTerms: {
|
||||
merchant: {
|
||||
name: "the merchant",
|
||||
logo: merchantIcon,
|
||||
website: "https://www.themerchant.taler",
|
||||
email: "contact@merchant.taler",
|
||||
},
|
||||
minimum_age: 18,
|
||||
summary: "some beers",
|
||||
amount: "USD:10",
|
||||
} as Partial<ContractTerms> as any,
|
||||
|
@ -105,7 +105,6 @@ export function BaseView(state: SupportedStates): VNode {
|
||||
</section>
|
||||
<PaymentButtons
|
||||
amount={state.amount}
|
||||
balance={state.balance}
|
||||
payStatus={state.payStatus}
|
||||
uri={state.uri}
|
||||
payHandler={state.status === "ready" ? state.payHandler : undefined}
|
||||
|
Loading…
Reference in New Issue
Block a user