Skip to content
This repository has been archived by the owner on Dec 6, 2022. It is now read-only.

Commit

Permalink
Moved to Rails 3... again
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Godawa committed Dec 17, 2010
1 parent 2669c43 commit acb7a23
Show file tree
Hide file tree
Showing 23 changed files with 698 additions and 0 deletions.
34 changes: 34 additions & 0 deletions README.textile
@@ -0,0 +1,34 @@
h1. przelewy24

h2. What it is?

* This is the gem that consist of generator, to generate files to play with polish payment service "Przelewy24.pl":http://www.przelewy24.pl
* Generator creates model, controller and views for dealing with Przelewy24.

h2. What for?

* Application that have products to sell finally sends the form to Przelewy24 service. All transaction security and verification is held by generated files and Przelewy24 side.

h2. Installation on Rails 3 app

Add this to your Gemfile
@gem 'przelewy24'@

Then install it
@bundle install@

Generate the files for Przelewy24 with ModelName and Przelewy24 SellerID
@rails generate przelewy24 payment 1034@

and you are free to connect your transactions with Przelewy24 payment service.

h2. Contribute

Thanks for forking and helping!

major issues:
- rspecs or tests to gem needs to be done

h3. License

Copyright (c) 2010 ["Jakub Godawa":http://github.com/vysogot], released under the MIT license
24 changes: 24 additions & 0 deletions Rakefile
@@ -0,0 +1,24 @@
require 'rake/testtask'

Rake::TestTask.new do |test|
test.pattern = 'test/**/*_test.rb'
test.libs << 'test'
end


begin
require "jeweler"
Jeweler::Tasks.new do |gem|
gem.name = "przelewy24"
gem.homepage = "http://github.com/rails3-przelewy24"
gem.summary = "This is a Rails engine to play with Polish payment service Przelewy24.pl"
gem.description = "Gem consist of a generator 'przelewy24'. Application that have products for sale finally sends the form to Przelewy24 service. All transaction security and verification is held by generated files and Przelewy24 side."
gem.email = "jakub.godawa@gmail.com"
gem.authors = ["Jakub Godawa"]
gem.files = Dir["{lib}/**/*", "{app}/**/*", "{public}/**/*", "{config}/**/*"]
gem.rubyforge_project = "rails-p24"
end
Jeweler::GemcutterTasks.new
rescue
puts "Jeweler or dependency not available."
end
1 change: 1 addition & 0 deletions VERSION
@@ -0,0 +1 @@
0.0.3
14 changes: 14 additions & 0 deletions lib/generators/przelewy24/USAGE
@@ -0,0 +1,14 @@
Description:
Stubs out new model and controller for Przelewy24 payment service.
Pass the name of the model you want to be responsible for that.

Example:
rails generate przelewy24 Payment

This will create:
app/models/payment.rb
app/controllers/payments_controller.rb
app/views/payments/...
db/migration/*_create_payments.rb
config/locales/przelewy24.yml
routes...
76 changes: 76 additions & 0 deletions lib/generators/przelewy24/przelewy24_generator.rb
@@ -0,0 +1,76 @@
class Przelewy24Generator < Rails::Generators::Base
source_root File.expand_path('../templates', __FILE__)
argument :class_name, :type => :string, :default => "Payment"
argument :seller_id, :type => :string, :default => "1000"
class_option :migration, :type => :boolean, :default => true, :desc => "Include migration file."

def generate_files

# Generate views
views.each do |view|
template "views/#{view}.html.erb", "app/views/#{plural_name}/#{view}.html.erb"
end

# Copy locales
copy_file "przelewy24.yml", "config/locales/przelewy24.yml"

# Generate controller
template 'controller.rb', "app/controllers/#{plural_name}_controller.rb"

# Generate helper
template 'helper.rb', "app/helpers/#{plural_name}_helper.rb"

# Generate model
template 'model.rb', "app/models/#{singular_name}.rb"

# Generate routes
routes_string=<<FINITO
resources :#{plural_name} do
collection do
get 'confirm'
get 'error'
post 'ok'
end
end
FINITO

route(routes_string)

# Generate migration
if options.migration?
# #{Time.now.utc.strftime("%Y%m%d%H%M%S")}_
migration_file_name = "#{Time.now.utc.strftime("%Y%m%d")}_create_#{table_name}"
template 'migration.rb', "db/migrate/#{migration_file_name}.rb"

# migrate
rake("db:migrate", :env => :development)
end
end

private

def views
%w(new index _form show ok error confirm)
end


# imagine model: SuperService
def controller_class_name
class_name.pluralize # SuperServices
end

def singular_name
class_name.underscore # super_service
end

def migration_name
"Create#{controller_class_name}" # CreateSuperServices
end

def plural_name
singular_name.pluralize # super_services
end

alias table_name plural_name # super_services
alias file_name singular_name # super_service
end
113 changes: 113 additions & 0 deletions lib/generators/przelewy24/templates/controller.rb
@@ -0,0 +1,113 @@
# responsible for transactions and connection with payments service
# Przelewy24.pl
class <%= controller_class_name %>Controller < ApplicationController
# requests from Przelewy24.pl
protect_from_forgery :except => [:ok, :error]

# If you want to use ssl, uncomment that line
# before_filter :require_ssl, :only => [:new, :confirm]

def index
@<%= table_name %> = <%= class_name %>.all
end

def show
@<%= file_name %> = <%= class_name %>.find(params[:id])
end

def new
@<%= file_name %> = <%= class_name %>.new
end

# create new transaction with <%= file_name %> before verifing it with <%= file_name %> confirm form
def create
@<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])

if @<%= file_name %>.save
flash[:notice] = t('transaction_created')
session[:<%= file_name %>_id] = @<%= file_name %>.id

redirect_to confirm_<%= plural_name %>_url
else
render :action => 'new'
end
end

def destroy
@<%= file_name %> = <%= class_name %>.find(params[:id])
@<%= file_name %>.destroy
flash[:notice] = t('transaction_destroyed')
redirect_to <%= table_name %>_url
end

# transaction confirmation
def confirm
@<%= file_name %> = <%= class_name %>.find(session[:<%= file_name %>_id])
end

# first verification from Przelewy24.pl
def ok
@<%= file_name %> = <%= class_name %>.find_by_session_id(params[:p24_session_id])
if @<%= file_name %> && @<%= file_name %>.update_attributes(:order_id => params[:p24_order_id],
:metoda => params[:p24_karta],
:order_id_full => params[:p24_order_id_full])

# verification with service - name in polish to be consistent with current PHP spec
przelewy24_weryfikuj
else
flash[:error] = 'Transaction not found'
redirect_to <%= table_name %>_url
end
end

def error
end

private

# Przelewy24.pl final verification process
def przelewy24_weryfikuj

# verification script url
url = URI.parse('https://secure.przelewy24.pl/transakcja.php')

# post request with '&' PHP connectors
req = Net::HTTP::Post.new(url.path)
req.set_form_data(@<%= file_name %>.attributes_for_verify, '&')
# create new http object with ssl usage
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
# UNCOMMENT THAT IF OpenSSL throws unwanted errors
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# get the response from Przelewy24.pl
res = http.start {|http| http.request(req) }
case res
when Net::HTTPSuccess, Net::HTTPRedirection
results = res.body.split("\r\n")
if results[1] == "TRUE"
# check if transaction is not already used
unless @<%= file_name %>.is_verified
@<%= file_name %>.update_attribute(:is_verified, true)
return
else
error_desc = t('transaction_already_used')
end
else
error_desc = "#{results[2]} #{results[3]}"
end
else
error_desc = t('connection_error')
end
@<%= file_name %>.update_attribute(:error_code, results[2])
# display error flash and redirect to error action
flash[:error] = error_desc
redirect_to :action => :error
end
end
2 changes: 2 additions & 0 deletions lib/generators/przelewy24/templates/helper.rb
@@ -0,0 +1,2 @@
module <%= controller_class_name %>Helper
end
28 changes: 28 additions & 0 deletions lib/generators/przelewy24/templates/migration.rb
@@ -0,0 +1,28 @@
class <%= migration_name %> < ActiveRecord::Migration
def self.up
create_table :<%= table_name %> do |t|
t.string :session_id
t.string :id_sprzedawcy
t.integer :kwota
t.string :klient
t.string :adres
t.string :kod
t.string :miasto
t.string :kraj
t.string :email
t.text :opis
t.integer :order_id
t.integer :order_id_full
t.string :error_code
t.string :language
t.integer :metoda
t.boolean :is_verified, :default => false

t.timestamps
end
end

def self.down
drop_table :<%= table_name %>
end
end
90 changes: 90 additions & 0 deletions lib/generators/przelewy24/templates/model.rb
@@ -0,0 +1,90 @@
# responsible for process with payment service Przelewy24.pl
class <%= class_name %> < ActiveRecord::Base
before_create :set_session_id
SELLER_ID = <%= seller_id %> # Put here you account login on przelewy24
COUNTRY = 'PL'
LANGUAGE = 'pl'

validates_presence_of :email, :klient, :adres, :kod, :miasto
validates_format_of :kod, :with => /[0-9]{2}-[0-9]{3}/ # polish post code check

# price to display - in db is in cents
def kwota_pln
kwota.to_f/100
end

# generate 64-char long key to przelewy24.pl
def self.generate_session_id
<%= class_name %>Tools::generate(64, 26, 97)
end
# attributes that are needed in second verification
def attributes_for_verify
{
'p24_session_id' => session_id,
'p24_order_id' => order_id,
'p24_id_sprzedawcy' => SELLER_ID,
'p24_kwota' => kwota
}
end

# attibutes that are needed for first contact with przelewy24.pl
def attributes_for_p24
{
'p24_session_id' => session_id,
'p24_id_sprzedawcy' => SELLER_ID,
'p24_opis' => <%= class_name %>Tools::replace_polish_chars(opis),
'p24_kwota' => kwota,
'p24_klient' => <%= class_name %>Tools::replace_polish_chars(klient),
'p24_adres' => <%= class_name %>Tools::replace_polish_chars(adres),
'p24_kod' => kod,
'p24_miasto' => <%= class_name %>Tools::replace_polish_chars(miasto),
'p24_kraj' => COUNTRY,
'p24_email' => email,
'p24_language' => LANGUAGE
}
end

# after the payment correct verification
def set_account
transaction do
unless is_verified
update_attribute(:is_verified, true)

# Here you should put what happen after correct verification process
end
end
end

private

# setting session id for connection with przelewy24
def set_session_id
self.session_id = <%= class_name %>.generate_session_id
self.id_sprzedawcy = SELLER_ID
self.kraj = COUNTRY
self.language = LANGUAGE
end
class <%= class_name %>Tools

# Generate a string with given length from given ascii range
def self.generate(length, from, to)
string = ""
length.times { |i| string << (rand(from)+to).chr }
string
end

# Replace polish chars, so there will be no funny signs on Przelewy24 in transactions
def self.replace_polish_chars(string)
ascii = "acelnoszzACELNOSZZ"
cep = "\271\346\352\263\361\363\234\277\237\245\306\312\243\321\323\214\257\217"
string = Iconv.new("cp1250", "UTF-8").iconv(string)
string.tr(cep,ascii)
end

end

end

0 comments on commit acb7a23

Please sign in to comment.