#alexzada-PaymentSheet

1 messages ยท Page 1 of 1 (latest)

viscid pilot
#

๐Ÿ‘‹ happy to help

#

do you mean like a recurring payment?

honest hinge
#

hi ๐Ÿ‘‹

honest hinge
# viscid pilot do you mean like a recurring payment?

the flow is as follows, the customer needs to pay for a ride and this amount can be paid in installments, with a number of installments of his choice, for example, if the ride has a value of 300, the customer can choose to pay in 2 installments of 150, or in 3 installments of 100

viscid pilot
#

is it always the same amount planned on x months?

honest hinge
#

sorry, I did not understand the question

viscid pilot
#

could the installments be different? e.g. the amount is 250 so the customer chooses 100 for 2 months and 50 for the last or is it always the same amount per installment

honest hinge
viscid pilot
#

in that case Stripe's subscriptions are enough for you

honest hinge
#

but, i'm using CardField

#

and I would like to use PaymentSheet

viscid pilot
#

ok so you have the subscription part figured out, now you just need to know how to integrate with PaymentSheet?

viscid pilot
#

ok when you create a subscription you can expand on latest_invoice.payment_intent which will give you access to a client_secret that you need to pass to the PaymentSheet

honest hinge
#

`app.post('/pay', async (request, response) => {
try {
const customer = await stripe.customers.create({
description: 'Test Customer',
email: 'test@costumer.com'
});

let pm = await stripe.paymentMethods.attach(request.body.paymentMethodId, {customer: customer.id});

const product = await stripe.products.create({
  name: 'Delivery',
})

const price = await stripe.prices.create({
  unit_amount: 100000,
  currency: 'brl',
  product: product.id,
  recurring: {interval: 'month'},
});

const subscription = await stripe.subscriptions.create({
  customer: customer.id,
  default_payment_method: pm.id,
  items: [
    {price: price.id},
  ],
  expand: ['latest_invoice.payment_intent'],
});

return response.send({
  clientSecret: subscription.latest_invoice.payment_intent.client_secret,
  status: subscription.latest_invoice.payment_intent.status,
});

} catch (e) {
return response.send({ error: e.message });
}
});`

viscid pilot
#

if you're going to use the Payment Sheet you would have to remove this
let pm = await stripe.paymentMethods.attach(request.body.paymentMethodId, {customer: customer.id});

honest hinge
viscid pilot
#

right

honest hinge
#

so far i think i understand

viscid pilot
#

and in your subscription creation you should put default_payment_method: pm.id,

#

the id is that PaymentSheet will handle all of this for you

honest hinge
#

I strip let pm = await stripe.paymentMethods.attach(request.body.paymentMethodId, {customer: customer.id}); but leave default_payment_method: pm.id in the subscription? I didn't understand

viscid pilot
#

no you would remove them both

honest hinge
#

ah, ok

#

i then have this error now message: 'This customer has no attached payment source or default payment method. Consider adding a default payment method. For more information, visit https://stripe.com/docs/billing/subscriptions/payment-methods-setting#payment-method-priority.',

viscid pilot
#

yeah sorry my bad, you need to add payment_behavior: "default_incomplete", when creating the subscription

honest hinge
#

ok, I managed to open the PaymentSheet, now how could I let the customer choose the number of installments for the payment?

sudden violet
#

you'd have to handle that in UI in your own app before opening the PaymentSheet.

honest hinge
sudden violet
#

There's no built in UI (user interface) in Stripe's PaymentSheet for something like picking a number of installments in a subscription, and it's not possible to add custom UI to the sheet itself for that. So you'd have to get that information from the customer in your own app's interface before using the PaymentSheet(and probably send that information to your server so you can set up the subscription appropriately).

honest hinge
honest hinge
#

I found out that I will need to use subscription_schedules instead of subscription, how can I do that with PaymentSheet?

sudden violet
#

It's quite complicated really

honest hinge
sudden violet
#

this is going to be quite hard to do so you need to experiment with the API a lot.

honest hinge
#

let me ask you a question, maybe I'm following the wrong path, the flow of our application is like Uber's, the customer requests the ride and pays for it, but in our app, this payment can be made in installments, the customer will be able to decide how many times he wants to make the payment of this amount, for example: the fare was 100, but he does not have 100 to pay in cash, so he will pay twice of 50 monthly, 50 once a month until finalize the total amount, in this example, it would be 2 months, this is very common in Brazil, I don't know if it is different in other countries

grand furnace
honest hinge
grand furnace
#

Yes that's right

honest hinge
#

Installment plans allow customers to make partial payments for a set amount of time until the total amount is paid. For example, when The Pacific buys new printing presses, they sell the used ones to other publications. Smaller publications rarely have enough funds to pay for a printing press upfront, so they pay using an installment plan instead.

grand furnace
#

Yeah that's up to you if you want to use Subscription Schedules. A plain Subscription could work too

honest hinge
#

๐Ÿ˜–

grand furnace
#

That's why I suggested a plain subscription while setting cancel_at. It's a bit simpler

honest hinge
grand furnace
#

The plan selection would have to be prior to creating the Subscription object

honest hinge
grand furnace
#

You will need to have the user select their plan prior to creating the Subscription. You won't be able to update the Subscription once it's been created with default_incomplete

#

I recommend reading that guide, as this should make a bit more sense after that

honest hinge
grand furnace
#

Yeah

honest hinge
#

see if I understand correctly what you mean by using Subscription with cancel_at, if the customer chooses to pay the amount of 100 in two times of 50, I would create the Subscription with the value of 50 and the cancel_at calculating two months?

grand furnace
honest hinge
#

I did not understand this part You should account for any retries (your payment settings define your retry behavior: https://dashboard.stripe.com/settings/billing/automatic)

grand furnace
#

So if your retry schedule allows for payment retries for 7 days, then you would want cancel_at to be 2 months from the subscription creation timestamp + 7 days

#

But really if your use-case is installments only, then the Subscription Schedule option shouldn't be that complicated

#

If you want to go that route instead

#

Subscription Schedules usually just get rough when you have many phases

honest hinge
grand furnace
#

Idea is you don't want the subscription to cancel before payment is collected (if it fails and then needs to retry a few times)

honest hinge
grand furnace
#

No that's at the link I sent above in your account settings

#

But really if your Subscription Schedule use-case is just installments, it wouldn't be that difficult to go that route if you'd rather just do that

honest hinge
#

ok, it's starting to make a little more sense

steady dune
#

If your payments are the same amount and same spacing in time, then a regular subscription with cancel_at can achieve the same result at the subscription schedule installment plan suggestion

#

the advantage of the subscription schedule approach is it allows you to easily customize the payment schedule (different amounts, different timing) without needing to track when up update the subscription in real time as payments happen

#

The schedule manages that for you

#

The payment retries are for each individual invoice the subscription creates (in either case)

honest hinge
#

ok, so in our use case Subscription is enough

#

thank you very much for the explanations

steady dune
#

The existing invoices can still be paid and will retry, but no new invoices will be created

honest hinge
#

Could you explain to me what proration is? I've never seen that term before

steady dune
#

That means partial charges or credits based on partial periods of the billing cycle

#

eg: if you charge $10/month on the first of the month, if a customer cancels on the 15th of a month you might want to credit them $5 for the remaining half month of service they paid for but did not use.

#

(similarly when upgrading or downgrading plans)

#

Most ways you can changes subscriptions support enabling or disabling prorations according to your business needs.

#

For the installment plan use case, this is mostly not relevant. You'd have the subscription cancel following the final invoice and there would be no proration.

honest hinge
#

got it, I don't think we will need to deal with this in our use case

honest hinge
#

why does the second installment of this Subscription have a different value than the first sub_1Kz1ExJ1bzV4VWW3fSlVYQrT?

#

`app.post('/pay', async (request, response) => {
const installmentsNumber = request.body.installments;

try {
const customer = await stripe.customers.create({
description: 'Test Customer',
email: 'test@costumer.com'
});

const product = await stripe.products.create({
  name: 'Delivery',
})

const total = 1800

const price = await stripe.prices.create({
  unit_amount: total / installmentsNumber,
  currency: 'brl',
  product: product.id,
  recurring: {
    interval: 'month',
  }
});

const subscription = await stripe.subscriptions.create({
  customer: customer.id,
  payment_behavior: "default_incomplete",
  cancel_at: new Date(new Date().getTime() + (installmentsNumber - 1) * 30 * 24 * 60 * 60 * 1000 + 7 * 24 * 60 * 60 * 1000),
  items: [
    {
      quantity: 1,
      price: price.id,
    },
  ],
  expand: ['latest_invoice.payment_intent'],
});

return response.send({
  clientSecret: subscription.latest_invoice.payment_intent.client_secret,
});

} catch (e) {
return response.send({ error: e.message });
}
});`

red flicker
#

Hi ๐Ÿ‘‹ I'm stepping in for @steady dune Give me a minute to catch up

#

What value are you talking about here?

honest hinge
red flicker
#

Dashboard links are useless to. me.

#

Since it's your dashboard and I don't have access to it

#

What is the "value" you are referencing here?

honest hinge
#

the total amount is 18, so I made a subscription of 9 to count twice, the first installment had the value of 9 but the second is with the value of 1.80

red flicker
#

By value do you mean the 'price'?

#

9 whats?

honest hinge
red flicker
#

Okay so the price amount?

honest hinge
red flicker
#

can you actually copy/paste that price ID in here?

#

Or better yet, the subscription ID

honest hinge
red flicker
#

That is because the current monthly period goes from May 13th - June 13th. But you have the subscription cancelling on June 19th. That means the second invoice, by default, is only charging your customer for the 6 days of the second period.

honest hinge
red flicker
#

If you want to charge them for 2 whole months then I would wait until the second invoice is created. That will update the current_period_start and current_period_end for the Subscription. Then you could update the the Subscription cancel_on_date to be the same as current_period_end.

#

This may be a bit more complicated but installments are a good use case for Subscription Schedules

#

Using Subscription Schedules you can specify how many times you want the billing cycle to repeat and then cancel the subscription when those cycles are over

honest hinge
#

๐Ÿ˜–

red flicker
#

It definitely can be. You just need to make sure your cancel_on_date is at the end of the billing cycle so you don't create prorations

#

But you can try out using the Node snippet for creating a schedule and see how that works for you

#

Just drop than in your code where you create the Subscription and swap out your price ID and change the iterations to 2

honest hinge
red flicker
#

You would need to retrieve the subscription, invoice, and payment intent. Like you do currently, just one more layer.

honest hinge
#

I'm doing some tests here but I'm having another problem, I've already tested several different versions of stripe-react-native in expo, but they are all having the same problem with confirmPayment and PaymentSheet, whenever I finish the additional authentication step, it redirects me out of the app

red flicker
#

Where does it redirect you?

honest hinge
red flicker
#

What version of the Stripe React Native SDK are you using?

honest hinge
red flicker
#

A huge number of changes have been introduced since then. I would request you upgrade your version.

honest hinge
red flicker
#

This is a known bug with Expo and the Stripe RN SDK. You will need to update to resolve it.

honest hinge
#

ok, I'll update then, another question, how can I make my PaymentSheet have my local language? He always appears in English

peak jetty
#

๐Ÿ‘‹ stepping in. Hi @honest hinge. PaymentSheet is localized based on the device's language settings.

#

You can't override this currently

honest hinge
#

I believe I managed to make the flow with Schedule Subscription, can you guys evaluate this code snippet and tell me if that's right?

`app.post('/pay', async (request, response) => {
const installmentsNumber = request.body.installments;

try {
const customer = await stripe.customers.create({
description: 'Test Customer',
email: 'test@costumer.com'
});

const product = await stripe.products.create({
  name: 'Delivery',
})

const total = 10000

const price = await stripe.prices.create({
  unit_amount: total / installmentsNumber,
  currency: 'brl',
  product: product.id,
  recurring: {
    interval: 'month',
  }
});

const schedule = await stripe.subscriptionSchedules.create({
  customer: customer.id,
  start_date: 'now',
  end_behavior: 'cancel',
  phases: [
    {
      items: [
        {
          price: price.id,
          quantity: 1,
        },
      ],
      iterations: installmentsNumber,
    },
  ],
  expand: ['subscription.latest_invoice.payment_intent']
});

const invoice = await stripe.invoices.finalizeInvoice(
  schedule.subscription.latest_invoice.id
);

const paymentIntent = await stripe.paymentIntents.retrieve(
  invoice.payment_intent
)

return response.send({
  clientSecret: paymentIntent.client_secret,
});

} catch (e) {
return response.send({ error: e.message });
}
});`

peak jetty
#

Looks right to me. Have you tested it?

#

Actually I'm not sure you will be able to expand the sub when creating the schedule

honest hinge
peak jetty
#

Instead you just grab the response

#

Huh

#

Oh never mind

honest hinge
peak jetty
#

That's correct

#

No no

#

I misread

#

You are expanding the response by doing that

#

So you can properly grab the client secret

#

Looks good

honest hinge
#

would this be the flow to create a Schedule Subscription type payment (obviously that some fixed data in the code will be received by parameter)? Do I need to do anything else before going to the webhook or can I believe that everything is ok?

peak jetty
#

I don't know what you mean exactly by: "would this be the flow to create a Schedule Subscription type payment "

#

That flow will create a Subscription yes

#

And that Subscription will follow the Sub Schedule that you created

honest hinge
peak jetty
#

Yep test clocks will be helpful to ensure your schedule is working as you desire end-to-end!

honest hinge
peak jetty
#

๐Ÿ™‚

honest hinge
#

should the charge keep happening even after reaching the threshold set in shcedule? In this example I put it as 2 iterations, which would be May and June, but it keeps charging each time I advance one month

peak jetty
#

No that shouldn't happen if you set end_behavior: cancel on your sub schedule

#

Can you provide the subscription ID for that test?

honest hinge
peak jetty
#

Ah okay that subscription wasn't created from a schedule

#

You created it via the Dashboarad

#

So it will continue after 2 months

honest hinge
#

make sense