feat: add donations feature with one-time payments - M6 (refs #55)

This commit is contained in:
Eric Gullickson
2026-01-18 16:51:20 -06:00
parent 6c1a100eb9
commit 56da99de36
14 changed files with 815 additions and 4 deletions

View File

@@ -400,6 +400,9 @@ export class SubscriptionsService {
case 'invoice.payment_failed':
await this.handlePaymentFailed(event);
break;
case 'payment_intent.succeeded':
await this.handleDonationPaymentSucceeded(event);
break;
default:
logger.info('Unhandled webhook event type', { eventType: event.type });
}
@@ -598,6 +601,43 @@ export class SubscriptionsService {
});
}
/**
* Handle payment_intent.succeeded webhook for donations
*/
private async handleDonationPaymentSucceeded(event: StripeWebhookEvent): Promise<void> {
const paymentIntent = event.data.object;
// Check if this is a donation (based on metadata)
if (paymentIntent.metadata?.type !== 'donation') {
logger.info('PaymentIntent is not a donation, skipping', {
paymentIntentId: paymentIntent.id,
});
return;
}
// Find donation by payment intent ID
const donation = await this.repository.findDonationByPaymentIntentId(
paymentIntent.id
);
if (!donation) {
logger.warn('Donation not found for payment intent', {
paymentIntentId: paymentIntent.id,
});
return;
}
// Update donation status to succeeded
await this.repository.updateDonation(donation.id, {
status: 'succeeded',
});
logger.info('Donation marked as succeeded via webhook', {
donationId: donation.id,
paymentIntentId: paymentIntent.id,
});
}
/**
* Sync subscription tier to user_profiles table
*/