thunderpix
Version:
Biblioteca javascript de padronização de gateways de pagamentos PIX
387 lines (343 loc) • 12 kB
text/typescript
import axios from 'axios';
import ProviderInterface from '../../interfaces/ProviderInterface';
import { randomUUID } from '../../utils/all/index';
interface ProviderConstruct {
apiKey: string;
isTest: boolean | false;
}
export default class PagarMeProvider implements ProviderInterface {
private baseUrl: string;
private apiKey: string;
// private accessToken: string | null;
public providerInfo = {
name: 'Pagar.me',
description: 'A plataforma completa para aceitar pagamentos online.',
documentation: 'https://docs.pagar.me',
isOnline: true,
vendor: {
name: 'Pagar.me',
shotname: 'pagarme',
url: 'https://pagar.me',
api: 'https://api.pagar.me',
versions: [
{
name: 'br.com.pagarme.api-v1',
version: '1.0.0',
path: '/core/v1',
},
{
name: 'br.com.pagarme.api-v2',
version: '1.2.0',
path: '/core/v2',
},
{
name: 'br.com.pagarme.api-v3',
version: '2.3.0',
path: '/core/v3',
},
{
name: 'br.com.pagarme.api-v4',
version: '3.4.0',
path: '/core/v4',
},
{
name: 'br.com.pagarme.api-v5',
version: '4.5.0',
path: '/core/v5',
},
],
},
};
constructor(configs: ProviderConstruct) {
this.apiKey = configs.apiKey;
this.baseUrl = 'https://api.pagar.me/core/v5';
}
// Função auxiliar para configurar os headers com token de autorização
private getHeaders(): any {
return {
'Content-Type': 'application/json',
};
}
// Geração de cobrança via Pagar.me (Cartão de Crédito)
async gerarTransacaoCredito(
valueCents: number,
cardDetails: {
number: string;
expiration_date: string;
holder_name: string;
cvv: string;
},
customer: {
name: string;
email: string;
document: string;
phone: string;
},
) {
const payload = {
api_key: this.apiKey,
amount: valueCents,
payment_method: 'credit_card',
card_number: cardDetails.number,
card_expiration_date: cardDetails.expiration_date,
card_holder_name: cardDetails.holder_name,
card_cvv: cardDetails.cvv,
customer,
};
const response = await axios.post(
`${this.baseUrl}/transactions`,
payload,
{
headers: this.getHeaders(),
},
);
return response.data;
}
// Geração de cobrança via Pagar.me (PIX)
async gerarQrCode(
valueCents: number,
expirationTime?: number,
description?: string,
) {
const payload = {
api_key: this.apiKey,
amount: valueCents,
payment_method: 'pix',
pix_expiration_date: expirationTime
? new Date(expirationTime * 1000).toISOString()
: new Date(Date.now() + 3600 * 1000).toISOString(),
description,
};
const response = await axios.post(
`${this.baseUrl}/transactions`,
payload,
{
headers: this.getHeaders(),
},
);
return response.data;
}
// Listar transações
async listarTransacoes(
page: number = 1,
startDate?: string,
endDate?: string,
) {
const params = {
api_key: this.apiKey,
page,
count: 20,
date_created_since: startDate,
date_created_until: endDate,
};
const response = await axios.get(`${this.baseUrl}/transactions`, {
headers: this.getHeaders(),
params,
});
return response.data;
}
// Consultar transação por ID
async consultarTransacaoPorId(transactionId: string) {
const response = await axios.get(
`${this.baseUrl}/transactions/${transactionId}`,
{
params: { api_key: this.apiKey },
headers: this.getHeaders(),
},
);
return response.data;
}
// Estornar uma transação
async estornarTransacao(transactionId: string) {
const response = await axios.post(
`${this.baseUrl}/transactions/${transactionId}/refund`,
{
api_key: this.apiKey,
},
{
headers: this.getHeaders(),
},
);
return response.data;
}
// Cadastrar Webhook no Pagar.me
async cadastrarWebhook(url: string, event: string) {
const payload = {
api_key: this.apiKey,
url,
events: [event],
};
const response = await axios.post(`${this.baseUrl}/webhooks`, payload, {
headers: this.getHeaders(),
});
return response.data;
}
// Exemplo de geração de cobrança PIX
async generatingPixBilling(
body: PixGeneratingPixBillingInterface,
): Promise<Object> {
var valueCents: number = Number.isInteger(body.valueCents)
? body.valueCents
: Math.round(body.valueCents * 100);
var expireTimestamp = Math.round(
new Date().getTime() / 1000 + (body.expires ?? 3600),
);
await this.gerarQrCode(valueCents, expireTimestamp);
return {
pixkey: body.pixkey,
value: {
original: body.valueCents,
cents: valueCents,
fixed: (valueCents / 100).toFixed(2),
float: valueCents / 100,
},
expires: {
timestamp: expireTimestamp,
dateTime: new Date(expireTimestamp * 1000).toLocaleString(
'pt-BR',
),
iso: new Date(expireTimestamp * 1000).toISOString(),
},
code: randomUUID(),
};
}
// Listar cobranças PIX
async listingPixBilling(
body: PixlistingPixBilling,
): Promise<listingPixBillingOutput> {
var data = await this.listarTransacoes(
body.page ?? 1,
body.registrationDateStart ?? new Date().toISOString(),
body.registrationDateEnd ?? new Date().toISOString(),
);
data = data.data.map((mp: any) => {
return {
referenceCode: mp.id,
valueCents: mp.amount,
content: mp.pix_qr_code,
status: mp.status,
registrationDate: mp.date_created,
paymentDate: mp.date_updated,
};
});
return {
qrcodes: data,
meta: {
current_page: body.page || 1,
total_pages: Math.ceil(data.length / 20),
total_items_amount: data.length,
total_value_cents: data.reduce(
(acc: number, curr: any) => acc + curr.valueCents,
0,
),
},
};
}
async getBalance(): Promise<BalanceOutput> {
return {
valueCents: 0,
valueFloat: 0.0,
};
}
async searchPixBilling(
body: searchPixBilling,
): Promise<searchPixBillingOutput> {
var data = await this.consultarTransacaoPorId(body.reference);
return {
referenceCode: data.id,
valueCents: data.amount,
status: data.status,
registrationDate: data.date_created,
paymentDate: data.date_updated,
};
}
// Função responsavel por gerar uma retirada (saque)
async generateProviderWidthdraw(body: PixGenerateProviderWidthdraw): Promise<generateProviderWidthdrawOutput> {
const payload = {
api_key: this.apiKey,
amount: body.valueCents,
bank_account: {
bank_code: body.bankIspb,
agencia: body.agency,
conta: body.account,
conta_dv: '0', // Considerando um exemplo básico
type: body.accountType === 'checking' ? 'conta_corrente' : 'conta_poupanca',
document_number: body.receiverDocument,
legal_name: body.receiverName,
},
};
const response = await axios.post(`${this.baseUrl}/transfers`, payload, {
headers: this.getHeaders(),
});
return {
reference_code: response.data.id,
idempotent_id: body.idempotentId,
value_cents: body.valueCents,
pix_key_type: body.pixKeyType || '',
pix_key: body.pixKey || '',
receiver_name: body.receiverName,
receiver_document: body.receiverDocument,
status: response.data.status,
};
}
// Função responsavel por listar todas as retiradas
async listProviderWidthdraw(body: listProviderWidthdraw): Promise<listProviderWidthdrawOutput> {
const params = {
api_key: this.apiKey,
page: body.page || 1,
count: 20,
date_created_since: body.registrationDateStart,
date_created_until: body.registrationDateEnd,
};
const response = await axios.get(`${this.baseUrl}/transfers`, {
headers: this.getHeaders(),
params,
});
const withdrawals = response.data.map((transfer: any) => ({
referenceCode: transfer.id,
idempotentId: transfer.correlation_id || '',
valueCents: transfer.amount,
pixKeyType: 'N/A',
pixKey: 'N/A',
receiverName: transfer.recipient_name,
receiverDocument: transfer.recipient_document_number,
status: transfer.status,
registrationDate: transfer.date_created,
paymentDate: transfer.date_updated,
cancellationDate: transfer.date_canceled || null,
cancellationReason: transfer.reason || null,
endToEnd: 'N/A',
}));
return {
payments: withdrawals,
meta: {
current_page: body.page || 1,
total_pages: Math.ceil(response.data.length / 20),
total_items_amount: response.data.length,
total_value_cents: withdrawals.reduce((acc: any, withdrawal: any) => acc + withdrawal.valueCents, 0),
},
};
}
// Função responsavel por obter um saque a partir da referência
async searchProviderWidthdraw(body: { correlationId: string }): Promise<Object> {
const response = await axios.get(`${this.baseUrl}/transfers/${body.correlationId}`, {
headers: this.getHeaders(),
params: { api_key: this.apiKey },
});
const transfer = response.data;
return {
referenceCode: transfer.id,
idempotentId: transfer.correlation_id || '',
valueCents: transfer.amount,
pixKeyType: 'N/A',
pixKey: 'N/A',
receiverName: transfer.recipient_name,
receiverDocument: transfer.recipient_document_number,
status: transfer.status,
registrationDate: transfer.date_created,
paymentDate: transfer.date_updated,
cancellationDate: transfer.date_canceled || null,
endToEnd: 'N/A',
};
}
}