# Testing
source: https://developer.mastercard.com/presentment/documentation/testing/index.md

## Overview {#overview}

Use this page to plan and execute Sandbox validation for the Offers for Publishers API. It covers the recommended workflow and coverage for positive and negative testing.
Tip: Start all validation in Sandbox before moving to Production.

## Choose a testing method {#choose-a-testing-method}

Choose a testing method that best matches how you want to validate requests:

* [Reference Application](https://developer.mastercard.com/presentment/documentation/developer-tools/reference-application/index.md)
* [Postman Collection](https://developer.mastercard.com/presentment/documentation/developer-tools/postman-collection/index.md)
* [Insomnia Collection](https://developer.mastercard.com/presentment/documentation/developer-tools/insomnia-collection/index.md)

## Presentment {#presentment}

### Positive testing {#positive-testing}

Positive testing confirms that valid requests succeed and return the expected data.

#### Validate these behaviors {#validate-these-behaviors}

* Valid request bodies return success codes such as `200 OK`.
* Authentication requests return a valid access token.
* Offer requests return assigned offer data.
* Offer detail requests return complete offer information.
* Offer activation requests return a successful activation result.
* Savings requests return accumulated cardholder savings data.
* Reward requests return cardholder reward or rebate data.

#### Testing workflow {#testing-workflow}

Use this sequence to validate endpoints for the Presentment API:

1. Generate an access token
2. Retrieve offers
3. Retrieve offer details
4. Activate offer
5. Retrieve savings
6. Retrieve rewards
7. Platform offers
8. Platform adjustments

#### Positive test cases {#positive-test-cases}

Use the tabs to view positive test cases.
Generate an access token


`POST /loyalty/offers/presentment/access-tokens`

```json
{
"fiId": "999999",
"userId": "1PCLOSANDBOXBCN00002tra6athatR",
"utcOffset": "-07:00"
}
```

Expected result: `200 OK` and a response body containing the access token
Retrieve offers


`GET /loyalty/offers/presentment/offers`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>",
      "Accept-Language": "en-US"
    },
    "query_params": {
      "offset": "0",
      "limit": "25"
    }
}
}    
```

* Dependency: `X-Auth-Token` returned by the access token resource
* Expected result: `200 OK` and a response containing a list of offers assigned based on a cardholder's spend history, each accompanied by relevant content, such as marketing materials, terms and conditions, logos, images, and translations. Offers are displayed in descending order of propensity score, showing those with the highest potential for redemption at the top.
Retrieve offer details


`GET /loyalty/offers/presentment/offers/{offer_id}`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>",
      "Accept-Language": "en-US"
    }
  }
}  
```

* Dependency: `X-Auth-Token` returned by the access token resource and `offer_id` which represents the system-wide identifier for the offer campaign
* Expected result: `200 OK` and a response containing details for the requested offer with information such as category, associated merchant, and merchant location
Activate offer


`POST /loyalty/offers/presentment/activations`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>",
      "Content-Type": "application/json"
    },
    "body": {
      "offerId": "d82e1e7c-c6b9-3b46-acd0-5498731c2838"
    }
  }
}
```

* Dependency: `X-Auth-Token` returned by the access token resource and `offer_id` which represents the system-wide identifier for the offer campaign
* Expected result: `200 OK` and a response containing a confirmation of the offer activation
Retrieve savings


`GET /loyalty/offers/presentment/savings`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>"
    }
  }
}
```

* Dependency: `X-Auth-Token` returned by the access token resource
* Expected result: `200 OK` and a response containing savings information accumulated throughout the cardholder's participation in the program
Retrieve rewards


`GET /loyalty/offers/presentment/adjustments`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>"
    },
    "query_params": {
      "offset": "0",
      "limit": "25"
    }
  }
}
```

* Dependency: `X-Auth-Token` returned by the access token resource
* Expected result: `200 OK` and a response containing reward data
Platform offers


`GET /loyalty/offers/presentment/platforms/offers`

```json
{
  "request": {
    "query_params": {
      "fid": "999999",
      "offset": "0",
      "limit": "25"
    }
  },
}
```

* Dependency: `fid` (Financial Institution Identifier), provided by Mastercard during the implementation process
* Expected result: `200 OK` and a list of platform offers based on the specified criteria
Platform adjustments


`GET /loyalty/offers/presentment/platforms/adjustments`

```json
{
  "request": {
    "query_params": {
      "fid": "999999",
      "offset": "0",
      "limit": "25"
    }
  },
}
```

* Dependency: `fid` (Financial Institution Identifier), provided by Mastercard during the implementation process
* Expected result: `200 OK` and a response containing rewards data

### Negative testing {#negative-testing}

Negative testing confirms that invalid requests fail cleanly and return useful error details.

#### Validate these behaviors {#validate-these-behaviors-1}

* Missing required fields return error codes such as `400 BAD_REQUEST`, `401 UNAUTHORIZED`, or `404 NOT_FOUND`.
* Invalid field values return validation errors with a clear `ReasonCode` and description.
* Requests for unknown resources return `404 NOT_FOUND`.
* Incorrect or missing authentication data is rejected.
* Encrypted endpoints reject malformed or unencrypted payloads when encryption is required.

#### Negative test cases {#negative-test-cases}

Generate an access token


`POST /loyalty/offers/presentment/access-tokens`

```json
{
"userId": "1PCLOSANDBOXBCN00002tra6athatR",
"utcOffset": "-07:00"
}
```

Expected result: `400 BAD_REQUEST` because the Financial Institution Identifier (`fiId`) is missing
Retrieve offers


`GET /loyalty/offers/presentment/offers`

```json
{
  "request": {
    "headers": {
      "Accept-Language": "en-US"
    },
    "query_params": {
      "offset": "0",
      "limit": "25"
    }
}
}    
```

Expected result: `401 UNAUTHORIZED` because the `x-auth-token` is missing
Retrieve offer details


`GET /loyalty/offers/presentment/offers/{offer_id}`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>",
      "Accept-Language": "en-US"
    }
  }
}  
```

Expected result: `404 NOT_FOUND` because the `offer_id` is unknown or does not exist
Activate offer


`POST /loyalty/offers/presentment/activations`

```json
{
  "request": {
    "headers": {
      "X-Auth-Token": "<token>",
      "Content-Type": "application/json"
    },
    "body": {
    }
  }
}
```

Expected result: `400 BAD_REQUEST` because the request body is empty
Retrieve savings


`GET /loyalty/offers/presentment/savings`

```json
{
  "request": {
    "headers": {
    }
  }
}
```

Expected result: `401 UNAUTHORIZED` because the `x-auth-token` is missing
Retrieve rewards


`GET /loyalty/offers/presentment/adjustments`

```json
{
  "request": {
    "headers": {
    },
    "query_params": {
      "offset": "0",
      "limit": "25"
    }
  }
}
```

Expected result: `401 UNAUTHORIZED` because the `x-auth-token` is missing
Platform offers


`GET /loyalty/offers/presentment/platforms/offers`

```json
{
  "request": {
    "query_params": {
      "offset": "0",
      "limit": "25"
    }
  },
}
```

Expected result: `401 UNAUTHORIZED` because the required `fid` (Financial Institution Identifier) is missing
Platform adjustments


`GET /loyalty/offers/presentment/platforms/adjustments`

```json
{
  "request": {
    "query_params": {
      "fid": "999999",
      "offset": "0",
      "limit": "25"
    }
  },
}
```

Expected result: `401 UNAUTHORIZED` because the required `fid` (Financial Institution Identifier) is missing

#### Example error response {#example-error-response}

```json
{
  "Errors": {
    "Error": [
      {
        "Source": "PRESENTMENT_API",
        "ReasonCode": "BAD_REQUEST",
        "Description": "We could not handle your request.",
        "Recoverable": false,
        "Details": "Invalid JSON payload."
      }
    ]
  }
}
```

```json
{
"error": "BAD_REQUEST",
"error_description": "We could not handle your request.",
"details": "Invalid JSON payload.",
"source": "PRESENTMENT_API",
"recoverable": false
}
```

Refer to [Code and Formats](https://developer.mastercard.com/presentment/documentation/code-and-formats/index.md) for the complete list of response codes, reason codes, and formatting rules.

## User Account Administration {#user-account-administration}

### Positive testing {#positive-testing-1}

Positive testing confirms that valid requests succeed and return the expected data.

#### Validate these behaviors {#validate-these-behaviors-2}

* Valid request bodies return success codes such as `200 OK` or `201 CREATED`.
* Eligibility requests return enrollment eligibility information for the specified account.
* Enrollment requests return the identifiers required for subsequent User Account Administration operations.
* User retrieval requests return user profile information associated with the specified identifier.
* Account retrieval requests return account information associated with the enrolled user.
* Account creation requests return a newly created account identifier.
* User and account update requests persist changes and return a successful response.
* Replacement requests return a confirmation indicating successful processing.
* Rebate creation requests return a newly created rebate identifier.
* Rebate retrieval requests return rebate information and associated metadata matching the specified criteria.

#### Testing workflow {#testing-workflow-1}

Use this sequence to validate endpoints for the User Account Administration API:

1. Eligibility
2. Enroll user and first account
3. Retrieve details by Customer Reference Key (`crk`)
4. Retrieve details by Customer Reference Key (`crk`) and Account Reference Key (ARK)
5. Add subsequent account
6. Update user
7. Update account
8. Replacement
9. Submit rebates
10. Retrieve rebates

Note: User Account Administration refers to users as cardholders and an account as a unique card. Each user can have multiple accounts, meaning cardholders can have multiple cards.

#### Positive test cases {#positive-test-cases-1}

Use the tabs to view positive test cases.
Eligibility


`POST /enrollments/eligibilities/searches`

```json
{
"ban": "5330333671236516",
"enrollmentType": "TARGETED",
"fiIds": [
15100
],
"includeEnrollmentExist": true,
"includeProductDetails": true,
"programType": "MTR"
}
```

Expected result: `200 OK` and a response body indicating eligibility status of enrollment
Enroll user and first account

`POST /enrollments/users`

```json
{
  "userId": "BCN1235677089985",
  "userIdType": "BCN",
  "firstName": "John",
  "lastName": "Smith",
  "businessPhoneNumber": "+1(0)1234567890",
  "mobilePhoneNumber": "+1(0)1234567891",
  "emailAddress": "john.smith@mastercard.com",
  "vip": true,
  "employee": false,
  "preferredLanguage": "en_US",
  "genderCode": "1",
  "controlGroupIndicator": "Y",
  "customerSegmentId": "Nb03",
  "lastFourCardDigits": "4321",
  "selfEnrollmentSource": "01",
  "offersUser": {
    "offersAcceptPromotionalOffers": false,
    "offersAcceptEmails": false,
    "offersAcceptSms": false
  },
  "address": {
    "addressLine1": "10 Upper Bank Street",
    "addressLine2": "Chesterfield",
    "addressLine3": "Canary Wharf",
    "city": "London",
    "countryCode": "ENG",
    "postalCode": "63368",
    "stateProvinceCode": "JS"
  },
  "account": {
    "accountId": "5330333671236516",
    "accountIdType": "BAN",
    "bankProductCode": "MEB",
    "enrollmentDate": "2025-05-21T15:10:00.000Z",
    "externalAccountId": "2222332322",
    "accountReferenceCode": "123456abcdef123456abcdef123456abcdef0",
    "programIdentifier": "PGM42051"
  }
}
```

* Dependency: 4-6 digit `X-FID` value
* Expected result: `200 OK` and a response body containing the Customer Reference Key (`crk`) and Account Reference Key (ARK) values. These values must be passed in all subsequent User Account Administration calls. Do not use fixed values.
Retrieve details by Customer Reference Key (`crk`)

`GET enrollments/users/{CRK}`

* Request sample: Not applicable for this endpoint
* Dependency: Customer Reference Key (`crk`) value from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `200 OK` and a response body containing user details
Retrieve details by Customer Reference Key (`crk`) and Account Reference Key (ARK)

`GET enrollments/users/{CRK}/accounts/{ark}`

* Request sample: Not applicable for this endpoint
* Dependency: Customer Reference Key (`crk`) and Account Reference Key (ARK) values from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `200 OK` and a response body containing user and account details
Add subsequent account

`POST /enrollments/users/{crk}/accounts`

```json
{
"accountId": "5330333671236516",
"accountIdType": "BAN",
"bankProductCode": "MEB",
"programIdentifier": "PGM42051",
"enrollmentDate": "2025-05-21T15:10:00.000Z",
"externalAccountId": "2222332322",
"accountReferenceCode": "123456abcdef123456abcdef123456abcdef0"
}
```

* Dependency: Customer Reference Key (`crk`) value from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `200 OK` and a response body containing the Account Reference Key (ARK).
Update user

`PUT /enrollments/users/{crk}`

```json
{
"firstName": "John",
"lastName": "Smith",
"businessPhoneNumber": "+1(0)1234567890",
"mobilePhoneNumber": "+1(0)1234567891",
"emailAddress": "john.smith@mastercard.com",
"vip": true,
"employee": false,
"preferredLanguage": "en_US",
"genderCode": "0",
"controlGroupIndicator": "Y",
"customerSegmentId": "Nb03",
"lastFourCardDigits": "4321",
"selfEnrollmentSource": "01",
"offersUser": {
"offersAcceptPromotionalOffers": false,
"offersAcceptEmails": false,
"offersAcceptSms": false
},
"address": {
"addressLine1": "10 Upper Bank Street",
"addressLine2": "Chesterfield",
"addressLine3": "Canary Wharf",
"city": "London",
"countryCode": "ENG",
"postalCode": "63368",
"stateProvinceCode": "JS"
}
}
```

Expected result:

* Dependency: Customer Reference Key (`crk`) value from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `200 OK` and a successful response
Update account

`PUT /enrollments/users/{crk}/accounts/{ark}`

```json
{
"bankProductCode": "FIDOCASHBACK",
"programIdentifier": "PGM42051",
"externalAccountId": "2222332322",
"offersAccountStatusCode": "INACTIVE"
}
```

Expected result:

* Dependency: Customer Reference Key (`crk`) and Account Reference Key (ARK) values from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `200 OK` and a successful response
Replacement

`POST /enrollments/users/{crk}/replacements`

```json
{
"oldAccountId": "6fe2875af0794ecdaac8156863e7f7",
"newAccountNumber": "1234567890123456",
"newCustomerNumber": "BCN1235677089986",
"accountStatus": "GOOD_STANDING",
"actionCode": "B"
}
```

Expected result:

* Dependency: Customer Reference Key (`crk`) value from `POST /enrollments/users` and 4-6 digit `X-FID` value
* Expected result: `201 CREATED` and a confirmation message
Submit rebates

`POST /rebates`

```json
{
"accountIdentifier": "6fe2875af0794ecdaac8156863e7f7",
"identifierType": "ARK",
"merchantCategoryCode": 6555,
"merchantId": "6555",
"rebateAmount": 50,
"rebateCurrencyCode": "ARG",
"rebateReversalIndicator": "N",
"rebateSourceCode": "rrt",
"transactionAmount": 100,
"transactionDate": "2019-08-01",
"transactionDescriptionMerchantName": "Rebate",
"transactionSequenceNumber": 11123
}
```

* Dependency: 4-6 digit `X-FID` value
* Expected result: `201 CREATED` and a response body containing the Rebate ID
Retrieve rebates

`GET /rebates`

* Request sample: Not applicable for this endpoint
* Dependency: 4-6 digit `X-FID` value
* Expected result: `200 OK` and a response with the rebate or list of rebates matching the criteria and their associated metadata such as creation date and status code

### Negative testing {#negative-testing-1}

Negative testing confirms that invalid requests fail cleanly and return useful error details.

#### Validate these behaviors {#validate-these-behaviors-3}

* Missing required fields return error codes such as `400 BAD_REQUEST` or `401 UNAUTHORIZED`.
* Invalid field values return validation errors with a clear `ReasonCode` and description.
* Incorrect or missing authentication data is rejected.
* Encrypted endpoints reject malformed or unencrypted payloads when encryption is required.

#### Negative test cases {#negative-test-cases-1}

Use the tabs to view negative test cases.
* Scenario: Remove `X-FID` header parameter
* Expected result: `400 BAD_REQUEST` or `401 UNAUTHORIZED`
Eligibility


`POST /enrollments/eligibilities/searches`

```json
{
"ban": "123",
"enrollmentType": "TARGETED",
"fiIds": [
15100
],
"includeEnrollmentExist": true,
"includeProductDetails": true,
"programType": "MTR"
}
```

* Scenario: Enter an invalid Bank Account Number (BAN)
* Expected result: `400 BAD_REQUEST`

```json
{
  "request": {}
} 
```

* Scenario: Submit the request with an empty JSON object ({}) or no request body
* Expected result: `400 BAD_REQUEST`

```json
{
  "userId": "BCN1235677089985",
  "userIdType": "BCN",
  "firstName": "John",
  "lastName": "Smith",
  "businessPhoneNumber": "+1(0)1234567890",
  "mobilePhoneNumber": "+1(0)1234567891",
  "emailAddress": "john.smith@mastercard.com",
  "vip": true,
  "employee": false,
  "preferredLanguage": "en_US",
  "genderCode": "1",
  "controlGroupIndicator": "Y",
  "customerSegmentId": "Nb03",
  "lastFourCardDigits": "4321",
  "selfEnrollmentSource": "01",
  "offersUser": {
    "offersAcceptPromotionalOffers": false,
    "offersAcceptEmails": false,
    "offersAcceptSms": false
  ,
  "address": {
    "addressLine1": "10 Upper Bank Street",
    "city": "London"
  }
}
```

* Scenario: Corrupt the request body. For example, the offersUser object is not properly closed before the address object begins.
* Expected response: `400 BAD_REQUEST`

#### Example error response {#example-error-response-1}

```json
{
  "Errors": {
    "Error": [
      {
        "Source": "Publisher-Service",
        "ReasonCode": "INVALID_FIELD_FORMAT",
        "Description": "Email Address must be in the valid format.",
        "Recoverable": false,
        "Details": "Email used to create user is not valid."
      }
    ]
  }
}
```

```json
{
"error": "invalid_request",
"error_description": "Email Address must be in the valid format.",
"details": "Email used to create user is not valid.",
"source": "Publisher-Service",
"recoverable": false
}
```

Refer to [Code and Formats](https://developer.mastercard.com/presentment/documentation/code-and-formats/index.md) for the complete list of response codes, reason codes, and formatting rules.

## Next steps {#next-steps}

Continue with the documentation that matches your next task:

* [User Account Administration API Reference](https://developer.mastercard.com/presentment/documentation/api-reference/user-account-admin/index.md) and [Presentment and platform offers API Reference](https://developer.mastercard.com/presentment/documentation/api-reference/presentment-and-platform-offers/index.md) for complete endpoint specifications, request and response schemas, and environment URLs.
* [Tutorials and Guides](https://developer.mastercard.com/presentment/documentation/tutorials-and-guides/index.md) to learn how to set up a Sandbox environment and test Offers for Publishers User Account Administration integrations.
* [Onboarding Checklist](https://developer.mastercard.com/presentment/documentation/tutorials-and-guides/onboarding-checklist/index.md) for the full operational go-live process
* [Code and Formats](https://developer.mastercard.com/presentment/documentation/code-and-formats/index.md) for the complete list of response codes, reason codes, and formatting rules.
* [Support](https://developer.mastercard.com/presentment/documentation/support/index.md) section to access frequently asked questions and access technical support.
