139 lines
4.2 KiB
JavaScript
139 lines
4.2 KiB
JavaScript
'use strict'
|
|
|
|
// Fetch nativo do Node.js (Node 18+)
|
|
|
|
class AsaasService {
|
|
static getApiUrl() {
|
|
return process.env.ASAAS_ENV === 'production'
|
|
? 'https://api.asaas.com/v3'
|
|
: 'https://sandbox.asaas.com/api/v3'
|
|
}
|
|
|
|
static getApiKey() {
|
|
return process.env.ASAAS_API_KEY;
|
|
}
|
|
|
|
/**
|
|
* Busca ou cria um cliente no Asaas
|
|
*/
|
|
static async getOrCreateCustomer(nome, cpf, telefone, email) {
|
|
const key = this.getApiKey();
|
|
if (!key) throw new Error('API Key do Asaas não configurada');
|
|
|
|
if (key === 'sandbox_local') {
|
|
return 'cus_mock_' + Math.floor(Math.random() * 1000000);
|
|
}
|
|
|
|
const cleanCpf = cpf.replace(/\D/g, '')
|
|
|
|
// Tentar encontrar cliente existente pelo CPF
|
|
const searchRes = await fetch(`${this.getApiUrl()}/customers?cpfCnpj=${cleanCpf}`, {
|
|
headers: { 'access_token': key }
|
|
})
|
|
if (!searchRes.ok) {
|
|
console.warn('[AsaasService] busca de cliente retornou', searchRes.status)
|
|
} else {
|
|
const searchData = await searchRes.json()
|
|
if (searchData?.data?.length > 0) return searchData.data[0].id
|
|
}
|
|
|
|
// Criar novo cliente
|
|
const createRes = await fetch(`${this.getApiUrl()}/customers`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'access_token': key,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
name: nome,
|
|
cpfCnpj: cleanCpf,
|
|
email: email || `${cleanCpf}@alemaoconveniencias.com.br`,
|
|
mobilePhone: telefone || null
|
|
})
|
|
})
|
|
|
|
const createData = await createRes.json()
|
|
if (!createRes.ok) {
|
|
console.error('Erro Asaas (Criar Cliente):', createData)
|
|
throw new Error(createData.errors ? createData.errors[0].description : 'Erro ao criar cliente no Asaas')
|
|
}
|
|
|
|
return createData.id
|
|
}
|
|
|
|
/**
|
|
* Cria uma cobrança via PIX
|
|
*/
|
|
static async createPixCharge(customerId, amount, description) {
|
|
const key = this.getApiKey();
|
|
if (!key) throw new Error('API Key do Asaas não configurada');
|
|
|
|
if (key === 'sandbox_local') {
|
|
return {
|
|
orderId: 'pay_mock_' + Math.floor(Math.random() * 1000000),
|
|
qrCodeUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', // transparent pixel fallback
|
|
pixCopyPaste: '00020101021126360014br.gov.bcb.pix0114sandbox_local_mock_12345652040000530398654041.005802BR5906Mocked6006Mocked62070503***6304ABCD'
|
|
}
|
|
}
|
|
|
|
// Data de vencimento hoje
|
|
const dueDate = new Date()
|
|
dueDate.setHours(23, 59, 59, 999)
|
|
|
|
const chargeRes = await fetch(`${this.getApiUrl()}/payments`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'access_token': key,
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
customer: customerId,
|
|
billingType: 'PIX',
|
|
value: amount,
|
|
dueDate: dueDate.toISOString().split('T')[0],
|
|
description: description
|
|
})
|
|
})
|
|
|
|
const chargeData = await chargeRes.json()
|
|
if (!chargeRes.ok) {
|
|
console.error('Erro Asaas (Criar Cobrança):', chargeData)
|
|
throw new Error(chargeData.errors ? chargeData.errors[0].description : 'Erro ao criar cobrança no Asaas')
|
|
}
|
|
|
|
// Gerar QR Code para a cobrança criada
|
|
const qrCodeRes = await fetch(`${this.getApiUrl()}/payments/${chargeData.id}/pixQrCode`, {
|
|
headers: { 'access_token': key }
|
|
})
|
|
|
|
let qrCodeData = null
|
|
if (qrCodeRes.ok) {
|
|
qrCodeData = await qrCodeRes.json()
|
|
}
|
|
|
|
return {
|
|
orderId: chargeData.id,
|
|
qrCodeUrl: qrCodeData ? qrCodeData.encodedImage : chargeData.invoiceUrl, // encodedImage é base64 ou usar invoiceUrl
|
|
pixCopyPaste: qrCodeData ? qrCodeData.payload : null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Busca os detalhes de uma cobrança existente
|
|
*/
|
|
static async getCharge(paymentId) {
|
|
const key = this.getApiKey();
|
|
if (key === 'sandbox_local') {
|
|
const orderStatus = process.env.MOCK_ORDER_PAID === 'true' ? 'RECEIVED' : 'PENDING';
|
|
return { status: orderStatus, id: paymentId };
|
|
}
|
|
|
|
const chargeRes = await fetch(`${this.getApiUrl()}/payments/${paymentId}`, {
|
|
headers: { 'access_token': key }
|
|
})
|
|
return await chargeRes.json()
|
|
}
|
|
}
|
|
|
|
module.exports = AsaasService
|