1

I've been working with Stripe Payment Integration and currently find myself stuck with a particular use-case.

Stripe has the option to hold a payment for future, and capture the amount later based on business logic. This is explained here ( https://stripe.com/docs/payments/save-and-reuse) and works perfectly fine.

However, I need to save the card details and create a subscription later on ( instead of a one time payment as explained in the docs link above ). Has anyone worked on a similar use case ?

Thanks in advance.

Bernerd
  • 68
  • 5

3 Answers3

1

I found a workaround for this by first creating a paymentIntent with setup_future_usage="off_session" and capture_method="manual" to first place a hold and save the paymentMethod, and then, only after capturing this paymentIntent, creating a subscription using the newly saved paymentMethod with billing_cycle_anchor that equals your subscription's interval from now.

This way it's like your customer has paid for the first interval using the paymentIntent, but will be charged from the second interval using the subscriptions API, which allows you to cancel the hold on the first payment and not create a subscription if something goes wrong.

VRSEN
  • 121
  • 2
  • 4
1

I was interested in this process too and found this method on the stripe site, albeit with some difficulty.

Your above method was a nifty workaround but a little clunky for me so hopefully others will find the following to be a smoother way of handling the process.

To create a subscription and capture a payment at once

the flow is as follows:

  1. Create customer if it has not been done,
  2. Create a subscription with the parameters in the code below including your Price ID which has its own billing cycle associated with it,
  3. Use the Client Secret from the subscription created in step 2 to use with the Payment Elements form to capture the payment and store the Payment Method.

This way you do not have to manually mess around with subscription start dates, cycles etc, thereby simplifying the process and reducing room for human error.

$stripe = new \Stripe\StripeClient(
    'your_secret_stripe_key'
);
        // *Create customer if not already created *

$customer = $stripe->customers->create([
    'description' => 'example customer',
    'email' => 'example@blah.com'
]);
$customer_id = $customer->id;


        //*Create subscription*

$subscription = $stripe->subscriptions->create([
  'customer' => $customer_id,
  'items' => [['price' => '*your_previously_created_price_id*']],
  'payment_behavior' => 'default_incomplete',
  'payment_settings' => ['save_default_payment_method' => 'on_subscription'],
  'expand' => ['latest_invoice.payment_intent']
]);

      // *Use this client secret to capture payment with the Payment Elements form*

$clientSecret = $subscription->latest_invoice->payment_intent->client_secret;

As you can see, creating the subscription generates an invoice which creates a Payment Intent, the Client Secret of which can be used to capture a card and save it as the Default Payment Method for the subscription. Your customer enters the card details, the payment is processed and the subscription becomes 'active'.

midget
  • 88
  • 8
0

You can use setupIntents to create a payment method attached to a customer, and you can subsequently use that paymentMethod, "offsession", to create a subscription. Given current 3DS features of card payments, and the fact that there is no hold or available balance check in this flow, the possibility still exists that customer will need to be brought back on-session for a confirmation flow or change of card, but it does most frequently work. I'll note that "hold and capture" is limited to 7 days - a setupIntent and later off-session charge is entirely different (there is no hold).

LeadDreamer
  • 3,303
  • 2
  • 15
  • 18