{"id":13878075,"url":"https://github.com/rubymonolith/nocheckout","last_synced_at":"2025-07-16T14:30:51.924Z","repository":{"id":193577115,"uuid":"689082485","full_name":"rubymonolith/nocheckout","owner":"rubymonolith","description":"Rails controllers for Stripe Checkout Sessions and Webhooks","archived":false,"fork":false,"pushed_at":"2023-10-06T18:13:11.000Z","size":40,"stargazers_count":20,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-09-16T17:46:34.750Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubymonolith.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-08T18:55:46.000Z","updated_at":"2024-01-26T20:35:33.000Z","dependencies_parsed_at":"2023-09-08T21:08:43.711Z","dependency_job_id":null,"html_url":"https://github.com/rubymonolith/nocheckout","commit_stats":null,"previous_names":["rubymonolith/nocheckout"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubymonolith%2Fnocheckout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubymonolith%2Fnocheckout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubymonolith%2Fnocheckout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubymonolith%2Fnocheckout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubymonolith","download_url":"https://codeload.github.com/rubymonolith/nocheckout/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226134226,"owners_count":17578778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-06T08:01:39.168Z","updated_at":"2025-07-16T14:30:51.908Z","avatar_url":"https://github.com/rubymonolith.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# NoCheckout\n\n[![Gem Version](https://badge.fury.io/rb/nocheckout.svg)](https://badge.fury.io/rb/nocheckout) [![Tests](https://github.com/rubymonolith/nocheckout/actions/workflows/main.yml/badge.svg)](https://github.com/rubymonolith/nocheckout/actions/workflows/main.yml)\n\n\u003e [!IMPORTANT]\n\u003e This project is a work in progress. This README was written to better understand the implementation for developers. **Some of the APIs may not have yet been implemented, renamed, or removed**. When the API settles down and is running in production for a while, a 1.0 release will be cut and this notice removed.\n\nNoCheckout is a set of Rails controllers that does the least amount possible to integrate with Stripe. That might sound lazy at first, and it is, but if you try to roll your own signup and payment form and keep your Rails database sync'ed with your payment info, you'll quickly find out there's better things in life to worry about. Its best to delegate as much payment collection, processing, and reporting to your payment processor as you can. Fortunately Stripe does a great job sweating all the details in checkout UX and reporting that I'm OK delegating everything out to them.\n\nThis gem does that--it sends your users down the [Stripe Checkout](https://stripe.com/docs/payments/checkout/how-checkout-works) path for buying stuff, then sends them back to your site via the CheckoutSessions controller. There's also a StripeWebhooks controller that handles Stripe's callbacks in a plain 'ol controller. You don't even have to include the `stripe.js` file on your website, which means your users experience a faster, more private browsing session.\n\nThat's it! There's not much to it and that's the point.\n\n## Installation\n\nInstall the gem and add to the application's Gemfile by executing:\n\n    $ bundle add nocheckout\n\nIf bundler is not being used to manage dependencies, install the gem by executing:\n\n    $ gem install nocheckout\n\n## Get a Stripe API key\n\nBefore you do anything you'll need to go to https://dashboard.stripe.com/test/apikeys and get the \"Secret Key\". You can set the `STRIPE_SECRET_KEY` environment variable or create an initializer using your configuration manager of choice:\n\n```ruby\n# Set the API key in ./config/initializers/stripe.rb\nStripe.api_key = Rails.configuration.stripe[:secret_key]\n```\n\n## Checkout Sessions Controller\n\n[Stripe Checkout Sessions](https://stripe.com/docs/api/checkout/sessions) send users from your website to a branded stripe.com page where they can enter their credit card details and complete the purchase. Once the purchase is complete, the user is redirected back to your website.\n\nThe NoCheckout::CheckoutSessionsController handles the interface between Stripe and your Rails application and tries to be as small as possible.\n\nTo get started, create a base CheckoutSessionsController that maps the Users from your application with [Stripe Customers](https://stripe.com/docs/api/customers).\n\n### Create user record after checkout is complete\n\nThis approach creates a new user record after the checkout is complete with the name and email they give during the Stripe checkout process.\n\n```ruby\nclass PaymentsController \u003c NoCheckout::Stripe::CheckoutSessionsController\n  STRIPE_PRICE = \"test_price_...\"\n\n  def show\n    # Retrieve info from Stripe\n    customer = Stripe::Customer.retrieve checkout_session.customer\n    subscription = Stripe::Subscription.retrieve checkout_session.subscription\n\n    # Do stuff with Stripe info\n    user = User.find_or_create_by email: customer.email\n    customer.metadata.user_id = user.id\n    customer.save\n    user.name = customer.name\n    user.save!\n\n    # In this example we set the current user to stripe info. This likely\n    # doesn't make sense for your security context, so be careful...\n    self.current_user = user\n    redirect_to root_url\n  end\n\n  protected\n    def create_checkout_session\n      super \\\n        mode: \"subscription\",\n        line_items: [{\n          price: self.class::STRIPE_PRICE,\n          quantity: 1\n        }]\n    end\nend\n```\n\nThen, for each product you want to offer, create a controller and inherit the `CheckoutSessionsController`.\n\n```ruby\nclass PlusCheckoutSessionsController \u003c PaymentsController\n  STRIPE_PRICE = \"price_...\"\nend\n```\n\nThere's a lot of different ways you can wire up the controllers depending on how many Stripe prices are in your application. This README assumes you're selling just a few products, so the prices are hard coded as constants in the controller. This could easily be populated from a database.\n\n### Create a user record before checkout is complete\n\n```ruby\nclass PaymentsController \u003c NoCheckout::Stripe::CheckoutSessionsController\n  before_action :authorize_user # Loads a current_user\n\n  STRIPE_PRICE = \"test_price_...\"\n\n  def show\n    customer = Stripe::Customer.retrieve checkout_session.customer\n    subscription = Stripe::Subscription.retrieve checkout_session.subscription\n\n    # Do stuff with Stripe info\n\n    redirect_to root_url\n  end\n\n  protected\n    def create_checkout_session\n      super \\\n        mode: \"subscription\",\n        customer: retrieve_or_create_customer(\n          id: current_user.id,\n          email: current_user.email,\n          name: current_user.name\n        ),\n        line_items: [{\n          price: self.class::STRIPE_PRICE,\n          quantity: 1\n        }]\n    end\nend\n```\n\n## Webhooks Controller\n\n[Stripe Webhooks](https://stripe.com/docs/webhooks) are extensive and keep your application up-to-date with what Stripe. In this example, we'll look at how to handle a subscription that's expiring and update a User record in our database.\n\n```ruby\nclass StripesController \u003c NoCheckout::Stripe::WebhooksController\n  STRIPE_SIGNING_SECRET = ENV[\"STRIPE_SIGNING_SECRET\"]\n\n  def customer_subscription_created\n    user.subscription_expires_at data.current_period_end\n  end\n\n  def customer_subscription_updated\n    user.subscription_expires_at data.current_period_end\n  end\n\n  def customer_subscription_deleted\n    user.subscription_expires_at Time.now\n  end\n\n  def user\n    @user ||= User.find data.customer\n  end\nend\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/rubymonolith/nocheckout. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/rubymonolith/nocheckout/blob/main/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Code of Conduct\n\nEveryone interacting in the NoCheckout project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/rubymonolith/nocheckout/blob/main/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubymonolith%2Fnocheckout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubymonolith%2Fnocheckout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubymonolith%2Fnocheckout/lists"}