stripe-payments

Can I confirm payment and save card for future uses in case of subscription in one call?


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?


Solution

  • The Stripe public docs have a pretty good walkthrough that describes the recommended way to handle this:

    https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=elements&lang=java#create-subscription

    In short, the flow is:

    Here’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);
      }
    );