Skip to content

Commit

Permalink
feat: payment methods step added
Browse files Browse the repository at this point in the history
  • Loading branch information
milan-bc committed Jul 15, 2020
1 parent 26384af commit 92d19c0
Show file tree
Hide file tree
Showing 21 changed files with 434 additions and 75 deletions.
Expand Up @@ -837,7 +837,7 @@
"modals.onboarding.linktoexchangeaccount.loading.waitingbody": "If a new browser tab did not open, try clicking the button below.",
"modals.onboarding.linktoexchangeaccount.na.connectnow": "Connect Now",
"modals.onboarding.linktoexchangeaccount.na.left.point1-2": "Access More Cryptos",
"modals.onboarding.linktoexchangeaccount.na.left.point2-1": "Deposit & Withdraw
Euros/Dollars",
"modals.onboarding.linktoexchangeaccount.na.left.point2-1": "Deposit & WithdrawEuros/Dollars",
"modals.onboarding.linktoexchangeaccount.na.left.point3-1": "Lightning Fast Trading",
"modals.onboarding.linktoexchangeaccount.na.left.point4-1": "Built by the Pros",
"modals.onboarding.linktoexchangeaccount.na.resendemail": "Resend Email",
Expand Down Expand Up @@ -1112,6 +1112,7 @@
"modals.simplebuy.save_my_card": "Save My Card",
"modals.simplebuy.selectcurrency": "Select Your Currency",
"modals.simplebuy.cryptoselect": "Buy with Cash or Card",
"modals.simplebuy.paymentmethods": "Payment Methods",
"modals.simplebuy.selectcrypto": "Select the crypto you want to buy.",
"modals.simplebuy.setupaccount": "Next, we'll set up your account.",
"modals.simplebuy.success": "Trade Complete",
Expand Down
Expand Up @@ -1138,6 +1138,7 @@ type MessagesType = {
'modals.simplebuy.save_my_card': 'Save My Card'
'modals.simplebuy.selectcurrency': 'Select Your Currency'
'modals.simplebuy.cryptoselect': 'Buy with Cash or Card'
'modals.simplebuy.paymentmethods': 'Payment Methods'
'modals.simplebuy.selectcrypto': 'Select the crypto you want to buy.'
'modals.simplebuy.setupaccount': "Next, we'll set up your account."
'modals.simplebuy.success': 'Trade Complete'
Expand Down
Expand Up @@ -373,14 +373,8 @@ export const initializeBillingAddress = () => ({
type: AT.INITIALIZE_BILLING_ADDRESS
})

export const initializeCheckout = (
paymentMethods: SBPaymentMethodsType,
cards: Array<SBCardType>,
orderType: 'BUY' | 'SELL'
) => ({
export const initializeCheckout = (orderType: 'BUY' | 'SELL') => ({
type: AT.INITIALIZE_CHECKOUT,
paymentMethods,
cards,
orderType
})

Expand Down
Expand Up @@ -13,6 +13,7 @@ const INITIAL_STATE: SimpleBuyState = {
everypay3DS: Remote.NotAsked,
fiatCurrency: undefined,
fiatEligible: Remote.NotAsked,
method: undefined,
methods: Remote.NotAsked,
order: undefined,
orders: Remote.NotAsked,
Expand Down
Expand Up @@ -34,8 +34,7 @@ import {
SBAddCardErrorType,
SBAddCardFormValuesType,
SBBillingAddressFormValuesType,
SBCheckoutFormValuesType,
SBFormPaymentMethod
SBCheckoutFormValuesType
} from './types'
import { UserDataType } from 'data/modules/types'
import moment from 'moment'
Expand Down Expand Up @@ -531,45 +530,19 @@ export default ({
}

const initializeCheckout = function * ({
paymentMethods,
cards,
orderType
}: ReturnType<typeof A.initializeCheckout>) {
try {
yield call(createUser)
yield call(waitForUserData)

const defaultMethod = S.getDefaultMethod(yield select())
const fiatCurrency = S.getFiatCurrency(yield select())
if (!fiatCurrency) throw new Error(NO_FIAT_CURRENCY)

yield put(A.fetchSBSuggestedAmounts(fiatCurrency))

const isSimpleBuyCCInvited = true
const cardMethod = paymentMethods.methods.find(
method => method.type === 'PAYMENT_CARD'
)
const activeCard = cards.find(card => card.state === 'ACTIVE')

const method: SBFormPaymentMethod =
defaultMethod ||
(activeCard
? cardMethod
? {
...activeCard,
limits: cardMethod.limits,
type: 'USER_CARD'
}
: paymentMethods.methods[0]
: paymentMethods.methods[0])

yield put(
actions.form.initialize('simpleBuyCheckout', {
method: isSimpleBuyCCInvited
? method
: paymentMethods.methods.find(
method => method.type === 'BANK_ACCOUNT'
),
orderType
} as SBCheckoutFormValuesType)
)
Expand Down
Expand Up @@ -34,6 +34,9 @@ export const getSBPairs = (state: RootState) => state.components.simpleBuy.pairs

export const getSBPair = (state: RootState) => state.components.simpleBuy.pair

export const getSBPaymentMethod = (state: RootState) =>
state.components.simpleBuy.method

export const getSBPaymentMethods = (state: RootState) =>
state.components.simpleBuy.methods

Expand Down
Expand Up @@ -34,7 +34,6 @@ export type SBAddCardErrorType =
export type SBBillingAddressFormValuesType = NabuAddressType
export type SBCheckoutFormValuesType = {
amount: string
method?: SBFormPaymentMethod
orderType: 'BUY' | 'SELL'
}
export type SBCurrencySelectFormType = {
Expand Down Expand Up @@ -81,6 +80,7 @@ export type SimpleBuyState = {
everypay3DS: RemoteDataType<string, Everypay3DSResponseType>
fiatCurrency: undefined | FiatType
fiatEligible: RemoteDataType<string, FiatEligibleType>
method: undefined | SBFormPaymentMethod
methods: RemoteDataType<string, SBPaymentMethodsType>
order: undefined | SBOrderType
orders: RemoteDataType<string, Array<SBOrderType>>
Expand Down Expand Up @@ -311,8 +311,8 @@ export type StepActionsPayload =
step: 'CRYPTO_SELECTION'
}
| {
cryptoCurrency: CoinType
defaultMethod: SBFormPaymentMethod
cryptoCurrency?: CoinType
defaultMethod?: SBFormPaymentMethod
fiatCurrency: FiatType
pair: SBPairType
step: 'PAYMENT_METHODS'
Expand Down
Expand Up @@ -8,7 +8,7 @@ import { Field } from 'redux-form'
import { getFiatFromPair } from 'data/components/simpleBuy/model'
import { Icon, Text } from 'blockchain-info-components'
import { Props } from '../template.success'
import { SBCheckoutFormValuesType } from 'data/types'
import { SBFormPaymentMethod } from 'data/types'
import { SelectBox } from 'components/Form'
import React, { PureComponent, ReactElement } from 'react'
import styled from 'styled-components'
Expand Down Expand Up @@ -261,6 +261,6 @@ class MethodSelect extends PureComponent<Props> {
}
}

type ElementValueType = Exclude<SBCheckoutFormValuesType['method'], undefined>
type ElementValueType = Exclude<SBFormPaymentMethod, undefined>

export default MethodSelect
Expand Up @@ -24,20 +24,13 @@ import Success from './template.success'

class Checkout extends PureComponent<Props> {
componentDidMount () {
this.props.simpleBuyActions.initializeCheckout(
this.props.paymentMethods,
this.props.cards,
'BUY'
)
this.props.simpleBuyActions.initializeCheckout('BUY')
}

handleSubmit = () => {
// if the user is < tier 2 go to kyc but save order info
// if the user is tier 2 try to submit order, let BE fail
const { formValues, userData } = this.props.data.getOrElse({
formValues: {
method: { limits: { min: '0', max: '0' }, type: 'BANK_ACCOUNT' }
} as SBCheckoutFormValuesType,
userData: { tiers: { current: 0, next: 0, selected: 0 } } as UserDataType
} as SuccessStateType)

Expand All @@ -51,19 +44,26 @@ class Checkout extends PureComponent<Props> {
)
this.props.simpleBuyActions.createSBOrder(
undefined,
formValues?.method?.type as SBPaymentMethodType['type']
this.props.method.type as SBPaymentMethodType['type']
)
} else if (formValues && formValues.method) {
// eslint-disable-next-line
console.log('here we gooo', formValues.method.type)
switch (formValues.method.type) {
} else if (formValues && !this.props.method) {
const fiatCurrency = this.props.fiatCurrency || 'USD'
this.props.simpleBuyActions.setStep({
step: 'PAYMENT_METHODS',
fiatCurrency,
pair: this.props.pair
})
} else if (formValues && this.props.method) {
switch (this.props.method.type) {
case 'PAYMENT_CARD':
this.props.simpleBuyActions.setStep({
step: 'ADD_CARD'
})
break
case 'USER_CARD':
this.props.simpleBuyActions.createSBOrder(formValues.method.id)
// TODO figure out id
// this.props.simpleBuyActions.createSBOrder(formValues.method.id)
this.props.simpleBuyActions.createSBOrder()
break
case 'BANK_ACCOUNT':
this.props.simpleBuyActions.createSBOrder()
Expand Down
Expand Up @@ -20,7 +20,6 @@ import { SBCheckoutFormValuesType } from 'data/types'
import ActionButton from './ActionButton'
import Currencies from 'blockchain-wallet-v4/src/exchange/currencies'
import Failure from '../template.failure'
import MethodSelect from './MethodSelect'
import React from 'react'
import styled from 'styled-components'

Expand Down Expand Up @@ -126,7 +125,7 @@ const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
const prop = amtError === 'ABOVE_MAX' ? 'max' : 'min'
const value = convertStandardToBase(
'FIAT',
getMaxMin(props.pair, prop, props.formValues)
getMaxMin(props.pair, prop, props.formValues, props.method)
)
props.simpleBuyActions.handleSBSuggestedAmountClick(value)
}
Expand Down Expand Up @@ -177,7 +176,12 @@ const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
values={{
value: fiatToString({
unit: fiatCurrency,
value: getMaxMin(props.pair, 'max', props.formValues),
value: getMaxMin(
props.pair,
'max',
props.formValues,
props.method
),
digits: 0
}),
orderType:
Expand All @@ -191,7 +195,12 @@ const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
values={{
value: fiatToString({
unit: fiatCurrency,
value: getMaxMin(props.pair, 'min', props.formValues),
value: getMaxMin(
props.pair,
'min',
props.formValues,
props.method
),
digits: 0
}),
orderType:
Expand Down Expand Up @@ -254,7 +263,6 @@ const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
</GreyBlueCartridge>
</Amounts>
)}
<MethodSelect {...props} />
{props.error && (
<ErrorText>
<Icon
Expand Down
@@ -1,37 +1,32 @@
import { convertBaseToStandard } from 'data/components/exchange/services'
import { SBCheckoutFormValuesType } from 'data/types'
import { SBCheckoutFormValuesType, SBFormPaymentMethod } from 'data/types'
import BigNumber from 'bignumber.js'

import { SBPairType } from 'core/types'

export const getMaxMin = (
pair: SBPairType,
minOrMax?: 'min' | 'max',
allValues?: SBCheckoutFormValuesType
allValues?: SBCheckoutFormValuesType,
method?: SBFormPaymentMethod
) => {
switch (minOrMax || 'max') {
case 'max':
const defaultMax = convertBaseToStandard('FIAT', 0)
if (!allValues) return defaultMax
if (!allValues.method) return defaultMax
if (!method) return defaultMax
if (!pair) return defaultMax

const max = BigNumber.minimum(
allValues.method.limits.max,
pair.buyMax
).toString()
const max = BigNumber.minimum(method.limits.max, pair.buyMax).toString()

return convertBaseToStandard('FIAT', max)
case 'min':
const defaultMin = convertBaseToStandard('FIAT', 0)
if (!allValues) return defaultMin
if (!allValues.method) return defaultMin
if (!method) return defaultMin
if (!pair) return defaultMin

const min = BigNumber.maximum(
allValues.method.limits.min,
pair.buyMin
).toString()
const min = BigNumber.maximum(method.limits.min, pair.buyMin).toString()

return convertBaseToStandard('FIAT', min)
}
Expand Down
Expand Up @@ -11,6 +11,7 @@ import {
} from 'core/types'
import { getData } from './selectors'
import { RootState } from 'data/rootReducer'
import { SBFormPaymentMethod } from 'data/components/simpleBuy/types'
import Failure from './template.failure'
import Loading from './template.loading'
import React, { PureComponent } from 'react'
Expand Down Expand Up @@ -49,6 +50,7 @@ const connector = connect(mapStateToProps, mapDispatchToProps)

export type OwnProps = {
handleClose: () => void
method: SBFormPaymentMethod
pair: SBPairType
}
export type SuccessStateType = {
Expand Down
@@ -0,0 +1,53 @@
import { FlyoutWrapper } from 'components/Flyout'
import { Form, InjectedFormProps, reduxForm } from 'redux-form'
import { FormattedMessage } from 'react-intl'
import { Icon, Text } from 'blockchain-info-components'
import { Props as OwnProps, SuccessStateType } from '../index'
import React from 'react'
import styled from 'styled-components'

const Wrapper = styled.div`
display: flex;
justify-content: space-between;
flex-direction: column;
height: 100%;
`
const TopText = styled(Text)`
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 7px;
`

export type Props = OwnProps & SuccessStateType

const Payments: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
return (
<Wrapper>
<Form>
<FlyoutWrapper>
<TopText color='grey800' size='20px' weight={600}>
<FormattedMessage
id='modals.simplebuy.paymentmethods'
defaultMessage='Payment Methods'
/>
<Icon
cursor
data-e2e='sbCloseModalIcon'
name='close'
size='20px'
color='grey600'
role='button'
onClick={props.handleClose}
/>
</TopText>
</FlyoutWrapper>
</Form>
</Wrapper>
)
}

export default reduxForm<{}, Props>({
form: 'sbPaymentMethods',
destroyOnUnmount: false
})(Payments)

0 comments on commit 92d19c0

Please sign in to comment.