#Dooing

1 messages ยท Page 1 of 1 (latest)

balmy portal
#

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"
]);```
quaint path
#

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?

#

RENEW or NONE are no listed ๐Ÿ˜ฆ

balmy portal
#

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.

balmy portal
quaint path
#

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?

balmy portal
quaint path
#

//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();

balmy portal
#

which one works when you try it in test mode?

quaint path
#

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

balmy portal
#

yes you can

#

B I don't think will work since it omits the first phase

quaint path
#

and for A) its then correct to speak of NOW and not the end of the phase?

balmy portal
#

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 ?

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

balmy portal
balmy portal
#

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.

quaint path
#

So this is rather 3) Adding a schedule to an existing subsccription and not 4) upgrading a subscription

#

thats confusing in the doc

balmy portal
#

yeah I don't disagree

#

just adapt the code I gave you, it works.

quaint path
#

\SubscriptionSchedule::update

#

what is this?

#

cant find an upate in the api or documentatipon

quaint path
#

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?

balmy portal
#

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.

quaint path
#

"items": [
{
"billing_thresholds": null,
"price": "price_1LcSdNF2iEUqWxhTedR97oBQ",
"quantity": 1,
"tax_rates": []
}

#

there are no plans.

#

I assume you ran an old api

steady yarrow
#

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!

balmy portal
#

yes it's called prices on the latest version, so my bad there

#

actually it's called items

quaint path
#

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?

balmy portal
#

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)

quaint path
#

subscription.getItems()
.getData()
.get(0)
.getId()

#

but thats the subscription id, I assume, not the price id.. or am I wrong???

steady yarrow
quaint path
#

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?

steady yarrow
steady yarrow