You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have an app that uses Next.js. I attached my braintree.ts file. Also attached my Signup.tsx, where I want my Braintree payment methods to be displayed. And finally I attached my route.ts. My route.ts has the issue: Cannot find module @/utils/braintree/braintree or its corresponding type declarations.ts(2307).
Can you please advise on the best steps to solve this issue?
Signup.tsx
'use client';
import Button from '@/components/ui/Button';
import React, { useEffect, useState } from 'react';
import Link from 'next/link';
import { signUp } from '@/utils/auth-helpers/server';
import { handleRequest } from '@/utils/auth-helpers/client';
import { useRouter } from 'next/navigation';
import Script from 'next/script';
interface SignUpProps {
allowEmail: boolean;
redirectMethod: string;
}
export default function SignUp({ allowEmail, redirectMethod }: SignUpProps) {
const router = redirectMethod === 'client' ? useRouter() : null;
const [isSubmitting, setIsSubmitting] = useState(false);
const [showBraintree, setShowBraintree] = useState(false);
const [braintreeInstance, setBraintreeInstance] = useState<any>(null);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setIsSubmitting(true);
// Here, instead of calling handleRequest, we'll just show the Braintree UI
setShowBraintree(true);
setIsSubmitting(false);
};
useEffect(() => {
if (showBraintree && (window as any).braintree) {
(window as any).braintree.dropin.create({
authorization: process.env.NEXT_PUBLIC_BRAINTREE_TOKENIZATION_KEY,
container: '#dropin-container'
}, (createErr: any, instance: any) => {
if (createErr) {
console.error(createErr);
return;
}
setBraintreeInstance(instance);
});
}
}, [showBraintree]);
const handlePayment = async () => {
if (!braintreeInstance) {
console.error('Braintree instance not available');
return;
}
try {
const { nonce } = await braintreeInstance.requestPaymentMethod();
console.log('Payment nonce:', nonce);
// Here you would typically send the nonce to your server
// along with the user's email and password to complete the sign-up process
alert('Payment method successfully created! Sign-up would be completed here.');
// After successful sign-up and payment, you might want to redirect the user
if (router) router.push('/dashboard');
} catch (error) {
console.error('Payment error:', error);
alert('Payment failed. Please try again.');
}
};
return (
<div className="my-8">
<form
noValidate={true}
className="mb-4"
onSubmit={(e) => handleSubmit(e)}
>
<div className="grid gap-2">
<div className="grid gap-1">
<label htmlFor="email">Email</label>
<input
id="email"
placeholder="[email protected]"
type="email"
name="email"
autoCapitalize="none"
autoComplete="email"
autoCorrect="off"
className="w-full p-3 rounded-md bg-zinc-800"
/>
<label htmlFor="password">Password</label>
<input
id="password"
placeholder="Password"
type="password"
name="password"
autoComplete="current-password"
className="w-full p-3 rounded-md bg-zinc-800"
/>
</div>
<Button
variant="slim"
type="submit"
className="mt-1"
loading={isSubmitting}
>
Continue to Payment
</Button>
</div>
</form>
{showBraintree && (
<div id="dropin-wrapper">
<div id="dropin-container"></div>
<Button onClick={handlePayment} variant="slim" className="mt-4">
Complete Sign Up and Pay
</Button>
</div>
)}
<p>Already have an account?</p>
<p>
<Link href="/signin/password_signin" className="font-light text-sm">
Sign in with email and password
</Link>
</p>
{allowEmail && (
<p>
<Link href="/signin/email_signin" className="font-light text-sm">
Sign in via magic link
</Link>
</p>
)}
<Script
src="https://js.braintreegateway.com/web/dropin/1.33.0/js/dropin.min.js"
strategy="lazyOnload"
/>
</div>
);
}
route.ts
import Stripe from 'stripe';
import { stripe } from '@/utils/stripe/config';
import {
upsertProductRecord,
upsertPriceRecord,
manageSubscriptionStatusChange,
deleteProductRecord,
deletePriceRecord
} from '@/utils/supabase/admin';
import { gateway } from '@/utils/braintree/braintree';
const relevantEvents = new Set([
'product.created',
'product.updated',
'product.deleted',
'price.created',
'price.updated',
'price.deleted',
'checkout.session.completed',
'customer.subscription.created',
'customer.subscription.updated',
'customer.subscription.deleted'
]);
export async function POST(req: Request) {
if (req.headers.get('Content-Type') === 'application/json') {
const body = await req.json();
const { paymentMethodNonce } = body;
if (!paymentMethodNonce) {
return new Response('Payment method nonce is required', { status: 400 });
}
try {
const result = await gateway.transaction.sale({
amount: '10.00',
paymentMethodNonce: paymentMethodNonce,
options: {
submitForSettlement: true
}
});
if (result.success) {
return new Response(JSON.stringify({ success: true, transaction: result.transaction }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
} else {
return new Response(JSON.stringify({ success: false, error: result.message }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
} catch (error) {
console.error('Braintree transaction error:', error);
return new Response('An error occurred while processing the payment', { status: 500 });
}
} else {
const body = await req.text();
const sig = req.headers.get('stripe-signature') as string;
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;
let event: Stripe.Event;
try {
if (!sig || !webhookSecret)
return new Response('Webhook secret not found.', { status: 400 });
event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
console.log(`🔔 Webhook received: ${event.type}`);
} catch (err: any) {
console.log(`❌ Error message: ${err.message}`);
return new Response(`Webhook Error: ${err.message}`, { status: 400 });
}
if (relevantEvents.has(event.type)) {
try {
switch (event.type) {
case 'product.created':
case 'product.updated':
await upsertProductRecord(event.data.object as Stripe.Product);
break;
case 'price.created':
case 'price.updated':
await upsertPriceRecord(event.data.object as Stripe.Price);
break;
case 'price.deleted':
await deletePriceRecord(event.data.object as Stripe.Price);
break;
case 'product.deleted':
await deleteProductRecord(event.data.object as Stripe.Product);
break;
case 'customer.subscription.created':
case 'customer.subscription.updated':
case 'customer.subscription.deleted':
const subscription = event.data.object as Stripe.Subscription;
await manageSubscriptionStatusChange(
subscription.id,
subscription.customer as string,
event.type === 'customer.subscription.created'
);
break;
case 'checkout.session.completed':
const checkoutSession = event.data.object as Stripe.Checkout.Session;
if (checkoutSession.mode === 'subscription') {
const subscriptionId = checkoutSession.subscription;
await manageSubscriptionStatusChange(
subscriptionId as string,
checkoutSession.customer as string,
true
);
}
break;
default:
throw new Error('Unhandled relevant event!');
}
} catch (error) {
console.log(error);
return new Response(
'Webhook handler failed. View your Next.js function logs.',
{
status: 400
}
);
}
} else {
return new Response(`Unsupported event type: ${event.type}`, {
status: 400
});
}
return new Response(JSON.stringify({ received: true }));
}
}
braintree.ts
import braintree from 'braintree';
export const gateway = new braintree.BraintreeGateway({
environment: braintree.Environment.Sandbox,
merchantId: process.env.BRAINTREE_MERCHANT_ID!,
publicKey: process.env.BRAINTREE_PUBLIC_KEY!,
privateKey: process.env.BRAINTREE_PRIVATE_KEY!
});
The text was updated successfully, but these errors were encountered:
I have an app that uses Next.js. I attached my braintree.ts file. Also attached my Signup.tsx, where I want my Braintree payment methods to be displayed. And finally I attached my route.ts. My route.ts has the issue: Cannot find module @/utils/braintree/braintree or its corresponding type declarations.ts(2307).
Can you please advise on the best steps to solve this issue?
Signup.tsx
route.ts
braintree.ts
The text was updated successfully, but these errors were encountered: