Example Workflow Execution

Script to give visibility into an example workflow integration

alfred Transaction

Description

This Node.js script is used to interact with a third-party API. It performs several operations such as initiating a transaction, logging in, uploading documents, verifying the phone, and sending a transaction.

Configuration

The script uses environment variables to configure various aspects of its operation. These variables can be set in a .env file in the root directory of the project.

URL=https://api-dev-services.alfredpay.app/api/v1
API_KEY=your_api_key
API_SECRET=your_api_secret
COUNTRY_WITHDRAWAL=MEX
BUSINESS_TO=your_business_to
METHOD_WITHDRAWAL=BANK
TYPE=your_type
ID_CARD_FRONT_PATH=path_to_id_card_front
ID_CARD_BACK_PATH=path_to_id_card_back
SELFIE_PATH=path_to_selfie
DRIVER_DOC_FRONT_PATH=path_to_driver_doc_front
DRIVER_DOC_BACK_PATH=path_to_driver_doc_back

Functions

getHeaders(token)

Generates and returns the necessary headers for requests to the API.

makeRequest(method, url, body, token)

Makes a request to the API with the provided method, URL, body, and token.

getInitTransaction()

Initiates a transaction with the API and returns the transaction ID.

loginSofKyc(initialTransaction)

Logs in to the API using the provided initial transaction.

uploadDocument(token, docPath, docType)

Uploads a document to the API using the provided token, document path, and document type.

paymentMethod(initTransaction)

Sets the payment method using the provided initial transaction.

verificationPhone()

Verifies the phone number with the API.

submitTransaction(initTransaction, exchangeFactor)

Submits a transaction to the API using the provided initial transaction and exchange factor.

updateBankUser()

Updates the user's bank information in the API.

updateInvoice(invoice)

Updates the status of the invoice in the API. The invoice status can only be changed to 'approved'.

getInvoice(invoice)

Gets the invoice information from the API.

main()

Main function that coordinates all the above operations.

Usage

To run the script, first install the dependencies with npm install and then run the script with node script.js.

Dependencies

  • dotenv: To load environment variables from a .env file

  • axios: To make HTTP requests.

  • fs: To read files from the file system.

  • form-data: To create multipart/form-data forms.

Package.Json

{
  "name": "alfred",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "dotenv": "^10.0.0",
    "axios": "^0.24.0",
    "form-data": "^4.0.0"
  },
  "devDependencies": {},
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Index.js

require('dotenv').config();
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');

const KycDocTypes = {
  idCardFront: 'idCardFront',
  idCardBack: 'idCardBack',
  selfie: 'selfie',
  driverDocFront: 'driverDocFront',
  driverDocBack: 'driverDocBack',
};

const URL = process.env.URL || 'https://api-dev-services.alfredpay.app/api/v1';
const API_KEY = process.env.API_KEY;
const API_SECRET = process.env.API_SECRET;
const COUNTRY_WITHDRAWAL = process.env.COUNTRY_WITHDRAWAL || 'ARG';
const BUSINESS_TO = process.env.BUSINESS_TO;
const METHOD_WITHDRAWAL = process.env.METHOD_WITHDRAWAL || 'BANK';
const TYPE = process.env.TYPE;

const files = {
  [KycDocTypes.idCardFront]: process.env.ID_CARD_FRONT_PATH,
  [KycDocTypes.idCardBack]: process.env.ID_CARD_BACK_PATH,
  [KycDocTypes.selfie]: process.env.SELFIE_PATH,
  [KycDocTypes.driverDocFront]: process.env.DRIVER_DOC_FRONT_PATH,
  [KycDocTypes.driverDocBack]: process.env.DRIVER_DOC_BACK_PATH,
};

let token = '';

function getHeaders(token) {
  return {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
    'api-key': API_KEY,
    'api-secret': API_SECRET,
  };
}

async function makeRequest(method, url, body, token) {
  try {
    const response = await axios({
      method,
      url,
      data: body,
      headers: getHeaders(token),
    });

    return response.data;
  } catch (error) {
    console.error(`Failed to make request: ${error?.response?.data?.message} `);
    throw error?.response?.data?.message ?? error.message;
  }
}

async function getInitTransaction() {
  const body = {
    type: TYPE,
    balance: 11,
    currency: 'USDC',
    user: '@JohnDoe',
    chain: 'stellar',
  };

  const response = await makeRequest(
    'POST',
    `${URL}/third-party-service/my-info`,
    body,
    token,
  );

  const url = response.data.url;
  const urlSplit = url.split('/');
  const urlParam = urlSplit[urlSplit.length - 1];

  return urlParam;
}

async function loginSofKyc(initialTransaction) {
  const body = {
    initial_transaction: initialTransaction,
    phonenumber: '+4915156889665',
    email: 'Name@gmail.com',
    firstname: 'John',
    lastname: 'Doe',
    address: 'Muinura 33(5',
    country: 'MEX',
    city: 'Ciudad de MΓ©xico',
    zipcode: 11650,
    birthday: '1984-07-07',
  };

  const response = await makeRequest(
    'POST',
    `${URL}/third-party-service/login-sof-kyc`,
    body,
    token,
  );

  token = response.data.token;

  return token;
}

async function uploadDocument(token, docPath, docType) {
  try {
    const url = `${URL}/third-party-service/kyc/upload-document`;

    const formData = new FormData();

    formData.append('doc', await fs.createReadStream(docPath), {
      filename: docPath.split('/').pop(),
    });

    formData.append('docType', docType);

    const config = {
      method: 'PUT',
      url: url,
      headers: {
        ...formData.getHeaders(),
        Authorization: `Bearer ${token}`,
        'api-key': API_KEY,
        'api-secret': API_SECRET,
      },
      data: formData,
    };

    console.log('upload document docType:', docType);

    const response = await axios(config);

    return response.data;
  } catch (error) {
    console.error(
      `Failed to update document: ${error?.response?.data?.message} `,
    );
    throw error?.response?.data?.message ?? error.message;
  }
}

async function paymentMethod(initTransaction) {
  const body = {
    initial_transaction: initTransaction,
    phonenumber: '+4915100089665',
    email: 'Name@gmail.com',
    fullname: 'John Doe',
    address: 'Muinurax 35',
    country: 'MEX',
    city: 'Ciudad de MΓ©xico',
    countrywithdraw: COUNTRY_WITHDRAWAL,
  };

  const response = await makeRequest(
    'POST',
    `${URL}/third-party-service/payment-method`,
    body,
    token,
  );

  return response.data;
}

async function verificationPhone() {
  const body = {
    ref: userData.phoneNumber,
  };

  const data = await makeRequest(
    'POST',
    `${URL_CORE}/transacction/phone/withdrawl`,
    body,
    token,
  );

  return data;
}

async function submitTransaction(initTransaction, exchangeFactor) {
  const body = {
    amount: 10,
    withdrawlPhone: '+4915156889665',
    businessInitTx: initTransaction,
    BusinessTo: BUSINESS_TO,
    exchangeId: exchangeFactor,
    typeProcesor: METHOD_WITHDRAWAL,
  };

  const response = await makeRequest(
    'POST',
    `${URL}/third-party-service/submit-transaction`,
    body,
    token,
  );
  return response.data;
}

async function updateBankUser() {
  const body = {
    id: '323',
    bankName: 'Banco Ciudad',
    bankNumber: '020000110000520139425',
    bankAccountOwner: 'John',
    countryCode: 'ARG',
    DNI: '41586849',
    typeId: 'NONE',
  };

  const response = await makeRequest(
    'POST',
    `${URL}/third-party-service/update-bank`,
    body,
    token,
  );

  return response.data;
}

async function updateInvoice(invoice) {
  const body = {
    status: 'approved',
  };
  // change the status of the invoice only to 'approve'
  const response = await makeRequest(
    'PUT',
    `${URL}/third-party-service/invoice/${invoice}`,
    body,
    token,
  );

  return response.data;
}

async function getInvoice(invoice) {
  const response = await makeRequest(
    'GET',
    `${URL}/third-party-service/invoice/${invoice}`,
  );

  return response.data;
}

async function main() {
  try {
    const initTransaction = await getInitTransaction();
    console.log('Init Transaction:', initTransaction);

    const loginSofKycResult = await loginSofKyc(initTransaction);
    console.log('Login Sof Kyc:', loginSofKycResult);

    const paymentMethodResult = await paymentMethod(initTransaction);
    console.log('Payment Method Result:', paymentMethodResult);

    const uploadDocuments = Object.keys(files).map((docType) =>
      uploadDocument(token, files[docType], docType),
    );

    await Promise.all(uploadDocuments);

    if (METHOD_WITHDRAWAL === 'ATM') {
      await verificationPhone(initTransaction);
    }

    const submitTransactionResult = await submitTransaction(
      initTransaction,
      paymentMethodResult?.exchangeFactor?.id,
    );
    console.log('Submit Transaction Result:', submitTransactionResult);

    const updateBank = await updateBankUser();
    console.log('updateBank', updateBank);

    const updateInvoiceUser = await updateInvoice(
      submitTransactionResult?.invoice?.id,
    );
    console.log('updateInvoiceUser', updateInvoiceUser);

    const invoice = await getInvoice(submitTransactionResult?.invoice?.id);
    console.log('Invoice', invoice);
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

main();

Download Example Script zip here:

Last updated