mirror of
https://github.com/Sea-Haven-Industries/payments-dashboard.git
synced 2026-10-07 06:59:02 +00:00
Add OAuth token exchange to BoA sandbox test script
Use correct sandbox base URL (api-sb.bofa.com), proper OAuth client-credentials flow with applicationID, and routing number for transaction inquiries. Both APIs now return 200 in sandbox.
This commit is contained in:
parent
a9ad5f7dd1
commit
957fb726ab
1 changed files with 81 additions and 15 deletions
|
|
@ -1,8 +1,11 @@
|
||||||
/**
|
/**
|
||||||
* One-off script to test BoA CashPro sandbox API connectivity.
|
* One-off script to test BoA CashPro sandbox API connectivity.
|
||||||
* Reads credentials from SSM Parameter Store (same params as production),
|
* Reads credentials from SSM Parameter Store, exchanges them for
|
||||||
* makes test API calls, and prints the full responses so you can capture
|
* OAuth Bearer tokens, then makes test API calls to both Check
|
||||||
* the client ID, timestamp, and transactionIdentification for BoA onboarding.
|
* Management and Reporting APIs.
|
||||||
|
*
|
||||||
|
* Prints full responses so you can capture the client ID, timestamp,
|
||||||
|
* and transactionIdentification for BoA production onboarding.
|
||||||
*
|
*
|
||||||
* Usage:
|
* Usage:
|
||||||
* node scripts/test-boa-sandbox.js
|
* node scripts/test-boa-sandbox.js
|
||||||
|
|
@ -11,7 +14,8 @@
|
||||||
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
|
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
|
||||||
|
|
||||||
const ssm = new SSMClient();
|
const ssm = new SSMClient();
|
||||||
const BOA_BASE_URL = "https://developer.bankofamerica.com";
|
const SANDBOX_BASE = "https://api-sb.bofa.com";
|
||||||
|
const AUTH_URL = `${SANDBOX_BASE}/authn/v1/client-authentication`;
|
||||||
|
|
||||||
async function getSSMParam(name) {
|
async function getSSMParam(name) {
|
||||||
const { Parameter } = await ssm.send(
|
const { Parameter } = await ssm.send(
|
||||||
|
|
@ -20,31 +24,88 @@ async function getSSMParam(name) {
|
||||||
return Parameter.Value;
|
return Parameter.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAccessToken(applicationID, clientId, clientSecret) {
|
||||||
|
console.log(` Requesting token for ${applicationID}...`);
|
||||||
|
|
||||||
|
const res = await fetch(AUTH_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
applicationID,
|
||||||
|
authn: {
|
||||||
|
client_id: clientId,
|
||||||
|
client_secret: clientSecret,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const text = await res.text();
|
||||||
|
console.log(` Auth response (${res.status}):`, text, "\n");
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error(`Auth failed for ${applicationID}: ${res.status} - ${text}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = JSON.parse(text);
|
||||||
|
return data.access_token;
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log("Loading credentials from SSM...\n");
|
console.log("Loading credentials from SSM...\n");
|
||||||
|
|
||||||
const [checkMgmtToken, accountInfoToken, accountNumber, companyId] = await Promise.all([
|
const [
|
||||||
|
checkMgmtClientId,
|
||||||
|
checkMgmtSecret,
|
||||||
|
accountInfoClientId,
|
||||||
|
accountInfoSecret,
|
||||||
|
accountNumber,
|
||||||
|
companyId,
|
||||||
|
] = await Promise.all([
|
||||||
|
getSSMParam("/payments-dashboard/boa-check-mgmt-client-id"),
|
||||||
getSSMParam("/payments-dashboard/boa-check-mgmt-token"),
|
getSSMParam("/payments-dashboard/boa-check-mgmt-token"),
|
||||||
|
getSSMParam("/payments-dashboard/boa-account-info-client-id"),
|
||||||
getSSMParam("/payments-dashboard/boa-account-info-token"),
|
getSSMParam("/payments-dashboard/boa-account-info-token"),
|
||||||
getSSMParam("/payments-dashboard/boa-account-number"),
|
getSSMParam("/payments-dashboard/boa-account-number"),
|
||||||
getSSMParam("/payments-dashboard/boa-company-id"),
|
getSSMParam("/payments-dashboard/boa-company-id"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
console.log("Credentials loaded. Testing sandbox endpoints...\n");
|
console.log("Credentials loaded.\n");
|
||||||
|
|
||||||
// --- Test 1: Check Issue (add_issue with a test check) ---
|
// --- Step 1: Get OAuth tokens for both APIs ---
|
||||||
console.log("=".repeat(60));
|
console.log("=".repeat(60));
|
||||||
console.log("TEST 1: Check Issue (add_issue)");
|
console.log("STEP 1: OAuth Token Exchange");
|
||||||
|
console.log("=".repeat(60));
|
||||||
|
|
||||||
|
console.log("\n[Check Management]");
|
||||||
|
const checkMgmtBearerToken = await getAccessToken(
|
||||||
|
"app_SeaHavenIndustries_Checkmanagement_SB",
|
||||||
|
checkMgmtClientId,
|
||||||
|
checkMgmtSecret
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("[Account Info / Reporting]");
|
||||||
|
const accountInfoBearerToken = await getAccessToken(
|
||||||
|
"app_SeaHavenIndustries_Reporting_SB",
|
||||||
|
accountInfoClientId,
|
||||||
|
accountInfoSecret
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Both tokens acquired.\n");
|
||||||
|
|
||||||
|
// --- Step 2: Check Issue (add_Issue with a test check) ---
|
||||||
|
console.log("=".repeat(60));
|
||||||
|
console.log("TEST 1: Check Issue (add_Issue)");
|
||||||
console.log("=".repeat(60));
|
console.log("=".repeat(60));
|
||||||
|
|
||||||
const issuePayload = {
|
const issuePayload = {
|
||||||
issueList: [
|
issueList: [
|
||||||
{
|
{
|
||||||
accountNumber,
|
accountNumber,
|
||||||
|
issueAction: "add_Issue",
|
||||||
checkNumber: "999999",
|
checkNumber: "999999",
|
||||||
amount: "1.00",
|
amount: "1.00",
|
||||||
issueAction: "add_issue",
|
|
||||||
issueDate: new Date().toISOString().split("T")[0],
|
issueDate: new Date().toISOString().split("T")[0],
|
||||||
|
payee: "Sandbox Test",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
@ -53,12 +114,12 @@ async function main() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const issueRes = await fetch(
|
const issueRes = await fetch(
|
||||||
`${BOA_BASE_URL}/cashpro/checkmanagement/v1/check-issues`,
|
`${SANDBOX_BASE}/cashpro/checkmanagement/v1/check-issues`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: `Bearer ${checkMgmtToken}`,
|
Authorization: `Bearer ${checkMgmtBearerToken}`,
|
||||||
companyId,
|
companyId,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(issuePayload),
|
body: JSON.stringify(issuePayload),
|
||||||
|
|
@ -75,7 +136,7 @@ async function main() {
|
||||||
console.error("Check Issue request failed:", err.message);
|
console.error("Check Issue request failed:", err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Test 2: Previous Day Transaction Inquiry ---
|
// --- Step 3: Previous Day Transaction Inquiry ---
|
||||||
console.log("\n" + "=".repeat(60));
|
console.log("\n" + "=".repeat(60));
|
||||||
console.log("TEST 2: Previous Day Transaction Inquiry");
|
console.log("TEST 2: Previous Day Transaction Inquiry");
|
||||||
console.log("=".repeat(60));
|
console.log("=".repeat(60));
|
||||||
|
|
@ -85,21 +146,26 @@ async function main() {
|
||||||
const dateStr = yesterday.toISOString().split("T")[0];
|
const dateStr = yesterday.toISOString().split("T")[0];
|
||||||
|
|
||||||
const inquiryPayload = {
|
const inquiryPayload = {
|
||||||
accounts: [{ accountNumber, bankId: "BOFAFRPP" }],
|
|
||||||
fromDate: dateStr,
|
fromDate: dateStr,
|
||||||
toDate: dateStr,
|
toDate: dateStr,
|
||||||
|
accounts: [
|
||||||
|
{
|
||||||
|
accountNumber,
|
||||||
|
bankId: "021000322",
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Request:", JSON.stringify(inquiryPayload, null, 2), "\n");
|
console.log("Request:", JSON.stringify(inquiryPayload, null, 2), "\n");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const inquiryRes = await fetch(
|
const inquiryRes = await fetch(
|
||||||
`${BOA_BASE_URL}/cashpro/reporting/v1/transaction-inquiries/previous-day`,
|
`${SANDBOX_BASE}/cashpro/reporting/v1/transaction-inquiries/previous-day`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: `Bearer ${accountInfoToken}`,
|
Authorization: `Bearer ${accountInfoBearerToken}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(inquiryPayload),
|
body: JSON.stringify(inquiryPayload),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue