Skip to content

Commit

Permalink
ggg (#130)
Browse files Browse the repository at this point in the history
* remove blur hashe

* add stripe page
  • Loading branch information
dogfrogfog authored Oct 3, 2024
1 parent b992c19 commit 6e8bdc5
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 3 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"@radix-ui/react-select": "^2.1.0",
"@radix-ui/react-slot": "^1.0.2",
"@react-input/mask": "^1.2.5",
"@stripe/react-stripe-js": "^2.8.0",
"@stripe/stripe-js": "^4.6.0",
"@uidotdev/usehooks": "^2.4.1",
"blurhash-base64": "^0.0.3",
"clsx": "2.1.0",
Expand Down
32 changes: 29 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 107 additions & 0 deletions src/app/payment/stripe/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"use client";

import { useState } from "react";
import { loadStripe } from "@stripe/stripe-js";
import {
Elements,
CardElement,
useStripe,
useElements,
} from "@stripe/react-stripe-js";

const stripePromise = loadStripe(
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
);

function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const [error, setError] = useState<string | null>(null);
const [processing, setProcessing] = useState(false);
const [succeeded, setSucceeded] = useState(false);

const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();

if (!stripe || !elements) {
return;
}

setProcessing(true);

const { error: backendError, clientSecret } = await fetch(
"/api/create-payment-intent",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ amount: 1000 }), // Amount in cents
},
).then((res) => res.json());

if (backendError) {
setError(backendError.message);
setProcessing(false);
return;
}

const { error, paymentIntent } = await stripe.confirmCardPayment(
clientSecret,
{
payment_method: {
card: elements.getElement(CardElement)!,
billing_details: {
name: "Customer Name",
},
},
},
);

if (error) {
setError(`Payment failed: ${error.message}`);
} else if (paymentIntent.status === "succeeded") {
setSucceeded(true);
}

setProcessing(false);
};

return (
<form onSubmit={handleSubmit} className="mx-auto mt-8 max-w-md">
<div className="mb-4">
<label
htmlFor="card-element"
className="block text-sm font-medium text-gray-700"
>
Credit or debit card
</label>
<div className="mt-1">
<CardElement id="card-element" className="rounded-md border p-2" />
</div>
</div>
<button
type="submit"
disabled={!stripe || processing || succeeded}
className="w-full rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 disabled:opacity-50"
>
{processing ? "Processing..." : "Pay"}
</button>
{error && <div className="mt-4 text-red-600">{error}</div>}
{succeeded && (
<div className="mt-4 text-green-600">Payment succeeded!</div>
)}
</form>
);
}

export default function StripePaymentPage() {
return (
<div className="container mx-auto px-4 py-8">
<h1 className="mb-4 text-2xl font-bold">Stripe Payment</h1>
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>
</div>
);
}

0 comments on commit 6e8bdc5

Please sign in to comment.