API Authentication Keys {#uctp_keys_api_keys}
=============================================

API authentication keys are credentials that are required to authenticate every server-to-server request to `Cybersource` APIs. They are used to construct the HTTP signature header that `Cybersource` validates before processing requests. You must use valid API authentication keys to retrieve a capture context JWT and start the SDK integration workflow.  
API authentication keys are made up of three credentials:

* `MERCHANT_ID`: Uniquely identifies the merchant account on `Cybersource`. You must include the `MERCHANT_ID` as the `v-c-merchant-id` HTTP header on every API request. Merchants must get the `MERCHANT_ID` from the `Cybersource` `Business Center` when their account is created.

* `API_KEY_ID`: Identifies which hash-based message authentication code (HMAC) key is used for HTTP signature authentication. You must include the `API_KEY_ID` as the `keyid` parameter in the `Signature` header. Merchants may have multiple API keys. `Cybersource` uses the `API_KEY_ID` to determine which key to use for signature verification.

* `API_SECRET_KEY`: The Base64-encoded HMAC shared secret that is paired with the `API_KEY_ID`. Used with the `HmacSHA256` algorithm to compute the HTTP Signature over specific request headers. This secret must never be logged, committed to source control, or sent to the client.  
  These credentials are configured under Payment Configuration \&gt; Key Management in the `Cybersource` `Business Center`:

* Test URL: ` `<https://businesscentertest.cybersource.com/ebc2>` `

* Production URL: ` `<https://businesscenter.cybersource.com>` `
  If you are unable to access this page, contact your sales representative.

> IMPORTANT You must store these credentials on the server side in environment variables or a secrets manager. Do not hard-code the credentials in source files, embed them in client bundles, or expose them in API responses. If the credentials get exposed, an attacker could make authenticated API calls on the merchant's behalf.

JavaScript Example: HTTP Signature Authentication
-------------------------------------------------

```
const crypto = require('crypto');

function generateSignatureHeaders(method, resourcePath, body) {
  const date = new Date().toUTCString();
  const digest = body
    ? 'SHA-256=' + crypto.createHash('sha256').update(body).digest('base64')
    : null;

  const headers = ['host', 'date', '(request-target)'];
  const signingParts = [
    `host: ${API_HOST}`,
    `date: ${date}`,
    `(request-target): ${method.toLowerCase()} ${resourcePath}`
  ];

  if (body) {
    headers.push('digest', 'v-c-merchant-id');
    signingParts.push(`digest: ${digest}`, `v-c-merchant-id: ${MERCHANT_ID}`);
  } else {
    headers.push('v-c-merchant-id');
    signingParts.push(`v-c-merchant-id: ${MERCHANT_ID}`);
  }

  const signature = crypto
    .createHmac('sha256', Buffer.from(API_SECRET_KEY, 'base64'))
    .update(signingParts.join('\n'))
    .digest('base64');

  return {
    host: API_HOST,
    date: date,
    'v-c-merchant-id': MERCHANT_ID,
    signature: `keyid="${API_KEY_ID}", algorithm="HmacSHA256", headers="${headers.join(' ')}", signature="${signature}"`,
    'Content-Type': 'application/json',
    ...(digest ? { digest } : {})
  };
}

// Make the capture context request
const headers = generateSignatureHeaders('POST', '/uctp/v1/sessions', requestBody);
```

