# Example Workflow Execution

## 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.

```env
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.\ <br>

#### 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:

{% file src="<https://348635407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSQ8Njhm6SXdA2eVQZrJM%2Fuploads%2F3VGVg65Bps58RTqbJl4P%2FArchive%20Script.zip?alt=media&token=48d3ab2f-0c09-4901-8989-ffee0839fd9b>" %}
