// @flow import * as ICONS from 'constants/icons'; import React from 'react'; import Button from 'component/button'; import Card from 'component/common/card'; import Page from 'component/page'; import { Lbryio } from 'lbryinc'; import { URL, WEBPACK_WEB_PORT, STRIPE_PUBLIC_KEY } from 'config'; import moment from 'moment'; const isDev = process.env.NODE_ENV !== 'production'; let stripeEnvironment = 'test'; // if the key contains pk_live it's a live key // update the environment for the calls to the backend to indicate which environment to hit if (STRIPE_PUBLIC_KEY.indexOf('pk_live') > -1) { stripeEnvironment = 'live'; } let successStripeRedirectUrl, failureStripeRedirectUrl; let successEndpoint = '/$/settings/tip_account'; let failureEndpoint = '/$/settings/tip_account'; if (isDev) { successStripeRedirectUrl = 'http://localhost:' + WEBPACK_WEB_PORT + successEndpoint; failureStripeRedirectUrl = 'http://localhost:' + WEBPACK_WEB_PORT + failureEndpoint; } else { successStripeRedirectUrl = URL + successEndpoint; failureStripeRedirectUrl = URL + failureEndpoint; } type Props = { source: string, user: User, doOpenModal: (string, {}) => void, doToast: ({ message: string }) => void, }; type State = { error: boolean, loading: boolean, content: ?string, stripeConnectionUrl: string, // alreadyUpdated: boolean, accountConfirmed: boolean, accountPendingConfirmation: boolean, accountNotConfirmedButReceivedTips: boolean, unpaidBalance: number, pageTitle: string, accountTransactions: any, // define this type }; class StripeAccountConnection extends React.Component { constructor(props: Props) { super(props); this.state = { error: false, content: null, loading: true, accountConfirmed: false, accountPendingConfirmation: false, accountNotConfirmedButReceivedTips: false, unpaidBalance: 0, stripeConnectionUrl: '', pageTitle: 'Add Payout Method', accountTransactions: [], // alreadyUpdated: false, }; } componentDidMount() { const { user } = this.props; let doToast = this.props.doToast; // $FlowFixMe this.experimentalUiEnabled = user && user.experimental_ui; var that = this; function getAndSetAccountLink(stillNeedToConfirmAccount) { Lbryio.call( 'account', 'link', { return_url: successStripeRedirectUrl, refresh_url: failureStripeRedirectUrl, environment: stripeEnvironment, }, 'post' ).then((accountLinkResponse) => { // stripe link for user to navigate to and confirm account const stripeConnectionUrl = accountLinkResponse.url; // set connection url on frontend that.setState({ stripeConnectionUrl, }); // show the account confirmation link if not created already if (stillNeedToConfirmAccount) { that.setState({ accountPendingConfirmation: true, }); } }); } // call the account status endpoint Lbryio.call( 'account', 'status', { environment: stripeEnvironment, }, 'post' ) .then((accountStatusResponse) => { const yetToBeCashedOutBalance = accountStatusResponse.total_received_unpaid; if (yetToBeCashedOutBalance) { that.setState({ unpaidBalance: yetToBeCashedOutBalance, }); Lbryio.call( 'account', 'list', { environment: stripeEnvironment, }, 'post' ).then((accountListResponse: any) => { // TODO type this that.setState({ accountTransactions: accountListResponse.reverse(), }); }); } // if charges already enabled, no need to generate an account link if (accountStatusResponse.charges_enabled) { // account has already been confirmed that.setState({ accountConfirmed: true, }); // user has not confirmed an account but have received payments } else if (accountStatusResponse.total_received_unpaid > 0) { that.setState({ accountNotConfirmedButReceivedTips: true, }); getAndSetAccountLink(); // user has not received any amount or confirmed an account } else { // get stripe link and set it on the frontend // pass true so it updates the frontend getAndSetAccountLink(true); } }) .catch(function (error) { // errorString passed from the API (with a 403 error) const errorString = 'account not linked to user, please link first'; // if it's beamer's error indicating the account is not linked yet if (error.message.indexOf(errorString) > -1) { // get stripe link and set it on the frontend getAndSetAccountLink(true); } else { // probably an error from stripe const displayString = 'There was an error getting your account setup, please let support know'; doToast({ message: displayString, isError: true }); // not an error from Beamer, throw it throw new Error(error); } }); } render() { const { stripeConnectionUrl, accountConfirmed, accountPendingConfirmation, unpaidBalance, accountNotConfirmedButReceivedTips, pageTitle, accountTransactions, } = this.state; const { user } = this.props; if (user.fiat_enabled) { return ( {__('Connect a bank account')}} isBodyList body={
{/* show while waiting for account status */} {!accountConfirmed && !accountPendingConfirmation && !accountNotConfirmedButReceivedTips && (

{__('Getting your bank account connection status...')}

)} {/* user has yet to complete their integration */} {!accountConfirmed && accountPendingConfirmation && (

{__('Connect your bank account to Odysee to receive donations directly from users')}

)} {/* user has completed their integration */} {accountConfirmed && (

{__('Congratulations! Your account has been connected with Odysee.')}

{unpaidBalance > 0 ? (

{__('Your pending account balance is $%balance% USD.', { balance: unpaidBalance / 100 })}

) : (

{__('Your account balance is $0 USD. When you receive a tip you will see it here.')}

)}
)} {accountNotConfirmedButReceivedTips && (

{__('Congratulations, you have already begun receiving tips on Odysee!')}


{__('Your pending account balance is $%balance% USD.', { balance: unpaidBalance / 100 })}


{__( 'Connect your bank account to be able to cash your pending balance out to your account.' )}

)}
} />
{/* customer already has transactions */} {accountTransactions && accountTransactions.length > 0 && (
{accountTransactions && accountTransactions.map((transaction) => ( ))}
{__('Date')} {<>{__('Receiving Channel Name')}} {__('Tip Location')} {__('Amount (USD)')} {__('Processing Fee')} {__('Odysee Fee')} {__('Received Amount')}
{moment(transaction.created_at).format('LLL')} ${transaction.tipped_amount / 100} ${transaction.transaction_fee / 100} ${transaction.application_fee / 100} ${transaction.received_amount / 100}
} /> )}
); } else { return <>; // probably null; } } } export default StripeAccountConnection;