Reputation: 1
I am creating a membership based site where members pay in full on the date of joining and every August 1 thereafter. However, when I go to change the billing_cycle_anchor, it has an error stating that the billing cycle anchor must be 'now', 'unset' or 'unchanged', despite the documentation stating that the parameter accepts unix timestamps (https://docs.stripe.com/billing/subscriptions/billing-cycle?locale=en-GB)
Here is my code:
def get_next_august_1st():
current_year = datetime.now().year
if datetime.now().month < 8:
return datetime(current_year, 8, 1)
return datetime(current_year + 1, 8, 1)
@app.route('/webhook', methods=['POST'])
def stripe_webhook():
payload = request.get_data(as_text=True)
sig_header = request.headers.get('Stripe-Signature')
print(f"Received Stripe-Signature: {sig_header}")
print(f"Recieved payload: {payload}")
if not sig_header:
print("Error: Missing Stripe-Signature header")
return jsonify(success=False, message="Missing Stripe-Signature"), 400
try:
event = stripe.Webhook.construct_event(
payload, sig_header, endpoint_secret
)
if event['type'] == 'checkout.session.completed':
session = event['data']['object']
if 'subscription' in session:
subscription_id = session['subscription']
subscription = stripe.Subscription.retrieve(subscription_id)
next_august_1st = get_next_august_1st()
updated_subscription = stripe.Subscription.modify(
subscription_id,
billing_cycle_anchor=int(next_august_1st.timestamp()),
proration_behavior='none'
)
print(f"Subscription {subscription_id} billing cycle anchor updated to {next_august_1st}")
else:
print("No subscription found in session. Ignoring event.")
return jsonify(success=True)
Upvotes: 0
Views: 30
Reputation: 1087
There is no direct way to do what you're looking for unfortunately. You have though multiple workarounds that I'm going to list here:
When creating the Checkout Session in mode subscription
you can pass 2 items, the subscription price and a one-off price for the first period. You can then set subscription_data.billing_cycle_anchor
to the 1st of August and pass subscription_data.proration_behavior: 'none'
. This will make your customer pay a full price for the period until August 1st and then start a yearly period from that point. This is more accurate/readable to your customers, since they will be able to see on the Checkout page how they will be invoiced.
The other option is to create a subscription schedule instead of modifying the subscription in your webhook endpoint when listening to the checkout.session.completed
event. As explained here you can set the first phase to end before Aug 1st and the billing cycle will then be bound the second phase's start date.
Upvotes: 0