Integrating payu payment gateway (active_merchant_payu_in) with spree - ruby-on-rails

I am trying to integrate payu.in payment gateway with spree into my rails application. I have included gem 'active_merchant_payu_in' in the application.
My app/models/spree/gateway/payu.rb looks like this:
module Spree
class Gateway::Payu < Gateway
def provider_class
ActiveMerchant::Billing::Integrations::PayuIn
end
end
end
In application.rb
config.after_initialize do |app|
app.config.spree.payment_methods += [
Spree::Gateway::Payu
]
end
Development.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
$payu_merchant_id = ActiveMerchant::Billing::Integrations::PayuIn.merchant_id = '--ID--'
$payu_secret_key = ActiveMerchant::Billing::Integrations::PayuIn.secret_key = '--Key--'
end
I have enabled Spree::Gateway::Payu from admin credentials. Now when i do a checkout i get below error.
NoMethodError in Spree::CheckoutController#update
undefined method `authorize' for ActiveMerchant::Billing::Integrations::PayuIn:Module
can someone guide me towards right path.
Many Thanks :)

Incase anyone is still facing this problem.
Solution: Edit your payment method "Spree::Gateway::Payu" and set auto_capture? field to true.
Payu does not support authorize method which is called when "auto capture" is set to false, when set to true, "purchase" method is called which is supported by payu.
You can read more about auto capture in Spree's documentation. https://guides.spreecommerce.com/developer/payments.html

Related

Rails activestorage not working with shopify_app gem

I am creating a Shopify app, I want to attach the image with the shop model.
but I can not able to start to serve when I add active storage association with the shop model.
error
/home/web/.rvm/gems/ruby-2.6.1/gems/activerecord-6.0.1/lib/active_record/dynamic_matchers.rb:22:in method_missing': undefined method has_one_attached' for Shop (call 'Shop.connection' to establish a connection):Class (NoMethodError)
configuration:
rails:- 6.0.1, ruby:- 2.6.1, shopify_app:- 11.3.2
This is what my code looks like now
shop.rb
class Shop < ActiveRecord::Base
include ShopifyApp::SessionStorage
has_one_attached :icon, dependent: :destroy
end
config/initializers/shopify_app.rb
ShopifyApp.configure do |config|
config.application_name = "App Name"
config.api_key = ENV['shopify_api_key']
config.secret = ENV['shopify_api_secret']
config.old_secret = "<old_secret>"
config.scope = "write_script_tags,read_script_tags,read_themes"
config.embedded_app = false
config.after_authenticate_job = false
config.api_version = ShopifyVersion.shopify_api_version
config.session_repository = Shop
config.webhooks = [
{topic: 'app/uninstalled', address: 'https://example.com/webhooks/app_uninstalled', format: 'json'},
{topic: 'shop/update', address: 'https://example.com/webhooks/shop_update', format: 'json'},
end
I tried this:
config/initializers/shopify_app.rb
config.session_repository = 'ShopifyApp::InMemorySessionStore'
but still, it's not working on the production.
error
ShopifyApp::InMemorySessionStore::EnvironmentError (Cannot use InMemorySessionStore in a Production environment. Please initialize ShopifyApp with a model that can store and retrieve sessions):
also, try to upgrade the gem version but no hope then create a demo with the current configuration and it will work. I can not understand why it will not work on my current project.
can anyone explain it to me?
I really appreciate your suggestions.
sorry for bad English.
Thanks in advance.
After doing google and try to search on the Shopify community. i got some suggestions, and base on suggestion i try to update only the shopify_app gem version and configuration base on the new version.
It works for me.
change 13.2.0 instead of 11.3.2.

Messenger bot using Rails: setup for multiple pages

I want to create a Messenger Bot used by different users for their Facebook pages. I created a rails app and use the facebook-messenger gem.
I successfully created the bot and it works when I do the set up for one page. Now, I follow the instructions to make my bot live on multiple Facebook Pages (see "Make a configuration provider" section).
I'm new to rails and I'm not sure where to put the class ExampleProvider? I put it in my config/application.rb file:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module BotletterApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.paths.add File.join('app', 'bot'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'bot', '*')]
end
class BotProvider < Facebook::Messenger::Configuration::Providers::Base
def valid_verify_token?(verify_token)
bot.exists?(verify_token: verify_token)
end
def app_secret_for()
ENV['APP_SECRET']
end
def access_token_for(page_id)
bot.find_by(user_id: page_id).page_access_token
end
private
def bot
MyApp::Bot
end
end
Facebook::Messenger.configure do |config|
config.provider = BotProvider.new
end
end
Then I have my app/bot/setup.rb file to create the bot. I don't know how to use the provider I created in place of the ENV variables?
require "facebook/messenger"
include Facebook::Messenger
Facebook::Messenger::Subscriptions.subscribe(access_token: ENV["ACCESS_TOKEN"])
Facebook::Messenger::Profile.set({
get_started: {
payload: 'GET_STARTED_PAYLOAD'
}
}, access_token: ENV['ACCESS_TOKEN'])
I searched in the Rails documentation how to make it work but unfortunately could not find anything.
UPDATE:
Now I'm able to set up the bots for different pages. Unfortunately, the following line of my ConfigProvider is getting an error:
config/initializers/config_provider.rb
def bot
Rails.application.class.parent::Bot
end
I'm getting the following error:
NameError (uninitialized constant BotletterApp::Bot):
config/initializers/config_provider.rb:17:in bot'
config/initializers/config_provider.rb:7:inapp_secret_for'
Do you know how should I name my app?
My BotModule:
module BotletterApp
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
config.paths.add File.join('app', 'listen'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'listen', '*')]
end
end
UPDATE, it works with ::Application, here is the new file:
class ConfigProvider < Facebook::Messenger::Configuration::Providers::Base
def valid_verify_token?(verify_token)
ENV['VERIFY_TOKEN']
end
def app_secret_for(page_id)
ENV['APP_SECRET']
end
def access_token_for(page_id)
CoreBot.find_by_page_id(page_id).page_access_token
end
private
def bot
BotletterApp::Application
end
end
Facebook::Messenger.configure do |config|
config.provider = ConfigProvider.new
end
The problem is I get the following error unless my db query seems working (it works in the rails console):
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column:
page_id.id: SELECT "core_bots".* FROM "core_bots" WHERE
"page_id"."id" = ? LIMIT ?):
Moving to an answer for improved readability ;)
Regarding 'plain'... Instead of
def bot
BotletterApp::Application
end
use
def bot
Bot
end
or (it looks like you named your model containing all pages CoreBot(?) (assuming you have a typical ActiveRecord model in /app/models/core_bot.rb, I was assuming Bot)
def bot
CoreBot
end
Then you should be able to use the template code from the README.md
As for your latest problem: it seems like the access_token_for-method gets called with a hash, searching with something like {id: 1}. You might want to check where that value is coming from. I would suggest to take a few steps back, and stay closer to the template code.

Rails - conditionally log for a specific hostname

I'm looking for a way to configure a Rails server log only if the client has contacted a specific hostname. e.g. I could make it so that http://public.example.com doesn't get logged, but http://debug.example.com (same underlying Rails app server) does get logged (or ideally gets logged in more detail than the regular host). It would help with production debugging.
You can use gem Lograge to customize your log. This gem will give you much more custom to your log. For example, in your case, I will do this
After install the gem. Create a file at config/initializers/lograge.rb
# config/initializers/lograge.rb
Rails.application.configure do
config.lograge.enabled = true
config.lograge.custom_options = lambda do |event|
# custom log on specific domain
if event.payload[:host] == "debug.example.com"
{:host => event.payload[:host]}
else
{}
end
end
end
And in your Application Controller
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# This will add request's host to lograge so you can use it to filter log later
def append_info_to_payload(payload)
super
payload[:host] = request.host
end
end
Now you can customize your log base on domain, on how to customize it please read at: https://github.com/roidrage/lograge

Uninitialized constant error after uploading on Heroku

There is the following problem: I'm developing some Rails application on my local machine, and all is good, app works, but after uploading on Heroku there would be the following error (I saw it using 'heroku logs'):
NameError (uninitialized constant Api::V1::ApiV1Controller::UndefinedTokenTypeError)
My code:
def require_token
begin
Some code which generates UndefinedTokenTypeError
rescue UndefinedTokenTypeError => e
render json: e.to_json
end
end
UndefinedTokenTypeError is in lib/errors.rb file:
class EmptyCookieParamsError < StandardError
def to_json
{ result_code: 1 }
end
end
class UndefinedTokenTypeError < StandardError
def to_json
{ result_code: 2 }
end
end
I've got the same version for Rails/Ruby on my local machine (2.0). How can I fix it? Thanks.
From what I can see, you may be experiencing either a CORS-related issue or you're not authenticating properly
Cross Origin Resource Sharing
CORS is a standard HTML protocol, which basically governs which websites can "ping" your site. Facebook & Twitter's third-party widgets only work because they allow any site to send them data
For Rails to work with CORS, it's recommended to install the Rack-CORS gem. This will allow you to put this code in your config/application.rb file:
#CORS
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/data*', :headers => :any, :methods => :post
end
end
Because you're experiencing these issues on Heroku, it could be the problem you're experiencing. Even if it isn't, it's definitely useful to appreciate how CORS works
Authentication
Unless your API is public, you'll likely be authenticating the requests
The way we do this is with the authenticate_or_request_with_http_token function, which can be seen here:
#Check Token
def restrict_access
authenticate_or_request_with_http_token do |token, options|
user = User.exists?(public_key: token)
#token = token if user
end
end
We learnt how to do this with this Railscast, which discusses how to protect an API. The reason I asked about your code was because the above works for us on Heroku, and you could gain something from it!
Running on Heroku will be using the production environment. Check to see what is different between environments/development.rb and environments/production.rb
You can try running your app in production mode on your local machine, rails server -e production
I am guessing your config.autoload_paths isn't set correctly. Should be in config/application.rb

Integrating Payment Gateway (activemerchant based) with spree

I am trying to integrate payu.in payment gateway into my rails app.
I have integrated their gem in the application but when i go to
/admin/payment_methods/new
I am not able to see the payment gateway under the provider options.
I have followed the steps as prescribed in http://guides.spreecommerce.com/payment_gateways.html
My app/models/spree/gateway/payu.rb looks like this:
module Spree
class Gateway::Payu < Gateway
def provider_class
ActiveMerchant::Billing::Integrations::PayuIn
end
end
end
I believe you need something like this:
config.after_initialize do |app|
app.config.spree.payment_methods += [
Spree::BillingIntegration::PaypalExpress,
Spree::BillingIntegration::PaypalExpressUk
]
end
(See: https://github.com/spree/spree_paypal_express/blob/master/lib/spree_paypal_express/engine.rb#L23-28 )
For me it just worked when I added a similar line of code:
config.after_initialize do
Rails.configuration.spree.payment_methods << Spree::PaymentMethod::Pagarme
end
To my config/application.rb file.
(I saw it in http://blog.siyelo.com/active-merchant-and-spree)

Resources