338 lines
8.9 KiB
Bash
Executable File
338 lines
8.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# 🏦 Script para Implementar PIX no Liberi Kids
|
|
# Execute: ./implementar-pix.sh
|
|
|
|
echo "🏦 Implementando PIX no Liberi Kids"
|
|
echo "=================================="
|
|
|
|
# Cores para output
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
info() {
|
|
echo -e "${BLUE}[PIX]${NC} $1"
|
|
}
|
|
|
|
# Instalar dependência do Mercado Pago
|
|
log "Instalando SDK do Mercado Pago..."
|
|
npm install mercadopago
|
|
|
|
# Criar arquivo de configuração PIX
|
|
log "Criando configuração PIX..."
|
|
cat > config/mercadopago.js << 'EOF'
|
|
const mercadopago = require('mercadopago');
|
|
|
|
class MercadoPagoService {
|
|
constructor() {
|
|
if (process.env.MERCADOPAGO_ACCESS_TOKEN) {
|
|
mercadopago.configurations.setAccessToken(process.env.MERCADOPAGO_ACCESS_TOKEN);
|
|
}
|
|
}
|
|
|
|
async gerarPix(dados) {
|
|
try {
|
|
const payment_data = {
|
|
transaction_amount: parseFloat(dados.valor),
|
|
description: dados.descricao || `Venda #${dados.venda_id} - Liberi Kids`,
|
|
payment_method_id: 'pix',
|
|
payer: {
|
|
email: dados.cliente_email || 'cliente@liberikids.com',
|
|
first_name: dados.cliente_nome || 'Cliente',
|
|
identification: {
|
|
type: 'CPF',
|
|
number: dados.cliente_cpf || '00000000000'
|
|
}
|
|
},
|
|
external_reference: dados.venda_id.toString(),
|
|
notification_url: `${process.env.BASE_URL || 'http://localhost:5000'}/api/pix/webhook`,
|
|
date_of_expiration: new Date(Date.now() + 30 * 60 * 1000).toISOString() // 30 minutos
|
|
};
|
|
|
|
const payment = await mercadopago.payment.create(payment_data);
|
|
|
|
return {
|
|
success: true,
|
|
payment_id: payment.body.id,
|
|
qr_code: payment.body.point_of_interaction.transaction_data.qr_code,
|
|
qr_code_base64: payment.body.point_of_interaction.transaction_data.qr_code_base64,
|
|
pix_copy_paste: payment.body.point_of_interaction.transaction_data.qr_code,
|
|
expiration_date: payment.body.date_of_expiration,
|
|
transaction_amount: payment.body.transaction_amount,
|
|
status: payment.body.status
|
|
};
|
|
|
|
} catch (error) {
|
|
console.error('Erro ao gerar PIX:', error);
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
|
|
async consultarPagamento(payment_id) {
|
|
try {
|
|
const payment = await mercadopago.payment.get(payment_id);
|
|
return {
|
|
success: true,
|
|
status: payment.body.status,
|
|
status_detail: payment.body.status_detail,
|
|
transaction_amount: payment.body.transaction_amount,
|
|
date_approved: payment.body.date_approved,
|
|
external_reference: payment.body.external_reference
|
|
};
|
|
} catch (error) {
|
|
console.error('Erro ao consultar pagamento:', error);
|
|
return {
|
|
success: false,
|
|
error: error.message
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new MercadoPagoService();
|
|
EOF
|
|
|
|
# Criar CSS para PIX
|
|
log "Criando estilos PIX..."
|
|
cat > client/src/styles/pix-integration.css << 'EOF'
|
|
/* PIX Integration Styles */
|
|
|
|
.pix-modal {
|
|
max-width: 500px;
|
|
width: 90vw;
|
|
}
|
|
|
|
.pix-content {
|
|
text-align: center;
|
|
}
|
|
|
|
.qr-code-section {
|
|
margin-bottom: 20px;
|
|
padding: 20px;
|
|
background: #f8f9fa;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.qr-code-image {
|
|
max-width: 200px;
|
|
height: auto;
|
|
border: 2px solid #ddd;
|
|
border-radius: 8px;
|
|
padding: 10px;
|
|
background: white;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.pix-copy-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.pix-code-container {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
.pix-code-input {
|
|
flex: 1;
|
|
padding: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
font-size: 12px;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.btn-copy-pix {
|
|
background: #00d4aa;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 15px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
font-weight: bold;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-copy-pix:hover {
|
|
background: #00b894;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.pix-info {
|
|
background: #e8f5e8;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
text-align: left;
|
|
border-left: 4px solid #00d4aa;
|
|
}
|
|
|
|
.pix-instructions {
|
|
margin-top: 10px;
|
|
font-size: 14px;
|
|
color: #666;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.btn-pix {
|
|
background: #00d4aa;
|
|
color: white;
|
|
border: none;
|
|
padding: 8px 12px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-pix:hover {
|
|
background: #00b894;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.btn-pix:disabled {
|
|
background: #ccc;
|
|
cursor: not-allowed;
|
|
transform: none;
|
|
}
|
|
|
|
.pix-status {
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.pix-status.pending {
|
|
background: #fff3cd;
|
|
color: #856404;
|
|
border: 1px solid #ffeaa7;
|
|
}
|
|
|
|
.pix-status.approved {
|
|
background: #d4edda;
|
|
color: #155724;
|
|
border: 1px solid #c3e6cb;
|
|
}
|
|
|
|
.pix-status.rejected {
|
|
background: #f8d7da;
|
|
color: #721c24;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
|
|
.pix-timer {
|
|
background: #fff3cd;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
margin: 10px 0;
|
|
text-align: center;
|
|
font-weight: bold;
|
|
color: #856404;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.pix-modal {
|
|
width: 95vw;
|
|
margin: 10px;
|
|
}
|
|
|
|
.qr-code-image {
|
|
max-width: 150px;
|
|
}
|
|
|
|
.pix-code-container {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.btn-copy-pix {
|
|
width: 100%;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Atualizar .env.example
|
|
log "Atualizando .env.example com configurações PIX..."
|
|
cat >> .env.example << 'EOF'
|
|
|
|
# =====================================================
|
|
# CONFIGURAÇÕES PIX - MERCADO PAGO
|
|
# =====================================================
|
|
|
|
# Access Token do Mercado Pago (TEST para desenvolvimento, PROD para produção)
|
|
MERCADOPAGO_ACCESS_TOKEN=TEST-sua_access_token_aqui
|
|
|
|
# Public Key do Mercado Pago
|
|
MERCADOPAGO_PUBLIC_KEY=pk_test_sua_public_key_aqui
|
|
|
|
# URL base para webhooks (importante para produção)
|
|
BASE_URL=http://localhost:5000
|
|
|
|
# =====================================================
|
|
# INSTRUÇÕES PIX
|
|
# =====================================================
|
|
|
|
# 1. Acesse: https://www.mercadopago.com.br/developers
|
|
# 2. Crie uma conta de desenvolvedor
|
|
# 3. Vá em "Suas integrações" > "Criar aplicação"
|
|
# 4. Escolha "Pagamentos online" e "Checkout Pro"
|
|
# 5. Copie as credenciais de TEST para desenvolvimento
|
|
# 6. Para produção, use as credenciais PROD
|
|
# 7. Configure o webhook URL no painel do Mercado Pago
|
|
EOF
|
|
|
|
# Criar script SQL para PIX
|
|
log "Criando migração do banco para PIX..."
|
|
cat > sql/add-pix-fields.sql << 'EOF'
|
|
-- Adicionar campos PIX na tabela vendas
|
|
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS status_pagamento VARCHAR(20) DEFAULT 'pendente';
|
|
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS data_pagamento TIMESTAMP;
|
|
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_payment_id VARCHAR(100);
|
|
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS pix_qr_code TEXT;
|
|
ALTER TABLE vendas ADD COLUMN IF NOT EXISTS metodo_pagamento VARCHAR(20) DEFAULT 'dinheiro';
|
|
|
|
-- Criar índices para performance
|
|
CREATE INDEX IF NOT EXISTS idx_vendas_status_pagamento ON vendas(status_pagamento);
|
|
CREATE INDEX IF NOT EXISTS idx_vendas_pix_payment_id ON vendas(pix_payment_id);
|
|
|
|
-- Comentários para documentação
|
|
COMMENT ON COLUMN vendas.status_pagamento IS 'Status do pagamento: pendente, pago, cancelado, expirado';
|
|
COMMENT ON COLUMN vendas.data_pagamento IS 'Data e hora da confirmação do pagamento';
|
|
COMMENT ON COLUMN vendas.pix_payment_id IS 'ID do pagamento no Mercado Pago';
|
|
COMMENT ON COLUMN vendas.pix_qr_code IS 'Código PIX para copiar e colar';
|
|
COMMENT ON COLUMN vendas.metodo_pagamento IS 'Método: dinheiro, cartao, pix, transferencia';
|
|
EOF
|
|
|
|
echo ""
|
|
info "🎉 Implementação PIX configurada com sucesso!"
|
|
echo ""
|
|
warn "📝 PRÓXIMOS PASSOS:"
|
|
echo "1. Crie conta no Mercado Pago: https://www.mercadopago.com.br/developers"
|
|
echo "2. Configure as credenciais no arquivo .env"
|
|
echo "3. Execute a migração do banco: psql -f sql/add-pix-fields.sql"
|
|
echo "4. Adicione as rotas PIX no server-supabase.js"
|
|
echo "5. Implemente o modal PIX no frontend"
|
|
echo ""
|
|
info "📖 Consulte o arquivo INTEGRACAO-PIX-GUIDE.md para instruções completas"
|
|
echo ""
|
|
log "Arquivos criados:"
|
|
echo " - config/mercadopago.js (Serviço PIX)"
|
|
echo " - client/src/styles/pix-integration.css (Estilos)"
|
|
echo " - sql/add-pix-fields.sql (Migração banco)"
|
|
echo " - .env.example (Configurações atualizadas)"
|