@jackiemacklein/nettz-utils
Version:
Serviços de imagem, e-mail, códigos de barras, utilitários numéricos e componentes React para apps Node.js com TypeScript
248 lines (247 loc) • 11 kB
JavaScript
;
/**
* @author Jackiê Macklein
* @company Onside tecnologia/Nettz
* @copyright Todos direitos reservados.
* @description Cliente HTTP para APIs do Mercado Pago (OAuth, Point e pagamentos).
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMercadoPagoClient = createMercadoPagoClient;
const errors_1 = require("./errors");
const types_1 = require("./types");
async function readResponseBody(res) {
try {
return await res.text();
}
catch {
return "";
}
}
function computeExpiresAt(expiresInSeconds) {
const now = new Date();
now.setSeconds(now.getSeconds() + expiresInSeconds);
return now.toISOString();
}
function createMercadoPagoClient(config = {}) {
var _a, _b, _c;
const baseUrl = ((_a = config.baseUrl) !== null && _a !== void 0 ? _a : types_1.MERCADOPAGO_DEFAULT_BASE_URL).replace(/\/$/, "");
const timeoutMs = (_b = config.timeoutMs) !== null && _b !== void 0 ? _b : 30000;
const fetchFn = (_c = config.fetchImpl) !== null && _c !== void 0 ? _c : fetch;
async function request(path, init) {
var _a, _b;
const url = `${baseUrl}${path.startsWith("/") ? path : `/${path}`}`;
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), (_a = init === null || init === void 0 ? void 0 : init.timeoutMs) !== null && _a !== void 0 ? _a : timeoutMs);
try {
const res = await fetchFn(url, {
...init,
signal: (_b = init === null || init === void 0 ? void 0 : init.signal) !== null && _b !== void 0 ? _b : controller.signal,
headers: {
Accept: "application/json",
...((init === null || init === void 0 ? void 0 : init.body) ? { "Content-Type": "application/json" } : {}),
...init === null || init === void 0 ? void 0 : init.headers,
},
});
const text = await readResponseBody(res);
if (!res.ok) {
throw new errors_1.MercadoPagoApiError(`MercadoPago HTTP ${res.status} ${res.statusText}`, res.status, text);
}
if (!text || text.trim() === "") {
return undefined;
}
try {
return JSON.parse(text);
}
catch {
throw new errors_1.MercadoPagoApiError("MercadoPago resposta não é JSON válido", res.status, text);
}
}
finally {
clearTimeout(t);
}
}
function bearerHeader(accessToken) {
return { authorization: `Bearer ${accessToken}` };
}
return {
baseUrl,
async oauthToken(input) {
var _a, _b, _c;
const clientId = (_a = input.clientId) !== null && _a !== void 0 ? _a : config.clientId;
const clientSecret = (_b = input.clientSecret) !== null && _b !== void 0 ? _b : config.clientSecret;
const redirectUri = (_c = input.redirectUri) !== null && _c !== void 0 ? _c : config.redirectUri;
if (!clientId || !clientSecret || !redirectUri) {
throw new errors_1.MercadoPagoApiError("MercadoPago: clientId, clientSecret e redirectUri são obrigatórios para oauthToken", 400, "");
}
const data = await request("/oauth/token", {
method: "POST",
body: JSON.stringify({
client_id: clientId,
client_secret: clientSecret,
grant_type: "authorization_code",
redirect_uri: redirectUri,
code: input.code,
}),
});
return {
...data,
expires_at: computeExpiresAt(data.expires_in),
};
},
async oauthRefreshToken(input) {
var _a, _b;
const clientId = (_a = input.clientId) !== null && _a !== void 0 ? _a : config.clientId;
const clientSecret = (_b = input.clientSecret) !== null && _b !== void 0 ? _b : config.clientSecret;
if (!clientId || !clientSecret) {
throw new errors_1.MercadoPagoApiError("MercadoPago: clientId e clientSecret são obrigatórios para oauthRefreshToken", 400, "");
}
const data = await request("/oauth/token", {
method: "POST",
body: JSON.stringify({
client_id: clientId,
client_secret: clientSecret,
grant_type: "refresh_token",
refresh_token: input.refreshToken,
}),
});
return {
...data,
expires_at: computeExpiresAt(data.expires_in),
};
},
async listDevices(accessToken) {
var _a;
const data = await request("/point/integration-api/devices", { headers: bearerHeader(accessToken) });
return (_a = data.devices) !== null && _a !== void 0 ? _a : [];
},
async listStores(userId, accessToken) {
var _a;
const data = await request(`/users/${encodeURIComponent(String(userId))}/stores/search`, { headers: bearerHeader(accessToken) });
return (_a = data.results) !== null && _a !== void 0 ? _a : [];
},
async listPos(accessToken) {
var _a;
const data = await request("/pos", {
headers: bearerHeader(accessToken),
});
return (_a = data.results) !== null && _a !== void 0 ? _a : [];
},
async updatePos(posId, externalPosId, accessToken) {
return request(`/pos/${encodeURIComponent(posId)}`, {
method: "PUT",
headers: bearerHeader(accessToken),
body: JSON.stringify({ external_id: externalPosId }),
});
},
async createPos(params, accessToken) {
return request("/pos", {
method: "POST",
headers: bearerHeader(accessToken),
body: JSON.stringify(params),
});
},
async createStore(userId, params, accessToken) {
return request(`/users/${encodeURIComponent(String(userId))}/stores`, {
method: "POST",
headers: bearerHeader(accessToken),
body: JSON.stringify(params),
});
},
async changeDeviceMode(accessToken, deviceId, mode) {
return request(`/point/integration-api/devices/${encodeURIComponent(deviceId)}`, {
method: "PATCH",
headers: bearerHeader(accessToken),
body: JSON.stringify({ operating_mode: mode }),
});
},
async createDeviceCardPayment(deviceId, params, accessToken) {
var _a, _b, _c, _d;
const payload = {
amount: params.amount,
description: params.description,
payment: {
type: (_a = params.paymentType) !== null && _a !== void 0 ? _a : "debit_card",
},
additional_info: {
external_reference: params.reference,
print_on_terminal: (_b = params.printOnTerminal) !== null && _b !== void 0 ? _b : false,
},
};
if (((_c = params.paymentType) !== null && _c !== void 0 ? _c : "debit_card") === "credit_card") {
payload.payment.installments =
(_d = params.installments) !== null && _d !== void 0 ? _d : 1;
payload.payment.installments_cost = "seller";
}
return request(`/point/integration-api/devices/${encodeURIComponent(deviceId)}/payment-intents`, {
method: "POST",
headers: bearerHeader(accessToken),
body: JSON.stringify(payload),
});
},
async createPixPayment(userId, posId, params, accessToken) {
const payload = {
cash_out: { amount: 0 },
external_reference: params.reference,
description: params.description,
items: [
{
sku_number: params.reference,
category: "marketplace",
title: params.description,
description: params.description,
unit_measure: "unit",
quantity: 1,
unit_price: params.amount / 100,
total_amount: params.amount / 100,
},
],
notification_url: params.notificationUrl,
expiration_date: params.expirationDate,
sponsor: { id: params.sponsorId },
title: params.description,
total_amount: params.amount / 100,
};
return request(`/instore/orders/qr/seller/collectors/${encodeURIComponent(String(userId))}/pos/${encodeURIComponent(String(posId))}/qrs`, {
method: "POST",
headers: bearerHeader(accessToken),
body: JSON.stringify(payload),
});
},
async getPixPayment(externalReference, accessToken, returnFirst = true) {
const query = new URLSearchParams({
external_reference: externalReference,
}).toString();
const data = await request(`/merchant_orders?${query}`, {
headers: bearerHeader(accessToken),
});
if (returnFirst &&
Array.isArray(data.elements) &&
data.elements.length > 0 &&
data.elements[0]) {
return data.elements[0];
}
return data;
},
async cancelDevicePayment(deviceId, paymentId, accessToken) {
return request(`/point/integration-api/devices/${encodeURIComponent(deviceId)}/payment-intents/${encodeURIComponent(paymentId)}`, {
method: "DELETE",
headers: bearerHeader(accessToken),
});
},
async getDevicePayment(paymentId, accessToken) {
return request(`/point/integration-api/payment-intents/${encodeURIComponent(paymentId)}`, { headers: bearerHeader(accessToken) });
},
async getDetailsPayment(paymentId, accessToken) {
return request(`/v1/payments/${encodeURIComponent(String(paymentId))}`, {
headers: bearerHeader(accessToken),
});
},
async refundPayment(paymentId, accessToken) {
return request(`/v1/payments/${encodeURIComponent(String(paymentId))}/refunds`, {
method: "POST",
headers: bearerHeader(accessToken),
body: JSON.stringify({}),
});
},
};
}