useutility-flowcl-api
Version:
Este proyecto es una herramienta de gestión de tareas diseñada para hacer transacciones de manera rápida y eficaz con FLOWCL.
463 lines (448 loc) • 15.7 kB
JavaScript
// src/utils/methods.utils.ts
var post = async (url, params) => {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams(params).toString()
// Puedes agregar otros options como 'mode', 'credentials', etc., según tus necesidades
});
const result = await response.json();
if (!response.ok) {
const error = result;
throw error;
}
const success = result;
return success;
};
var get = async (url, params) => {
const paramsOrder = new URLSearchParams(params);
const response = await fetch(`${url}?${paramsOrder}`, { method: "GET" });
const result = await response.json();
if (!response.ok) {
const error = result;
throw error;
}
const success = result;
return success;
};
// src/utils/service.util.ts
import { JSDOM } from "jsdom";
import DOMPurify from "dompurify";
import { HmacSHA256, enc } from "crypto-js";
function service(params, apiKey, secretKey) {
try {
if (!apiKey || !secretKey)
throw "credentials problem";
let service2 = { ...params };
const window = new JSDOM("").window;
const purify = DOMPurify(window);
service2.apiKey = apiKey;
const keys = Object.keys(service2).sort();
let toSign = "";
let order = {};
for (const key of keys) {
const myParam = purify.sanitize(key);
toSign += myParam + service2[myParam];
order[myParam] = service2[myParam];
}
const signature = { s: HmacSHA256(toSign, secretKey).toString(enc.Hex), ...order };
return signature;
} catch (error) {
throw new Error("problems to use service()");
}
}
// src/classes/Transaction.ts
var Transaction = class {
API_KEY;
SECRET_KEY;
API_URL;
constructor(apiKey, secretKey, apiUrl) {
this.API_KEY = apiKey;
this.SECRET_KEY = secretKey;
this.API_URL = apiUrl;
}
/**
* @function service
*
*
* Language:
*
* en -> adds the APIKEY property, purifies and uses the parameters by returning the object with the "s" property needed for FLOWCL
*
* es -> añade la propiedad de APIKEY , purifica y utiliza los parametros retornando el objeto con la propiedad "s" necesaria para FLOWCL
*/
service(params) {
try {
const signature = service(params, this.API_KEY, this.SECRET_KEY);
return signature;
} catch (error) {
throw new Error("problems to use service()");
}
}
async get(URL, params) {
const request = this.service(params);
return await get(URL, request);
}
async post(URL, params) {
const request = this.service(params);
return await post(URL, request);
}
};
// src/classes/modules/Payment.ts
var Payment = class extends Transaction {
/**
* @function create
* @param {string} params Payment_CreateEmail_Options
* @return {Promise<Payment_Create_Result>} a object with type Payment_Create_Result
*
* example: http://localhost:3003/create
*
* const params: Payment_Create_Options = {
* commerceOrder: "useutility-dev-" + Math.floor(Math.random() * 1000) + 1,
* subject: "subject",
* amount: 3300,
* email: "test@useutility.dev",
* urlConfirmation: "http://localhost:3003",
* urlReturn: "https://flow.cl"
* }
*
* express::
* app.post("/create", async (req, res) => {
const params: Payment_Create_Options = {
commerceOrder: "useutility-dev-" + Math.floor(Math.random() * 1000) + 1,
subject: "subject",
amount: 3300,
email: "test@useutility.dev",
urlConfirmation: "http://localhost:3003",
urlReturn: "https://flow.cl"
}
const createEmailFlow = await FlowAPI.payment().create(params)
res.json(createEmailFlow)
})
*/
async create(params) {
const request = this.service(params);
const URL = `${this.API_URL}/payment/create`;
return await post(URL, request);
}
/**
* @function createEmail
* @param {string} params Payment_CreateEmail_Options
* @return {Promise<Payment_CreateEmail_Result>} a object with type Payment_CreateEmail_Result
*
* example: http://localhost:3003/createEmail
*
* const params: Payment_CreateEmail_Options = {
* commerceOrder: "useutility-dev-" + Math.floor(Math.random() * 1000) + 1,
* subject: "subject",
* amount: 3300,
* email: "test@useutility.dev",
* urlConfirmation: "http://localhost:3003",
* urlReturn: "https://flow.cl"
* }
*
* express::
* app.post("/createEmail", async (req, res) => {
const params: Payment_CreateEmail_Options = {
commerceOrder: "useutility-dev-" + Math.floor(Math.random() * 1000) + 1,
subject: "subject",
amount: 3300,
email: "test@useutility.dev",
urlConfirmation: "http://localhost:3003",
urlReturn: "https://flow.cl"
}
const createEmailFlow = await FlowAPI.payment().createEmail(params)
res.json(createEmailFlow)
})
*/
async createEmail(params) {
const request = this.service(params);
const URL = `${this.API_URL}/payment/createEmail`;
return await post(URL, request);
}
/**
* @function getStatus
* @param {string} token
* @return {Promise<Payment_GetStatus_Result>} a object with type Payment_GetStatus_Result
*
* example: http://localhost:3003/getStatus/C86FD5BDE466939CA194AE9AF0C0A708ABE6E26X
*
* app.get("/getStatus/:token", async (req, res) => {
*
* const { token } = req.params
*
* const createFlow = await FlowAPI.payment().getStatusByCommerceId(token)
*
* res.json(createFlow)
*
* })
*/
async getStatus(token) {
const request = this.service({ token });
const URL = `${this.API_URL}/payment/getStatus`;
return await get(URL, request);
}
/**
* @function getStatusByCommerceId
* @param {string} commerceId
* @return {Promise<Payment_GetStatusByCommerceId_Result>} a object with type Payment_GetStatusByCommerceId_Result
*
* example: http://localhost:3003/getStatusByCommerceId/mf334
*
* app.get("/getStatusByCommerceId/:commerceOrder", async (req, res) => {
*
* const { commerceOrder } = req.params
*
* const createFlow = await FlowAPI.payment().getStatusByCommerceId(commerceOrder)
*
* res.json(createFlow)
*
* })
*/
async getStatusByCommerceId(commerceId) {
const request = this.service({ commerceId });
const URL = `${this.API_URL}/payment/getStatusByCommerceId`;
return await get(URL, request);
}
/**
* @function getStatusByFlowOrder
* @param {string} flowOrder
* @return {Promise<Payment_GetStatusByFlowOrder_Result>} a object with type Payment_GetStatusByFlowOrder_Result
*
* example: http://localhost:3003/getStatusByFlowOrder/1943140
*
* app.get("/getStatusByFlowOrder/:flowOrder", async (req, res) => {
*
* const { flowOrder } = req.params
*
* const createFlow = await FlowAPI.payment().getStatusByFlowOrder(flowOrder)
*
* res.json(createFlow)
*
* })
*/
async getStatusByFlowOrder(flowOrder) {
const request = this.service({ flowOrder });
const URL = `${this.API_URL}/payment/getStatusByFlowOrder`;
return await get(URL, request);
}
/**
* @function getPayments
* @param {object} params Payment_getPayments_Options
* @return {Promise<Payment_getPayments_Result>} a object with type Payment_getPayments_Result
*
* example: http://localhost:3003/getPayments?date=2024-01-01
*
* app.get("/getPayments", async (req, res) => {
*
* const params = req.query as unknown as Payment_getPayments_Options
*
* const createFlow = await FlowAPI.payment().getPayments(params)
*
* res.json(createFlow)
*
* })
*/
async getPayments(params) {
const request = this.service(params);
const URL = `${this.API_URL}/payment/getPayments`;
return await get(URL, request);
}
/**
* @function getStatusExtended
* @param {string} token
* @return {Promise<Payment_getStatusExtended_Result>} a object with type Payment_getStatusExtended_Result
*
* example: http://localhost:3003/getStatusExtended/C86FD5BDE466939CA194AE9AF0C0A708ABE6E26X
*
* app.get("/getStatusExtended/:token", async (req, res) => {
*
* const { token } = req.params
*
* const createFlow = await FlowAPI.payment().getStatusExtended(token)
*
* res.json(createFlow)
*
* })
*/
async getStatusExtended(token) {
const request = this.service({ token });
const URL = `${this.API_URL}/payment/getStatusExtended`;
return await get(URL, request);
}
/**
* @function getStatusByFlowOrderExtended
* @param {string} flowOrder
* @return {Promise<Payment_GetStatusByFlowOrderExtended_Result>} a object with type Payment_GetStatusByFlowOrderExtended_Result
*
* example: http://localhost:3003/getStatusByFlowOrderExtended/1943140
*
* app.get("/getStatusByFlowOrderExtended/:flowOrder", async (req, res) => {
*
* const { flowOrder } = req.params
*
* const createFlow = await FlowAPI.payment().getStatusByFlowOrderExtended(flowOrder)
*
* res.json(createFlow)
*
* })
*/
async getStatusByFlowOrderExtended(flowOrder) {
const request = this.service({ flowOrder });
const URL = `${this.API_URL}/payment/getStatusByFlowOrderExtended`;
return await get(URL, request);
}
/**
* @function getTransactions
* @param {object} params Payment_GetTransactions_Options
* @return {Promise<Payment_getPayments_Result>} a object with type Payment_GetTransactions_Result
*
*
* example: http://localhost:3003/getTransactions?date=2024-01-01
*
* query : {data : string , start: 1, limit:10 }
*
* app.get("/getTransactions", async (req, res) => {
*
* const params = req.query as unknown as Payment_GetTransactions_Options
*
* const createFlow = await FlowAPI.payment().getTransactions(params)
*
* res.json(createFlow)
*
* })
*/
async getTransactions(params) {
const request = this.service(params);
const URL = `${this.API_URL}/payment/getTransactions`;
return await get(URL, request);
}
};
// src/utils/generateCommerceOrder.utils.ts
var createHash = async (text) => {
const textoArrayBuffer = new TextEncoder().encode(text);
const hashBuffer = await crypto.subtle.digest("SHA-1", textoArrayBuffer);
const hashHex = Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
const hashCorto = hashHex.slice(0, 31);
return hashCorto;
};
var createRandom = () => {
const caracteres = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let codigoAleatorio = "";
for (let i = 0; i < 5; i++) {
const indiceAleatorio = Math.floor(Math.random() * caracteres.length);
codigoAleatorio += caracteres.charAt(indiceAleatorio);
}
return codigoAleatorio;
};
// src/classes/modules/Refound.ts
var Refound = class extends Transaction {
/**
* Iniciamos el envio de los parametros.
* @type {Object} RefoundCreateOptions
* @property {string} commerceOrder El orden del comercio : required
* @property {string} subject - La Descripción de la orden : required
* @property {number} amount - El Monto de la orden : required
* @property {string} email - El email del pagador : required
* @property {uri} urlConfirmation - <uri> El url callback del comercio donde Flow confirmará el pago : required
* @property {string} urlReturn - <uri> El url de retorno del comercio donde Flow redirigirá al pagador : required
* @property {number} paymentMethod ? - Identificador del medio de pago. Si se envía el identificador, el pagador será redireccionado directamente al medio de pago que se indique, de lo contrario Flow le presentará una página para seleccionarlo. El medio de pago debe haber sido previamente contratado. Podrá ver los identificadores de sus medios de pago en la sección "Mis Datos" ingresando a Flow con sus credenciales. Para indicar todos los medios de pago utilice el identificador: 9 Todos los medios
* @property {number} timeout ? - tiempo en segundos para que una orden expire después de haber sido creada. Si no se envía este parámetro la orden no expirará y estará vigente para pago por tiempo indefinido. Si envía un valor en segundos, la orden expirará x segundos después de haber sido creada y no podrá pagarse.
* @property {string} merchantId ? - El Id de comercio asociado. Solo aplica si usted es comercio integrador.
* @property {string} payment_currency ? - La moneda en que se espera se pague la orden
* @property {string} currency ? - La moneda de la orden
* @returns {Promise<{}>}
*/
async create(params) {
const request = this.service(params);
const URL = `${this.API_URL}/refound/create`;
return await post(URL, request);
}
async cancel(params) {
const request = this.service(params);
const URL = `${this.API_URL}/refound/cancel`;
return await post(URL, request);
}
/**
* getStatus : Obtener datos de compra segun el Token utilizado
* @param {string} token
* @returns Promise<Payment_GetStatus_Result >
*/
async getStatus(token) {
const request = this.service({ token });
const URL = `${this.API_URL}/refound/getStatus`;
return await get(URL, request);
}
};
// src/classes/index.ts
function useFlowAPI(params) {
return new useutilityFlowAPI(params);
}
var useutilityFlowAPI = class {
//Secret key designada por su cuenta flowcl
SECRET_KEY;
//Api key designada por su cuenta flowcl
API_KEY;
//Api URL de Flow modo produccion o desarrollo
API_URL;
API_PROD;
/**
* @param apiKey string |undefined
* @param secretKey string |undefined
* @param development boolean ( production | developemnt )
*/
constructor(params) {
if (!params.apiKey)
throw "no apiKey";
if (!params.secretKey)
throw "no secretKey";
this.API_KEY = params.apiKey;
this.SECRET_KEY = params.secretKey;
this.API_PROD = this.checkProduction(params.production);
this.API_URL = this.API_PROD ? "https://www.flow.cl/api" : "https://sandbox.flow.cl/api";
if (params.debug) {
if (this.API_PROD) {
this.debugs_prod();
} else
this.debugs_dev();
}
}
checkProduction(type) {
if (type)
return true;
return false;
}
debugs_dev() {
console.debug(`DEVELOPMENT: useutility-flowcl-api .use(), for *production* use: 'p', 'prod', 'production'`);
}
debugs_prod() {
console.debug(`PRODUCTION: useutility-flowcl-api`);
}
payment() {
return new Payment(this.API_KEY, this.SECRET_KEY, this.API_URL);
}
refound() {
return new Refound(this.API_KEY, this.SECRET_KEY, this.API_URL);
}
async post(URL, params) {
const request = service(params, this.API_KEY, this.SECRET_KEY);
return await post(URL, request);
}
async get(URL, params) {
const request = service(params, this.API_KEY, this.SECRET_KEY);
return await get(URL, request);
}
};
async function generateCommerceOrder(text) {
var fechaActual = /* @__PURE__ */ new Date();
var day = fechaActual.getDate();
var month = fechaActual.getMonth() + 1;
var year = fechaActual.getFullYear();
var Timestamp = Date.now();
const hashHex = await createHash(`${Timestamp}-${text}`);
return `${day}${month}${year}-${hashHex}-${createRandom()}`;
}
export {
generateCommerceOrder,
useFlowAPI
};