Skip to main content

Subscribe to GoRails to get access to this episode and all other pro episodes, and new awesome content every month.

Subscribe Now
Only $19/month

Unlimited access. Cancel anytime.

35 Payments with Stripe:

Adding Stripe update card form, Cancel, and Resubscribe

Episode 91 · October 23, 2015

Learn how to polish your Stripe subscriptions by adding update card forms, cancellation buttons, and letting users seamlessly resubscribe

Payments


Transcripts

Subscribe or login to view the transcript for this episode.

Discussion


Fallback

Hello Chris! Thx for a great episode! So i noticed in this video that you updated some field on the current user to save the last 4 etc on the card. I was thinking that i could use that function to update other fields for the user as they subscribe to my service. I use pundit to setup a role based access to my app and i was successful in changing the role from demo to premium at the same time as they added a card and subscribe to my services but when i also try to update other fields it fails.. could the reason it fails be because of the way the form is built?

Fallback

That form should work just fine for that. If they're submitting other information, for those fields you'll want to make sure they have the 'name' attribute so they get submitted (unlike the credit card fields). Aside from that, make sure you're permitting those extra params and that should probably do the trick.

Fallback

So i need to name it with that ever the field it is under the user model? and then put what params in the controller to permitting,

Fallback

Yep! Just like you would with a normal form. This one isn't really much different aside from it taking the credit card fields and handling them specially with JS. The JS will submit the form like normal, so your other fields will get treated just fine.

Fallback

So like <%= user.something %> as name of the field?

Fallback

You can use the regular form field helpers like input_tag to make that easier.

Fallback
Fallback

I added form tags for the fields like this: "<%= text_field_tag :address1, current_user.address1, :class => "form-control" %> but i still get the "You must supply either a card, customer, or bank account to create a token." when i try to post the form.. and i'm not getting much in the console so i don't know what is breaking :)

Fallback

Sounds like your JS isn't sending over a token through to the server.

Fallback

I'm getting a 400 Bad request in the javascript console


Fallback

Have you had the issue where the pay button doesn't respond until you either have reloaded the page or clicked it 2 or 3 times?

Fallback

Nope, but might want to check to see if you've got JS errors or conflicts with Turbolinks.

Fallback

Just in case anyone else runs into the Turbolinks issue where your jQuery/JS doesn't work unless you refresh, the last answer here worked for me:)

http://stackoverflow.com/qu...

Fallback

I had same issue and its a simple fix.

Turbolinks is the problem so to fix wrap your stripe javascript function like so in your coffee file:

ready = ->

...
the stripe functions go here
...

$(document).ready(ready)
$(document).on('page:load', ready)


Fallback

Awesome episodes Chris...got me through many huddles!! One question: How do I display the dates of the current billing period to the user on the Edit page? I would like to show the date when the current payment expires.

Thanks

Fallback

I think the current_period_end timestamp on the Stripe Subscription is what you want there. You could cache this on the user so you don't have to hit their API every time.


Fallback

Thanks again Chris for this. For some reason my "Card update" is giving the following error:
"Invalid source object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs"

I have exactly the same code as you do. When I inspect the element on this page it says:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)

Not sure why, but has anyone witnessed this issue? See screenshot for error message. Thanks.

Fallback

First I would check to make sure that the user has a stripe_subscription_id saved in the record. You might be passing a nil in on accident.

Fallback

Yes, the user has a stripe_subscription_id. In fact, cancellations and resubscriptions are fine, but the error comes in the card update.

Fallback

Oh interesting. In that case, is your stripeToken nil?

Fallback

Ok, it is working now. I think another javascript in my template was causing a few errors. I took care of all javascript errors that were showing up in the console and suddenly card update is working again. Thanks for your pointers Chris.

Fallback

Always something like that, cascading into a bug showing up elsewhere. :) Glad you got it fixed!

Fallback

Hi Chris, i'm getting the same error as Fusi - my subscription.source gives a nil result and i am unsure why - my coffee script all seems fine. my user has a stripe_subscription_id saved

Fallback

i have no idea what happened - it all works now....oddly enough i did not change anything at all :-)

Fallback
Weird, I'm running into the same exact issue "invalid source object: " where it talks about the token being nil. 

In your course about this @Chris, you also noticed that at one point in the Requiring Cards for Sign Up — Payments with Stripe and Rails Master Class / Bonus Videos. At 23 minutes, 20 seconds, you pull up the user in the console. The user has a stripe token but it's saved as nil, that's the same thing that is happening and like these guys I've also combed through my code and compared it to yours. 

Is it possible someone can share why that's happening?
Fallback
Same issue trying to get my head around this. Is anyone able to share how to solve the issue?

Fallback

Hi Chris,
How easy is it to extend this so that if a payment does not succeed (say a renewal), the user's account is downgraded to basic (Free) account automatically?

Fallback

Pretty simple. You'd need to basically listen for the subscription cancellation webhook to come across and then in there you can just move the user's plan over. The webhook will be your way of knowing that the last payment attempt failed and the user's paid subscription canceled. It'll just send a notification to your server and as long as you're listening for it, you can run the code to downgrade to the free plan. Make sense?

Check out this episode on the webhook stuff if you haven't already: https://gorails.com/episode...


Fallback

Hi Chris,
Great tutorial. I wanted to pick your brain for a second. I followed your tutorial to the letter aside from using rails 5.0.2 and Bootstrap V4. For some reason when in the process of resubscribing a customer who needs to update to a new payment method using the "Use a different card" button, the hidden form only appears for a second and then disappears. I've checked my code against yours on Github and everything appears in order. If I click into one of the form fields before it disappears, the form will not go away but when I click on the submit button, the customers card is not updated. Any thoughts?

Fallback

Hmm, hard to say. I would start by inspecting the HTML and then stepping through the JS code line by line and making sure those are working as expected. You'll figure it out pretty quickly if you break it down and find the spot that's not working like you want it.

Fallback

Thanks for the quick reply, I'll keep digging and let you know what I find.


Fallback

Hey Chris, I am getting same error Fusi had below.Also like Fusi nothing is returning Nil and it fails same way as his screen shot. I also just completed your newer Stripe Elements Javascript and got everything to work there no problem. My main question though is I don't know how to combine the Jquery in this video into the Javascript of the new first video in this series. I don't know how or if you can combine both jquery and javascript together in the subscription.js file. I also don't know how to convert the jquery to Javascript if that is the right way to go. The only warning and only .js in my app is the line var stripe = Stripe(public_key); this is saying Stripe is not defind. Thanks in advance for your help.


Fallback
Hey Chris, I went through your video. I'm running into 2 issues that I think are connected. 
1. In "my/users/edit" where i'm placing most of the work I'm running into an error in the console.
Uncaught ReferenceError: Stripe is not defined - subscription.self-     xxx.js?body=1:5 

2. After cancelling then when I go to "subscription/new" and click "use a different card" The div is flashing the update form for maybe a 10th a second and going back to the previous page.

I'm curious if these issues are caused by the same thing? I think it's not loading the javascript right or the turbolinks? Can you give me any ideas?
Thanks

Login or create an account to join the conversation.