webpay_rails 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -2
- data/.travis.yml +4 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +2 -0
- data/README.md +32 -7
- data/config.ru +7 -0
- data/lib/webpay_rails.rb +5 -0
- data/lib/webpay_rails/base.rb +107 -32
- data/lib/webpay_rails/errors.rb +46 -8
- data/lib/webpay_rails/soap.rb +28 -51
- data/lib/webpay_rails/soap_normal.rb +52 -0
- data/lib/webpay_rails/soap_nullify.rb +32 -0
- data/lib/webpay_rails/transaction.rb +4 -11
- data/lib/webpay_rails/transaction_base.rb +11 -0
- data/lib/webpay_rails/transaction_nullified.rb +18 -0
- data/lib/webpay_rails/transaction_result.rb +5 -13
- data/lib/webpay_rails/vault.rb +36 -0
- data/lib/webpay_rails/version.rb +1 -1
- data/spec/internal/app/controllers/orders_controller.rb +107 -0
- data/spec/internal/app/models/concerns/universally_unique_identifiable.rb +15 -0
- data/spec/internal/app/models/order.rb +17 -0
- data/spec/internal/app/models/order_blank.rb +4 -0
- data/spec/internal/app/models/order_invalid.rb +14 -0
- data/spec/internal/app/views/orders/failed.html.erb +1 -0
- data/spec/internal/app/views/orders/gateway.html.erb +8 -0
- data/spec/internal/app/views/orders/new.html.erb +6 -0
- data/spec/internal/app/views/orders/success.html.erb +18 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +10 -0
- data/spec/internal/db/schema.rb +22 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/internal/vendor/vault/597020000541.crt +22 -0
- data/spec/internal/vendor/vault/597020000541.key +27 -0
- data/spec/internal/vendor/vault/tbk.pem +17 -0
- data/spec/spec_helper.rb +31 -4
- data/spec/vault_helper.rb +67 -0
- data/spec/webpay_rails_spec.rb +296 -185
- data/webpay_rails.gemspec +18 -12
- metadata +162 -6
@@ -0,0 +1,52 @@
|
|
1
|
+
module WebpayRails
|
2
|
+
class SoapNormal < Soap
|
3
|
+
def init_transaction(args)
|
4
|
+
request = client.build_request(:init_transaction,
|
5
|
+
message: init_transaction_message(args))
|
6
|
+
|
7
|
+
call(request, :init_transaction)
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_transaction_result(args)
|
11
|
+
request = client.build_request(:get_transaction_result,
|
12
|
+
message: { tokenInput: args[:token] })
|
13
|
+
|
14
|
+
call(request, :get_transaction_result)
|
15
|
+
end
|
16
|
+
|
17
|
+
def acknowledge_transaction(args)
|
18
|
+
request = client.build_request(:acknowledge_transaction,
|
19
|
+
message: { tokenInput: args[:token] })
|
20
|
+
|
21
|
+
call(request, :acknowledge_transaction)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def wsdl_path
|
27
|
+
case @environment
|
28
|
+
when :production
|
29
|
+
'https://webpay3g.transbank.cl/WSWebpayTransaction/cxf/WSWebpayService?wsdl'
|
30
|
+
when :certification, :integration
|
31
|
+
'https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSWebpayService?wsdl'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def init_transaction_message(args)
|
36
|
+
{
|
37
|
+
wsInitTransactionInput: {
|
38
|
+
wSTransactionType: 'TR_NORMAL_WS',
|
39
|
+
buyOrder: args[:buy_order],
|
40
|
+
sessionId: args[:session_id],
|
41
|
+
returnURL: args[:return_url],
|
42
|
+
finalURL: args[:final_url],
|
43
|
+
transactionDetails: {
|
44
|
+
amount: args[:amount],
|
45
|
+
commerceCode: @commerce_code,
|
46
|
+
buyOrder: args[:buy_order]
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module WebpayRails
|
2
|
+
class SoapNullify < Soap
|
3
|
+
def nullify(args)
|
4
|
+
request = client.build_request(:nullify, message: nullify_message(args))
|
5
|
+
|
6
|
+
call(request, :nullify)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def wsdl_path
|
12
|
+
case @environment
|
13
|
+
when :production
|
14
|
+
'https://webpay3g.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
15
|
+
when :certification, :integration
|
16
|
+
'https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def nullify_message(args)
|
21
|
+
{
|
22
|
+
nullificationInput: {
|
23
|
+
authorizationCode: args[:authorization_code],
|
24
|
+
authorizedAmount: args[:authorized_amount],
|
25
|
+
buyOrder: args[:buy_order],
|
26
|
+
commerceId: @commerce_code,
|
27
|
+
nullifyAmount: args[:nullify_amount]
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,24 +1,17 @@
|
|
1
1
|
module WebpayRails
|
2
|
-
class Transaction
|
2
|
+
class Transaction < TransactionBase
|
3
3
|
def self.attr_list
|
4
4
|
[:token, :url]
|
5
5
|
end
|
6
6
|
|
7
|
-
def initialize(document)
|
8
|
-
self.class.attr_list.each do |k|
|
9
|
-
v = document.at_xpath("//#{k.to_s.tr('_', '')}")
|
10
|
-
send("#{k}=", v.text.to_s) unless v.nil?
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
7
|
def success?
|
15
8
|
!token.blank?
|
16
9
|
end
|
17
10
|
|
18
|
-
attr_reader
|
11
|
+
attr_reader(*attr_list)
|
19
12
|
|
20
|
-
|
13
|
+
private
|
21
14
|
|
22
|
-
attr_writer
|
15
|
+
attr_writer(*attr_list)
|
23
16
|
end
|
24
17
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module WebpayRails
|
2
|
+
class TransactionBase
|
3
|
+
def initialize(response)
|
4
|
+
document = Nokogiri::HTML(response.to_s)
|
5
|
+
self.class.attr_list.each do |k|
|
6
|
+
v = document.at_xpath("//#{k.to_s.tr('_', '')}")
|
7
|
+
send("#{k}=", v.text.to_s) unless v.nil?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module WebpayRails
|
2
|
+
class TransactionNullified < TransactionBase
|
3
|
+
def self.attr_list
|
4
|
+
[:token, :authorization_code, :authorization_date, :balance,
|
5
|
+
:nullified_amount]
|
6
|
+
end
|
7
|
+
|
8
|
+
def success?
|
9
|
+
!token.blank?
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader(*attr_list)
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_writer(*attr_list)
|
17
|
+
end
|
18
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module WebpayRails
|
2
|
-
class TransactionResult
|
3
|
-
|
2
|
+
class TransactionResult < TransactionBase
|
4
3
|
def self.attr_list
|
5
4
|
[
|
6
5
|
:buy_order, :session_id, :accounting_date, :transaction_date, :vci,
|
@@ -15,21 +14,14 @@ module WebpayRails
|
|
15
14
|
]
|
16
15
|
end
|
17
16
|
|
18
|
-
def initialize(document)
|
19
|
-
self.class.attr_list.each do |k|
|
20
|
-
v = document.at_xpath("//#{k.to_s.tr('_', '')}")
|
21
|
-
send("#{k}=", v.text.to_s) unless v.nil?
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
17
|
def approved?
|
26
|
-
response_code.to_i
|
18
|
+
response_code.to_i.zero?
|
27
19
|
end
|
28
20
|
|
29
|
-
attr_reader
|
21
|
+
attr_reader(*attr_list)
|
30
22
|
|
31
|
-
|
23
|
+
private
|
32
24
|
|
33
|
-
attr_writer
|
25
|
+
attr_writer(*attr_list)
|
34
26
|
end
|
35
27
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module WebpayRails
|
2
|
+
class Vault
|
3
|
+
def initialize(args)
|
4
|
+
args.map { |k, v| send("#{k}=", v) if respond_to? k }
|
5
|
+
|
6
|
+
raise WebpayRails::MissingPrivateKey unless @private_key
|
7
|
+
raise WebpayRails::MissingWebpayCertificate unless @webpay_cert
|
8
|
+
raise WebpayRails::MissingPublicCertificate unless @public_cert
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :webpay_cert, :private_key, :public_cert
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def webpay_cert=(cert)
|
16
|
+
@webpay_cert ||= OpenSSL::X509::Certificate.new(read(cert))
|
17
|
+
end
|
18
|
+
|
19
|
+
def private_key=(key)
|
20
|
+
@private_key ||= OpenSSL::PKey::RSA.new(read(key))
|
21
|
+
end
|
22
|
+
|
23
|
+
def public_cert=(cert)
|
24
|
+
@public_cert ||= OpenSSL::X509::Certificate.new(read(cert))
|
25
|
+
end
|
26
|
+
|
27
|
+
def read(val)
|
28
|
+
return val if val.include? '-----BEGIN'
|
29
|
+
|
30
|
+
path = Pathname.new(val)
|
31
|
+
return path.read if path.file?
|
32
|
+
|
33
|
+
raise WebpayRails::FileNotFound, val
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/webpay_rails/version.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
class OrdersController < ActionController::Base
|
2
|
+
before_action :find_order, only: [:return, :final]
|
3
|
+
before_action :verify_order, only: :return
|
4
|
+
|
5
|
+
def new
|
6
|
+
@order = Order.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@order = Order.new(create_params)
|
11
|
+
|
12
|
+
if @order.save
|
13
|
+
if init_transaction
|
14
|
+
render :gateway
|
15
|
+
else
|
16
|
+
@order.update(status: :failed)
|
17
|
+
render :failed
|
18
|
+
end
|
19
|
+
else
|
20
|
+
render action: :new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def return
|
25
|
+
if transaction_result && @order.update(update_params) && @result.approved?
|
26
|
+
@method = :get
|
27
|
+
@url = @result.url_redirection
|
28
|
+
@token = params[:token_ws]
|
29
|
+
@order.update(status: :approved)
|
30
|
+
render :gateway
|
31
|
+
else
|
32
|
+
@order.update(status: :failed)
|
33
|
+
render :failed
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def final
|
38
|
+
if @order.approved?
|
39
|
+
render :success
|
40
|
+
else
|
41
|
+
render :failed
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def find_order
|
48
|
+
@order = Order.find(params[:id])
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_params
|
52
|
+
params.require(:order).permit(:amount)
|
53
|
+
end
|
54
|
+
|
55
|
+
def update_params
|
56
|
+
{
|
57
|
+
tbk_token_ws: params[:token_ws],
|
58
|
+
tbk_accounting_date: @result.accounting_date,
|
59
|
+
tbk_buy_order: @result.buy_order,
|
60
|
+
tbk_card_number: @result.card_number,
|
61
|
+
tbk_commerce_code: @result.commerce_code,
|
62
|
+
tbk_authorization_code: @result.authorization_code,
|
63
|
+
tbk_payment_type_code: @result.payment_type_code,
|
64
|
+
tbk_response_code: @result.response_code,
|
65
|
+
tbk_transaction_date: @result.transaction_date,
|
66
|
+
tbk_vci: @result.vci,
|
67
|
+
tbk_session_id: @result.session_id,
|
68
|
+
tbk_card_expiration_date: @result.card_expiration_date,
|
69
|
+
tbk_shares_number: @result.shares_number,
|
70
|
+
amount: @result.amount
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def verify_order
|
75
|
+
render :failed if @order.approved?
|
76
|
+
end
|
77
|
+
|
78
|
+
def init_transaction
|
79
|
+
transaction = Order.init_transaction(init_transaction_params)
|
80
|
+
if transaction.success?
|
81
|
+
@method = :post
|
82
|
+
@url = transaction.url
|
83
|
+
@token = transaction.token
|
84
|
+
end
|
85
|
+
|
86
|
+
transaction.success?
|
87
|
+
rescue WebpayRails::SoapError
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
def transaction_result
|
92
|
+
@result = Order.transaction_result(token: params[:token_ws])
|
93
|
+
true
|
94
|
+
rescue WebpayRails::SoapError
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
def init_transaction_params
|
99
|
+
{
|
100
|
+
amount: @order.amount,
|
101
|
+
buy_order: @order.buy_order_for_transbank,
|
102
|
+
session_id: session.id,
|
103
|
+
return_url: url_for(action: :return, id: @order.id),
|
104
|
+
final_url: url_for(action: :final, id: @order.id)
|
105
|
+
}
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module UniversallyUniqueIdentifiable
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
before_create :set_uuid
|
6
|
+
end
|
7
|
+
|
8
|
+
def set_uuid
|
9
|
+
assign_attributes(uuid: SecureRandom.uuid)
|
10
|
+
end
|
11
|
+
|
12
|
+
def buy_order_for_transbank
|
13
|
+
uuid.first(30).delete!('-')
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Order < ActiveRecord::Base
|
2
|
+
include UniversallyUniqueIdentifiable
|
3
|
+
extend WebpayRails
|
4
|
+
|
5
|
+
webpay_rails(
|
6
|
+
commerce_code: 597020000541,
|
7
|
+
private_key: Rails.root.join('vendor/vault/597020000541.key').to_s,
|
8
|
+
public_cert: Rails.root.join('vendor/vault/597020000541.crt').to_s,
|
9
|
+
webpay_cert: Rails.root.join('vendor/vault/tbk.pem').to_s
|
10
|
+
)
|
11
|
+
|
12
|
+
enum status: [:created, :approved, :failed, :canceled, :expired, :pending,
|
13
|
+
:refunded]
|
14
|
+
|
15
|
+
scope :approved, -> { where(status: Order.statuses[:approved]) }
|
16
|
+
scope :normal_selling, -> { where(tbk_payment_type_code: 'VN') }
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class OrderInvalid < ActiveRecord::Base
|
2
|
+
include UniversallyUniqueIdentifiable
|
3
|
+
extend WebpayRails
|
4
|
+
|
5
|
+
webpay_rails(
|
6
|
+
commerce_code: 597020000541,
|
7
|
+
private_key: Rails.root.join('vendor/vault/597020000541.key').to_s,
|
8
|
+
public_cert: Rails.root.join('vendor/vault/597020000541.crt').to_s,
|
9
|
+
webpay_cert: Rails.root.join('vendor/vault/597020000541.crt').to_s
|
10
|
+
)
|
11
|
+
|
12
|
+
enum status: [:created, :approved, :failed, :canceled, :expired, :pending,
|
13
|
+
:refunded]
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Failed transaction</h1>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<h1>Success transaction</h1>
|
2
|
+
|
3
|
+
<p><strong>id</strong>: <%= @order.id %></p>
|
4
|
+
<p><strong>tbk_token_ws</strong>: <%= @order.tbk_token_ws %></p>
|
5
|
+
<p><strong>tbk_accounting_date</strong>: <%= @order.tbk_accounting_date %></p>
|
6
|
+
<p><strong>tbk_buy_order</strong>: <%= @order.tbk_buy_order %></p>
|
7
|
+
<p><strong>tbk_card_number</strong>: <%= @order.tbk_card_number %></p>
|
8
|
+
<p><strong>tbk_commerce_code</strong>: <%= @order.tbk_commerce_code %></p>
|
9
|
+
<p><strong>tbk_authorization_code</strong>: <%= @order.tbk_authorization_code %></p>
|
10
|
+
<p><strong>tbk_payment_type_code</strong>: <%= @order.tbk_payment_type_code %></p>
|
11
|
+
<p><strong>tbk_response_code</strong>: <%= @order.tbk_response_code %></p>
|
12
|
+
<p><strong>tbk_transaction_date</strong>: <%= @order.tbk_transaction_date %></p>
|
13
|
+
<p><strong>tbk_vci</strong>: <%= @order.tbk_vci %></p>
|
14
|
+
<p><strong>tbk_session_id</strong>: <%= @order.tbk_session_id %></p>
|
15
|
+
<p><strong>tbk_card_expiration_date</strong>: <%= @order.tbk_card_expiration_date %></p>
|
16
|
+
<p><strong>tbk_shares_number</strong>: <%= @order.tbk_shares_number %></p>
|
17
|
+
<p><strong>amount</strong>: <%= @order.amount %></p>
|
18
|
+
<p><strong>status</strong>: <%= @order.status %></p>
|