webpay_rails 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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>
|