Beneficiaries Guide
This beneficiaries guide assumes that you have already completed the TheM>Getting Started>Quick Start guide and are familiar with TheM class, TheM submodule initialization, and creating/listening for custom events. This guide also assumes that you have already installed the amplifi_mobile_sdk package into your project and placed the following minified libraries in the /lib folder of your project: axios.min.js (Optional - fetch will be used if axios is not present), crypto-js.min.js, lz-string.min.js, moment.min.js, and socket.io.min.js. In addition, you should have completed the Onboarding Guide tutorial in order to create and onboard a user which can be logged into your ampliFi instance.
1. In the src folder of your project (from the Quick Start guide of the TheM Getting Started section), create a new file called beneficiaries.js
with the following code.
beneficiaries.js
import ClassTheM from "../node_modules/@PayGearsCorp/amplifi_mobile_sdk/TheM/them.mjs";
import { thisDevice } from "./android-demo-device.js"; //android device emulator for testing
const AMPLIFI_BASE_URL = "PUT_YOUR_INSTANCE_URL_HERE"; //Speak to a support representative to be issued a sandbox instance URL
const AMPLIFI_CORE_URL = `${AMPLIFI_BASE_URL}core/`;
const DEVICE_TAG = "PUT_YOUR_DEVICE_TAG_HERE"; //Use deviceTag obtained from onboarding tutorial for this device
const subClassesToInit = [
"accounts",
"beneficiaries",
"cards",
//"cheques",
"common",
//"externalAccounts",
//"fdrs",
//"fundstransfer",
//"fxrates",
//"genericRequests",
//"ious",
//"onboarding",
//"payees",
//"remittance",
//"restrictions",
//"statics",
"user"
];
export const beneficiariesTutorial = async (subClasses = "") => {
TheM = new ClassTheM({
config: {
AFiInstanceId: "test",
modulesFolder: "",
modulesFolderOnboarding: "",
webworkerFolder: "../TheM/",
baseLibURL: "../demo/lib/",
backEndURL: AMPLIFI_CORE_URL,
socketURL: AMPLIFI_BASE_URL,
},
libs: {
}
});
//Emulate user device before initializing TheM submodules
TheM.thisDevice = {
...thisDevice,
TheM,
deviceTag: DEVICE_TAG,
};
//Initialize desired submodules
//Some modules depend on others so must be initialized together
//For instance, most submodules require the "common" subclass to be initialized
await TheM.doInit(subClasses);
//beneficiaries workflow to try
//Uncomment to run the whole workflow or follow the instructions in the browser
/*
//Prepare for logging in
//Log in using the instructions in the browser or use the doAuthenticate method from the device emulator we created during onboarding
await TheM.thisDevice.doAuthenticate(DEVICE_TAG);
//Pull beneficiaries data from the server if it is not fresh enough
await TheM.beneficiaries.doUpdate();
console.log(`TheM.beneficiaries.isReady: ${JSON.stringify(TheM.beneficiaries.isReady)}`)
const newACHBeneficiary = TheM.beneficiaries.newTempBeneficiary("USA", {
txnType: "USA",
name: "ACH Payee",
accountNumber: "1234567890123456",
bankName: "Citibank NA",
destinationName: "Receiving account title",
routingNumber: "123456789",
defaultAmount: 20,
narrativeDebit: "ACH payment",
isFavourite: true,
type: "CHECKING"
});
await newACHBeneficiary.doSubmit({});
const newWireBeneficiary = TheM.beneficiaries.newTempBeneficiary("USA_wire", {
txnType: "USA_wire",
name: "Wire Payee",
accountNumber: "1234567890123456",
bankName: "Citibank NA",
destinationName: "Receiving account title",
routingNumber: "123456789",
defaultAmount: 20,
narrativeDebit: "Wire payment",
isFavourite: true,
type: "CHECKING",
address: {
addressLine1: '123 Main Str.',
addressLine2: 'Suite 456',
city: 'Harrisburg',
province: 'PA',
state: 'PA',
postalCode: '12345',
countryCode: 'US'
}
});
await newWireBeneficiary.doSubmit({});
const newPayPalBeneficiary = TheM.beneficiaries.newTempBeneficiary("paypal", {
txnType: "paypal",
name: "PayPal Payee",
paypalId: "paypalname@email.test",
defaultAmount: 20,
narrativeDebit: "PayPal payment",
isFavourite: true
});
await newPayPalBeneficiary.doSubmit({});
const newCheckBeneficiary = TheM.beneficiaries.newTempBeneficiary("cheque", {
txnType: "cheque",
name: "Check Payee",
legalName: "John Doe",
defaultAmount: 20,
narrativeDebit: "Check payment",
isFavourite: true,
address: {
addressLine1: '123 Main Str.',
addressLine2: 'Suite 456',
city: 'Harrisburg',
province: 'PA',
state: 'PA',
postalCode: '12345'
}
});
await newCheckBeneficiary.doSubmit({});
const newCardBeneficiary = TheM.beneficiaries.newTempBeneficiary("tocard", {
txnType: "tocard",
name: "To Card Payee",
destinationPAN: "1234567890123456",
cvv: "123",
expiryMM: "10",
expiryYY: "26",
destinationFirstName: "John",
destinationLastName: "Doe",
mobile: "5556667777",
defaultAmount: 20,
narrativeDebit: "Card payment",
isFavourite: true,
type: "CHECKING",
address: {
addressLine1: '123 Main Str.',
addressLine2: 'Suite 456',
city: 'Harrisburg',
province: 'PA',
state: 'PA',
postalCode: '12345',
countryCode: 'US'
}
});
await newCardBeneficiary.doSubmit({});
console.log(`Beneficiaries with txnType 'USA_wire': ${JSON.stringify(TheM.beneficiaries.forTxnTypes("USA_wire"))}`);
console.log(`All active beneficiaries: ${JSON.stringify(TheM.beneficiaries.allActive)}`);
console.log(`A filtered list of beneficiaries where status is 'Pending': ${JSON.stringify(TheM.beneficiaries.filtered({ status: "Pending" }))}`);
//Modify the AFiPayeeId property for the most recently added beneficiary
TheM.beneficiaries[TheM.beneficiaries.length-1].AFiPayeeId = TheM.beneficiaries[TheM.beneficiaries.length-1].AFiBeneficiaryId;
//Make a payment to the first beneficiary in the beneficiaries array
await TheM.beneficiaries[0].doPay({amount: 20, currency: "USD", narrativeDebit: "payment"});
//Delete the most recently added beneficiary. Marks the beneficiary as isActive=false and sends the request to the server
await TheM.beneficiaries[TheM.beneficiaries.length-1].doDelete();
//Logout when finished
//await TheM.user.doLogout();
*/
};
await beneficiariesTutorial(subClassesToInit.join(" "));
2. The beneficiaries module expects the user to be using some type of device so make sure the android-demo-device.js file used during onboarding is still in your /src folder.
3. Create a new file in the /demo folder of your project called beneficiaries.html with the following code.
beneficiaries.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<title>ampliFi</title>
<script>
var TheM;
var TheM_config;
</script>
<script src="../lib/socket.io.min.js"></script>
<script src="../lib/lz-string.min.js"></script>
<script src="../lib/moment.min.js"></script>
<script src="../lib/axios.min.js"></script>
<script src="../lib/crypto-js.min.js"></script>
<script type="module" src="/../src/beneficiaries.js"></script>
<style>
html {
color: white;
background-color: black;
}
</style>
</head>
<body>
<div>
Hit F12 to open the browser console.
Start working with TheM by typing "TheM" into the browser console.
</div>
<br />
<br />
<div>
1. In order to log a user in, we will need to prepare the user credentials using the encryptedServerSecret
stored locally during onboarding. Type the following to retrieve the encryptedServerSecret. (Or skip steps 1-5
by using the doAuthenticate method in the device emulator like so, `await
TheM.thisDevice.doAuthenticate(DEVICE_TAG);`.)
<br /><br />
<code>let { encryptedServerSecret } = await TheM.thisDevice.retrieveLocally("encryptedServerSecret", true);</code>
<br /><br />
Type <code>encryptedServerSecret</code> into the browser console and hit enter to view the encryptedServerSecret
value.
<br /><br />
2. Since we are using an emulated android device to log in, we need to get the cryptotext value like so.
<br /><br />
<code>
let _SUPER_SECRET = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";<br />
let _dtsValueString = (new Date()).valueOf().toString();<br />
let serverSecret = CryptoJS.AES.decrypt(encryptedServerSecret, _SUPER_SECRET).toString(CryptoJS.enc.Utf8);<br />
let cryptotext = CryptoJS.AES.encrypt((TheM.thisDevice.deviceTag) + _dtsValueString, serverSecret).toString();
</code>
<br /><br />
3. Set a socket connection for bidirectional communication.
<br /><br />
<pre><code>TheM.thisDevice.halfRef = TheM.common.GetRandomSTR(40);<br />let manager = new TheM.io.Manager(TheM.config.socketURL + "?halfRef=" + TheM.thisDevice.halfRef, {<br /> autoConnect: false<br />});<br />let socket = manager.socket("/");</code></pre>
<br />
4. Open the socket connection.
<br /><br />
<pre><code>manager.connect(function (data) {<br /> console.log("established real-time comm channel for onboarding");<br /> TheM.thisDevice.isRealTimeCommAvailable = true;<br />});</code></pre>
<br />
5. Log the user in using the deviceTag obtained during onboarding and the newly created cryptotext.
<br /><br />
<pre><code>const credentials = {<br /> "dtsValueString": _dtsValueString,<br /> "deviceTag": "PUT_DEVICE_TAG_HERE",<br /> "deviceData": TheM.thisDevice.data,<br /> "channel": TheM.thisDevice.platform,<br /> "dynamicScreensVersion": TheM.thisDevice.dynamicScreensVersion,<br /> "socket": {<br /> halfRef: TheM.thisDevice.halfRef<br /> },<br /> "pushMessToken": TheM.thisDevice.pushMessToken,<br /> "cryptotext": cryptotext<br />};<br />await TheM.user.doLogin(credentials);</code></pre>
<br />
6. After authentication, the locally stored data should be automatically loaded. You can check to see if the
beneficiaries submodule is fully ready like so.
<br /><br />
<code>
TheM.beneficiaries.isReady;
</code>
<br /><br />
7. Pull beneficiaries data from the server if it is not fresh enough.
<br /><br />
<code>await TheM.beneficiaries.doUpdate();</code>
<br /><br />
8. You can create a new beneficiary using a TheM.benficiaries.newTempBeneficiary(givenTxnType, given) call where
givenTxnType is the beneficiary transaction type and given is an object containing all required beneficiary
properties for the specified transaction type.
<br />
<pre><code>const newACHBeneficiary = TheM.beneficiaries.newTempBeneficiary("USA", {<br /> txnType: "USA",<br /> name: "ACH Payee",<br /> accountNumber: "1234567890123456",<br /> bankName: "Citibank NA",<br /> destinationName: "Receiving account title",<br /> routingNumber: "123456789",<br /> defaultAmount: 20,<br /> narrativeDebit: "ACH payment",<br /> isFavourite: true,<br /> type: "CHECKING"<br />});<br />await newACHBeneficiary.doSubmit({});</code></pre>
<br />
9. You can modify a property of the beneficiary that was just added (such as the AFiPayeeId) like this.
<br /><br />
<code>TheM.beneficiaries[TheM.beneficiaries.length-1].AFiPayeeId = TheM.beneficiaries[TheM.beneficiaries.length-1].AFiBeneficiaryId;</code>
<br /><br />
10. Make a payment to the beneficiary that was just added.
<br /><br />
<code>await TheM.beneficiaries[TheM.beneficiaries.length-1].doPay({amount: 20, currency: "USD", narrativeDebit: "payment"});</code>
<br /><br />
11. Delete the recently added beneficiary like this.
<br /><br />
<code>
await TheM.beneficiaries[TheM.beneficiaries.length-1].doDelete();
</code>
<br /><br />
12. Keep exploring TheM.beneficiaries properties and methods and log out when finished.
<br /><br />
<code>
await TheM.user.doLogout();
</code>
<br /><br />
</div>
</body>
</html>
4. Start a server in the root folder of your project.
5. Open a browser and enter the following URL: http://localhost:8000/demo/
6. Click on the link for "beneficiaries.html" and follow the instructions to log in, add a new beneficiary, make a payment, delete a beneficiary, and log out.