#Dooing
1 messages ยท Page 1 of 1 (latest)
what code have you tried?
I'm just going to save myself some time and post this. Take some time to read it and let me know if it helps.
'customer' => $customer->id,
'items' => [
[
'plan' => $gold->id,
],
]
]);
// schedule a change from gold to silver at the end of the period
$sched = \Stripe\SubscriptionSchedule::create([
'from_subscription' => $subscription->id,
]);
\Stripe\SubscriptionSchedule::update($sched->id, [
'phases' => [
[
"start_date" => $subscription->current_period_start,
"end_date" => $subscription->current_period_end,
'plans' => [
[
'plan' => $gold->id,
'quantity' => 1,
],
],
"prorate" => "true"
],
[
"start_date" => $subscription->current_period_end,
'plans' => [
[
'plan' => $silver->id,
'quantity' => 1,
],
],
],
],
"end_behavior" => "release"
]);```
see also https://stripe.com/docs/billing/subscriptions/subscription-schedules/use-cases#upgrading-subscriptions which describes all this too.
In your, as well as the java sample on the site.. what do I need to define the current period for? This is the already running subscription
So wouldnt it just be enough to define one single phase with the start date as for example the end date of the current period
and the new price
quantity probably means "buy ONE subscription and not two"
is one not the default?
.setIterations(12L)
what if I do not set iterations.. will it continue forever, as I would need?
And what is the endbehaviour, CANCEL, NONE, RELEASE, RENEW?
Does release just mean, leave things as they are, after you applied the step(s)?
And CANCEL means, cancel the subscription at the end of the phases again?
What means NONE or RENEW?
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
RENEW or NONE are no listed ๐ฆ
it's just how this API works
it makes you re-declare all the existing phases when you edit the schedule, since the phases are declarative. I know it's confusing but it's how that API is.
yep. You don't need iterations at all really
so, you are saying, I have to set again that the current period stays as is, so i need to retrieve the current subscription, retrieve the current price, and re-define that this will stay as is. And this won't subscribe the customer a second time to the same price, for the currently active period?
just use release. It means, "leave things as they are, after you applied the step(s)?" yes.
yes
//A)
SubscriptionScheduleCreateParams.builder()
.setCustomer(stripeCustomerId)
.setStartDate(SubscriptionScheduleCreateParams.StartDate.NOW)
.setEndBehavior(SubscriptionScheduleCreateParams.EndBehavior.RELEASE)
.addPhase(
SubscriptionScheduleCreateParams.Phase.builder()
.addItem(
SubscriptionScheduleCreateParams.Phase.Item.builder()
.setPrice(currentStripePriceId) // current price during current period
.build())
.setIterations(1)
.build())
.addPhase(
SubscriptionScheduleCreateParams.Phase.builder()
.addItem(
SubscriptionScheduleCreateParams.Phase.Item.builder()
.setPrice(newStripePriceId) // new price, atarting at the end of the current period
.build())
.build())
.build();
OR...
SubscriptionScheduleCreateParams.builder()
.setCustomer(stripeCustomerId)
.setStartDate(subscription.getCurrentPeriodEnd())
.setEndBehavior(SubscriptionScheduleCreateParams.EndBehavior.RELEASE)
.addPhase(
SubscriptionScheduleCreateParams.Phase.builder()
.addItem(
SubscriptionScheduleCreateParams.Phase.Item.builder()
.setPrice(newStripePriceId) // new price, starting at the end of the current period
.build())
.build())
.build();
which one works when you try it in test mode?
From what you told me, it's A, but given that B) defines the start date as the current period end... it should also work and is much simpler?
which one works when you try it in test mode?
I cant so easily do that
and for A) its then correct to speak of NOW and not the end of the phase?
nope, it should be the start of the subscription like I posted in my example
I'm really sorry but I gave you a working example I myself use all the time and I know works for exactly your use case and I've used to help many other people, I'm not sure why we have to argue about it
if you try to do B and not include the current phase you get an error like Uncaught (Status 400) (Request req_Au0bG4pk56TuVN) You can not modify the start date of the current phase. for example
if you try to do A and use now you get the same error
it's because there's implicitly a phase on the schedule that matches the current period of the subscription, you have to redeclare that one when updating the schedule.
is that all clear @quaint path ?
could you please stop the aggressive tone
not its not clear.
.setStartDate(SubscriptionScheduleCreateParams.StartDate.NOW)
.setEndBehavior(SubscriptionScheduleCreateParams.EndBehavior.CANCEL)
.addPhase(
this is, from the JAVA samples I see on the site, as well as live from my coding sample -
not part of the phase as you put it in (Phyton?)
it is one layer above
so the start date will apply to all phases, as I see it
it's PHP
you don't need any of the CreateParams because you're not creating a fresh schedule
you have an existing subscription [0]. So you are using the from_subscription field to make a schedule from that
[0] - ": I want to change an existing monthly subscription of a customer at the end of their current billing cycle."
and then updating that schedule. That's what my PHP code is doing
I agree step 4 in the docs I linked doesn't really work for you
so that's why I saved time at the start of the conversation by just giving you the exact code that shows the exact working flow.
So this is rather 3) Adding a schedule to an existing subsccription and not 4) upgrading a subscription
thats confusing in the doc
\SubscriptionSchedule::update
what is this?
cant find an upate in the api or documentatipon
can this be done without submitting the request, in one go, or do I need to actually send a CREATE reques to stripe, an empty one basically, and then update this again with a second one?
the latter
again, that's why I shared the code I did, that is the only way that works
please just spend a bit of time on your own trying it in test mode, it will all make sense.
I have to leave, my colleagues will take over but please do spend a bit of time trying this out in test mode and if you have questions later, post the exact code you ran and the IDs sub_xxx and sub_sched_xxx of any objects you created that are behaving in ways you don't expect.
"items": [
{
"billing_thresholds": null,
"price": "price_1LcSdNF2iEUqWxhTedR97oBQ",
"quantity": 1,
"tax_rates": []
}
there are no plans.
I assume you ran an old api
Taking over for my colleague. Let me catch up.
Could you try to summarize your latest request? or just let me know if there's any follow-up Qs I can answer!
yes it's called prices on the latest version, so my bad there
actually it's called items
thats what I found / put above
public void downgradeSubscriptionAtCurrentPeriodEnd(String stripeCustomerId, String stripeSubscriptionId, String currentStripePriceId, String newStripePriceId){
Subscription subscription = retrieveSubscription(stripeSubscriptionId, SubscriptionRetrieveParams.builder()
.build());
try {
SubscriptionSchedule schedule = SubscriptionSchedule
.create(SubscriptionScheduleCreateParams.builder()
.setFromSubscription(stripeSubscriptionId).build()
);
schedule.update(
SubscriptionScheduleUpdateParams.builder()
.addPhase(
SubscriptionScheduleUpdateParams.Phase.builder()
.setStartDate(subscription.getCurrentPeriodStart())
.setEndDate(subscription.getCurrentPeriodEnd())
.addItem(SubscriptionScheduleUpdateParams.Phase.Item.builder()
.setPrice(currentStripePriceId)
.setQuantity(1L)
.build()).build()
)
.addPhase(
SubscriptionScheduleUpdateParams.Phase.builder()
.setStartDate(subscription.getCurrentPeriodEnd())
.addItem(SubscriptionScheduleUpdateParams.Phase.Item.builder()
.setPrice(newStripePriceId)
.setQuantity(1L)
.build()).build()
)
.setEndBehavior(SubscriptionScheduleUpdateParams.EndBehavior.RELEASE)
.build());
} catch (StripeException e) {
throw new StripeExternalException(e);
}
}
thats a big big shoot
๐ฆ
Since I have to retrieve the actual subscription as a THIRD call for that anyway - is there a way to retrieve the -currentStripePriceId- from the subscription, instead of having to give it as input to the method?
subscription.getItems()[0].getPriceId() , or similiar
however that would work in Java. Or if you're asking if you can just omit .setPrice(currentStripePriceId) in the call and have the API infer the current ID, no that's not possible ((Status 400) (Request req_dBt5D5O8fyg3SI) All phase items must pass one of plan, price, or price_data. if you take the time to test it)
subscription.getItems()
.getData()
.get(0)
.getId()
but thats the subscription id, I assume, not the price id.. or am I wrong???
Here is where you can find the priceId
https://stripe.com/docs/api/subscriptions/object#subscription_object-items-data-price-id and the priceId looks like price_....
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
subscription.getItems()
.getData()
.get(0)
.getPrice().getId();
and this wont need an extension?
and this, I assume will only work in this simple way, if there is only one subscription at a time for the customer, right?
What do you mean by extension ?
I recommend you to test and try it on your own, and if you are having an error please share it so that we can help solving it