more form fixes

This commit is contained in:
Paul Miller
2022-04-04 10:46:39 -04:00
parent 4e338154e7
commit 27263770d8
4 changed files with 25 additions and 64 deletions

View File

@@ -1,7 +1,7 @@
import { faBitcoin } from "@fortawesome/free-brands-svg-icons";
import { faCreditCard } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { fetchPostJSON } from "../utils/api-helpers";
import Spinner from "./Spinner";
@@ -22,6 +22,8 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
const [btcPayLoading, setBtcpayLoading] = useState(false);
const [fiatLoading, setFiatLoading] = useState(false);
const formRef = useRef<HTMLFormElement | null>(null);
const radioHandler = (event: React.ChangeEvent<HTMLInputElement>) => {
setDeductable(event.target.value);
};
@@ -31,22 +33,8 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
setAmount(value)
}
// This should be a react form event but their typescript doesn't include submitter
function handleSubmit(e: any) {
e.preventDefault();
const submitter = e.nativeEvent?.submitter?.name;
if (submitter === "btcpay") {
handleBtcPay()
} else {
handleFiat()
}
}
useEffect(() => {
if (amount && typeof parseInt(amount) === "number") {
console.log("have amount")
if (deductable === "no" || (name && email)) {
setReadyToPay(true)
} else {
@@ -58,6 +46,10 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
}, [deductable, amount, email, name])
async function handleBtcPay() {
const validity = formRef.current?.checkValidity();
if (!validity) {
return
}
setBtcpayLoading(true);
try {
const data = await fetchPostJSON("/api/btcpay", { amount, project_slug: projectSlug, project_name: projectNamePretty })
@@ -73,6 +65,10 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
};
async function handleFiat() {
const validity = formRef.current?.checkValidity();
if (!validity) {
return
}
setFiatLoading(true);
try {
const data = await fetchPostJSON("/api/stripe_checkout", { amount, project_slug: projectSlug, project_name: projectNamePretty })
@@ -88,7 +84,7 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
}
return (
<form className="flex flex-col gap-4" onSubmit={handleSubmit}>
<form ref={formRef} className="flex flex-col gap-4" onSubmit={(e) => e.preventDefault()}>
<section className="flex flex-col gap-1">
<h3>Do you want this donation as tax deductable?</h3>
<div className="flex space-x-4 pb-4">
@@ -151,20 +147,20 @@ const DonationSteps: React.FC<DonationStepsProps> = ({ projectNamePretty, projec
</div>
</section>
<div className="flex flex-wrap items-center gap-4">
<button name="btcpay" type="submit" className="pay" disabled={!readyToPay || btcPayLoading}>
<button name="btcpay" onClick={handleBtcPay} className="pay" disabled={!readyToPay || btcPayLoading}>
{btcPayLoading ? <Spinner /> : <FontAwesomeIcon icon={faBitcoin} className="text-primary h-8 w-8" />}
<span className="whitespace-nowrap">
Donate with Bitcoin
</span>
</button>
<button name="stripe" type="submit" className="pay" disabled={!readyToPay || fiatLoading}>
<button name="stripe" onClick={handleFiat} className="pay" disabled={!readyToPay || fiatLoading}>
{fiatLoading ? <Spinner /> : <FontAwesomeIcon icon={faCreditCard} className="text-primary h-8 w-8" />}
<span className="whitespace-nowrap">
Donate with fiat
</span>
</button>
</div>
</form >
</form>
)
};

View File

@@ -21,7 +21,10 @@ export default async function handler(
`${process.env
.BTCPAY_URL!}stores/${process.env.BTCPAY_STORE_ID}/invoices`,
`token ${process.env.BTCPAY_API_KEY}`,
{ amount, currency: CURRENCY, metadata: { orderId: project_slug, project_name, buyerName: name || "anonymous", email: email || "none" }, checkout: { redirectURL: REDIRECT } }
{
amount, currency: CURRENCY,
metadata: { orderId: project_slug, project_name, buyerName: name || "anonymous", buyerEmail: email || "none" }, checkout: { redirectURL: REDIRECT }
}
);
console.log({ data })

View File

@@ -1,44 +0,0 @@
import { NextApiRequest, NextApiResponse } from "next";
import { CURRENCY, MIN_AMOUNT, MAX_AMOUNT } from "../../config";
import { formatAmountForStripe } from "../../utils/stripe-helpers";
import Stripe from "stripe";
import { PayReq } from "../../utils/types";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
// https://github.com/stripe/stripe-node#configuration
apiVersion: "2020-08-27",
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === "POST") {
const { amount, project_name, project_slug, email, name }: PayReq = req.body;
const REDIRECT = "localhost:3000"
try {
// Validate the amount that was passed from the client.
if (!(amount >= MIN_AMOUNT && amount <= MAX_AMOUNT)) {
throw new Error("Invalid amount.");
}
// Create PaymentIntent from body params.
const params: Stripe.PaymentIntentCreateParams = {
payment_method_types: ["card"],
amount: formatAmountForStripe(amount, CURRENCY),
currency: CURRENCY,
description: `OpenSats donation: ${project_name}`,
};
const payment_intent: Stripe.PaymentIntent =
await stripe.paymentIntents.create(params);
res.status(200).json(payment_intent);
} catch (err) {
res.status(500).json({ statusCode: 500, message: (err as Error).message });
}
} else {
res.setHeader("Allow", "POST");
res.status(405).end("Method Not Allowed");
}
}

View File

@@ -36,6 +36,12 @@ export default async function handler(
],
success_url: `${req.headers.origin}/?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${req.headers.origin}/`,
metadata: {
donor_email: email || null,
donor_name: name || null,
recipient_campaign: 'ZAPRITE_CAMPAIGN_UUID',
recipient_uuid: 'ZAPRITE_USER_UUID',
}
};
const checkoutSession: Stripe.Checkout.Session =
await stripe.checkout.sessions.create(params);