From 5f1904532900c491b8793d117299c7d4bf9f971c Mon Sep 17 00:00:00 2001 From: Thorsten Schaeff Date: Wed, 12 Feb 2020 14:10:37 +0800 Subject: [PATCH 1/8] Update stripe-node. --- examples/with-stripe-typescript/package.json | 2 +- .../pages/api/checkout_sessions/[id].ts | 5 +---- .../pages/api/checkout_sessions/index.ts | 5 +---- .../pages/api/payment_intents/index.ts | 5 +---- examples/with-stripe-typescript/pages/api/webhooks/index.ts | 5 +---- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/examples/with-stripe-typescript/package.json b/examples/with-stripe-typescript/package.json index 0745e8578d4c3b0..ed9894360c96588 100644 --- a/examples/with-stripe-typescript/package.json +++ b/examples/with-stripe-typescript/package.json @@ -17,7 +17,7 @@ "next": "latest", "react": "^16.12.0", "react-dom": "^16.12.0", - "stripe": "^8.8.1", + "stripe": "^8.15.0", "swr": "^0.1.16" }, "devDependencies": { diff --git a/examples/with-stripe-typescript/pages/api/checkout_sessions/[id].ts b/examples/with-stripe-typescript/pages/api/checkout_sessions/[id].ts index 5c7bc3a3c6e126f..815a1e4db345b2e 100644 --- a/examples/with-stripe-typescript/pages/api/checkout_sessions/[id].ts +++ b/examples/with-stripe-typescript/pages/api/checkout_sessions/[id].ts @@ -1,12 +1,9 @@ import { NextApiRequest, NextApiResponse } from 'next' import Stripe from 'stripe' -const stripeSecretKey: string = process.env.STRIPE_SECRET_KEY! -const stripe = new Stripe(stripeSecretKey, { +const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { // https://github.com/stripe/stripe-node#configuration apiVersion: '2019-12-03', - typescript: true, - telemetry: true, }) export default async (req: NextApiRequest, res: NextApiResponse) => { diff --git a/examples/with-stripe-typescript/pages/api/checkout_sessions/index.ts b/examples/with-stripe-typescript/pages/api/checkout_sessions/index.ts index 469c700d1135dda..3b8706adfbea106 100644 --- a/examples/with-stripe-typescript/pages/api/checkout_sessions/index.ts +++ b/examples/with-stripe-typescript/pages/api/checkout_sessions/index.ts @@ -4,12 +4,9 @@ import { CURRENCY, MIN_AMOUNT, MAX_AMOUNT } from '../../../config' import { formatAmountForStripe } from '../../../utils/stripe-helpers' import Stripe from 'stripe' -const stripeSecretKey: string = process.env.STRIPE_SECRET_KEY! -const stripe = new Stripe(stripeSecretKey, { +const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { // https://github.com/stripe/stripe-node#configuration apiVersion: '2019-12-03', - typescript: true, - telemetry: true, }) export default async (req: NextApiRequest, res: NextApiResponse) => { diff --git a/examples/with-stripe-typescript/pages/api/payment_intents/index.ts b/examples/with-stripe-typescript/pages/api/payment_intents/index.ts index 7e6cc9d56d2f122..5f6228479cbacc0 100644 --- a/examples/with-stripe-typescript/pages/api/payment_intents/index.ts +++ b/examples/with-stripe-typescript/pages/api/payment_intents/index.ts @@ -4,12 +4,9 @@ import { CURRENCY, MIN_AMOUNT, MAX_AMOUNT } from '../../../config' import { formatAmountForStripe } from '../../../utils/stripe-helpers' import Stripe from 'stripe' -const stripeSecretKey: string = process.env.STRIPE_SECRET_KEY! -const stripe = new Stripe(stripeSecretKey, { +const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { // https://github.com/stripe/stripe-node#configuration apiVersion: '2019-12-03', - typescript: true, - telemetry: true, }) export default async (req: NextApiRequest, res: NextApiResponse) => { diff --git a/examples/with-stripe-typescript/pages/api/webhooks/index.ts b/examples/with-stripe-typescript/pages/api/webhooks/index.ts index 700d43594cab2b2..4c375bbb892d04a 100644 --- a/examples/with-stripe-typescript/pages/api/webhooks/index.ts +++ b/examples/with-stripe-typescript/pages/api/webhooks/index.ts @@ -3,12 +3,9 @@ import Cors from 'micro-cors' import { NextApiRequest, NextApiResponse } from 'next' import Stripe from 'stripe' -const stripeSecretKey: string = process.env.STRIPE_SECRET_KEY! -const stripe = new Stripe(stripeSecretKey, { +const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { // https://github.com/stripe/stripe-node#configuration apiVersion: '2019-12-03', - typescript: true, - telemetry: true, }) const webhookSecret: string = process.env.STRIPE_WEBHOOK_SECRET! From 7f02f412f09b22ff579cdf36b4780e7677e6328a Mon Sep 17 00:00:00 2001 From: Thorsten Schaeff Date: Wed, 12 Feb 2020 14:16:21 +0800 Subject: [PATCH 2/8] Update casting. --- .../pages/api/webhooks/index.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/with-stripe-typescript/pages/api/webhooks/index.ts b/examples/with-stripe-typescript/pages/api/webhooks/index.ts index 4c375bbb892d04a..0ae6ef52c3ef1be 100644 --- a/examples/with-stripe-typescript/pages/api/webhooks/index.ts +++ b/examples/with-stripe-typescript/pages/api/webhooks/index.ts @@ -42,18 +42,16 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => { // Cast event data to Stripe object. if (event.type === 'payment_intent.succeeded') { - const stripeObject: Stripe.PaymentIntent = event.data - .object as Stripe.PaymentIntent - console.log(`💰 PaymentIntent status: ${stripeObject.status}`) - } else if (event.type === 'charge.succeeded') { - const stripeObject = event.data.object as Stripe.Charge - console.log(`💵 Charge id: ${stripeObject.id}`) + const paymentIntent = event.data.object as Stripe.PaymentIntent + console.log(`💰 PaymentIntent status: ${paymentIntent.status}`) } else if (event.type === 'payment_intent.payment_failed') { - const stripeObject: Stripe.PaymentIntent = event.data - .object as Stripe.PaymentIntent + const paymentIntent = event.data.object as Stripe.PaymentIntent console.log( - `❌ Payment failed: ${stripeObject.last_payment_error?.message}` + `❌ Payment failed: ${paymentIntent.last_payment_error?.message}` ) + } else if (event.type === 'charge.succeeded') { + const charge = event.data.object as Stripe.Charge + console.log(`💵 Charge id: ${charge.id}`) } else { console.warn(`🤷‍♀️ Unhandled event type: ${event.type}`) } From 9e241048a5ebee8d6eb766ba5ed26c99a29132cf Mon Sep 17 00:00:00 2001 From: Thorsten Schaeff Date: Thu, 13 Feb 2020 22:05:55 +0800 Subject: [PATCH 3/8] =?UTF-8?q?Add=20global=20CSS=20styles=20=F0=9F=92=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/CheckoutForm.tsx | 11 +- .../components/CustomDonationInput.tsx | 12 + .../components/ElementsForm.tsx | 75 +++-- .../components/Layout.tsx | 44 +-- .../with-stripe-typescript/pages/_app.tsx | 9 + .../pages/donate-with-checkout.tsx | 14 +- .../pages/donate-with-elements.tsx | 14 +- .../with-stripe-typescript/pages/index.tsx | 29 +- .../with-stripe-typescript/pages/result.tsx | 19 +- .../public/checkout-one-time-payments.svg | 1 + .../public/elements-card-payment.svg | 1 + .../with-stripe-typescript/public/logo.png | Bin 0 -> 10186 bytes examples/with-stripe-typescript/styles.css | 270 ++++++++++++++++++ 13 files changed, 406 insertions(+), 93 deletions(-) create mode 100644 examples/with-stripe-typescript/pages/_app.tsx create mode 100644 examples/with-stripe-typescript/public/checkout-one-time-payments.svg create mode 100644 examples/with-stripe-typescript/public/elements-card-payment.svg create mode 100644 examples/with-stripe-typescript/public/logo.png create mode 100644 examples/with-stripe-typescript/styles.css diff --git a/examples/with-stripe-typescript/components/CheckoutForm.tsx b/examples/with-stripe-typescript/components/CheckoutForm.tsx index 4e7de2c956bb07c..3844523570ec79e 100644 --- a/examples/with-stripe-typescript/components/CheckoutForm.tsx +++ b/examples/with-stripe-typescript/components/CheckoutForm.tsx @@ -9,7 +9,9 @@ import * as config from '../config' import { useStripe } from '@stripe/react-stripe-js' const CheckoutForm: React.FunctionComponent = () => { - const [input, setInput] = useState({ customDonation: config.MIN_AMOUNT }) + const [input, setInput] = useState({ + customDonation: Math.round(config.MAX_AMOUNT / config.AMOUNT_STEP), + }) const stripe = useStripe() const handleInputChange: React.ChangeEventHandler = e => @@ -46,6 +48,7 @@ const CheckoutForm: React.FunctionComponent = () => { return (
{ currency={config.CURRENCY} onChange={handleInputChange} /> - diff --git a/examples/with-stripe-typescript/components/CustomDonationInput.tsx b/examples/with-stripe-typescript/components/CustomDonationInput.tsx index 67e1d7a117530ff..ffc64839807c4c2 100644 --- a/examples/with-stripe-typescript/components/CustomDonationInput.tsx +++ b/examples/with-stripe-typescript/components/CustomDonationInput.tsx @@ -9,6 +9,7 @@ type Props = { currency: string step: number onChange: (e: React.ChangeEvent) => void + className?: string } const CustomDonationInput: React.FunctionComponent = ({ @@ -19,11 +20,13 @@ const CustomDonationInput: React.FunctionComponent = ({ currency, step, onChange, + className, }) => ( ) diff --git a/examples/with-stripe-typescript/components/ElementsForm.tsx b/examples/with-stripe-typescript/components/ElementsForm.tsx index 6686e1fab73fae3..cd822895a072473 100644 --- a/examples/with-stripe-typescript/components/ElementsForm.tsx +++ b/examples/with-stripe-typescript/components/ElementsForm.tsx @@ -9,9 +9,32 @@ import * as config from '../config' import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js' +const CARD_OPTIONS = { + style: { + base: { + iconColor: '#6772e5', + color: '#6772e5', + fontWeight: '500', + fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif', + fontSize: '16px', + fontSmoothing: 'antialiased', + ':-webkit-autofill': { + color: '#fce883', + }, + '::placeholder': { + color: '#6772e5', + }, + }, + invalid: { + iconColor: '#ef2961', + color: '#ef2961', + }, + }, +} + const ElementsForm: React.FunctionComponent = () => { const [input, setInput] = useState({ - customDonation: config.MIN_AMOUNT, + customDonation: Math.round(config.MAX_AMOUNT / config.AMOUNT_STEP), cardholderName: '', }) const [payment, setPayment] = useState({ status: 'initial' }) @@ -36,7 +59,7 @@ const ElementsForm: React.FunctionComponent = () => { return ( <>

Error 😭

-

{errorMessage}

+

{errorMessage}

) @@ -53,6 +76,8 @@ const ElementsForm: React.FunctionComponent = () => { const handleSubmit: React.FormEventHandler = async e => { e.preventDefault() + // Abort if form isn't valid + if (!e.currentTarget.reportValidity()) return setPayment({ status: 'processing' }) // Create a PaymentIntent with the specified amount. @@ -95,6 +120,7 @@ const ElementsForm: React.FunctionComponent = () => { <>
{ currency={config.CURRENCY} onChange={handleInputChange} /> -
+
Your payment details: - - +
+ { + if (e.error) { + setPayment({ status: 'error' }) + setErrorMessage(e.error.message ?? 'An unknown error occured') + } + }} + /> +