solidus_mp_dois 0.0.4 → 0.0.5
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/app/models/solidus_mp_dois/card.rb +5 -0
- data/app/models/solidus_mp_dois/credit_card_source.rb +7 -0
- data/app/models/solidus_mp_dois/customer.rb +6 -0
- data/app/models/solidus_mp_dois/mp_card.rb +178 -0
- data/app/models/solidus_mp_dois/mp_gateway.rb +35 -0
- data/app/models/solidus_mp_dois/mp_pix.rb +143 -0
- data/app/models/solidus_mp_dois/pix_source.rb +20 -0
- data/app/views/spree/admin/payments/source_forms/_mercado_pago_card.html.erb +0 -0
- data/app/views/spree/admin/payments/source_forms/_mercado_pago_pix.html.erb +0 -0
- data/app/views/spree/admin/payments/source_views/_mercado_pago_card.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_mercado_pago_pix.html.erb +1 -0
- data/app/views/spree/api/payments/source_views/_mercado_pago_card.json.jbuilder +2 -0
- data/app/views/spree/api/payments/source_views/_mercado_pago_pix.json.jbuilder +1 -0
- data/lib/generators/solidus_mp_dois/install/install_generator.rb +38 -0
- data/lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/card_payment_brick_controller.js +86 -0
- data/lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/mp_three_ds_controller.js +40 -0
- data/lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/payment_brick_controller.js +97 -0
- data/lib/solidus_mp_dois/engine.rb +12 -0
- data/lib/solidus_mp_dois.rb +6 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6e4bf85326a054d6a1fd19f60af5aa5eed6140d077ba81f71b159b4e2438aea
|
4
|
+
data.tar.gz: 035767ed834305f06e8a5857a07c73cc323ba25231eca5d4dd7de273f6713108
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bfdf0ff84eefbd24ff8df01fd5aa8ac7cdd7cdc99c3ab6a5136a80d93e946dc8465eeb6f5fa7ff97614a6aefc5329d12ae6ae6863e1c04c2da1c44be8675fc0
|
7
|
+
data.tar.gz: d517b16dd8a9934e2b7a0df97b6dd55e23384353bf7db6d7e9be2b42ac5b3b92f0b9e0f0f38c9cac6542d1079ee8b3121897228fffec3f2d176e6898c28f1f46
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
class MpCard < Spree::PaymentMethod
|
3
|
+
preference :public_key, :string
|
4
|
+
preference :access_token, :string
|
5
|
+
preference :statement_descriptor, :string
|
6
|
+
|
7
|
+
def payment_source_class
|
8
|
+
CreditCardSource
|
9
|
+
end
|
10
|
+
|
11
|
+
def gateway_class
|
12
|
+
MpGateway
|
13
|
+
end
|
14
|
+
|
15
|
+
def supports?(source)
|
16
|
+
source.is_a?(payment_source_class)
|
17
|
+
end
|
18
|
+
|
19
|
+
def auto_capture?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def partial_name
|
24
|
+
"mercado_pago_card"
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_payment external_id
|
28
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
29
|
+
MpApi::Payment.find_by_id(external_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_payment order, source_params
|
33
|
+
customer = find_or_create_customer(order, source_params)
|
34
|
+
save_credit_card(source_params[:token], customer) if customer
|
35
|
+
|
36
|
+
payment = order.payments.new(amount: order.total, payment_method: self)
|
37
|
+
payment.source = init_source(order, source_params, customer)
|
38
|
+
payment.save
|
39
|
+
|
40
|
+
mp_payment = create_mp_payment(payment.source, customer.try(:external_id))
|
41
|
+
process_payment_response(payment, mp_payment)
|
42
|
+
payment
|
43
|
+
end
|
44
|
+
|
45
|
+
def purchase money, source, options = {}
|
46
|
+
gateway.purchase(money, source, options)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def init_source order, source_params, customer
|
52
|
+
tax_id = customer&.tax_id || source_params[:tax_id]
|
53
|
+
document_type = (tax_id.gsub(/\D/, "").length == 11) ? "CPF" : "CNPJ"
|
54
|
+
customer_email = source_params[:payer_email].present? ? source_params[:payer_email] : customer.email
|
55
|
+
|
56
|
+
CreditCardSource.new(
|
57
|
+
amount: order.total,
|
58
|
+
payer_identification_type: document_type,
|
59
|
+
tax_id: tax_id,
|
60
|
+
email: customer_email,
|
61
|
+
issuer_id: source_params[:issuer_id],
|
62
|
+
installments: source_params[:installments],
|
63
|
+
token: source_params[:token],
|
64
|
+
card_brand: source_params[:credit_card_brand],
|
65
|
+
payment_method: self,
|
66
|
+
saved_card: source_params[:saved_card]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_mp_payment payment_source, customer_id
|
71
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
72
|
+
MpApi::Payment.new(
|
73
|
+
amount: payment_source.amount.to_f,
|
74
|
+
payment_method: payment_source.card_brand,
|
75
|
+
payer_email: payment_source.email,
|
76
|
+
payer_identification_type: payment_source.payer_identification_type,
|
77
|
+
payer_identification_number: payment_source.tax_id,
|
78
|
+
token: payment_source.token,
|
79
|
+
issuer_id: payment_source.issuer_id,
|
80
|
+
installments: payment_source.installments,
|
81
|
+
three_d_secure_mode: true,
|
82
|
+
statement_descriptor: preferences[:statement_descriptor],
|
83
|
+
saved_card: payment_source.saved_card,
|
84
|
+
customer_id: customer_id
|
85
|
+
).create
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_or_create_customer(order, source_params)
|
89
|
+
return unless order.user
|
90
|
+
customer = SolidusMpDois::Customer.find_by(spree_user_id: order.user.id)
|
91
|
+
if customer.blank?
|
92
|
+
mp_customer = create_mp_customer(order, source_params)
|
93
|
+
if mp_customer.error.blank?
|
94
|
+
customer = SolidusMpDois::Customer.create(
|
95
|
+
external_id: mp_customer.external_id,
|
96
|
+
email: mp_customer.email,
|
97
|
+
first_name: mp_customer.first_name,
|
98
|
+
identification_type: mp_customer.identification_type,
|
99
|
+
tax_id: mp_customer.identification_number,
|
100
|
+
spree_user_id: order.user.id
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
customer
|
105
|
+
end
|
106
|
+
|
107
|
+
def create_mp_customer(order, source_params)
|
108
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
109
|
+
MpApi::Customer.new(
|
110
|
+
email: order.email,
|
111
|
+
first_name: order.ship_address.name,
|
112
|
+
identification_type: source_params[:payer_identification_type],
|
113
|
+
identification_number: source_params[:tax_id]
|
114
|
+
).create
|
115
|
+
end
|
116
|
+
|
117
|
+
def save_credit_card(card_token, customer)
|
118
|
+
return if customer.nil?
|
119
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
120
|
+
mp_credit_card = MpApi::Card.new(token: card_token, customer_id: customer.external_id).create
|
121
|
+
SolidusMpDois::Card.upsert(
|
122
|
+
{
|
123
|
+
external_id: mp_credit_card.external_id,
|
124
|
+
last_four_digits: mp_credit_card.last_four_digits,
|
125
|
+
mp_payment_method_id: mp_credit_card.mp_payment_method_id,
|
126
|
+
customer_id: customer.id
|
127
|
+
}, unique_by: :external_id
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
def process_payment_response(payment, mp_payment)
|
132
|
+
payment.source.update(
|
133
|
+
external_id: mp_payment.id,
|
134
|
+
three_ds_url: mp_payment.three_ds_info_external_resource_url,
|
135
|
+
three_ds_creq: mp_payment.three_ds_info_creq,
|
136
|
+
last_four_digits: mp_payment.last_four_digits
|
137
|
+
)
|
138
|
+
if mp_payment.error || mp_payment.internal_error
|
139
|
+
handle_payment_error(payment, mp_payment)
|
140
|
+
else
|
141
|
+
payment.order.update(email: payment.source.email)
|
142
|
+
update_payment_status(payment, mp_payment)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def update_payment_status(payment, mp_payment)
|
147
|
+
status = case mp_payment.status
|
148
|
+
when "approved" then "success"
|
149
|
+
when "pending" then "pending"
|
150
|
+
end
|
151
|
+
payment.source.update!(status: status)
|
152
|
+
end
|
153
|
+
|
154
|
+
def handle_payment_error(payment, mp_payment)
|
155
|
+
payment.invalidate
|
156
|
+
error_message = mp_payment.error || "Erro ao criar o pagamento"
|
157
|
+
response = failure_response(error_message)
|
158
|
+
payment.log_entries.create(parsed_payment_response_details_with_fallback: response)
|
159
|
+
payment.source.update(internal_error: error_message, status: "error")
|
160
|
+
end
|
161
|
+
|
162
|
+
def successful_response message, transaction_id
|
163
|
+
ActiveMerchant::Billing::Response.new(
|
164
|
+
true,
|
165
|
+
message,
|
166
|
+
{},
|
167
|
+
authorization: transaction_id
|
168
|
+
)
|
169
|
+
end
|
170
|
+
|
171
|
+
def failure_response message
|
172
|
+
ActiveMerchant::Billing::Response.new(
|
173
|
+
false,
|
174
|
+
message
|
175
|
+
)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
class MpGateway
|
3
|
+
def initialize(options)
|
4
|
+
MpApi.configuration.access_token = options[:access_token]
|
5
|
+
end
|
6
|
+
|
7
|
+
def purchase money, source, options = {}
|
8
|
+
mp_payment = source.retrieve_from_api
|
9
|
+
10.times do
|
10
|
+
break if ["approved", "rejected"].include? mp_payment.status
|
11
|
+
mp_payment = source.retrieve_from_api
|
12
|
+
end
|
13
|
+
if mp_payment.status == "approved"
|
14
|
+
source.update(status: "approved")
|
15
|
+
successful_response("Pagamento realizado", mp_payment.id)
|
16
|
+
else
|
17
|
+
failure_response(mp_payment.status_detail || mp_payment.status)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def void(transaction_id, options = {})
|
22
|
+
# Respondendo sempre com successful_response para funcionar o botão de "Cancelar" do pedido. Reembolso deve ser feito por fora.
|
23
|
+
successful_response("Pagamento cancelado. Se necessário, realize o reembolso.", transaction_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def successful_response message, transaction_id
|
27
|
+
ActiveMerchant::Billing::Response.new(
|
28
|
+
true,
|
29
|
+
message,
|
30
|
+
{},
|
31
|
+
authorization: transaction_id
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
class MpPix < Spree::PaymentMethod
|
3
|
+
preference :public_key, :string
|
4
|
+
preference :access_token, :string
|
5
|
+
preference :statement_descriptor, :string
|
6
|
+
|
7
|
+
def payment_source_class
|
8
|
+
PixSource
|
9
|
+
end
|
10
|
+
|
11
|
+
def gateway_class
|
12
|
+
MpGateway
|
13
|
+
end
|
14
|
+
|
15
|
+
def supports?(source)
|
16
|
+
source.is_a?(payment_source_class)
|
17
|
+
end
|
18
|
+
|
19
|
+
def auto_capture?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def partial_name
|
24
|
+
"mercado_pago_pix"
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_payment external_id
|
28
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
29
|
+
MpApi::Payment.find_by_id(external_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_payment order
|
33
|
+
payment = find_existing_payment(order)
|
34
|
+
return payment if payment_usable?(order, payment)
|
35
|
+
|
36
|
+
payment = order.payments.new(amount: order.total, payment_method: self)
|
37
|
+
payment.source = init_source(order)
|
38
|
+
payment.save
|
39
|
+
|
40
|
+
mp_payment = create_mp_payment(payment.source)
|
41
|
+
process_payment_response(payment, mp_payment)
|
42
|
+
payment
|
43
|
+
end
|
44
|
+
|
45
|
+
def invalidate_payment payment_source
|
46
|
+
return false unless payment_source&.external_id
|
47
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
48
|
+
mp_payment = find_payment(payment_source.external_id)
|
49
|
+
return false if mp_payment.pix_paid?
|
50
|
+
mp_payment.invalidate_pix!
|
51
|
+
payment_source.payments[0].log_entries.create!(parsed_payment_response_details_with_fallback: failure_response("Pagamento cancelado"))
|
52
|
+
payment_source.update(status: "cancelled")
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def purchase(money, source, options = {})
|
57
|
+
gateway.purchase(money, source, options)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def init_source(order)
|
63
|
+
PixSource.new(
|
64
|
+
amount: order.total,
|
65
|
+
expiration: DateTime.now + 10.minutes,
|
66
|
+
email: order.email,
|
67
|
+
tax_id: order.tax_id,
|
68
|
+
payment_method: self
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_mp_payment payment_source
|
73
|
+
MpApi.configuration.access_token = preferences[:access_token]
|
74
|
+
identification_type = (payment_source.tax_id.length > 14) ? "CNPJ" : "CPF"
|
75
|
+
MpApi::Payment.new(
|
76
|
+
payer_email: payment_source.email,
|
77
|
+
payer_identification_type: identification_type,
|
78
|
+
payer_identification_number: payment_source.tax_id,
|
79
|
+
payment_method: "pix",
|
80
|
+
amount: payment_source.amount.to_f,
|
81
|
+
statement_descriptor: preferences[:statement_descriptor],
|
82
|
+
description: payment_source.description
|
83
|
+
).create
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_existing_payment(order)
|
87
|
+
pix_payments = order.payments.checkout.where(source_type: "SolidusMpDois::PixSource")
|
88
|
+
raise "More than one valid payment for #{order.number}" if pix_payments.count > 1
|
89
|
+
pix_payments.first
|
90
|
+
end
|
91
|
+
|
92
|
+
def payment_usable?(order, payment)
|
93
|
+
return false if payment.blank?
|
94
|
+
payment.amount == order.total && payment.source.expiration.future?
|
95
|
+
end
|
96
|
+
|
97
|
+
def process_payment_response(payment, mp_payment)
|
98
|
+
payment.update(response_code: mp_payment.id)
|
99
|
+
payment.source.update(
|
100
|
+
external_id: mp_payment.id,
|
101
|
+
qr_code: mp_payment.qr_code,
|
102
|
+
qr_code_base64: mp_payment.qr_code_base_64,
|
103
|
+
ticket_url: mp_payment.ticket_url
|
104
|
+
)
|
105
|
+
if mp_payment.error || mp_payment.internal_error
|
106
|
+
handle_payment_error(payment, mp_payment)
|
107
|
+
else
|
108
|
+
update_payment_status(payment, mp_payment)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def update_payment_status(payment, mp_payment)
|
113
|
+
status = case mp_payment.status
|
114
|
+
when "pending" then "pending"
|
115
|
+
end
|
116
|
+
payment.source.update!(status: status)
|
117
|
+
end
|
118
|
+
|
119
|
+
def handle_payment_error(payment, mp_payment)
|
120
|
+
payment.invalidate
|
121
|
+
error_message = mp_payment.error || "Erro ao criar o pagamento"
|
122
|
+
response = failure_response(error_message)
|
123
|
+
payment.log_entries.create(parsed_payment_response_details_with_fallback: response)
|
124
|
+
payment.source.update(internal_error: error_message, status: "error")
|
125
|
+
end
|
126
|
+
|
127
|
+
def successful_response message, transaction_id
|
128
|
+
ActiveMerchant::Billing::Response.new(
|
129
|
+
true,
|
130
|
+
message,
|
131
|
+
{},
|
132
|
+
authorization: transaction_id
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
def failure_response message
|
137
|
+
ActiveMerchant::Billing::Response.new(
|
138
|
+
false,
|
139
|
+
message
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
class PixSource < Spree::PaymentSource
|
3
|
+
def retrieve_from_api
|
4
|
+
payment_method.find_payment(external_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def expired?
|
8
|
+
expiration.past?
|
9
|
+
end
|
10
|
+
|
11
|
+
def paid?
|
12
|
+
mp_payment = retrieve_from_api
|
13
|
+
mp_payment.pix_paid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def invalidate
|
17
|
+
payment_method.invalidate_payment(self)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
ID do pagamento: <%= payment.source.external_id %>
|
@@ -0,0 +1 @@
|
|
1
|
+
ID do pagamento: <%= payment.source.external_id %>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.call(payment_source, :id, :external_id, :status, :amount, :expiration, :email, :tax_id, :payment_method_id, :qr_code)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
class_option :auto_run_migrations, type: :boolean, default: false
|
5
|
+
source_root File.expand_path("templates", __dir__)
|
6
|
+
|
7
|
+
def self.exit_on_failure?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
def pin_mp_js
|
12
|
+
run "bin/importmap pin @mercadopago/sdk-js"
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_migrations
|
16
|
+
run "bin/rails railties:install:migrations FROM=solidus_mp_dois"
|
17
|
+
end
|
18
|
+
|
19
|
+
def install_mp_api
|
20
|
+
puts "Installing mp_api gem..."
|
21
|
+
run "bin/rails g mp_api:install"
|
22
|
+
end
|
23
|
+
|
24
|
+
def copy_app_files
|
25
|
+
directory "app", "app"
|
26
|
+
end
|
27
|
+
|
28
|
+
def run_migrations
|
29
|
+
run_migrations = options[:auto_run_migrations] || ["", "y", "Y"].include?(ask("Would you like to run the migrations now? [Y/n]")) # rubocop:disable Layout/LineLength
|
30
|
+
if run_migrations
|
31
|
+
run "bin/rails db:migrate"
|
32
|
+
else
|
33
|
+
puts "Skipping bin/rails db:migrate, don\"t forget to run it!" # rubocop:disable Rails/Output
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
import { loadMercadoPago } from "@mercadopago/sdk-js"
|
3
|
+
|
4
|
+
// Renderiza o Card Payment Brick (apenas cartão)
|
5
|
+
export default class extends Controller {
|
6
|
+
static values = { publicKey: String, amount: Number, email: String }
|
7
|
+
static targets = [
|
8
|
+
"token",
|
9
|
+
"paymentMethodId",
|
10
|
+
"installments",
|
11
|
+
"issuerId",
|
12
|
+
"transactionAmount",
|
13
|
+
"payerIdentificationType",
|
14
|
+
"payerIdentificationNumber",
|
15
|
+
"payerEmail"
|
16
|
+
]
|
17
|
+
async connect() {
|
18
|
+
await loadMercadoPago()
|
19
|
+
const mp = new MercadoPago(this.publicKeyValue, {
|
20
|
+
locale: 'pt-BR'
|
21
|
+
});
|
22
|
+
const bricksBuilder = mp.bricks();
|
23
|
+
const renderCardPaymentBrick = async (bricksBuilder) => {
|
24
|
+
const settings = {
|
25
|
+
initialization: {
|
26
|
+
amount: this.amountValue,
|
27
|
+
payer: {
|
28
|
+
email: this.emailValue
|
29
|
+
},
|
30
|
+
},
|
31
|
+
customization: {
|
32
|
+
visual: {
|
33
|
+
hidePaymentButton: true,
|
34
|
+
style: {
|
35
|
+
customVariables: {
|
36
|
+
theme: 'default'
|
37
|
+
}
|
38
|
+
}
|
39
|
+
},
|
40
|
+
paymentMethods: {
|
41
|
+
maxInstallments: 1,
|
42
|
+
}
|
43
|
+
},
|
44
|
+
callbacks: {
|
45
|
+
onReady: () => {
|
46
|
+
document.getElementById('submit_payment').removeAttribute('disabled')
|
47
|
+
},
|
48
|
+
onSubmit: (cardFormData) => {
|
49
|
+
},
|
50
|
+
onError: (error) => {
|
51
|
+
},
|
52
|
+
},
|
53
|
+
};
|
54
|
+
window.cardPaymentBrickController = await bricksBuilder.create('cardPayment', 'cardPaymentBrick_container', settings);
|
55
|
+
};
|
56
|
+
renderCardPaymentBrick(bricksBuilder);
|
57
|
+
const element = document.getElementById('checkout_form_payment');
|
58
|
+
element.addEventListener('submit', event => {
|
59
|
+
document.getElementById('submit_payment').setAttribute('disabled', "")
|
60
|
+
event.preventDefault();
|
61
|
+
this.createPayment()
|
62
|
+
});
|
63
|
+
}
|
64
|
+
|
65
|
+
async disconnect() {
|
66
|
+
window.cardPaymentBrickController.unmount()
|
67
|
+
}
|
68
|
+
|
69
|
+
createPayment(){
|
70
|
+
window.cardPaymentBrickController.getFormData()
|
71
|
+
.then((cardFormData) => {
|
72
|
+
this.tokenTarget.value = cardFormData.token
|
73
|
+
this.paymentMethodIdTarget.value = cardFormData.payment_method_id
|
74
|
+
this.installmentsTarget.value = cardFormData.installments
|
75
|
+
this.issuerIdTarget.value = cardFormData.issuer_id
|
76
|
+
this.transactionAmountTarget.value = cardFormData.transaction_amount
|
77
|
+
this.payerIdentificationTypeTarget.value = cardFormData.payer.identification.type
|
78
|
+
this.payerIdentificationNumberTarget.value = cardFormData.payer.identification.number
|
79
|
+
this.payerEmailTarget.value = cardFormData.payer.email
|
80
|
+
this.tokenTarget.form.submit()
|
81
|
+
})
|
82
|
+
.catch((error) => {
|
83
|
+
document.getElementById('submit_payment').removeAttribute('disabled')
|
84
|
+
});
|
85
|
+
}
|
86
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
// Connects to data-controller="credit-card"
|
4
|
+
export default class extends Controller {
|
5
|
+
|
6
|
+
static values = { threeDsUrl: String, threeDsCreq: String }
|
7
|
+
|
8
|
+
// Anytime the controller is connected to the DOM
|
9
|
+
async connect() {
|
10
|
+
if (!this.threeDsUrlValue) return
|
11
|
+
var iframe = document.createElement('iframe')
|
12
|
+
iframe.height = "460px"
|
13
|
+
iframe.width = "500px"
|
14
|
+
iframe.name = "myframe"
|
15
|
+
iframe.id = "myframe"
|
16
|
+
this.element.appendChild(iframe)
|
17
|
+
var idocument = iframe.contentWindow.document
|
18
|
+
var myform = idocument.createElement("form")
|
19
|
+
myform.name = "myform"
|
20
|
+
myform.setAttribute("target", "myframe")
|
21
|
+
myform.setAttribute("method", "post")
|
22
|
+
myform.setAttribute("action", this.threeDsUrlValue)
|
23
|
+
var hiddenField = idocument.createElement("input")
|
24
|
+
hiddenField.setAttribute("type", "hidden")
|
25
|
+
hiddenField.setAttribute("name", "creq")
|
26
|
+
hiddenField.setAttribute("value", this.threeDsCreqValue)
|
27
|
+
myform.appendChild(hiddenField)
|
28
|
+
iframe.appendChild(myform)
|
29
|
+
var submit_form = document.getElementById("checkout_confirm_button")
|
30
|
+
submit_form.setAttribute("class", "hidden")
|
31
|
+
myform.submit()
|
32
|
+
window.addEventListener("message", (e) => {
|
33
|
+
if (e.data.status === "COMPLETE") {
|
34
|
+
document.getElementById("checkout_form_confirm").submit();
|
35
|
+
}
|
36
|
+
})
|
37
|
+
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
import { loadMercadoPago } from "@mercadopago/sdk-js"
|
3
|
+
|
4
|
+
// Renderiza o Payment Brick (tem opção de ser vários métodos de pagamento)
|
5
|
+
export default class extends Controller {
|
6
|
+
static values = { publicKey: String, amount: Number, email: String, customerId: String, cardsIds: Array }
|
7
|
+
static targets = [
|
8
|
+
"token",
|
9
|
+
"paymentMethodId",
|
10
|
+
"installments",
|
11
|
+
"issuerId",
|
12
|
+
"transactionAmount",
|
13
|
+
"payerIdentificationType",
|
14
|
+
"payerIdentificationNumber",
|
15
|
+
"payerType",
|
16
|
+
"payerId",
|
17
|
+
"savedCard",
|
18
|
+
"payerEmail"
|
19
|
+
]
|
20
|
+
async connect() {
|
21
|
+
await loadMercadoPago()
|
22
|
+
const mp = new MercadoPago(this.publicKeyValue, {
|
23
|
+
locale: 'pt-BR'
|
24
|
+
});
|
25
|
+
const bricksBuilder = mp.bricks();
|
26
|
+
const renderPaymentBrick = async (bricksBuilder) => {
|
27
|
+
const settings = {
|
28
|
+
initialization: {
|
29
|
+
amount: this.amountValue,
|
30
|
+
payer: {
|
31
|
+
email: this.emailValue,
|
32
|
+
customerId: this.customerIdValue,
|
33
|
+
cardsIds: this.cardsIdsValue
|
34
|
+
}
|
35
|
+
},
|
36
|
+
customization: {
|
37
|
+
visual: {
|
38
|
+
hidePaymentButton: true,
|
39
|
+
},
|
40
|
+
paymentMethods: {
|
41
|
+
creditCard: "all",
|
42
|
+
maxInstallments: 1
|
43
|
+
},
|
44
|
+
},
|
45
|
+
callbacks: {
|
46
|
+
onReady: () => {
|
47
|
+
document.getElementById('submit_payment').removeAttribute('disabled')
|
48
|
+
},
|
49
|
+
onSubmit: ({ selectedPaymentMethod, formData }) => {
|
50
|
+
},
|
51
|
+
onError: (error) => {
|
52
|
+
},
|
53
|
+
},
|
54
|
+
};
|
55
|
+
window.paymentBrickController = await bricksBuilder.create(
|
56
|
+
"payment",
|
57
|
+
"paymentBrick_container",
|
58
|
+
settings
|
59
|
+
);
|
60
|
+
};
|
61
|
+
renderPaymentBrick(bricksBuilder);
|
62
|
+
|
63
|
+
const element = document.getElementById('checkout_form_payment');
|
64
|
+
element.addEventListener('submit', event => {
|
65
|
+
document.getElementById('submit_payment').setAttribute('disabled', "")
|
66
|
+
event.preventDefault();
|
67
|
+
this.createPayment()
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
async disconnect() {
|
72
|
+
window.paymentBrickController.unmount()
|
73
|
+
}
|
74
|
+
|
75
|
+
createPayment() {
|
76
|
+
window.paymentBrickController.getFormData()
|
77
|
+
.then(({ selectedPaymentMethod, formData }) => {
|
78
|
+
if (selectedPaymentMethod == "credit_card") {
|
79
|
+
this.tokenTarget.value = formData.token
|
80
|
+
this.paymentMethodIdTarget.value = formData.payment_method_id
|
81
|
+
this.installmentsTarget.value = formData.installments
|
82
|
+
this.issuerIdTarget.value = formData.issuer_id
|
83
|
+
this.transactionAmountTarget.value = formData.transaction_amount
|
84
|
+
this.payerIdentificationTypeTarget.value = formData.payer?.identification?.type || "" // Para cartão novo
|
85
|
+
this.payerIdentificationNumberTarget.value = formData.payer?.identification?.number || "" // Para cartão novo
|
86
|
+
this.payerTypeTarget.value = formData.payer?.type || "" // Para cartão salvo
|
87
|
+
this.payerIdTarget.value = formData.payer?.id || "" // Para cartão salvo
|
88
|
+
this.savedCardTarget.value = this.payerTypeTarget.value == "customer"
|
89
|
+
this.payerEmailTarget.value = formData.payer?.email || "" // Para cartão salvo
|
90
|
+
this.tokenTarget.form.submit()
|
91
|
+
}
|
92
|
+
})
|
93
|
+
.catch((error) => {
|
94
|
+
document.getElementById('submit_payment').removeAttribute('disabled')
|
95
|
+
});
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module SolidusMpDois
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
isolate_namespace SolidusMpDois
|
4
|
+
|
5
|
+
initializer "solidus_mp_dois.add_payment_method", after: "spree.register.payment_methods" do |app|
|
6
|
+
app.config.spree.payment_methods << "SolidusMpDois::MpCard"
|
7
|
+
app.config.spree.payment_methods << "SolidusMpDois::MpPix"
|
8
|
+
end
|
9
|
+
|
10
|
+
engine_name "solidus_mp_dois"
|
11
|
+
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solidus_mp_dois
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Todas Essas Coisas
|
@@ -44,7 +44,26 @@ email:
|
|
44
44
|
executables: []
|
45
45
|
extensions: []
|
46
46
|
extra_rdoc_files: []
|
47
|
-
files:
|
47
|
+
files:
|
48
|
+
- app/models/solidus_mp_dois/card.rb
|
49
|
+
- app/models/solidus_mp_dois/credit_card_source.rb
|
50
|
+
- app/models/solidus_mp_dois/customer.rb
|
51
|
+
- app/models/solidus_mp_dois/mp_card.rb
|
52
|
+
- app/models/solidus_mp_dois/mp_gateway.rb
|
53
|
+
- app/models/solidus_mp_dois/mp_pix.rb
|
54
|
+
- app/models/solidus_mp_dois/pix_source.rb
|
55
|
+
- app/views/spree/admin/payments/source_forms/_mercado_pago_card.html.erb
|
56
|
+
- app/views/spree/admin/payments/source_forms/_mercado_pago_pix.html.erb
|
57
|
+
- app/views/spree/admin/payments/source_views/_mercado_pago_card.html.erb
|
58
|
+
- app/views/spree/admin/payments/source_views/_mercado_pago_pix.html.erb
|
59
|
+
- app/views/spree/api/payments/source_views/_mercado_pago_card.json.jbuilder
|
60
|
+
- app/views/spree/api/payments/source_views/_mercado_pago_pix.json.jbuilder
|
61
|
+
- lib/generators/solidus_mp_dois/install/install_generator.rb
|
62
|
+
- lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/card_payment_brick_controller.js
|
63
|
+
- lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/mp_three_ds_controller.js
|
64
|
+
- lib/generators/solidus_mp_dois/install/templates/app/javascript/controllers/payment_brick_controller.js
|
65
|
+
- lib/solidus_mp_dois.rb
|
66
|
+
- lib/solidus_mp_dois/engine.rb
|
48
67
|
homepage: https://github.com/todasessascoisas/solidus_mp_dois
|
49
68
|
licenses: []
|
50
69
|
metadata: {}
|