//------------------------------------------------------------------------------------ //npm install --save axios moment dotenv const axios = require("axios"); const moment = require("moment"); require('dotenv').config() //------------------------------------------------------------------------------------ /* BEFORE RUNNING THIS EXAMPLE: * Set CONNECTFI_CLIENTID, CONNECTFI_PASSWORD, and CONNECTFI_BASE_URL in an .env file (Speak to a support representative to be issued client credentials and URL after receiving access to the sandbox.) * Set UNIQUE_REFERENCE_ID to a unique identifier. */ const CONNECTFI_CLIENTID = process.env.CONNECTFI_CLIENTID; const CONNECTFI_PASSWORD = process.env.CONNECTFI_PASSWORD; const CONNECTFI_BASE_URL = process.env.CONNECTFI_BASE_URL; const UNIQUE_REFERENCE_ID = "exampleRef1010"; //Update this value so that it is a unique ID before running //------------------------------------------------------------------------------------ //Get Authorization Token /* All other requests must have a valid authorization token in the request headers, so your first request in any workflow should be to /auth/get-token in order to receive an authorization token. A valid token should be included in the headers of all subsequent requests. */ async function getAuthToken() { const data = { "user": { "login": `${CONNECTFI_CLIENTID}`, "password": `${CONNECTFI_PASSWORD}` } }; const config = { method: 'POST', url: `${CONNECTFI_BASE_URL}/auth/get-token`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Print Check /* The first step in the printing process following authorization is to make a POST request to the /check/print endpoint with the details of the check to be printed. This will create a check entity in our system and a unique cFiCheckId will be returned with a successful response. */ async function printCheck(authToken, amount, reference) { const data = { "reference": reference, "checkAttributes": { "amount": amount, "currency": "USD", "returnAddress": { "addressLine1": "Platform Name, ATTN: Employee", "addressLine2": "100 Unicorn St", "addressLine3": "San Francisco, CA 12345" }, "payerName": "Jim Payer", "payerAddress": { "addressLine1": "3700 Loon Rd", "city": "Minneapolis", "state": "MN", "postalCode": "12345-1234" }, "payeeName": "ABC123abc Energy", "payeeAddress": { "addressLine1": "123 Some Road", "city": "Minneapolis", "state": "MN", "postalCode": "12345" }, "platformNumber": "+1 (555) 666-7777", "memo": "Check memo details" }, "webhookUrl": `https://your_webhook_url/${reference}` }; const config = { method: 'POST', url: `${CONNECTFI_BASE_URL}/check/print`, headers: { 'Content-Type': "application/json", 'x-connectfi-token': authToken //previously obtained authorization token is required }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Get Check /* After the check entity has been created, you may retrieve the details of the check using a GET request to /check/get/:checkId, where the cFiCheckId is a path parameter. */ async function getCheck(authToken, cFiCheckId) { const config = { method: 'GET', url: `${CONNECTFI_BASE_URL}/check/get/${cFiCheckId}`, headers: { 'x-connectfi-token': authToken //previously obtained authorization token is required } }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Query /* After requesting a printed check, if you have not received a webhook response with a status change within the expected time period, you may query the current status of up to 20 checks at a time using a /check/query request. It is recommended that you run a /check/query only once or twice per day. The conditions under which a /check/query should be made are as follows: * A status change was expected to have already occurred. For example, a check print request was sent. It is now 12 hours later, it is past time for the check file to have been sent through SFTP, and a status change to "Sent" was expected to have already occurred. * An expected webhook response has not been received for the check request. This is a rare occurrence and would indicate that something unforeseen has happened. * Do not send multiple queries for the same check within a 12 hour period. If a query confirms that the status of a check has not moved when expected, contact customer support with the cFiCheckId, current status, expected status, and date that the check request was created. * If you have more than one check to query, do not send multiple queries with one check at a time. The queries should be sent in batches of 20 cFiCheckIds/reference IDs per request. If you have less than 20 checks to query, they can all be queried in a single request. */ async function query(authToken, cFiCheckId) { const data = { "cFiCheckIds": [cFiCheckId] }; const config = { method: 'POST', url: `${CONNECTFI_BASE_URL}/check/query`, headers: { 'Content-Type': "application/json", 'x-connectfi-token': authToken //previously obtained authorization token is required }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //List /* It is possible to list up to 1000 checks at a time using search criteria with an /check/list request. Search criteria may include a date range, a status value, a voidStatus value, or a combination of these search criteria. Use case examples for an /check/list request include but are not limited to the following. * Listing all checks that still have a "Processing" status. * Listing all checks that have a "Cancelled" status with a date range of "2023-05-10T12:00:30.000Z" to "2023-05-11T12:00:00.000Z". * Listing all checks that have a "Completed" status in batches of 150. (You can use the "numberOfRecords" property and the "skipRecords" property to list up to 1000 transactions at a time or to skip a certain number of transactions.) */ async function list(authToken, status, numRecords, numToSkip) { const data = { "dateCreateFrom": `${new Date(moment(new Date()).add(-1, "hour")).toISOString()}`, "dateCreateTo": `${new Date(moment(new Date()).add(1, "hour")).toISOString()}`, "status": status, "numberOfRecords": numRecords, "skipRecords": numToSkip }; const config = { method: 'POST', url: `${CONNECTFI_BASE_URL}/check/list`, headers: { 'Content-Type': "application/json", 'x-connectfi-token': authToken //previously obtained authorization token is required }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Void Check /* It is possible to void a check after a print request has been made by sending a POST request to /check/void with the cFiCheckId of the check to be voided. If the check is voided before the initial print request is packaged and sent through SFTP to the bank, then the status will updated to "Cancelled" within seconds, which will trigger a webhook call to notify you of the status change. If the initial print request has already been packaged and sent to the bank, then the void request will also be packaged and sent to the bank as part of the regular check request files. Once the bank confirms receipt of a successful void request, the status of the check will update to "Cancelled". */ async function voidCheck(authToken, cFiCheckId) { const data = { "cFiCheckId": cFiCheckId, "reason": "Lost the check" }; const config = { method: 'POST', url: `${CONNECTFI_BASE_URL}/check/void`, headers: { 'Content-Type': "application/json", 'x-connectfi-token': authToken //previously obtained authorization token is required }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Run the walkthrough async function printingWalkthrough() { //Get Authorization Token console.log(`Start /auth/get-token example.\n`); const authObject = await getAuthToken(); let authToken = undefined; if (authObject) { console.log(`Successfully obtained authorization: ${JSON.stringify(authObject)}\n`); authToken = authObject.token; console.log(`Authorization token: ${authToken}\n`); } else { console.log(`Error getting authorization token\n`) } console.log(`End /auth/get-token example.\n`); //Print Check console.log(`Start /check/print example.\n`); let printResult; if (authToken) { printResult = await printCheck(authToken, 16.53, UNIQUE_REFERENCE_ID); } else { console.log(`Authorization token is required.\n`) } if (printResult) { console.log(`Successfully registered check for printing: ${JSON.stringify(printResult)}\n`); } console.log(`End /check/print example.\n`); //Get Check console.log(`Start /check/get/:checkId example.\n`); let getCheckResult; if (authToken && printResult && printResult.cFiCheckId) { getCheckResult = await getCheck(authToken, printResult.cFiCheckId); } else { console.log(`Authorization token and a valid cFiCheckId are required.\n`) } if (getCheckResult) { console.log(`Successfully retrieved check details: ${JSON.stringify(getCheckResult)}\n`); } console.log(`End /check/get/:checkId example.\n`); //Query console.log(`Start /check/query.\n`); let checksQueryResult; if (authToken && printResult && printResult.cFiCheckId) { checksQueryResult = await query(authToken, printResult.cFiCheckId); } else { console.log(`Authorization token and cFiCheckId are required.\n`) } if (checksQueryResult) { console.log(`Successfully queried checks: ${JSON.stringify(checksQueryResult)}\n`); } console.log(`End /check/query.\n`); //List console.log(`Start /check/list example.\n`); let listChecksResult; if (authToken) { listChecksResult = await list(authToken, "Processing", 5, 0); } else { console.log(`Authorization token is required.\n`) } if (listChecksResult) { console.log(`Successfully retrieved list of checks matching criteria: ${JSON.stringify(listChecksResult)}\n`); } console.log(`End /check/list example.\n`); console.log(`Start /check/void example.\n`); let voidCheckResult; if (authToken && printResult && printResult.cFiCheckId) { voidCheckResult = await voidCheck(authToken, printResult.cFiCheckId); } else { console.log(`Authorization token and cFiCheckId are required.\n`) } if (voidCheckResult) { console.log(`Successfully voided check: ${JSON.stringify(voidCheckResult)}\n`); } console.log(`End /check/void example.\n`); //Query Voided Check console.log(`Start /check/query for cancelled check.\n`); let voidQueryResult; if (authToken && printResult && printResult.cFiCheckId) { voidQueryResult = await query(authToken, printResult.cFiCheckId); } else { console.log(`Authorization token and cFiCheckId are required.\n`) } if (voidQueryResult) { console.log(`Successfully queried checks: ${JSON.stringify(voidQueryResult)}\n`); } console.log(`End /check/query for cancelled check.\n`); } if (process.env.CONNECTFI_CLIENTID && process.env.CONNECTFI_PASSWORD && process.env.CONNECTFI_BASE_URL) { printingWalkthrough(); } else { console.log("Before running the walkthrough, set the required .env variables."); }