initial setup for stripe

This commit is contained in:
Jacob
2024-01-22 17:25:09 -05:00
parent 8213091342
commit d9e49487a3
11 changed files with 155 additions and 31 deletions

View File

@@ -17,25 +17,34 @@ import {
isFormDataHasErrors,
} from "../../Utils/Form";
import { objectMap } from "../../Utils/Object";
import { signupfields } from "../../Constants/Fields/SignupFields";
import { signupFields } from "../../Constants/Fields/SignupFields";
import { paymentfields } from "../../Constants/Fields/PaymentFields";
import PaymentModal from "../Modals/PaymentModal";
import "../../styles/signup.scss";
import Stripe from 'stripe';
const SignupPage = () => {
const navigate = useNavigate();
const [notice, setNotice] = useState("");
const fieldsChunkSize = 2;
const [isBusy, setIsBusy] = useState(false);
const [data, setData] = useState(getFormDataDefaults(signupfields));
const [data, setData] = useState(getFormDataDefaults(signupFields));
const [paymentData, setPaymentData] = useState(
getFormDataDefaults(paymentfields)
);
const [showPaymentModal, setShowPaymentModal] = useState(false);
const modalText = "Description of monthly and annual subscriptions";
// this could also go in App.js if needed in the future
const stripe = new Stripe('pk_test_51NNoasBi8p7FeGFrI5SfpM6HuNMoxwImx6NRKyKbgbt6OPxMxQDiZ9I1GqvDa9qUwB3D3jlJOng6MyjPppWofxzP00Exvr8dBy')
const apiUrl =
process.env.NODE_ENV === "development"
? process.env.REACT_APP_API_DEV
: process.env.REACT_APP_API_PROD;
const handleChangeInput = (e, name) => {
const newData = handleFormDataChange(e, name, data, signupfields);
const newData = handleFormDataChange(e, name, data, signupFields);
if (newData !== null) {
setData(newData);
}
@@ -54,7 +63,7 @@ const SignupPage = () => {
};
const validateData = () => {
const newData = getValidatedFormData(data, signupfields);
const newData = getValidatedFormData(data, signupFields);
const hasErrors = isFormDataHasErrors(newData);
setData(newData);
return hasErrors ? null : objectMap(({ value }) => value, newData);
@@ -125,10 +134,45 @@ const SignupPage = () => {
setShowPaymentModal(true);
};
async function handleStripeAuthorization(paymentDataValues) {
async function handleStripeAuthorization(paymentDataValues, customerDataValues) {
// Do: calls to Stripe API
// if success, return some truthy value or
// handle failure in handleSignup
let error = false;
const token = await stripe.tokens.create({
card: {
number: paymentDataValues.cardNumber,
exp_month: paymentDataValues.cardExpirationMonth,
exp_year: paymentDataValues.cardExpirationYear,
cvc: paymentDataValues.cardCvvCode,
name: paymentDataValues.cardFirstName + ' ' + paymentDataValues.cardLastName,
}
})
try {
let response = await fetch(`${apiUrl}/create-subscription`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'monthly', // TODO: replace this with the user-chosen value later when we have the UI for it
customerData: {
email: customerDataValues.email,
name: customerDataValues.firstName + ' ' + customerDataValues.lastName,
},
token,
}),
})
}
catch (error) {
console.log(error)
error = true;
}
return !error;
}
const handleSignup = async (e) => {
@@ -144,25 +188,29 @@ const SignupPage = () => {
}
setIsBusy(true);
const paymentSuccess = handleStripeAuthorization(paymentDataValues);
if (paymentSuccess) {
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
dataValues.email,
dataValues.password
);
const user = userCredential.user;
try {
const userCredential = await createUserWithEmailAndPassword(
auth,
dataValues.email,
dataValues.password
);
const user = userCredential.user;
const paymentSuccess = await handleStripeAuthorization(paymentDataValues, dataValues);
if(paymentSuccess) {
await saveUserData(user.uid, dataValues);
navigate("/");
} catch (error) {
setIsBusy(false);
setNotice(
error.message || "Sorry, something went wrong. Please try again."
);
}
} else {
//handle payment failure
else {
// handle payment failure
}
} catch (error) {
setIsBusy(false);
setNotice(
error.message || "Sorry, something went wrong. Please try again."
);
}
};
@@ -174,7 +222,7 @@ const SignupPage = () => {
</div>
<Form className="signup-form">
{splitEvery(
Object.keys(signupfields).slice(0, -2),
Object.keys(signupFields).slice(0, -2),
fieldsChunkSize
).map((names, j) => (
<Row key={`row${j}`}>
@@ -189,11 +237,11 @@ const SignupPage = () => {
message={data[name].message}
label={
data[name].value.length === 0
? signupfields[name].label
? signupFields[name].label
: ""
}
type={signupfields[name].type}
values={signupfields[name].values}
type={signupFields[name].type}
values={signupFields[name].values}
disabled={isBusy}
/>
</Col>
@@ -207,7 +255,7 @@ const SignupPage = () => {
type="password"
label={
data.password.value.length === 0
? signupfields.password.label
? signupFields.password.label
: ""
}
value={data.password.value}
@@ -225,7 +273,7 @@ const SignupPage = () => {
type="password"
label={
data.confirmPassword.value.length === 0
? signupfields.confirmPassword.label
? signupFields.confirmPassword.label
: ""
}
value={data.confirmPassword.value}

View File

@@ -23,4 +23,16 @@ export const paymentfields = {
maxLength: 5,
type: "cardCvvCode",
},
cardExpirationMonth: {
required: true,
label: "Card Expiration Month",
maxLength: 2,
type: "cardExpirationMonth",
},
cardExpirationYear: {
required: true,
label: "Card Expiration Year",
maxLength: 4,
type: "cardExpirationYear",
},
};

View File

@@ -1,4 +1,4 @@
export const signupfields = {
export const signupFields = {
firstName: { required: true, label: "First Name", maxLength: 45 },
lastName: { required: true, label: "Last Name", maxLength: 45 },
firm: { required: true, label: "Firm", minLength: 2, maxLength: 45 },