Stripe event call using webhook and upgrade and downgrade of subscription
Posted By : Shubham Saxena | 23-Mar-2015
Webhook
In previous blogs on stripe, I wrote about the simple and customised implementation and also subscribing a user with a plan. In this blog, I will talk about the webhook of the stripe which is basically hit a URL given in the https://dashboard.stripe.com/account/webhooks . There are many events which could be attached to many URLs and on the trigger of the event the URL will be called. The events are like: customer.created, customer.deleted, payment.created, payment.failed, payment.paid. We can also set the envirnment of the URL set. It could be test or live environment and is based on the keys(test/live) we are using.
I am using the event invoice.payment_succeeded and using the URL (http://******/payment).
Below is the action which is called with the trigger of the URL.
def payment()
{
try{
Stripe.apiKey = "1234567890abc";
def json = request.JSON
def customerId = json.data.object.customer
def planId = json.data.object.lines.data[0].plan.id
long activeUntil = json.data.object.lines.data[0].period.end
def job_spaces
def subscriptionId = json.data.object.subscription
Customer cu = Customer.retrieve(customerId);
com.stripe.model.Subscription subscription = cu.getSubscriptions().retrieve(subscriptionId);
switch(planId){
case "Trial_Plan" : job_spaces = Plan.TRIAL.plan_job_spaces;
break;
case "Basic_Plan" : job_spaces = Plan.BASIC.plan_job_spaces;
break;
case "Unlimited_Plan" : job_spaces = Plan.UNLIMITED.plan_job_spaces;
break;
}
table s = table.findByCustomer_id(customerId)
if(s){
s.active_until = activeUntil
s.job_spaces = Integer.parseInt(job_spaces)
s.subscription_id = subscriptionId
s.plan_id = planId
s.save(flush:true)
}
render "DONE"
}
catch(Exception e)
{
render "Unsuccessful"
}
}
In the above code, I am retrieving the customer id, subscription id, end of period and other information from the object to save it in the table on server database so as to inform the customer.
Upgrade/Downgrade subscription
We could do the upgrade and downgrade from the existing subscription. For an instance, I have 3 plans(trial, gold, platinum) attached to my account on stripe and each plan renewed after 30 days. So suppose firstly, a customer is subscribed to the gold plan than that would be of $20 then after 5 days, he want to upgrade to platinum plan that would be of $80. Then we will charge him for 5 days according to the gold plan and remaining 25 days according to the platinum plan. This type of charge policy is called prorate.
To upgrade the subscription, we first need to retrieve the customer for which we need to change the subscription. Then retrive the existing subscription object. Then we can trigger the update subsctiption API call. Below is the code for upgrade/downgrade:
try{
Stripe.apiKey = "123456abc123";
def token = params.stripeToken;
Customer cu = Customer.retrieve(s.customer_id);
// update subscription for customer
com.stripe.model.Subscription subscription = cu.getSubscriptions().retrieve(s.subscription_id);
log.debug("old plan: " + subscription.plan.name)
// attach card to the customer retrieved from Stripe
Map<String, Object> updateParamsCard = new HashMap<String, Object>();
updateParamsCard.put("card", token);
cu.update(updateParamsCard);
// update subscription for customer.
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("plan", session.getAttribute("plan_id").toString());
// update subscription to new plan
def upgradeSubscriptionResponse = subscription.update(updateParams);
log.debug("upgradeSubscriptionResponse " + upgradeSubscriptionResponse)
log.debug("upgradeSubscriptionResponse.id " + upgradeSubscriptionResponse.id)
log.debug("upgradeSubscriptionResponse.plan.name " + upgradeSubscriptionResponse.plan.name)
// update subscription
updateSubscription(s.customer_id, upgradeSubscriptionResponse.id, upgradeSubscriptionResponse.plan.name, upgradeSubscriptionResponse.currentPeriodEnd, job_spaces)
}
catch(com.stripe.exception.CardException e)
{
flash.message = "card Error occured"
e.printStackTrace()
}
catch(Exception e){
flash.message = "Error occuered"
e.printStackTrace()
}
By this way, we could use prorate functionality of stripe as it is a default functionality but we could make it false by setting the "prorate: false" property while updating the subscription.
THANKS
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Shubham Saxena
Shubham is a Groovy/Grails Developer and has good exposure on FFMPEG. He has worked on development of various SaaS applications.