Ruby on rails - Stripe : "you did not set a valid publishable key" - ruby-on-rails

I have a problem I am following step by step this tutorial to include the gem stripe to my rails application : https://stripe.com/docs/checkout/rails
But I have an issue when I launch my payment:
you did not set a valid publishable key. Call Stripe.setPublishableKey() with your publishable key.
The tutorial I am following doesn't use this method Stripe.setPublishableKey() and it seems working as well ...
I am using a .env file to get the API keys and I use the test keys from the tutorial.
Any idea for the solution ?!
Thank you very much :) If you need more information please tell me
My actual code is a copy/paste from the tutorial I use.
Edit 1
I don't understand why but it working when I push the project on Heroku ... but I still don't understand why it's failing on local

From the guide you linked:
The application makes use of your publishable and secret API keys
to interact with Stripe. An initializer is a good place to set these
values, which will be provided when the application is started.
Add the following to config/initializers/stripe.rb:
Rails.configuration.stripe = {
:publishable_key => ENV['PUBLISHABLE_KEY'],
:secret_key => ENV['SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
These keys values are pulled out of environmental variables so as not
to hardcode them. It’s best practice not to write API keys into your
code, where they could easily wind up in source control repositories
and other non-private destinations.
Have you added that data into config/initializers/stripe.rb ?
If so, you may need to restart your server as the files in config/initializers are only loaded on server startup

I am using a .env file to get the API keys and I use the test keys from the tutorial.
Rails don't autoload environment variables from .env file. So, in the tutorial author set required variables from the console before server start, but you use .env file.
To fix that use gem dotenv-rails: just add in your Gemfile(not need add the same lines as in gem description)

I was able to overcome the same type of error in another tutorial by changing the last line of the stripe.rb file to:
Stripe.api_key = Rails.application.credentials.stripe[:secret_key]
with the key being saved in the credentials.yml.enc file in rails 5.2

Related

Where do you save the Aws.config file for the aws-skd gem?

I am trying to install the aws-skd gem:
https://github.com/aws/aws-sdk-ruby
They suggest either ENV variables or their shared config file. I have already gone down the path of secrets.yml and it works nicely so far. So then I figured I could just use Aws.config which they state takes precedence over the former. I took a guess and placed it in the config folder but that does not work.
You should be able to just call s3 = Aws::S3::Client.new but in my case the default region and credentials are not being stored / applied.
Where do I store this file or is there another way to do this?
PS I tried adding it in an initializer but that didn't work either.
UPDATE
Now that I RTFM a few more times I found my issue. I will answer my own question below.
As stated in the documenation: ~/.aws/credentials You can read more details here.
So for some reason I read the docs as Aws.config being an actual file vs setting the config (D'oh!).
So I tried an initializer again:
#config/initalizers/aws-sdk.rb
require 'aws-sdk'
Aws.config.update({
access_key_id: Rails.application.secrets.aws_access_key_id,
secret_access_key: Rails.application.secrets.aws_secret_access_key,
region: Rails.application.secrets.aws_region
})
I actual had tired this before but I thought it was not working. I did not actually quit and restart the console as well as the server - I just reloaded the console so the initializer changes did not get reflected. +1 to #mark-b for making me read the docs again.

Stripe on Ruby on Rails - Creating config/initializers/stripe.rb

Following the Stripe setup document for Ruby on Rails (https://stripe.com/docs/checkout/rails), it says that the config/initializers/stripe.rb will be created when the app is started.
I have shutdown the server and the restarted the server several times, but this file isn't being created under the path identified in the documentation.
What am I doing wrong? Appreciate the help.
Create this file manually. Initializers are not generated on application start. They are read by Rails to configure your specific application.
Create config/initializers/stripe.rb and fill it with the following.
Rails.configuration.stripe = {
:publishable_key => ENV['PUBLISHABLE_KEY'],
:secret_key => ENV['SECRET_KEY']
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
Set your secret key and publishable key in your ENVs. Restart your application after the change or you won't see any difference.
I can see how you would be confused, Stripe documentation says "An initializer is a good place to set these values, which will be provided when the application is started." They mean the values you set in that file will be provided to the application instance.
I really disliked the anti-pattern that Stripe Gem has, instead I end up overriding the Stripe::StripeConfiguration (even here we can see naming redundancy 😞) Here is my solution:
## Stripe Initializer
## {Rails.root}/config/initializers/stripe.rb
# frozen_string_literal: true
require 'stripe'
module Stripe
class StripeConfiguration
def api_key=(key_value)
#api_key = key_value || Rails.application.credentials.stripe.secret_key
end
end
end
Rails.configuration.stripe = {
publishable_key: Rails.application.credentials.stripe.secret_key,
secret_key: Rails.application.credentials.stripe.secret_key
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
NOTE: for the Stripe team, their implementation in no way gives an extra security layer, anyone who can have access to the console/credentials will be able to read it so it makes no sense that they override it on each request. You can always assign an attribute with an operator.
PS: I'm working on an app that would improve that security (Comming Soon)

Ruby on Rails Configuration - Plaid Gem

I am trying to integrate the plaid gem into one of my projects. From the docs it says to configure it as such.
https://github.com/plaid/plaid-ruby
Plaid.config do |p|
p.customer_id = 'Plaid provided customer ID here'
p.secret = 'Plaid provided secret key here'
p.environment_location = 'URL for the development or production environment'
end
My question is what file should I have this code? Should it go in my application.rb? config.rb? Just want to make sure I'm following convention. Thanks!
You should create this file in config/initializers directory with any file name i.e. plaid.rb.
FYI: Using Initializer Files.

How to pass keyfile as argument in Rails project

I'm using the bigQuery gem in my project. I initialize it with options client_id, service_email, key, project_id, and dataset. I have my .p12 file from Google that I want to pass in but I'm not sure where to put the file in my Rails project - I tried putting it in the same directory as my config file and passing the relative path name, but I'm getting an invalid passphrase error. Specifically, line 10 is throwing an error when load_key is being called:
key = Google::APIClient::PKCS12.load_key(
opts['key'],
"notasecret"
)
So clearly it's not loading the key file correctly. I'm terrible at Rails asset control - where should I put my keyfile and what pathname should I pass in my options hash?
You could place the keyfile into the config directory, then do the following:
opts['key'] = Rails.root.join('config','nameofkeyfile.p12').to_s
You don't want the key to be in a location that your application will serve up to the public, so config sounds like a good location to me.
You can experiment with the block you have above in the Rails console:
# run `rails c` then
keypath = Rails.root.join('config','nameofkeyfile.p12').to_s
key = Google::APIClient::PKCS12.load_key(keypath, "notasecret")
Looking at the Google::APIClient documentation, I see load_key is deprecated. They recommend using Google::APIClient::KeyUtils instead.
key = Google::APIClient::KeyUtils.load_from_pkcs12(keyfile, "notasecret")
As for a quick overview of the Rails asset pipeline, see here. (Please pardon the "for dummies" part of that url, it appears to be good, quick info.)

What is the best way to store app specific configuration in rails?

I need to store app specific configuration in rails. But it has to be:
reachable in any file (model, view, helpers and controllers
environment specified (or not), that means each environment can overwrite the configs specified in environment.rb
I've tried to use environment.rb and put something like
USE_USER_APP = true
that worked to me but when trying to overwrite it in a specific environment it wont work because production.rb, for instance, seems to be inside the Rails:Initializer.run block.
So, anyone?
Look at Configatron: http://github.com/markbates/configatron/tree/master
I have yet to use it, but he's actively developing it now, and looks quite nice.
I was helping a friend set up the solution mentioned by Ricardo yesterday. We hacked it a bit by loading the YAML file with something similar to this (going from memory here):
require 'ostruct'
require 'yaml'
require 'erb'
#config = OpenStruct.new(YAML.load_file("#{RAILS_ROOT}/config/config.yml"))
config = OpenStruct.new(YAML.load(ERB.new(File.read("#{RAILS_ROOT}/config/config.yml")).result))
env_config = config.send(RAILS_ENV)
config.common.update(env_config) unless env_config.nil?
::AppConfig = OpenStruct.new(config.common)
This allowed him to embed Ruby code in the config, like in Rhtml:
development:
path_to_something: <%= RAILS_ROOT %>/config/something.yml
The most basic thing to do is to set a class variable from your environment.rb. I've done this for Google Analytics. Essentially I want a different key depending on which environment I'm in so development or staging don't skew the metrics.
This is how I did it.
In lib/analytics/google_analytics.rb:
module Analytics
class GoogleAnalytics
##account_id = nil
cattr_accessor :account_id
end
end
And then in environment.rb or in environments/production.rb or any of the other environment files:
Analytics::GoogleAnalytics.account_id = "xxxxxxxxx"
Then anywhere you ned to reference, say the default layout with the Google Analytics JavaScript, it you just call Analytics::GoogleAnalytics.account_id.
I found a good way here
Use environment variables. Heroku uses this. Remember that if you keep configuration in the codebase, anyone with access to the code has access to any secret configuration (aws api keys, gateway api keys, etc).
daemontool's envdir is a good tool for setting configuration, I'm pretty sure that's what Heroku uses to give application their environment variables.
I have used Rails Settings Cached.
It is very simple to use, keeps your configuration values cached and allows you to change them dynamically.

Resources