> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://developer.americanexpress.ferndocs.com/open-banking/confirmation-of-funds/guide/data-apis-mac-generation/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.americanexpress.ferndocs.com/_mcp/server. # Data APIs MAC Generation ### Confirmation of Funds API MAC Generation ##### MAC Generation Steps Follow these steps to generate the MAC: 1. The HMAC SHA256 algorithm must be used. 2. The base string should be constructed using the following parameters in the listed order with each followed by a newline "`\n`" character (%x0A): * `ts` (timestamp in Unix Epoch format) * `nonce` * `httpMethod` * `resourcePath` (URL Encoded(UTF\_8\_ENC)) * `host` * `port` * `\n` (one extra character (%x0A)) 3. Use `mac_key` as the key (available from the response of the OAuth Get Access Token call). 4. Base-64 encode the output of the raw data. ##### Sample Code to Generate the Confirmation of Funds APIs MAC ``` import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URLEncoder; import java.util.*; public class DataAuthenticationHeaderGenerator{ private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256"; private static final String NONCE_SUFFIX = ":AMEX"; private static final String UTF_8_ENC = "UTF-8"; public static void main(String[] args) throws Exception{ String accessToken = "1e74169f-c7fe-4a68-b486-d3a00c933cff"; String macKey = "47d06261-e088-4829-bbcd-a07c6d9f22df"; String httpMethod = "POST"; String host = "openamex-qa.americanexpress.com"; String port = "443"; String resourcePath = "/servicing/v1/card_member/funds/confirmations"; String authorizationMacToken = generateAuthorizationMacToken(accessToken, macKey, httpMethod, host, port, resourcePath); System.out.println(authorizationMacToken); } public static String generateAuthorizationMacToken(String accessToken, String macKey, String httpMethod, String host, String port, String resourcePath) throws Exception{ String nonce = UUID.randomUUID().toString() + NONCE_SUFFIX; String timeInMillis = String.valueOf((System.currentTimeMillis())); StringBuilder baseStringBuilder = new StringBuilder(); baseStringBuilder.append(timeInMillis); baseStringBuilder.append("\n"); baseStringBuilder.append(nonce); baseStringBuilder.append("\n"); baseStringBuilder.append(httpMethod); baseStringBuilder.append("\n"); baseStringBuilder.append(URLEncoder.encode(resourcePath, UTF_8_ENC)); baseStringBuilder.append("\n"); baseStringBuilder.append(host); baseStringBuilder.append("\n"); baseStringBuilder.append(port); baseStringBuilder.append("\n"); baseStringBuilder.append("\n"); String baseString = baseStringBuilder.toString(); Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM); mac.init(new SecretKeySpec(macKey.getBytes(UTF_8_ENC), HMAC_SHA256_ALGORITHM)); String signatureStr = Base64.getEncoder().encodeToString(mac.doFinal(baseString.getBytes(UTF_8_ENC))); StringBuilder macTokenBuilder = new StringBuilder(); macTokenBuilder.append("MAC id=\""); macTokenBuilder.append(accessToken); macTokenBuilder.append("\",ts=\""); macTokenBuilder.append(timeInMillis); macTokenBuilder.append("\",nonce=\""); macTokenBuilder.append(nonce); macTokenBuilder.append("\",mac=\""); macTokenBuilder.append(signatureStr); macTokenBuilder.append("\""); return macTokenBuilder.toString(); } } ```