mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-06 01:02:04 +00:00
Progress on payment flow, added purchases endpoint
This commit is contained in:
parent
42a9d243ca
commit
573f560f28
@ -3,6 +3,7 @@ import dynamic from 'next/dynamic';
|
|||||||
import { initializeBitcoinConnect } from './BitcoinConnect';
|
import { initializeBitcoinConnect } from './BitcoinConnect';
|
||||||
import { LightningAddress } from '@getalby/lightning-tools';
|
import { LightningAddress } from '@getalby/lightning-tools';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import axios from 'axios'; // Import axios for API calls
|
||||||
|
|
||||||
const PayButton = dynamic(
|
const PayButton = dynamic(
|
||||||
() => import('@getalby/bitcoin-connect-react').then((mod) => mod.PayButton),
|
() => import('@getalby/bitcoin-connect-react').then((mod) => mod.PayButton),
|
||||||
@ -11,7 +12,7 @@ const PayButton = dynamic(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const PaymentButton = ({ lnAddress, amount, onSuccess, onError }) => {
|
const PaymentButton = ({ lnAddress, amount, onSuccess, onError, userId, resourceId }) => {
|
||||||
const [invoice, setInvoice] = useState(null);
|
const [invoice, setInvoice] = useState(null);
|
||||||
const { showToast } = useToast();
|
const { showToast } = useToast();
|
||||||
const [pollingInterval, setPollingInterval] = useState(null);
|
const [pollingInterval, setPollingInterval] = useState(null);
|
||||||
@ -64,14 +65,31 @@ const PaymentButton = ({ lnAddress, amount, onSuccess, onError }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePaymentSuccess = async (response) => {
|
const handlePaymentSuccess = async (response) => {
|
||||||
stopPolling(); // Stop polling after success
|
stopPolling();
|
||||||
|
|
||||||
// Close the modal
|
|
||||||
await closeModal();
|
await closeModal();
|
||||||
|
|
||||||
// After the modal is closed, show the success toast
|
try {
|
||||||
showToast('success', 'Payment Successful', `Paid ${amount} sats`);
|
// Create a new purchase record
|
||||||
if (onSuccess) onSuccess(response);
|
const purchaseData = {
|
||||||
|
userId: userId,
|
||||||
|
resourceId: resourceId,
|
||||||
|
amountPaid: parseInt(amount, 10) // Convert amount to integer
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make an API call to add the purchase to the user
|
||||||
|
const result = await axios.post('/api/purchases', purchaseData);
|
||||||
|
|
||||||
|
if (result.status === 200) {
|
||||||
|
showToast('success', 'Payment Successful', `Paid ${amount} sats and updated user purchases`);
|
||||||
|
if (onSuccess) onSuccess(response);
|
||||||
|
} else {
|
||||||
|
throw new Error('Failed to update user purchases');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error updating user purchases:', error);
|
||||||
|
showToast('error', 'Purchase Update Failed', 'Payment was successful, but failed to update user purchases.');
|
||||||
|
if (onError) onError(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePaymentError = (error) => {
|
const handlePaymentError = (error) => {
|
||||||
|
@ -44,6 +44,20 @@ export const getUserByPubkey = async (pubkey) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addPurchaseToUser = async (userId, purchaseData) => {
|
||||||
|
return await prisma.user.update({
|
||||||
|
where: { id: userId },
|
||||||
|
data: {
|
||||||
|
purchased: {
|
||||||
|
create: purchaseData
|
||||||
|
}
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
purchased: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const createUser = async (data) => {
|
export const createUser = async (data) => {
|
||||||
return await prisma.user.create({
|
return await prisma.user.create({
|
||||||
data,
|
data,
|
||||||
|
21
src/pages/api/purchases.js
Normal file
21
src/pages/api/purchases.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { addPurchaseToUser } from "@/db/models/userModels";
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
try {
|
||||||
|
const { userId, resourceId, amountPaid } = req.body;
|
||||||
|
|
||||||
|
const updatedUser = await addPurchaseToUser(userId, {
|
||||||
|
resourceId,
|
||||||
|
amountPaid: parseInt(amountPaid, 10) // Ensure amountPaid is an integer
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).json(updatedUser);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ error: error.message });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.setHeader('Allow', ['POST']);
|
||||||
|
res.status(405).end(`Method ${req.method} Not Allowed`);
|
||||||
|
}
|
||||||
|
}
|
@ -262,7 +262,15 @@ export default function Details() {
|
|||||||
className="w-[344px] h-[194px] object-cover object-top rounded-lg"
|
className="w-[344px] h-[194px] object-cover object-top rounded-lg"
|
||||||
/>
|
/>
|
||||||
<div className='w-full flex flex-row justify-between'>
|
<div className='w-full flex flex-row justify-between'>
|
||||||
{paidResource && !decryptedContent && <PaymentButton lnAddress={'bitcoinplebdev@stacker.news'} amount={processedEvent.price} onSuccess={handlePaymentSuccess} onError={handlePaymentError} />}
|
{paidResource && !decryptedContent && <PaymentButton
|
||||||
|
lnAddress={'bitcoinplebdev@stacker.news'}
|
||||||
|
amount={processedEvent.price}
|
||||||
|
onSuccess={handlePaymentSuccess}
|
||||||
|
onError={handlePaymentError}
|
||||||
|
userId={user.id} // Pass the user ID
|
||||||
|
resourceId={processedEvent.id} // Pass the course/resource ID
|
||||||
|
/>}
|
||||||
|
|
||||||
<ZapDisplay zapAmount={zapAmount} event={processedEvent} zapsLoading={zapsLoading} />
|
<ZapDisplay zapAmount={zapAmount} event={processedEvent} zapsLoading={zapsLoading} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user