I have created subscription using stripe api for 1 month interval.
const subscription = await stripe.subscriptions.create(
{
customer: customer.id,
items: [
{
price: productPrice.id,
},
],
// payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent'],
application_fee_percent: fee,
},
{
stripeAccount: accountId,
}
);
Subscription created successfully based on product and price.but i can't wait for 1 month (next billing) for testing so i need to test now how will work for next payment.it will auto deduct from payment method? or customer will notify about next due and have to pay? there need more code for it?
Stripe has a feature called Test Clocks that allows to move subscriptions forward in time. So you could create a subscription with a test clock, then advance the clock by one month to see exactly what happens.
But to answer your question: if the customer (or the subscription) has a default payment method set, then yes Stripe will automatically attempt to make a payment at the end of every billing cycle.
Related
I have implemented stripe recurring subscription that billed annually. I've proposed an offer for my customers that if they refer our website to 5 of their friends and they register, they will get 50% off on their subscription.
How I'll implement that discount for that particular customer on next payment?
The simplest option would be to apply a Coupon to the customer’s subscription. Then during the next billing cycle of the subscription, the coupon will be automatically applied. That can be done is two steps (here done node.js):
// Create the new Coupon, once
// Doc: https://stripe.com/docs/api/coupons/create
const coupon = await stripe.coupons.create({
percent_off: 50,
duration: 'once', // other possible value are 'forever' or 'repeating'
});
// Then every time a customer match your criteria, update their subscription
// Doc: https://stripe.com/docs/api/subscriptions/update
const subscription = await stripe.subscriptions.update(
'sub_xxx',
{ coupon: coupon.id }
);
Another option would be to apply the coupon to the customer instead of on the subscription directly. In that case the coupon would apply to all recurring charges for that customer.
// Doc: https://stripe.com/docs/api/customers/update
const customer = await stripe.customers.update(
'cus_xxx',
{ coupon: coupon.id }
);
I looked around at other solutions but none of them seem to be use case for me. We're not using webhooks instead Cron jobs on the 1st of the month after payments are processed.
My service offers X hours per month.
When user subscriptions they get X hours.
When the user upgrades they immediately get X hours difference between the two, only on upgrade. This works great, the sum is correct.
My issue is that when the user downgrade stripe issues a refund on the next invoice, incorret.
Here is an example that is incorrect, apprentely the user has nothing to pay the next billing cycle which makes no sense; they should pay the downgraded cost.
The code looks like so:
If it's an upgrade:
subscription = await stripe.subscriptions.update(existingSub.id, {
cancel_at_period_end: false,
proration_behavior: "always_invoice",
default_tax_rates: [taxRate.id],
items: [
{
// We need to upgrade the existing item.
id: existingSub.items.data[0].id,
price: price.id,
quantity: 1,
},
],
});
If it's a new sub
await stripe.subscriptions.create({
customer: req.user.stripeCustomerId,
items: [
{
price: price.id,
},
],
billing_cycle_anchor: endOfMonth.unix(),
default_tax_rates: [taxRate.id],
metadata: {
productId,
paymentMethodId,
amount,
userUid: req.user.uid,
},
default_payment_method: paymentMethodId,
});
I'm not sure how to downgrade.
In your scenario above, the user has already paid for the subscription upfront. When you downgraded the subscription, the difference between the subscriptions was pro-rated and credited to the Customer credit balance [0] and applied to the next invoice.
If you don’t want the difference to be prorated when downgrading (maybe your company has a no refund policy), then you would want to apply proration_behavior='none' [1] when downgrading
You can read more about upgrading/downgrading subscriptions here : https://stripe.com/docs/billing/subscriptions/upgrade-downgrade
[0]https://stripe.com/docs/billing/customer/balance#examples
[1]https://stripe.com/docs/api/subscriptions/update#update_subscription-proration_behavior
I'm trying to use SetupIntents to validate and save a Payment Method and then create a Subscription using it to charge the customer (inmediately and then monthly) for the required amount.
This appears to be working fine:
The Card is validated (including SCA if needed)
The Payment Method is created, attached to customer as default and enabled for future usage with the status SUCEEDED.
The Subscription is created and uses the above payment method
The problem is that Stripe then generates the corresponding Invoice and Payment Intent but the latter with the status "requires_action" whenever the provided Card requires Secure Customer Authorization (SCA), even though the right payment method (enabled for future usage) is being used and the card validation has been already performed.
I thought the whole point of using SetupIntents was precisely to validate the payment method beforehand and be able to charge the customer afterwards.
Is my assumption simply wrong or this is actually possible and I might just be missing something?
Thanks in advance
EDIT: This is the subscription creation code in the backend:
# Set the default payment method on the customer
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
subscription = Stripe::Subscription.create({
"customer" => stripe_customer_id,
"proration_behavior" => 'create_prorations',
"items" => [
[
"plan" => "#{#stripe_plan_api_id}",
],
],
'default_tax_rates' => [
"#{#stripe_tax_rate_id}",
],
"expand" => ["latest_invoice.payment_intent"]
});
Thanks for the question, Eduardo.
There are a couple ways to create a Subscription while gaining the Customers SCA authentication and permission to charge the card later. Assuming we already have a Stripe Customer object created and their ID is stored in stripe_customer_id. With the flow you have now there are a couple steps:
Create the SetupIntent. Note that if you create it with usage: 'off_session' and the Customer it'll attach the resulting PaymentMethod when confirmed.
setup_intent = Stripe::SetupIntent.create({
customer: stripe_customer_id,
usage: 'off_session',
})
Collect payment details and confirm the SetupIntent using its client_secret on the client which will attach the PaymentMethod to the customer. Note that it will attach but will not be set as the invoice_settings.default_payment_method by default, so you'll need to make a separate API call later to update the Customer (see step 3).
stripe.confirmCardSetup(
'{{setup_intent.client_secret}}',
{
payment_method: {
card: cardElement,
},
}
).then(function(result) {
// Handle result.error or result.setupIntent
});
Update the Customer and set its invoice_settings.default_payment_method equal to the ID of the PaymentMethod on the successfully confirmed SetupIntent.
Stripe::Customer.update(
stripe_customer_id, {
invoice_settings: {
default_payment_method: 'pm_xxxx', # passed to server from client. On the client this is available on the result of confirmCardSetup
}
})
Create the Subscription with off_session: true
subscription = Stripe::Subscription.create({
customer: stripe_customer_id,
proration_behavior: 'create_prorations',
items: [{
plan: "#{#stripe_plan_api_id}",
}],
default_tax_rates: [
"#{#stripe_tax_rate_id}",
],
expand: ["latest_invoice.payment_intent"],
off_session: true,
})
This uses what's called a "Merchant Initiated Transaction" (MIT) for the Subscription's first payment. This is technically okay if the Subscription is created later after the Customer leaves and should technically work.
If the customer is on your site/app when you create the Subscription, there's another flow that is a bit more correct and doesn't require using a MIT exemption for SCA. The flow is the following for a Subscription without a trial:
Collect card details with createPaymentMethod on the client (no SetupIntent)
stripe.createPaymentMethod({
type: 'card',
card: cardElement,
}).then(function(result) {
//pass result to your server.
})
Attach those card details to the Customer
Stripe::PaymentMethod.attach(
"pm_xxx", {
customer: stripe_customer_id
}
)
Update the Customer's invoice_settings.default_payment_method
Stripe::Customer.update(
stripe_customer_id,
invoice_settings: {
default_payment_method: #requested_source
}
)
Create the Subscription (without off_session: true)
subscription = Stripe::Subscription.create(
customer: data['customerId'],
items: [
{
price: 'price_H1NlVtpo6ubk0m'
}
],
expand: ['latest_invoice.payment_intent']
)
Use the Subscription's latest_invoice's payment_intent's client_secret to collect payment details and confirm on the client.
stripe.confirmCardPayment(
'{{subscription.latest_invoice.payment_intent.client_secret}}', { ......
This second payment flow is a bit more correct from an SCA standpoint for getting authorization to charge the card. The second approach is outlined in the guide here: https://stripe.com/docs/billing/subscriptions/fixed-price
We also have a Stripe Sample you can use to experiment here: https://github.com/stripe-samples/subscription-use-cases/tree/master/fixed-price-subscriptions
I am using Stripe in NodeJS to create subscirptions. I want an invoice to be generated near the end of the billing period. For example, if the billing period is 1-30 Septmeber, I want the invoice to be generated on 30 September. The API docs says that billing_cycle_anchor should do this. But it has no effect when I use it, as an invoice is generated straight away and the user is charged. Code example below.
stripeSubscription = await stripe.subscriptions.create({
customer: id,
items: [{ plan: planId }],
billing_cycle_anchor: moment()
.add('30', 'days')
.unix();,
});
How can I get monthly subscription to generate and charge at the end of the billing period?
Can billing_cycle_anchor be set to the 1st of January, regardless of when the user starts the subscription?
e.g.
this.currentYear = (new Date()).getFullYear();
this.newYear = (new Date(this.currentYear + 1 + '/01/01 00:01')).getTime()/1000;
Then in the function call:
firebase.default
.firestore()
.collection('users')
.doc(user.uid)
.collection('checkout_sessions')
.add({
price: 'price_BLAHBLAH',
billing_cycle_anchor: this.newYear, //1672503000 01/01/2023 12:10 AM
...
})
Using node-recurly. The idea is to create a charge without generating an invoice, then create a subscription and have recurly attach the charge to the subscription invoice. However, when I create a charge, the invoice gets generated automatically for it, so the user gets two separate invoices in the email: one for the charge, and one for the subscription.
This is the charge object that I use:
const shippingCharge = {
amount_in_cents: parseFloat(shippingMethod.amount) * 100,
currency: 'USD',
description: `${shippingMethod.provider} ${shippingMethod.servicelevel_name} shipping`,
account: {
account_code: activationCode,
},
};
I pass it to this function that creates a charge:
recurly.transactions.create(chargeObject, (response) => {
... blah blah blah
});
recurly.subscriptions.create is being called next (calls are being made sequentially using promises). The end result is two invoices instead of one.
Recurly's documentation is confusing. When I was trying to create a charge, I made an assumption that I have to create a transaction. After contacting support, I was provided with the link to create a charge. If you look at the code examples on the right, they reference Recurly_Adjustment, not transaction object. So to create a charge I have to create an adjustment, not a transaction. Switching to proper API call fixed the issue and I received a single invoice.
Alex is correct. You will also need to use revenue_schedule_type: at_invoice if you want the charges together. The Recurly API docs do not include NodeJS examples. Here you go:
return recurly.adjustments.create(accountId, {
unit_amount_in_cents: parseFloat(shippingMethod.amount) * 100,
currency: 'USD',
description: `${shippingMethod.provider} ${shippingMethod.servicelevel_name} shipping`,
revenue_schedule_type: 'at_invoice',
accounting_code: accountingCode,
}).then(() => {
// ...create an invoice, subscription, or whatever
});