Skip to content

Commit

Permalink
feat(simple buy): card number and cvc validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip London committed Apr 21, 2020
1 parent 45dde34 commit c71e5d9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { CommonFieldProps, WrappedFieldMetaProps } from 'redux-form'
import { DEFAULT_CARD_FORMAT, getCardTypeByValue } from './model'
import {
DEFAULT_CARD_FORMAT,
DEFAULT_CARD_SVG_LOGO,
getCardTypeByValue
} from './model'
import { FormattedMessage } from 'react-intl'
import { TextBox } from 'components/Form'
import React from 'react'
import styled from 'styled-components'

export const normalizeCreditCard = (value, previousValue) => {
if (!value) return value
Expand Down Expand Up @@ -44,6 +49,15 @@ export const validateCreditCard = value => {
)
}

if (value.replace(/[^\d]/g, '').length < cardType.minCardNumberLength) {
return (
<FormattedMessage
id='formhelper.invalid_card_number'
defaultMessage='Invalid card number'
/>
)
}

if (!cardType.supported) {
return (
<FormattedMessage
Expand All @@ -54,10 +68,32 @@ export const validateCreditCard = value => {
}
}

const Wrapper = styled.div`
width: 100%;
height: 100%;
position: relative;
`
const CardLogo = styled.img`
position: absolute;
height: 24px;
right: 8px;
top: 11px;
`

const CreditCardBox: React.FC<Props> = props => {
return <TextBox {...props} />
const cardType = getCardTypeByValue(props.input.value)

return (
<Wrapper>
<TextBox {...props} />
<CardLogo src={cardType ? cardType.logo : DEFAULT_CARD_SVG_LOGO} />
</Wrapper>
)
}

type Props = { input: CommonFieldProps; meta: WrappedFieldMetaProps }
type Props = {
input: CommonFieldProps & { value: string }
meta: WrappedFieldMetaProps
}

export default CreditCardBox
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const DEFAULT_CVC_LENGTH = 3
export const DEFAULT_ZIP_LENGTH = 5
export const DEFAULT_CARD_MIN = 13
export const DEFAULT_CARD_FORMAT = /(\d{1,4})/g
export const DEFAULT_CARD_SVG_LOGO =
'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNTc2IDM3NyIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5wbGFjZWhvbGRlcjwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9InBsYWNlaG9sZGVyIj4gICAgICAgICAgICA8cGF0aCBkPSJNNTI3LjkzMzc5MywzNzYuOTk4MjggTDQ4LjA2NjIwNjksMzc2Ljk5ODI4IEMzNS40MjM0ODAzLDM3Ny4xMDM5NjggMjMuMjU2NTg2NCwzNzIuMTg3ODkgMTQuMjQyMzI4MSwzNjMuMzMxNjE4IEM1LjIyODA2OTc1LDM1NC40NzUzNDYgMC4xMDQ5MTcxMDIsMzQyLjQwNDQwNyAwLDMyOS43NzQ0OTQgTDAsNDcuMjI1NDU1NCBDMC4xMDQ5MTcxMDIsMzQuNTk1NTQyNSA1LjIyODA2OTc1LDIyLjUyNDYwNCAxNC4yNDIzMjgxLDEzLjY2ODMzMTkgQzIzLjI1NjU4NjQsNC44MTIwNTk4NSAzNS40MjM0ODAzLC0wLjEwNDAxODI5NiA0OC4wNjYyMDY5LDAuMDAxNjY5NDg2NDYgTDUyNy45MzM3OTMsMC4wMDE2Njk0ODY0NiBDNTQwLjU3NjUyLC0wLjEwNDAxODI5NiA1NTIuNzQzNDE0LDQuODEyMDU5ODUgNTYxLjc1NzY3MiwxMy42NjgzMzE5IEM1NzAuNzcxOTMsMjIuNTI0NjA0IDU3NS44OTUwODMsMzQuNTk1NTQyNSA1NzYsNDcuMjI1NDU1NCBMNTc2LDMyOS45NzI5MTMgQzU3NS42NzI3ODYsMzU2LjE5NTY2MyA1NTQuMTg0MjczLDM3Ny4yMTg4NTcgNTI3LjkzMzc5MywzNzYuOTk4MjggWiIgaWQ9InNoYXBlIiBmaWxsPSIjRThFQkVFIiBmaWxsLXJ1bGU9Im5vbnplcm8iPjwvcGF0aD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiBzdHJva2U9IiM3NTc1NzUiIHN0cm9rZS13aWR0aD0iMjAiIHg9IjQxOCIgeT0iNTgiIHdpZHRoPSI5MSIgaGVpZ2h0PSI2MyIgcng9IjMwIj48L3JlY3Q+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS0yIiBmaWxsPSIjNzU3NTc1IiB4PSI1MyIgeT0iMjA4IiB3aWR0aD0iMTA3IiBoZWlnaHQ9IjQwIiByeD0iOCI+PC9yZWN0PiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUtMiIgZmlsbD0iIzc1NzU3NSIgeD0iNDEzIiB5PSIyMDgiIHdpZHRoPSIxMDciIGhlaWdodD0iNDAiIHJ4PSI4Ij48L3JlY3Q+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS0yIiBmaWxsPSIjNzU3NTc1IiB4PSIyOTMiIHk9IjIwOCIgd2lkdGg9IjEwNyIgaGVpZ2h0PSI0MCIgcng9IjgiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTIiIGZpbGw9IiM3NTc1NzUiIHg9IjE3MyIgeT0iMjA4IiB3aWR0aD0iMTA3IiBoZWlnaHQ9IjQwIiByeD0iOCI+PC9yZWN0PiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+'

export const CARD_TYPES = [
{
Expand All @@ -12,6 +14,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 15,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: 4,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -21,6 +24,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -30,6 +34,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 19,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -39,6 +44,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 14,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -48,6 +54,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -57,6 +64,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -66,6 +74,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 19,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -75,6 +84,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 19,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -84,6 +94,8 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo:
'data:image/svg+xml;base64,PHN2ZyBmb2N1c2FibGU9ImZhbHNlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAyMSI+ICA8ZyBpZD0iUGFnZS0xIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICA8ZyBpZD0ibWFzdGVyY2FyZCI+ICAgICAgPGcgaWQ9ImNhcmQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgMikiPiAgICAgICAgPHBhdGggaWQ9InNoYXBlIiBmaWxsPSIjMDAzNjYzIiBkPSJNMjYuNTggMTlIMi40MkEyLjQgMi40IDAgMCAxIDAgMTYuNjJWMi4zOEEyLjQgMi40IDAgMCAxIDIuNDIgMGgyNC4xNkEyLjQgMi40IDAgMCAxIDI5IDIuMzh2MTQuMjVBMi40IDIuNCAwIDAgMSAyNi41OCAxOXoiLz4gICAgICAgIDxjaXJjbGUgaWQ9InNoYXBlIiBjeD0iMTAuNSIgY3k9IjkuNSIgcj0iNi41IiBmaWxsPSIjRUIxQzI2Ii8+ICAgICAgICA8Y2lyY2xlIGlkPSJzaGFwZSIgY3g9IjE4LjUiIGN5PSI5LjUiIHI9IjYuNSIgZmlsbD0iI0Y5OUYxQiIvPiAgICAgICAgPHBhdGggaWQ9InNoYXBlIiBmaWxsPSIjRUY1RDIwIiBkPSJNMTQuNSA0LjM4YTYuNDkgNi40OSAwIDAgMCAwIDEwLjI0IDYuNDkgNi40OSAwIDAgMCAwLTEwLjI0eiIvPiAgICAgIDwvZz4gICAgPC9nPiAgPC9nPjwvc3ZnPg==',
supported: false
},
{
Expand All @@ -93,6 +105,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 19,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false,
luhn: false
},
Expand All @@ -103,6 +116,8 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo:
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1NzZweCIgaGVpZ2h0PSIzNzlweCIgdmlld0JveD0iMCAwIDU3NiAzNzkiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+ICAgICAgICA8dGl0bGU+dmlzYTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9InZpc2EiIGZpbGwtcnVsZT0ibm9uemVybyI+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgZmlsbD0iIzI2MzM3QSIgeD0iMCIgeT0iMCIgd2lkdGg9IjU3NiIgaGVpZ2h0PSIzNzkiIHJ4PSI1MiI+PC9yZWN0PiAgICAgICAgICAgIDxwb2x5bGluZSBpZD0iRmlsbC0zIiBmaWxsPSIjRkZGRkZFIiBwb2ludHM9IjIyMSAyNjggMjQyLjU1MTE5MyAxMTEgMjc3IDExMSAyNTUuNDUwNzc5IDI2OCAyMjEgMjY4Ij48L3BvbHlsaW5lPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0zOTQuNTIxOTgxLDExNy4zNzIyMjkgQzM4Ny4wNDE1NTcsMTE0LjMyNDA1NiAzNzUuMjc2NzEzLDExMSAzNjAuNjIwOTY4LDExMSBDMzIzLjIxNjY4MywxMTEgMjk2Ljg4Njk3NSwxMzEuNjEwNDk0IDI5Ni42Njg0MjcsMTYxLjEyMzI2OSBDMjk2LjQzMDQwMywxODIuOTUzOTI5IDMxNS40NTcxMjMsMTk1LjEyODY3OCAzMjkuODAxMjc0LDIwMi4zODQ2MzEgQzM0NC41NDM1NzQsMjA5LjgyMjI2MyAzNDkuNDk2NjIzLDIxNC41ODE4MDggMzQ5LjQzODE5OSwyMjEuMjMyMTY0IEMzNDkuMzM2NDk5LDIzMS40MDM5NTUgMzM3LjY3MTE5MSwyMzYuMDY0ODEyIDMyNi43OTM1MjUsMjM2LjA2NDgxMiBDMzExLjY0NjU4NywyMzYuMDY0ODEyIDMwMy41OTkyMzQsMjMzLjc3MDI3MiAyOTEuMTU3MTA1LDIyOC4xMDAwODcgTDI4Ni4yOTA2MTEsMjI1LjY4MjE4MyBMMjgxLDI1OS42Nzg2MiBDMjg5LjgyMjAxLDI2My45MDg4MjkgMzA2LjE3NjM3NywyNjcuNTgwNTQ0IDMyMy4xNDk2MDQsMjY3Ljc3MzQzOCBDMzYyLjkwMTY2NCwyNjcuNzczNDM4IDM4OC43MzE1MjIsMjQ3LjQxMTkxIDM4OS4wMzQ0NjIsMjE1Ljg5NjE4IEMzODkuMTcwNzg1LDE5OC41ODUwNjggMzc5LjA4OTQxNCwxODUuNDYzNzkzIDM1Ny4yNTYxODMsMTc0LjYzMDMzMiBDMzQ0LjAzNTA3LDE2Ny41ODc0NTkgMzM1LjkyMDYzOCwxNjIuOTIyMTE3IDMzNi4wMTM2ODMsMTU1Ljc5NDAxMiBDMzM2LjAyMjMzOSwxNDkuNDgyMzQzIDM0Mi44Njg3NTUsMTQyLjcyNDMyNiAzNTcuNjg2NzksMTQyLjcyNDMyNiBDMzcwLjA2MTgzOSwxNDIuNTE3OTc0IDM3OS4wMjAxNzEsMTQ1LjQ3NDE4NyAzODYuMDAwNzQ2LDE0OC41NjA0ODkgTDM4OS4zOTc5ODgsMTUwLjI5NjUzNSBMMzk0LjUyMTk4MSwxMTcuMzcyMjI5IiBpZD0iRmlsbC00IiBmaWxsPSIjRkZGRkZFIj48L3BhdGg+ICAgICAgICAgICAgPHBhdGggZD0iTTQ0OC4zNTgwMTIsMjEyLjI0NDQ0NCBDNDUxLjU4ODczMSwyMDMuMjE0NDE1IDQ2My44ODczMDgsMTY4LjMzMDk0IDQ2My44ODczMDgsMTY4LjMzMDk0IEM0NjMuNjU5ODg4LDE2OC43NDYyNDYgNDY3LjEwMDE4OSwxNTkuMjMxMzA2IDQ2OS4wNjg5NDIsMTUzLjM0Mjc2MSBMNDcxLjY5OTg5NCwxNjYuODkyNDQ2IEM0NzEuNjk5ODk0LDE2Ni44OTI0NDYgNDc5LjE4MDI2NSwyMDQuMzkwNzMyIDQ4MC43MjA5MzIsMjEyLjI0NDQ0NCBMNDQ4LjM1ODAxMiwyMTIuMjQ0NDQ0IFogTTQ5Ni40NTA4OTIsMTExIEw0NjYuMzI0MjgyLDExMSBDNDU2Ljk3OTk0OSwxMTEgNDQ5Ljk4NTYzNSwxMTMuNzc5NTQyIDQ0NS44OTIwNTQsMTI0LjAyMzAxIEwzODgsMjY4IEw0MjguOTQ0NzIxLDI2OCBDNDI4Ljk0NDcyMSwyNjggNDM1LjYyNDY1OSwyNDguNjMxMzc3IDQzNy4xNDA4MDEsMjQ0LjM4MDg2IEM0NDEuNjA2NzI2LDI0NC4zODA4NiA0ODEuMzkyMDQ2LDI0NC40NjIwNjUgNDg3LjA3MDg4NiwyNDQuNDYyMDY1IEM0ODguMjM5MjA2LDI0OS45NDQ1ODIgNDkxLjgxNzc0NCwyNjggNDkxLjgxNzc0NCwyNjggTDUyOCwyNjggTDQ5Ni40NTA4OTIsMTExIFoiIGlkPSJGaWxsLTUiIGZpbGw9IiNGRkZGRkUiPjwvcGF0aD4gICAgICAgICAgICA8cGF0aCBkPSJNMTg5Ljk1NTA2OCwxMTEgTDE1MS4xMjExNDYsMjE4LjIxOTk2NSBMMTQ2Ljk2MTU4NCwxOTYuNDI0Nzk3IEMxMzkuNzI0OSwxNzEuMzEyOTczIDExNy4xOTc5MTIsMTQ0LjA5NDU2MSA5MiwxMzAuNDU2MzIzIEwxMjcuNTI3NjA0LDI2OCBMMTY5LjUxODA3MywyNjcuOTc0NDUyIEwyMzIsMTExIEwxODkuOTU1MDY4LDExMSIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZGRkZGRSI+PC9wYXRoPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMTMuOTE4NTUxLDExMSBMNDcuNTQ2MTM4LDExMSBMNDcsMTE0LjMxNDUzMyBDOTguNjQ1NDgwNiwxMjcuNTY1NTc5IDEzMi44MTY4NTUsMTU5LjU1MDk0MyAxNDcsMTk4IEwxMzIuNTc2NzQzLDEyNC40OTY3NDEgQzEzMC4wODg1MTMsMTE0LjM1OTQyIDEyMi44NTY4NzQsMTExLjM1NDM3IDExMy45MTg1NTEsMTExIiBpZD0iRmlsbC03IiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=',
supported: true
},
{
Expand All @@ -112,6 +127,7 @@ export const CARD_TYPES = [
maxCardNumberLength: 16,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo: DEFAULT_CARD_SVG_LOGO,
supported: false
},
{
Expand All @@ -121,6 +137,8 @@ export const CARD_TYPES = [
maxCardNumberLength: 19,
minCardNumberLength: DEFAULT_CARD_MIN,
cvcLength: DEFAULT_CVC_LENGTH,
logo:
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1NzZweCIgaGVpZ2h0PSIzNzlweCIgdmlld0JveD0iMCAwIDU3NiAzNzkiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+ICAgICAgICA8dGl0bGU+dmlzYTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9InZpc2EiIGZpbGwtcnVsZT0ibm9uemVybyI+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZSIgZmlsbD0iIzI2MzM3QSIgeD0iMCIgeT0iMCIgd2lkdGg9IjU3NiIgaGVpZ2h0PSIzNzkiIHJ4PSI1MiI+PC9yZWN0PiAgICAgICAgICAgIDxwb2x5bGluZSBpZD0iRmlsbC0zIiBmaWxsPSIjRkZGRkZFIiBwb2ludHM9IjIyMSAyNjggMjQyLjU1MTE5MyAxMTEgMjc3IDExMSAyNTUuNDUwNzc5IDI2OCAyMjEgMjY4Ij48L3BvbHlsaW5lPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0zOTQuNTIxOTgxLDExNy4zNzIyMjkgQzM4Ny4wNDE1NTcsMTE0LjMyNDA1NiAzNzUuMjc2NzEzLDExMSAzNjAuNjIwOTY4LDExMSBDMzIzLjIxNjY4MywxMTEgMjk2Ljg4Njk3NSwxMzEuNjEwNDk0IDI5Ni42Njg0MjcsMTYxLjEyMzI2OSBDMjk2LjQzMDQwMywxODIuOTUzOTI5IDMxNS40NTcxMjMsMTk1LjEyODY3OCAzMjkuODAxMjc0LDIwMi4zODQ2MzEgQzM0NC41NDM1NzQsMjA5LjgyMjI2MyAzNDkuNDk2NjIzLDIxNC41ODE4MDggMzQ5LjQzODE5OSwyMjEuMjMyMTY0IEMzNDkuMzM2NDk5LDIzMS40MDM5NTUgMzM3LjY3MTE5MSwyMzYuMDY0ODEyIDMyNi43OTM1MjUsMjM2LjA2NDgxMiBDMzExLjY0NjU4NywyMzYuMDY0ODEyIDMwMy41OTkyMzQsMjMzLjc3MDI3MiAyOTEuMTU3MTA1LDIyOC4xMDAwODcgTDI4Ni4yOTA2MTEsMjI1LjY4MjE4MyBMMjgxLDI1OS42Nzg2MiBDMjg5LjgyMjAxLDI2My45MDg4MjkgMzA2LjE3NjM3NywyNjcuNTgwNTQ0IDMyMy4xNDk2MDQsMjY3Ljc3MzQzOCBDMzYyLjkwMTY2NCwyNjcuNzczNDM4IDM4OC43MzE1MjIsMjQ3LjQxMTkxIDM4OS4wMzQ0NjIsMjE1Ljg5NjE4IEMzODkuMTcwNzg1LDE5OC41ODUwNjggMzc5LjA4OTQxNCwxODUuNDYzNzkzIDM1Ny4yNTYxODMsMTc0LjYzMDMzMiBDMzQ0LjAzNTA3LDE2Ny41ODc0NTkgMzM1LjkyMDYzOCwxNjIuOTIyMTE3IDMzNi4wMTM2ODMsMTU1Ljc5NDAxMiBDMzM2LjAyMjMzOSwxNDkuNDgyMzQzIDM0Mi44Njg3NTUsMTQyLjcyNDMyNiAzNTcuNjg2NzksMTQyLjcyNDMyNiBDMzcwLjA2MTgzOSwxNDIuNTE3OTc0IDM3OS4wMjAxNzEsMTQ1LjQ3NDE4NyAzODYuMDAwNzQ2LDE0OC41NjA0ODkgTDM4OS4zOTc5ODgsMTUwLjI5NjUzNSBMMzk0LjUyMTk4MSwxMTcuMzcyMjI5IiBpZD0iRmlsbC00IiBmaWxsPSIjRkZGRkZFIj48L3BhdGg+ICAgICAgICAgICAgPHBhdGggZD0iTTQ0OC4zNTgwMTIsMjEyLjI0NDQ0NCBDNDUxLjU4ODczMSwyMDMuMjE0NDE1IDQ2My44ODczMDgsMTY4LjMzMDk0IDQ2My44ODczMDgsMTY4LjMzMDk0IEM0NjMuNjU5ODg4LDE2OC43NDYyNDYgNDY3LjEwMDE4OSwxNTkuMjMxMzA2IDQ2OS4wNjg5NDIsMTUzLjM0Mjc2MSBMNDcxLjY5OTg5NCwxNjYuODkyNDQ2IEM0NzEuNjk5ODk0LDE2Ni44OTI0NDYgNDc5LjE4MDI2NSwyMDQuMzkwNzMyIDQ4MC43MjA5MzIsMjEyLjI0NDQ0NCBMNDQ4LjM1ODAxMiwyMTIuMjQ0NDQ0IFogTTQ5Ni40NTA4OTIsMTExIEw0NjYuMzI0MjgyLDExMSBDNDU2Ljk3OTk0OSwxMTEgNDQ5Ljk4NTYzNSwxMTMuNzc5NTQyIDQ0NS44OTIwNTQsMTI0LjAyMzAxIEwzODgsMjY4IEw0MjguOTQ0NzIxLDI2OCBDNDI4Ljk0NDcyMSwyNjggNDM1LjYyNDY1OSwyNDguNjMxMzc3IDQzNy4xNDA4MDEsMjQ0LjM4MDg2IEM0NDEuNjA2NzI2LDI0NC4zODA4NiA0ODEuMzkyMDQ2LDI0NC40NjIwNjUgNDg3LjA3MDg4NiwyNDQuNDYyMDY1IEM0ODguMjM5MjA2LDI0OS45NDQ1ODIgNDkxLjgxNzc0NCwyNjggNDkxLjgxNzc0NCwyNjggTDUyOCwyNjggTDQ5Ni40NTA4OTIsMTExIFoiIGlkPSJGaWxsLTUiIGZpbGw9IiNGRkZGRkUiPjwvcGF0aD4gICAgICAgICAgICA8cGF0aCBkPSJNMTg5Ljk1NTA2OCwxMTEgTDE1MS4xMjExNDYsMjE4LjIxOTk2NSBMMTQ2Ljk2MTU4NCwxOTYuNDI0Nzk3IEMxMzkuNzI0OSwxNzEuMzEyOTczIDExNy4xOTc5MTIsMTQ0LjA5NDU2MSA5MiwxMzAuNDU2MzIzIEwxMjcuNTI3NjA0LDI2OCBMMTY5LjUxODA3MywyNjcuOTc0NDUyIEwyMzIsMTExIEwxODkuOTU1MDY4LDExMSIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZGRkZGRSI+PC9wYXRoPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMTMuOTE4NTUxLDExMSBMNDcuNTQ2MTM4LDExMSBMNDcsMTE0LjMxNDUzMyBDOTguNjQ1NDgwNiwxMjcuNTY1NTc5IDEzMi44MTY4NTUsMTU5LjU1MDk0MyAxNDcsMTk4IEwxMzIuNTc2NzQzLDEyNC40OTY3NDEgQzEzMC4wODg1MTMsMTE0LjM1OTQyIDEyMi44NTY4NzQsMTExLjM1NDM3IDExMy45MTg1NTEsMTExIiBpZD0iRmlsbC03IiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=',
supported: true
}
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
import { CommonFieldProps, WrappedFieldMetaProps } from 'redux-form'
import {
CommonFieldProps,
Normalizer,
Validator,
WrappedFieldMetaProps
} from 'redux-form'
import { DEFAULT_CVC_LENGTH, getCardTypeByValue } from '../CreditCardBox/model'
import { FormattedMessage } from 'react-intl'
import { SBAddCardFormValuesType } from 'data/types'
import { TextBox } from 'components/Form'
import React from 'react'

export const normalizeCreditCardCVC = (value, previousValue) => {
export const normalizeCreditCardCVC: Normalizer = (
value,
previousValue,
allValues: SBAddCardFormValuesType
) => {
if (!value) return value
if (value.length > 3) return previousValue

const onlyNums = value.replace(/[^\d]/g, '')
const { cvcLength } = getCardTypeByValue(allValues['card-number']) || {
cvcLength: DEFAULT_CVC_LENGTH
}

if (value.length > cvcLength) return previousValue

const onlyNums = value.replace(/[^\d]/g, '')
return onlyNums
}

export const validateCreditCardCVC: Validator = (
value,
allValues: SBAddCardFormValuesType
) => {
const { cvcLength } = getCardTypeByValue(allValues['card-number']) || {
cvcLength: DEFAULT_CVC_LENGTH
}
if (value.length < cvcLength) {
return (
<FormattedMessage
id='formhelper.invalidnumber'
defaultMessage='Invalid number'
/>
)
}
}

const CreditCardCVCBox: React.FC<Props> = props => {
return <TextBox {...props} />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
normalizeCreditCard,
validateCreditCard
} from 'components/Form/CreditCardBox'
import { normalizeCreditCardCVC } from 'components/Form/CreditCardCVCBox'
import {
normalizeCreditCardCVC,
validateCreditCardCVC
} from 'components/Form/CreditCardCVCBox'
import {
normalizeCreditCardExpiry,
validateCreditCardExpiry
Expand Down Expand Up @@ -107,7 +110,7 @@ const Success: React.FC<InjectedFormProps<{}, Props> & Props> = props => {
name='cvc'
component={CreditCardCVCBox}
normalize={normalizeCreditCardCVC}
validate={[required]}
validate={[required, validateCreditCardCVC]}
/>
</FormItem>
</FormGroup>
Expand Down

0 comments on commit c71e5d9

Please sign in to comment.