# Testing
source: https://developer.mastercard.com/consent-management/documentation/testing/index.md

## Prerequisites {#prerequisites}

Confirm the following before you send any requests:

* Your project is created and Sandbox credentials are available.
* Your client uses the Sandbox base URL: `https://sandbox.api.mastercard.com/openapis/consents` or `https://sandbox.api.mastercard.com/openapis/authentication`.
* OAuth 1.0a signing is configured correctly.

If you still need onboarding or credential setup, start with the [Quick Start Guide](https://developer.mastercard.com/consent-management/documentation/quick-start-guide/index.md).

### Validation Checklist {#validation-checklist}

Use this checklist after each test cycle:

* Confirm successful `POST /consents` and validate `cardReference` or `consentToken` values.
* Confirm authentication status transitions as expected for challenge and frictionless flows.
* Confirm retrieval and deletion endpoints return expected results for valid and invalid references.
* Confirm negative tests return expected HTTP and reason codes.

Note: The user consent endpoint is currently in an exploratory phase, intended for testing purposes, and we welcome feedback. Note: The bulk card consent endpoints (`POST /cards/bulk` and `POST /cards/bulk-revokes`) are not available in Sandbox and are intentionally excluded from the standard Sandbox validation workflow.

## Testing Workflow {#testing-workflow}

Follow this ordered checklist to validate your integration end-to-end.

| # |                            Test                            |                      Endpoint                       |                                                                                                                                     What to Verify                                                                                                                                      |
|---|------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | **Create Consent** (Card-based)                            | `POST /consents`                                    | Send card details with consent name. Confirm HTTP 200 and response contains `cardReference` and `auth` object with authentication type and status. See [Test Data](https://developer.mastercard.com/consent-management/documentation/testing/index.md#test-data) for test card details. |
| 2 | **Start 3DS Authentication**                               | `POST /consents/{card_ref}/start-authentication`    | Send authentication parameters. Confirm HTTP 200 and response contains an `auth` object. For challenge flows, expect `auth.status` = `AUTH_IN_PROGRESS` and challenge params. For frictionless flows, `auth.status` may already be `AUTHENTICATED`.                                     |
| 3 | **Verify Authentication** (challenge flow only)            | `POST /consents/{card_ref}/verify-authentication`   | Call this after the issuer challenge completes. Confirm HTTP 200 and response contains `auth.status` = `AUTHENTICATED`. Consent status should update to `APPROVED`.                                                                                                                     |
| 4 | **Get Consents**                                           | `GET /consents/{card_ref}`                          | Retrieve all consents for the card. Confirm HTTP 200 and response contains a `consents` array. After successful authentication, the relevant consent should have status `APPROVED`.                                                                                                     |
| 5 | **Delete Specific Consent**                                | `DELETE /consents/{card_ref}/consents/{consent_id}` | Delete individual consent. Confirm HTTP 200 response with empty body.                                                                                                                                                                                                                   |
| 6 | **Create Geo-level Enrollment or User Consent** (Optional) | `POST /consents`                                    | Send `userDetails` such as `fullName`, `postalCode`, and identities instead of card details. Confirm HTTP 200 and response contains `consentToken`, `auth` = `null`, and an approved consent in the `consents` array.                                                                   |
| 7 | **Delete All Consents**                                    | `DELETE /consents/{card_ref}`                       | Delete all consents for a card. Confirm HTTP 200 response with empty body. A subsequent `GET /consents/{card_ref}` should return not found or reflect the revoked state.                                                                                                                |
| 8 | **Bulk Create Card Consents** (Production-only)            | `POST /cards/bulk`                                  | Not available in Sandbox. This endpoint is intentionally excluded from the reference app and standard Sandbox validation workflow.                                                                                                                                                      |
| 9 | **Bulk Revoke Card Consents** (Production-only)            | `POST /cards/bulk-revokes`                          | Not available in Sandbox. This endpoint is intentionally excluded from the reference app and standard Sandbox validation workflow.                                                                                                                                                      |

## Test Data {#test-data}

To test different scenarios in sandbox using consent UI or APIs, use the following test card details:

|                            Scenario                             |                                 Card Detail                                  |                                                 Description                                                 |  Auth Result  |
|-----------------------------------------------------------------|------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|---------------|
| Successful Pre Auth Check and 3DS Authentication with challenge | PAN: 2303779951000297 OTP: 123456 Expiry: 12/27 CVC:123 CardholderName: John | Card passes the Pre Auth Check and supports successful 3DS authentication with challenge.                   | AUTHENTICATED |
| Successful Pre Auth Check and frictionless 3DS Authentication   | PAN: 5204730541009999 Expiry: 12/27 CVC:123 CardholderName: frictionless     | Card passes the Pre Auth Check and supports successful 3DS authentication without challenge (frictionless). | AUTHENTICATED |
| Successful Pre Auth Check and 3DS not supported                 | PAN: 5555555555554444 Expiry: 12/27 CVC:123 CardholderName: John             | Card passes the Pre Auth Check but does not support 3DS authentication.                                     | AUTHENTICATED |
| Pre Auth Check failure (Stolen card)                            | PAN: 5555424242424242 Expiry: 12/27 CVC:123 CardholderName: John             | Card fails Pre Auth Check with stolen card error code.                                                      | AUTH_FAILED   |
| Successful Pre Auth Check but 3DS authentication failure        | PAN: 2303779951000248 Expiry: 12/27 CVC:123 CardholderName: John             | Card passes the Pre Auth Check check but fails the 3DS authentication.                                      | AUTH_FAILED   |

## Test Cases {#test-cases}

### Create Card Consent - Positive Example {#create-card-consent---positive-example}

`POST /consents`

```json
{
  "cardDetails": {
    "pan": "2303779951000297",
    "expiryMonth": 12,
    "expiryYear": 2027,
    "cvc": "123",
    "cardholderName": "John"
  },
  "consents": [
    {
      "name": "notification",
      "details": {}
    }
  ]
}
```

**Expected result:** `200 OK` with response containing `cardReference`, `auth.type` = `THREEDS`, `auth.status` = `AUTH_READY_TO_START`, and a consent entry in `REQAUTH` state.

### Create Card Consent - Negative Example (Invalid Card) {#create-card-consent---negative-example-invalid-card}

`POST /consents`

```json
{
  "cardDetails": {
    "pan": "invalid",
    "expiryMonth": 12,
    "expiryYear": 2027,
    "cvc": "123",
    "cardholderName": "John"
  },
  "consents": [
    {
      "name": "notification",
      "details": {}
    }
  ]
}
```

**Expected result:** `400 Bad Request` with error indicating invalid PAN format.

### Create User Consent - Positive Example {#create-user-consent---positive-example}

`POST /consents`

```json
{
  "userDetails": {
    "fullName": "Jane Doe",
    "postalCode": "12345",
    "identities": [
      {
        "type": "EMAIL",
        "value": "jane@example.com",
        "verified": false
      }
    ]
  },
  "consents": [
    {
      "name": "insights",
      "details": {}
    }
  ]
}
```

**Expected result:** `200 OK` with response containing `consentToken`, `auth` = `null`, and an `APPROVED` consent in the `consents` array.

### Start Authentication - Positive Example (Challenge Flow) {#start-authentication---positive-example-challenge-flow}

`POST /consents/{card_ref}/start-authentication`

```json
{
  "authenticationDetails": {
    "browserDetails": {
      "acceptHeader": "text/html",
      "userAgent": "Mozilla/5.0",
      "screenHeight": 1080,
      "screenWidth": 1920,
      "javaEnabled": false,
      "language": "en-US",
      "colorDepth": 24,
      "timeZone": -300
    }
  }
}
```

**Expected result:** `200 OK` with response containing `auth.status` = `AUTH_IN_PROGRESS` and challenge parameters including `acsUrl` and `creq`.

### Start Authentication - Negative Example (Invalid Card Reference) {#start-authentication---negative-example-invalid-card-reference}

`POST /consents/{card_ref}/start-authentication`

Use an invalid or non-existent `card_ref` value.

**Expected result:** `404 Not Found` with error indicating the card reference does not exist.

### Verify Authentication - Positive Example {#verify-authentication---positive-example}

`POST /consents/{card_ref}/verify-authentication`

```json
{
  "authenticationDetails": {
    "transactionId": "abc123-transaction-id"
  }
}
```

**Expected result:** `200 OK` with response containing `auth.status` = `AUTHENTICATED`. The associated consent status updates to `APPROVED`.

### Verify Authentication - Negative Example (Challenge Not Completed) {#verify-authentication---negative-example-challenge-not-completed}

`POST /consents/{card_ref}/verify-authentication`

Call this endpoint before the issuer challenge completes or with invalid transaction details.

**Expected result:** Error response indicating authentication verification failed, with `auth.status` = `AUTH_FAILED`.

### Get Consents - Positive Example {#get-consents---positive-example}

`GET /consents/{card_ref}`

Use a valid `card_ref` returned from a previous `POST /consents` call.

**Expected result:** `200 OK` with response containing a `consents` array. Each consent includes `id`, `name`, and `status`.

### Get Consents - Negative Example (Unknown Card Reference) {#get-consents---negative-example-unknown-card-reference}

`GET /consents/{card_ref}`

Use a non-existent `card_ref` value.

**Expected result:** `404 Not Found` with error indicating the card is unknown.

### Delete Specific Consent - Positive Example {#delete-specific-consent---positive-example}

`DELETE /consents/{card_ref}/consents/{consent_id}`

Use valid `card_ref` and `consent_id` values from a previously created consent.

**Expected result:** `200 OK` with empty response body. A subsequent `GET /consents/{card_ref}` no longer includes the deleted consent.

### Delete All Consents - Positive Example {#delete-all-consents---positive-example}

`DELETE /consents/{card_ref}`

Use a valid `card_ref` with one or more active consents.

**Expected result:** `200 OK` with empty response body.

### Delete Consents - Negative Example (Unknown Reference) {#delete-consents---negative-example-unknown-reference}

`DELETE /consents/{card_ref}`

Use a non-existent `card_ref` value.

**Expected result:** `404 Not Found` with error indicating the reference was not found.
Note: These endpoints are not available in Sandbox and are intentionally excluded from the reference app. The samples below are for production API reference only.

### Bulk Create Card Consents - Positive Example {#bulk-create-card-consents---positive-example}

`POST /cards/bulk`

```json
{
  "cards": [
    {
      "recId": "rec-001",
      "pan": "2303779951000297",
      "expiryMonth": 12,
      "expiryYear": 2027,
      "consent": {
        "name": "notification"
      }
    },
    {
      "recId": "rec-002",
      "pan": "5204730541009999",
      "expiryMonth": 12,
      "expiryYear": 2027,
      "consent": {
        "name": "notification"
      }
    }
  ]
}
```

**Expected result:** `200 OK` with response containing a list of cards. Each card includes `recId` and `cardReference`. For successfully enrolled cards, `cardReference` is populated. For cards not in a supported account range, `cardReference` is null and `errorCode`/`error` are set.

### Bulk Create Card Consents - Negative Example (Invalid Consent Details) {#bulk-create-card-consents---negative-example-invalid-consent-details}

`POST /cards/bulk`

```json
{
  "cards": [
    {
      "recId": "rec-001",
      "pan": "invalid",
      "expiryMonth": 13,
      "expiryYear": 2020
    }
  ]
}
```

**Expected result:** `400 Bad Request` with error indicating invalid consent details.

### Bulk Revoke Card Consents - Positive Example {#bulk-revoke-card-consents---positive-example}

`POST /cards/bulk-revokes`

```json
{
  "cardRefs": [
    "9ce4fd0d-0fdb-4367-9854-fb2c6fa66eb1",
    "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  ]
}
```

**Expected result:** `200 OK` with response containing the IDs of the revoked consents.

### Bulk Revoke Card Consents - Negative Example (Unknown Card Reference) {#bulk-revoke-card-consents---negative-example-unknown-card-reference}

`POST /cards/bulk-revokes`

```json
{
  "cardRefs": [
    "non-existent-card-reference"
  ]
}
```

**Expected result:** `404 Not Found` with error indicating an unknown consent reference.

## Troubleshooting {#troubleshooting}

For a full list of error codes and their meanings, see [Codes and Formats](https://developer.mastercard.com/consent-management/documentation/codes-and-formats/index.md).

### Authentication Errors (HTTP 401) {#authentication-errors-http-401}

The following are common causes of authentication errors:

* Consumer key does not match the one in your Mastercard Developers project.
* Signing key (.p12 file) password is incorrect or the file is corrupted.
* OAuth timestamp is too far from the server time (must be within 5 minutes).
* The request body was modified after the OAuth signature was computed.

<br />

To resolve this error, try the following:

1. Verify your consumer key matches the value on your Mastercard Developers project page.
2. Re-download your .p12 keystore file and confirm the password is correct.
3. Ensure your system clock is synchronized.
4. If using a custom HTTP client, ensure the OAuth signature is computed over the final request body.

### Bad Request Errors (HTTP 400) {#bad-request-errors-http-400}

The following are common causes of bad request errors:

* Missing or malformed JSON request body.
* Invalid card details (PAN, `expiryMonth`, `expiryYear`, CVC, or cardholder name missing or invalid).
* Invalid user details for user-based consent (for example, missing `postalCode` or malformed identity values).
* Missing required consent details in request.

<br />

To resolve this error, try the following:

1. Validate your JSON payload with a JSON linter.
2. For card-based consent, ensure all card details are present and valid, and match the API schema used by the reference apps.
3. For user-based consent, include `postalCode` and provide valid identities when sending email or phone values.
4. Ensure each consent object has a `name` field with a valid consent type (for example, "notification", "insights").

### 3DS Authentication Issues {#3ds-authentication-issues}

The following are common causes of 3DS authentication failures:

* Test card does not support 3DS authentication.
* Browser fingerprinting failed or parameters not captured correctly.
* Authentication challenge window closed without completion.
* `start-authentication` was called with incomplete or invalid auth parameters.

<br />

To resolve this issue, try the following:

1. Use a test card that supports 3DS (for example, `2303779951000297` for challenge or `5204730541009999` for frictionless). See [Test Data](https://developer.mastercard.com/consent-management/documentation/testing/index.md#test-data) for options.
2. Ensure browser fingerprinting is completed if `auth.type` is `THREEDS`.
3. If `start-authentication` returns `AUTHENTICATED`, treat the flow as frictionless and do not call `verify-authentication`.
4. If a challenge is required, call `POST /consents/{card_ref}/verify-authentication` only after the challenge flow completes.

### Invalid Card Reference or Consent Token {#invalid-card-reference-or-consent-token}

The following are common causes of invalid reference errors:

* Card reference or consent token is null, incorrect, or not owned by the caller.
* Request uses the wrong reference for the intended consent flow.
* Consent was already revoked or the consent ID does not exist.

<br />

To resolve this issue, try the following:

1. Verify the card reference or consent token was successfully returned from the create consent response.
2. For card-based consent, use the `cardReference` field; for user-based consent, use the `consentToken` field.
3. Use `GET /consents/{reference}` to verify the consent still exists before calling delete or update operations.

## Environment Guidance {#environment-guidance}

For environment URLs and descriptions, see [API Basics - Environments](https://developer.mastercard.com/consent-management/documentation/api-basics/index.md#environments).

* Start in sandbox and complete your positive and negative validation there.
* Move to production only after sandbox testing is complete and production access has been approved.

## Next Steps {#next-steps}

* Start with the [Quick Start Guide](https://developer.mastercard.com/consent-management/documentation/quick-start-guide/index.md) if you still need credentials or project setup.
* Use [Developer Tools](https://developer.mastercard.com/consent-management/documentation/developer-tools/index.md) if you want ready-to-run collections.
* Follow the endpoint tutorials when you are ready to run detailed positive and negative test cases.
