Skip to content

42 stripe step 2#108

Merged
thaninbew merged 19 commits intomainfrom
42_stripe_step_2
Apr 18, 2026
Merged

42 stripe step 2#108
thaninbew merged 19 commits intomainfrom
42_stripe_step_2

Conversation

@jaydencarvajal511
Copy link
Copy Markdown
Contributor

@jaydencarvajal511 jaydencarvajal511 commented Apr 7, 2026

Description

Implemented the stripe api within the donation form and shadcn in step 2 component.

Testing & Verification

When you put in a card that should fail on charge 4000 0000 0000 0341
image
Verification Steps:

When you put in a card that should succeed 4242 4242 4242 4242
image

Closes #42

@aaronashby aaronashby self-requested a review April 7, 2026 19:14
@@ -1,9 +1,14 @@
import React, { useState } from 'react';
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import { CardElement, useElements, useStripe } from '@stripe/react-stripe-js';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can stick with CardElement for demo day, but Stripe deprecated it, and recommends using PaymentElement moving forward

@@ -1,9 +1,14 @@
import React, { useState } from 'react';
import React, { forwardRef, useImperativeHandle, useState } from 'react';
import { CardElement, useElements, useStripe } from '@stripe/react-stripe-js';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works for demo day, but Stripe deprecated CardElement in favor of PaymentElement. Would be good to keep in mind to prep for deployment. The flow should be something like:

  • Pass clientSecret to <Elements options={{ clientSecret }}>
  • Use in the form
  • Call stripe.confirmPayment() on submit


try {
const paymentIntent: Stripe.PaymentIntent =
await this.stripe.paymentIntents.create({
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good practice to also include an idempotency key as an argument to prevent multiple payment intents from being made if the network drops in the middle of this call.

We can generate one using crypto.randomUUID() when DonationForm loads and then pass it in here and in payments.service.ts

amount: request.amount,
currency: request.currency,
metadata: request.metadata,
payment_method_types: ['card', 'us_bank_accounts'],
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stripe recommends letting them manage payment methods dynamically by using automatic_payment_methods: { enabled: true }

try {
// Step 1: Create PaymentIntent
const amountInCents = Math.round(amount * 100);
const paymentIntentResponse = await apiClient.createPaymentIntent({
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure how this works, but it seems like recurring donations would fall back to one-times. There's a createSubscription method in payments.service.ts but it's not currently wired up to anything.

@thaninbew thaninbew self-requested a review April 18, 2026 02:11
@thaninbew thaninbew merged commit 3c97cb6 into main Apr 18, 2026
4 checks passed
@thaninbew thaninbew deleted the 42_stripe_step_2 branch April 18, 2026 05:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Donation Form] Step 2 - Stripe.js implementation and migrate to Tailwind CSS + shadcn/ui

4 participants