/* 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 */ /** * * @author Sebastian Javier Marchano (sebasjm) */ import { AbsoluteTime, ExtendedStatus, PaymentStatus, RefreshReason, TalerProtocolTimestamp, TransactionCommon, TransactionDeposit, TransactionMajorState, TransactionPayment, TransactionPeerPullCredit, TransactionPeerPullDebit, TransactionPeerPushCredit, TransactionPeerPushDebit, TransactionRefresh, TransactionRefund, TransactionTip, TransactionType, TransactionWithdrawal, WithdrawalDetails, WithdrawalType, } from "@gnu-taler/taler-util"; import { tests } from "@gnu-taler/web-util/lib/index.browser"; import beer from "../../static-dev/beer.png"; import { TransactionView as TestedComponent } from "./Transaction.js"; export default { title: "transaction details", component: TestedComponent, argTypes: { onRetry: { action: "onRetry" }, onDelete: { action: "onDelete" }, onCancel: { action: "onCancel" }, onBack: { action: "onBack" }, }, }; const commonTransaction = { amountRaw: "KUDOS:11", amountEffective: "KUDOS:9.2", extendedStatus: ExtendedStatus.Done, pending: undefined as any as boolean, //deprecated timestamp: TalerProtocolTimestamp.now(), transactionId: "txn:deposit:12", frozen: undefined as any as boolean, //deprecated type: TransactionType.Deposit, txState: { major: TransactionMajorState.Unknown, }, } as TransactionCommon; import merchantIcon from "../../static-dev/merchant-icon.jpeg"; const exampleData = { withdraw: { ...commonTransaction, type: TransactionType.Withdrawal, exchangeBaseUrl: "http://exchange.taler", withdrawalDetails: { reserveIsReady: false, confirmed: false, reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", exchangePaytoUris: ["payto://x-taler-bank/bank.demo.taler.net/Exchange"], type: WithdrawalType.ManualTransfer, }, } as TransactionWithdrawal, payment: { ...commonTransaction, amountEffective: "KUDOS:12", type: TransactionType.Payment, posConfirmation: undefined, info: { contractTermsHash: "ASDZXCASD", merchant: { name: "the merchant", logo: merchantIcon, website: "https://www.themerchant.taler", email: "contact@merchant.taler", }, orderId: "2021.167-03NPY6MCYMVGT", products: [], summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth", fulfillmentMessage: "", // delivery_date: { t_s: 1 }, // delivery_location: { // address_lines: [""], // }, }, refunds: [], refundPending: undefined, totalRefundEffective: "KUDOS:0", totalRefundRaw: "KUDOS:0", proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0", status: PaymentStatus.Accepted, refundQueryActive: false, } as TransactionPayment, deposit: { ...commonTransaction, type: TransactionType.Deposit, wireTransferDeadline: { t_s: new Date().getTime() / 1000, }, depositGroupId: "#groupId", targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange", } as TransactionDeposit, refresh: { ...commonTransaction, type: TransactionType.Refresh, refreshInputAmount: "KUDOS:1", refreshOutputAmount: "KUDOS:0.5", exchangeBaseUrl: "http://exchange.taler", refreshReason: RefreshReason.Manual, } as TransactionRefresh, tip: { ...commonTransaction, type: TransactionType.Tip, // merchant: { // name: "the merchant", // logo: merchantIcon, // website: "https://www.themerchant.taler", // email: "contact@merchant.taler", // }, merchantBaseUrl: "http://merchant.taler", } as TransactionTip, refund: { ...commonTransaction, type: TransactionType.Refund, refundedTransactionId: "payment:1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0", info: { contractTermsHash: "ASDZXCASD", merchant: { name: "the merchant", }, orderId: "2021.167-03NPY6MCYMVGT", products: [], summary: "Essay: Why the Devil's Advocate Doesn't Help Reach the Truth", fulfillmentMessage: "", }, refundPending: undefined, } as TransactionRefund, push_credit: { ...commonTransaction, type: TransactionType.PeerPushCredit, info: { expiration: { t_s: new Date().getTime() / 1000 + 2 * 60 * 60, }, summary: "take this money", completed: true, }, exchangeBaseUrl: "https://exchange.taler.net", } as TransactionPeerPushCredit, push_debit: { ...commonTransaction, type: TransactionType.PeerPushDebit, talerUri: "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0", info: { expiration: { t_s: new Date().getTime() / 1000 + 2 * 60 * 60, }, summary: "take this money", completed: true, }, exchangeBaseUrl: "https://exchange.taler.net", } as TransactionPeerPushDebit, pull_credit: { ...commonTransaction, type: TransactionType.PeerPullCredit, talerUri: "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0", info: { expiration: { t_s: new Date().getTime() / 1000 + 2 * 60 * 60, }, summary: "pay me, please?", completed: true, }, exchangeBaseUrl: "https://exchange.taler.net", } as TransactionPeerPullCredit, pull_debit: { ...commonTransaction, type: TransactionType.PeerPullDebit, info: { expiration: { t_s: new Date().getTime() / 1000 + 2 * 60 * 60, }, summary: "pay me, please?", completed: true, }, exchangeBaseUrl: "https://exchange.taler.net", } as TransactionPeerPullDebit, }; const transactionError = { code: 7005, details: { requestUrl: "http://merchant-backend.taler:9966/orders/2021.340-02AD5XCC97MQM/pay", httpStatusCode: 410, errorResponse: { code: 2161, hint: "The payment is too late, the offer has expired.", }, }, when: AbsoluteTime.now(), hint: "Error: WALLET_UNEXPECTED_REQUEST_ERROR", message: "Unexpected error code in response", }; const kycError = { code: 7025, hint: "KYC check required for withdrawal", kycUrl: "http://localhost:6666/oauth/v2/login?client_id=taler-exchange&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2F%2Fkyc-proof%2F59WFS5VXXY3CEE25BM45XPB7ZCDQZNZ46PJCMNXK05P65T9M1X90%2FKYC-PROVIDER-MYPROV%2F1", when: AbsoluteTime.now(), }; export const Withdraw = tests.createExample(TestedComponent, { transaction: exampleData.withdraw, }); export const WithdrawFiveMinutesAgo = tests.createExample( TestedComponent, () => ({ transaction: { ...exampleData.withdraw, timestamp: TalerProtocolTimestamp.fromSeconds( new Date().getTime() / 1000 - 60 * 5, ), }, }), ); export const WithdrawFiveMinutesAgoAndPending = tests.createExample( TestedComponent, () => ({ transaction: { ...exampleData.withdraw, timestamp: TalerProtocolTimestamp.fromSeconds( new Date().getTime() / 1000 - 60 * 5, ), extendedStatus: ExtendedStatus.Pending, }, }), ); export const WithdrawError = tests.createExample(TestedComponent, { transaction: { ...exampleData.withdraw, error: transactionError, }, }); export const WithdrawErrorKYC = tests.createExample(TestedComponent, { transaction: { ...exampleData.withdraw, error: kycError, }, }); // export const WithdrawErrorInDevMode = tests.createExampleInCustomContext( // TestedComponent, // { // transaction: { // ...exampleData.withdraw, // error: transactionError, // }, // }, // DevContextProviderForTesting, // { value: true }, // ); export const WithdrawPendingManual = tests.createExample( TestedComponent, () => ({ transaction: { ...exampleData.withdraw, withdrawalDetails: { type: WithdrawalType.ManualTransfer, exchangePaytoUris: ["payto://iban/ES8877998399652238"], reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", } as WithdrawalDetails, extendedStatus: ExtendedStatus.Pending, }, }), ); export const WithdrawPendingTalerBankUnconfirmed = tests.createExample( TestedComponent, { transaction: { ...exampleData.withdraw, withdrawalDetails: { type: WithdrawalType.TalerBankIntegrationApi, confirmed: false, reserveIsReady: false, reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", bankConfirmationUrl: "http://bank.demo.taler.net", }, extendedStatus: ExtendedStatus.Pending, }, }, ); export const WithdrawPendingTalerBankConfirmed = tests.createExample( TestedComponent, { transaction: { ...exampleData.withdraw, withdrawalDetails: { type: WithdrawalType.TalerBankIntegrationApi, confirmed: true, reserveIsReady: false, reservePub: "A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG", }, extendedStatus: ExtendedStatus.Pending, }, }, ); export const Payment = tests.createExample(TestedComponent, { transaction: exampleData.payment, }); export const PaymentError = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, error: transactionError, }, }); export const PaymentWithRefund = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", totalRefundEffective: "KUDOS:1", totalRefundRaw: "KUDOS:1", refunds: [ { transactionId: "1123123", amountRaw: "KUDOS:1", amountEffective: "KUDOS:1", timestamp: TalerProtocolTimestamp.fromSeconds(1546546544), }, ], }, }); export const PaymentWithDeliveryDate = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", info: { ...exampleData.payment.info, delivery_date: { t_s: new Date().getTime() / 1000, }, }, }, }); export const PaymentWithDeliveryAddr = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", info: { ...exampleData.payment.info, delivery_location: { country: "Argentina", street: "Elm Street", district: "CABA", post_code: "1101", }, }, }, }); export const PaymentWithDeliveryFull = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", info: { ...exampleData.payment.info, delivery_date: { t_s: new Date().getTime() / 1000, }, delivery_location: { country: "Argentina", street: "Elm Street", district: "CABA", post_code: "1101", }, }, }, }); export const PaymentWithRefundPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", refundPending: "KUDOS:3", totalRefundEffective: "KUDOS:1", totalRefundRaw: "KUDOS:1", }, }); export const PaymentWithFeeAndRefund = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:11", totalRefundEffective: "KUDOS:1", totalRefundRaw: "KUDOS:1", }, }); export const PaymentWithFeeAndRefundFee = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:11", totalRefundEffective: "KUDOS:1", totalRefundRaw: "KUDOS:2", }, }); export const PaymentWithoutFee = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, amountRaw: "KUDOS:12", }, }); export const PaymentPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, extendedStatus: ExtendedStatus.Pending, }, }); export const PaymentWithProducts = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, info: { ...exampleData.payment.info, summary: "summary of 5 products", products: [ { description: "t-shirt", unit: "shirts", quantity: 1, }, { description: "t-shirt", unit: "shirts", quantity: 1, }, { description: "e-book", }, { description: "beer", unit: "pint", quantity: 15, image: beer, }, { description: "beer", unit: "pint", quantity: 15, image: beer, }, ], }, } as TransactionPayment, }); export const PaymentWithLongSummary = tests.createExample(TestedComponent, { transaction: { ...exampleData.payment, info: { ...exampleData.payment.info, summary: "this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, this is a very long summary that will occupy severals lines, ", products: [ { description: "an xl sized t-shirt with some drawings on it, color pink", unit: "shirts", quantity: 1, }, { description: "beer", unit: "pint", quantity: 15, }, ], }, } as TransactionPayment, }); export const Deposit = tests.createExample(TestedComponent, { transaction: exampleData.deposit, }); export const DepositTalerBank = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, targetPaytoUri: "payto://x-taler-bank/bank.demo.taler.net/Exchange", }, }); export const DepositBitcoin = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, amountRaw: "BITCOINBTC:0.0000011", amountEffective: "BITCOINBTC:0.00000092", targetPaytoUri: "payto://bitcoin/bcrt1q6ps8qs6v8tkqrnru4xqqqa6rfwcx5ufpdfqht4?amount=BTC:0.1&subject=0ZSX8SH0M30KHX8K3Y1DAMVGDQV82XEF9DG1HC4QMQ3QWYT4AF00", }, }); export const DepositIBAN = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, targetPaytoUri: "payto://iban/ES8877998399652238", }, }); export const DepositError = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, error: transactionError, }, }); export const DepositPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.deposit, extendedStatus: ExtendedStatus.Pending, }, }); export const Refresh = tests.createExample(TestedComponent, { transaction: exampleData.refresh, }); export const RefreshError = tests.createExample(TestedComponent, { transaction: { ...exampleData.refresh, error: transactionError, }, }); export const Tip = tests.createExample(TestedComponent, { transaction: exampleData.tip, }); export const TipError = tests.createExample(TestedComponent, { transaction: { ...exampleData.tip, error: transactionError, }, }); export const TipPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.tip, extendedStatus: ExtendedStatus.Pending }, }); export const Refund = tests.createExample(TestedComponent, { transaction: exampleData.refund, }); export const RefundError = tests.createExample(TestedComponent, { transaction: { ...exampleData.refund, error: transactionError, }, }); export const RefundPending = tests.createExample(TestedComponent, { transaction: { ...exampleData.refund, extendedStatus: ExtendedStatus.Pending, }, }); export const InvoiceCreditComplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_credit }, }); export const InvoiceCreditIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_credit, extendedStatus: ExtendedStatus.Pending, }, }); export const InvoiceDebit = tests.createExample(TestedComponent, { transaction: { ...exampleData.pull_debit }, }); export const TransferCredit = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_credit }, }); export const TransferDebitComplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_debit }, }); export const TransferDebitIncomplete = tests.createExample(TestedComponent, { transaction: { ...exampleData.push_debit, extendedStatus: ExtendedStatus.Pending, }, });