Is there a way to create Stipe subscription (I am using Java and React) that will require to add card for future subscription payments and charge first amount immediately in one call during confirmation on front end.
For now what I was able to research is that you first need to create Subscription and confirm SetupIntent
with clientSecret
by calling stripe.confirmCardSetup
in front end first and after successful confirmation - initiate stripe.confirmCardPayment
with clientSecret
retrieved from subscription.getLatestInvoiceObject().getPaymentIntentObject().getClientSecret()
;
Is it possible to associate card details with subscription when calling stripe.confirmCardPayment
instead of calling confirmCardSetup
first? I thought that if you confirmCardPayment
with clientSecret
that is associated with subscription, card details will be automatically saved for subscription without first confirming card setup?
The Stripe public docs have a pretty good walkthrough that describes the recommended way to handle this:
In short, the flow is:
latest_invoice.payment_intent.client_secret
back to frontend.
payment_settings.save_default_payment_method
parameter can be used to tell Stripe to automatically save the payment method later on.
https://docs.stripe.com/api/subscriptions/create#create_subscription-payment_settings-save_default_payment_methodHere’s the relevant code snippet that shows you how you should configure your server code to save the default payment method and pass the client secret back.
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
Stripe.apiKey = "your_test_key";
post(
"/create-subscription",
(request, response) -> {
response.type("application/json");
String customerId = request.cookie("customer");
CreateSubscriptionRequest postBody = gson.fromJson(
request.body(),
CreateSubscriptionRequest.class
);
String priceId = postBody.getPriceId();
// Automatically save the payment method to the subscription
// when the first payment is successful
SubscriptionCreateParams.PaymentSettings paymentSettings =
SubscriptionCreateParams.PaymentSettings
.builder()
.setSaveDefaultPaymentMethod(SaveDefaultPaymentMethod.ON_SUBSCRIPTION)
.build();
// Create the subscription. Note we're expanding the Subscription's
// latest invoice and that invoice's payment_intent
// so we can pass it to the front end to confirm the payment
SubscriptionCreateParams subCreateParams = SubscriptionCreateParams
.builder()
.setCustomer(customerId)
.addItem(
SubscriptionCreateParams
.Item.builder()
.setPrice(priceId)
.build()
)
.setPaymentSettings(paymentSettings)
.setPaymentBehavior(SubscriptionCreateParams.PaymentBehavior.DEFAULT_INCOMPLETE)
.addAllExpand(Arrays.asList("latest_invoice.payment_intent"))
.build();
Subscription subscription = Subscription.create(subCreateParams);
Map<String, Object> responseData = new HashMap<>();
responseData.put("subscriptionId", subscription.getId());
responseData.put("clientSecret", subscription.getLatestInvoiceObject().getPaymentIntentObject().getClientSecret());
return StripeObject.PRETTY_PRINT_GSON.toJson(responseData);
}
);