#sahilasopa

1 messages · Page 1 of 1 (latest)

tribal oxideBOT
nova birch
#

đź‘‹ happy to help

#

each time you create a subscription if you don't specify a specific payment behavior we will default to try to pay that subscription immediately meaning that you either need to specify the payment method or your customer has to have a pm attached and setup as a invoice_settings.default_payment_method

#

when you specify default_incomplete you will get the chance to collect the payment method before we try to pay the first invoice

vital light
#
const subscription = await stripe.subscriptions.create({
        currency: 'inr',
        customer: customerId,
        items: [
            {price: planId},
        ],
        payment_behavior: "allow_incomplete",
        payment_settings: { save_default_payment_method: 'on_subscription' },
        expand: ['latest_invoice.payment_intent']
    });
#

this is what I tried

vital light
nova birch
#

from the link I sent you

Use allow_incomplete to create subscriptions with status=incomplete if the first invoice cannot be paid. Creating subscriptions with this status allows you to manage scenarios where additional user actions are needed to pay a subscription’s invoice. For example, SCA regulation may require 3DS authentication to complete payment. See the SCA Migration Guide for Billing to learn more. This is the default behavior.

Use default_incomplete to create Subscriptions with status=incomplete when the first invoice requires payment, otherwise start as active. Subscriptions transition to status=active when successfully confirming the payment intent on the first invoice. This allows simpler management of scenarios where additional user actions are needed to pay a subscription’s invoice. Such as failed payments, SCA regulation, or collecting a mandate for a bank debit payment method. If the payment intent is not confirmed within 23 hours subscriptions transition to status=incomplete_expired, which is a terminal state.

#

in your case you need default_incomplete to collect the payment method

vital light
#

How can I get such a flow

  1. user creates an account on my website by giving their username and password
  2. I create a stripe customer and get the customer id
  3. then I use that customer Id to start PaymentSheet, and if the payment is successful the subscription is created

I already have done first 2 steps

nova birch
#

you should create the subscription first

#

as you're doing now and expanding the latest_invoice.payment_intent

#

and passing the client_secret to the PaymentSheet

#

then you pay

#

but you should use default_incomplete to allow the creation of the subscription without any attached PM

vital light
#

I have just changed allow_incomplete to default_incomplete I am yet to run the code, I am doing it rn, this should prevent the error mentioned above ?

nova birch
#

yes

#

and will let you collect the PM and save it on the subscription ( since you're using payment_settings: { save_default_payment_method: 'on_subscription' }) and pay the first invoice all at once

vital light
#

I get a new error this time

#

Passing apiVersion in a separate options hash is required to create an ephemeral key

#
const customerId = "cus_NE9pq2xHjSmOnw";
const planId = "price_1I2blSCZB9UZu9OeyCPrLl5P";
const subscription = await stripe.subscriptions.create({
    currency: 'inr',
    customer: customerId,
    items: [
        {price: planId},
    ],
    payment_behavior: "default_incomplete",
    payment_settings: { save_default_payment_method: 'on_subscription' },
    expand: ['latest_invoice.payment_intent']
});
const ephemeralKey = await stripe.ephemeralKeys.create(
    {customer: customerId},
)
return {
    ephemeralKey: ephemeralKey.secret,
    subscriptionId: subscription.id,
    paymentIntent: subscription.latest_invoice.payment_intent.client_secret,
    publishableKey: 'the key here'
}
#

this is my whole code for the backend

nova birch
#

why do you need the ephemeral key here?

vital light
#
customerConfig = new PaymentSheet.CustomerConfiguration(
  user.getStripeId(),
  result.getString("ephemeralKey")
);
#
 final PaymentSheet.Configuration configuration = new PaymentSheet.Configuration.Builder("Bhaktidwar Media Pvt Ltd.")
  .customer(customerConfig)
  .allowsDelayedPaymentMethods(true)
  .build();
nova birch
#

you don't really need an ephemeral key

vital light
#

req_diO0MCSkdUkeN7

vital light
#
customerConfig = new PaymentSheet.CustomerConfiguration(
        user.getStripeId(),
        result.getString("ephemeralKey")
);
paymentIntentClientSecret = result.getString("paymentIntent");
PaymentConfiguration.init(getApplicationContext(), result.getString("publishableKey"));
runOnUiThread(this::showStripePaymentSheet);
#
void showStripePaymentSheet() {
        final PaymentSheet.Configuration configuration = new PaymentSheet.Configuration.Builder("")
                .customer(customerConfig)
                .allowsDelayedPaymentMethods(true)
                .build();
        paymentSheet.presentWithPaymentIntent(
                paymentIntentClientSecret,
                configuration
        );
    }
#

this is what I am doing

nova birch
#

you don't need all of this, please read through the doc I sent you

nova birch
#

so you just need to follow the steps in that doc to pay the first invoice using the PaymentSheet

vital light
# nova birch you don't need all of this, please read through the doc I sent you

Yes I went through the documentation and my code seems to be working, I just would like to know if I did it the correct way
this is my frontend

paymentIntentClientSecret = result.getString("paymentIntent");
PaymentConfiguration.init(getApplicationContext(), result.getString("publishableKey"));
runOnUiThread(this::showStripePaymentSheet);

void showStripePaymentSheet() {
    final PaymentSheet.Configuration configuration = new PaymentSheet.Configuration.Builder("Name")
            .allowsDelayedPaymentMethods(true)
            .build();
    paymentSheet.presentWithPaymentIntent(
            paymentIntentClientSecret,
            configuration
    );
}

this is my backend

const customerId = "cus_NE9pq2xHjSmOnw";
    const planId = "price_1I2blSCZB9UZu9OeyCPrLl5P";
    const subscription = await stripe.subscriptions.create({
        currency: 'inr',
        customer: customerId,
        items: [
            {price: planId},
        ],
        payment_behavior: "default_incomplete",
        payment_settings: { save_default_payment_method: 'on_subscription' },
        expand: ['latest_invoice.payment_intent']
    });
    return {
        subscriptionId: subscription.id,
        paymentIntent: subscription.latest_invoice.payment_intent.client_secret,
        publishableKey: 'key'
    }
nova birch
#

what is the error you're getting?

vital light
nova birch
#

I don't see anything "problematic" you should try to test the full scenario and see if you get any errors

vital light
elder citrus
#

Hey! Taking over for my colleague. Let me catch up.

vital light
#

sure, thank you

elder citrus
#

the stripe payment element buffers for long time before loading
Could. you please give more details about this ? like how much ?

#

Did you checked if there is something blocking the UI rendering in your side (e.g. API call) ?

vital light
#

for the first time it takes around 10 secs, and after that it takes around 3 secs

vital light
#

the payment intent opens after the call is made

#

and it takes 10 secs after the call is made

elder citrus
#

Try to profile your app performance and see for that page what's blocking the UI rendering

vital light
#

As you can see, for the first time it took more then 10 secs, but for the second time it was almost instant

#

profiling shows nothing's blocking

elder citrus
#

try running paymentsheet-example and see if you notice the same behavior on that device please

vital light
#

alright gimme a min

elder citrus
#

Yes!

vital light
#

I am unable to download the repo

#

git clone gives errror

#

and zip file

#

also I had another question, documentation suggests using
Fuel.INSTANCE.post(url) for making calls
but I am using
FirebaseFunctions.getInstance().getHttpsCallable(url)
does this make a huge difference

elder citrus
# vital light

It looks like you OS (windows) blocking the clone due to file path too link I think, you need to fix this on your laptop, sorry don't knw a lot about windows

elder citrus
vital light
#

alright, thank you for your help, thanks to tarzan as well

elder citrus
#

You're welcome!