How can i block infinite trials stripe + next 13

The user takes advantage of the 3-day trial period, but as it approaches expiration, they cancel the subscription and then resubscribe to avail themselves of an additional 3-day free trial.

How can I address this issue?

const billingUrl = absoluteUrl("/")

export async function GET(
  request: Request,
  { params }: { params: { priceId: string } }
) {
  console.log(params.priceId)
  try {
    const session = await getServerSession(authOptions)

    if (!session?.user || !session?.user.email) {
      return new Response(null, { status: 403 })
    }

    const subscriptionPlan = await getUserSubscriptionPlan(session.user.id)

    // The user is on the pro plan.
    // Create a portal session to manage tion.
    if (subscriptionPlan.isPro && subscriptionPlan.stripeCustomerId) {
      const stripeSession = await stripe.billingPortal.sessions.create({
        customer: subscriptionPlan.stripeCustomerId,
        return_url: billingUrl
      })

      return new Response(JSON.stringify({ url: stripeSession.url }))
    }

    // The user is on the free plan.
    // Create a checkout session to upgrade.
    const stripeSession = await stripe.checkout.sessions.create({
      success_url: billingUrl,
      cancel_url: billingUrl,
      payment_method_types: ["card"],
      discounts: [{
        promotion_code: 'promo_1OkTmuK3h7UDnylM9PK1vZfL',
      }],
      mode: "subscription",
      subscription_data: {
        trial_period_days: 3,
      },
      billing_address_collection: "auto",
      // allow_promotion_codes: true,
      customer_email: session.user.email,
      client_reference_id: "true",
      line_items: [
        {
          price: params.priceId,
          quantity: 1,
        },
      ],

      metadata: {
        userId: session.user.id,
      },
    })

    return new Response(JSON.stringify({ url: stripeSession.url }))
  } catch (error) {
    if (error instanceof z.ZodError) {
      return new Response(JSON.stringify(error.issues), { status: 422 })
    }

    return new Response(null, { status: 500 })
  }
}

I already sent a message to stripe and they said we need add it from the logic of the website.

Upvotes: 0

Views: 58

Answers (1)

Nolan H
Nolan H

Reputation: 7459

You can limit this using the fingerprint (API ref)on the card Payment Method collected during Checkout. Using either the customer.subscription.created or checkout.session.completed events upon completion, you can inspect the payment method provided by the customer and where you detect the same fingerprint you can end the trial and do anything you need such as contact the customer with an appropriate message.

Upvotes: 0

Related Questions