use Stripe.js payment input fields

Signed-off-by: Loan Laux <loan@outgrow.io>
This commit is contained in:
Loan Laux 2021-07-30 15:47:34 +02:00
parent f5cdc66a68
commit b79a3cd13d
No known key found for this signature in database
GPG Key ID: AF9E9BD6548AD52E
6 changed files with 47 additions and 6 deletions

View File

@ -1,5 +1,12 @@
import { FC } from 'react' import { FC } from 'react'
import cn from 'classnames' import cn from 'classnames'
import {
CardNumberElement,
CardExpiryElement,
CardCvcElement,
useStripe,
useElements
} from '@stripe/react-stripe-js'
import { Button, Text } from '@components/ui' import { Button, Text } from '@components/ui'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import s from './PaymentMethodView.module.css' import s from './PaymentMethodView.module.css'
@ -20,15 +27,15 @@ const PaymentMethodView: FC = () => {
<div className="grid gap-3 grid-flow-row grid-cols-12"> <div className="grid gap-3 grid-flow-row grid-cols-12">
<div className={cn(s.fieldset, 'col-span-7')}> <div className={cn(s.fieldset, 'col-span-7')}>
<label className={s.label}>Card Number</label> <label className={s.label}>Card Number</label>
<input className={s.input} /> <CardNumberElement className={s.input} />
</div> </div>
<div className={cn(s.fieldset, 'col-span-3')}> <div className={cn(s.fieldset, 'col-span-3')}>
<label className={s.label}>Expires</label> <label className={s.label}>Expires</label>
<input className={s.input} placeholder="MM/YY" /> <CardExpiryElement className={s.input} placeholder='MM/YY' />
</div> </div>
<div className={cn(s.fieldset, 'col-span-2')}> <div className={cn(s.fieldset, 'col-span-2')}>
<label className={s.label}>CVC</label> <label className={s.label}>CVC</label>
<input className={s.input} /> <CardCvcElement className={s.input} />
</div> </div>
</div> </div>
<hr className="border-accent-2 my-6" /> <hr className="border-accent-2 my-6" />

View File

@ -0,0 +1,19 @@
import React, { Component } from 'react'
import { loadStripe } from '@stripe/stripe-js'
import { Elements } from '@stripe/react-stripe-js'
export default function withStripeElements(WrappedComponent) {
const stripe = loadStripe(process.env.STRIPE_PUBLIC_API_KEY)
return class extends Component {
static displayName = "withStripeElements"
render() {
return (
<Elements stripe={stripe}>
<WrappedComponent {...this.props} />
</Elements>
);
}
};
}

View File

@ -13,9 +13,9 @@ import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui' import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
import PaymentMethodView from '@components/checkout/PaymentMethodView' import PaymentMethodView from '@components/checkout/PaymentMethodView'
import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView' import CheckoutSidebarView from '@components/checkout/CheckoutSidebarView'
import LoginView from '@components/auth/LoginView' import LoginView from '@components/auth/LoginView'
import s from './Layout.module.css' import s from './Layout.module.css'
import withStripeElements from '@components/checkout/withStripeElements'
const Loading = () => ( const Loading = () => (
<div className="w-80 h-80 flex items-center text-center justify-center p-3"> <div className="w-80 h-80 flex items-center text-center justify-center p-3">
@ -123,4 +123,4 @@ const Layout: FC<Props> = ({
) )
} }
export default Layout export default withStripeElements(Layout)

View File

@ -14,6 +14,7 @@ const isVendure = provider === 'vendure'
module.exports = withCommerceConfig({ module.exports = withCommerceConfig({
env: { env: {
REACTION_API_DOMAIN: process.env.REACTION_API_DOMAIN, REACTION_API_DOMAIN: process.env.REACTION_API_DOMAIN,
STRIPE_PUBLIC_API_KEY: process.env.STRIPE_PUBLIC_API_KEY,
}, },
commerce, commerce,
i18n: { i18n: {

View File

@ -21,6 +21,8 @@
}, },
"dependencies": { "dependencies": {
"@react-spring/web": "^9.2.1", "@react-spring/web": "^9.2.1",
"@stripe/react-stripe-js": "^1.4.1",
"@stripe/stripe-js": "^1.16.0",
"@vercel/fetch": "^6.1.0", "@vercel/fetch": "^6.1.0",
"autoprefixer": "^10.2.6", "autoprefixer": "^10.2.6",
"body-scroll-lock": "^3.1.5", "body-scroll-lock": "^3.1.5",

View File

@ -1012,6 +1012,18 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@stripe/react-stripe-js@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@stripe/react-stripe-js/-/react-stripe-js-1.4.1.tgz#884d59286fff00ba77389b32c045516f65d7a340"
integrity sha512-FjcVrhf72+9fUL3Lz3xi02ni9tzH1A1x6elXlr6tvBDgSD55oPJuodoP8eC7xTnBIKq0olF5uJvgtkJyDCdzjA==
dependencies:
prop-types "^15.7.2"
"@stripe/stripe-js@^1.16.0":
version "1.16.0"
resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.16.0.tgz#73bce24fb7f47d719caa6b151e58e49b4167d463"
integrity sha512-ZSHbiwTrISoaTbpercmYGuY7QTg7HxfFyNgbJBaYbwHWbzMhpEdGTsmMpaBXIU6iiqwEEDaIyD8O6yJ+H5DWCg==
"@szmarczak/http-timer@^1.1.2": "@szmarczak/http-timer@^1.1.2":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -4880,7 +4892,7 @@ promise@^7.1.1:
dependencies: dependencies:
asap "~2.0.3" asap "~2.0.3"
prop-types@15.7.2: prop-types@15.7.2, prop-types@^15.7.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==