# Integration and Testing
source: https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md

Testing in Sandbox provides access to a rich set of data that mimics what is available in production. The data in sandbox is entirely mocked information that uses realistic Merchant locations data, but should not be used in any production system, the values for each location are not applicable to real world configurations.
Warning: The Merchant locations data used in sandbox are randomly generated mocked data and should not be treated as being an accurate representation of real world Merchant locations.

## Prerequisites {#prerequisites}

Confirm the following before you send any requests:

* Your project is created and Sandbox credentials are available.
* You are using the Sandbox base URL: `https://sandbox.api.mastercard.com/locations/merchants`
* 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/locations-merchants/documentation/quick-start-guide/index.md).

## How to Send Your Test Requests {#how-to-send-your-test-requests}

You can run every test on this page with whichever tool suits your workflow. All of them require the same Sandbox credentials and OAuth 1.0a signing.

|          Method           |                                 Best for                                 |                                                                  Where to start                                                                   |
|---------------------------|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| **Postman Collection**    | Running the whole suite quickly with pre-built requests and environments | [Postman Collection](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/postman-collection/index.md)              |
| **Insomnia Collection**   | An alternative REST client with a Mastercard OAuth 1.0a plugin           | [Insomnia Collection](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/insomnia-collection/index.md)            |
| **Your own API client**   | Validating the code you will actually ship                               | [Mastercard API Basics](https://developer.mastercard.com/locations-merchants/documentation/api-basics/index.md) for signing and client generation |
| **Interactive reference** | Inspecting a single request or response schema                           | [API Reference](https://developer.mastercard.com/locations-merchants/documentation/api-reference/index.md)                                        |

See [Developer Tools](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/index.md) for the full list of tooling options.

## Testing Workflow {#testing-workflow}

Follow this ordered checklist to validate your integration end-to-end. It covers every operation in the Location Services API, starting with the reference data endpoints that require no input, then the search operations, then the feedback flow.

### Stage 1: Reference Data Endpoints {#stage-1-reference-data-endpoints}

These endpoints take no input or a single parameter, so they are the fastest way to confirm your OAuth signing works before you tackle the search payloads.

| # |              Test              |          Endpoint           |                                                           Success Criteria                                                            |                                                                                                        Failure Criteria                                                                                                        |
|---|--------------------------------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | **Get Countries**              | `GET /countries`            | HTTP 200 with a `countries` array. Each entry has `countryName` and a three letter `countryCode` such as `USA`.                       | HTTP 401 means your OAuth signature or consumer key is wrong. See [Authentication Errors](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#authentication-errors-http-401). |
| 2 | **Get Merchant Categories**    | `GET /categories`           | HTTP 200 with a `categories` array. Each entry has `categoryName` and `categoryId`.                                                   | HTTP 401 or 403 indicates a credential or entitlement problem, not a request problem.                                                                                                                                          |
| 3 | **Get Country Subdivisions**   | `GET /country-subdivisions` | Send `?country_code=USA`. HTTP 200 with a `countrySubdivisions` array of `countrySubdivisionCode` and `countrySubdivisionName` pairs. | HTTP 400 `INVALID_INPUT_VALUE` if the code is not exactly 3 characters, or `MISSING_REQUIRED_INPUT` if omitted. See cases E14-E16.                                                                                             |
| 4 | **Get Feedback Problem Types** | `GET /feedback-problems`    | Send `?merchant_type=PAYPASS`. HTTP 200 with the list of valid `problemCode` values for that merchant type.                           | HTTP 400 if `merchant_type` is missing or is not PayPass, EasySavings or Cashback. See case E19.                                                                                                                               |

Capture a `countryCode`, a `countrySubdivisionCode` and a `problemCode` from these responses - you will reuse them in the later stages.

### Stage 2: Merchant Search and Lookup {#stage-2-merchant-search-and-lookup}

| # |                        Test                        |        Endpoint        |                                                                                                                                                                            Success Criteria                                                                                                                                                                            |                                                               Failure Criteria                                                                |
|---|----------------------------------------------------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
| 5 | **Get Merchant Names**                             | `GET /merchants-names` | Send `?merchant_name=Pizza&merchant_type=PAYPASS`. HTTP 200 with `searchedMerchantName`, `merchantType` and a `merchantNames` array.                                                                                                                                                                                                                                   | HTTP 400 `MISSING_REQUIRED_INPUT` if the term is under 2 characters or the merchant type is invalid. See cases E11-E13.                       |
| 6 | **Get Merchants by Address**                       | `POST /searches`       | Send an address from [Sandbox Test Data](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#sandbox-test-data) in the post body. HTTP 200 with location details. See [Merchants Search by Address](https://developer.mastercard.com/locations-merchants/documentation/use-cases/merchant-search-by-address/index.md). | HTTP 400 if the address is incomplete or the merchant type is invalid. An unseeded address returns HTTP 200 with an empty list, not an error. |
| 7 | **Get Merchants by GeoCode**                       | `POST /searches`       | Send `latitude`/`longitude` in the post body. HTTP 200 with location details ordered by `distance`. See [Merchants Search by GeoCode](https://developer.mastercard.com/locations-merchants/documentation/use-cases/merchant-search-by-geocode/index.md).                                                                                                               | HTTP 400 if latitude or longitude is out of range, or if the radius exceeds the maximum. See cases E3-E5c.                                    |
| 8 | **Get Merchants by GeoCode with missing lat/long** | `POST /searches`       | Send latitude without longitude. HTTP 400 with `INVALID_INPUT_VALUE` and "Valid address or latitude and longitude must be provided."                                                                                                                                                                                                                                   | A HTTP 200 here means your client is silently dropping the invalid field before sending.                                                      |

### Stage 3: Customer Feedback {#stage-3-customer-feedback}

| #  |             Test             |          Endpoint          |                                                                                          Success Criteria                                                                                           |                                    Failure Criteria                                    |
|----|------------------------------|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|
| 9  | **Submit Customer Feedback** | `POST /customer-feedbacks` | Send a `problemCode` from test 4 and a `locationId` from test 6 or 7. HTTP 200 with `{"success": true}`.                                                                                            | HTTP 400 `INVALID_PROBLEM_CODE` or `MISSING_PROBLEM_CODE`. See cases E17-E18.          |
| 10 | **Edge case sweep**          | All endpoints              | Run cases E1-E20 in [Negative and Edge Case Test Records](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#negative-and-edge-case-test-records). | Each request must return the documented HTTP status, reason code, or empty result set. |

## End-to-End Test Journey: Reference Data, Search, then Feedback {#end-to-end-test-journey-reference-data-search-then-feedback}

Complete all four steps before moving to production. A successful journey proves your OAuth signing, request formatting, response parsing and error handling work across GET and POST operations, and that you can chain values from one response into the next request.

| Step |            Operation             |                                                                                              Request                                                                                               |                                                                                                        Expected Result                                                                                                         |
|------|----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1    | **Look up reference data**       | `GET /countries`, then `GET /country-subdivisions?country_code=USA`                                                                                                                                | HTTP 200 from both. Use a returned `countryCode` and `countrySubdivisionCode` in step 2.                                                                                                                                       |
| 2    | **Search for nearby merchants**  | `POST /searches` with a valid `latitude`, `longitude` and `merchantType` in the request body                                                                                                       | HTTP 200 with a list of matching merchant locations. Note a `locationId` from the response.                                                                                                                                    |
| 3    | **Submit feedback for a result** | `GET /feedback-problems?merchant_type=PAYPASS`, then `POST /customer-feedbacks` with that `problemCode` and the `locationId` from step 2                                                           | HTTP 200 with `{"success": true}`, confirming you can chain a search result into a write operation.                                                                                                                            |
| 4    | **Negative and edge case sweep** | Run cases E1-E20 in [Negative and Edge Case Test Records](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#negative-and-edge-case-test-records) | Each request returns the documented HTTP status, reason code, or empty result set. See [Troubleshooting](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#troubleshooting). |

## Sandbox Test Data {#sandbox-test-data}

For a list of sandbox Merchant locations including sample input payloads please click [here](https://static.developer.mastercard.com/content/locations-merchants/uploads/locations_merchants_sandbox_data.xlsx)

### Positive Test Records {#positive-test-records}

Use these seeded Sandbox locations to exercise the happy path. Each city can be searched by address or by geocode.

| # |       City       | Country |       Merchant types available       |                                                Address payload values                                                |            Geocode payload values             |
|---|------------------|---------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
| 1 | Saint Peters, MO | USA     | `paypass`, `easysavings`, `cashback` | `addressLine1: 4033 Veterans Memorial Pkwy`, `city: SAINT PETERS`, `countrySubdivisionCode: MO`, `postalCode: 63376` | `latitude: 38.79390`, `longitude: -90.571608` |
| 2 | New York, NY     | USA     | `paypass`, `easysavings`, `cashback` | `addressLine1: 225 LIBERTY ST`, `city: NEW YORK`, `countrySubdivisionCode: NY`, `postalCode: 10281`                  | `latitude: 40.71325`, `longitude: -74.015676` |
| 3 | London           | GBR     | `paypass`                            | `addressLine1: 87-135 Brompton Rd`, `city: London`, `postalCode: SW1X 7QN`                                           | `latitude: 51.49974`, `longitude: -0.163314`  |
| 4 | Montréal, QC     | CAN     | `paypass`, `easysavings`             | `addressLine1: 303 RUE NOTRE-DAME E`, `city: MONTRÉAL`, `countrySubdivisionCode: QUEBEC`, `postalCode: H2Y 3Z2`      | `latitude: 45.50923`, `longitude: -73.55345`  |

Other reusable identifiers for Sandbox testing:

* `locationId: 17170838` - valid location for `POST /customer-feedbacks`.
* `problemCode: CONTACTLESS_NOT_EASILY_ACCESSIBLE` - valid feedback problem code for `merchant_type=PAYPASS`.
* `country_code: USA`, `CAN` - countries with subdivision data seeded in Sandbox.

### Negative and Edge Case Test Records {#negative-and-edge-case-test-records}

Every major endpoint has at least one documented error path below. Run these before requesting Production access so your client handles failures as well as successes. For the full error object structure, see [Codes and Formats](https://developer.mastercard.com/locations-merchants/documentation/code-and-formats/index.md).

#### `POST /searches` - Merchant Search {#post-searches---merchant-search}

|  #  |                    Scenario                     |                                                 Request                                                 |                                                   Expected outcome                                                   |
|-----|-------------------------------------------------|---------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| E1  | Invalid merchant type                           | `{"merchantType":"INVALID_TYPE","latitude":"38.79390","longitude":"-90.571608"}`                        | HTTP 400, `INVALID_INPUT_VALUE` - "Merchant Type is missing or invalid"                                              |
| E2  | Missing longitude                               | `{"merchantType":"paypass","latitude":"38.79390"}`                                                      | HTTP 400, `INVALID_INPUT_VALUE` - "Valid address or latitude and longitude must be provided."                        |
| E3  | Latitude out of range                           | `{"merchantType":"paypass","latitude":"95.0","longitude":"-90.571608"}`                                 | HTTP 400, `INVALID_INPUT_VALUE` - "Latitude must be between -90 and 90"                                              |
| E4  | Longitude out of range                          | `{"merchantType":"paypass","latitude":"38.79390","longitude":"-200.0"}`                                 | HTTP 400, `INVALID_INPUT_VALUE` - "Longitude must be between -180 and 180"                                           |
| E5  | Radius above maximum (miles)                    | Valid Saint Peters body with `?distance=50&distance_unit=MILE`                                          | HTTP 400, `INVALID_INPUT_VALUE` - "Out of range for the radius distance. The maximum distance is 25 miles"           |
| E5a | Radius at the boundary (miles)                  | Valid Saint Peters body with `?distance=25&distance_unit=MILE`                                          | HTTP 200 - `25` is inclusive and is accepted                                                                         |
| E5b | Radius above maximum (kilometres)               | Valid Saint Peters body with `?distance=50&distance_unit=KM`                                            | HTTP 400, `INVALID_INPUT_VALUE` - "Out of range for the radius distance. The maximum distance is 40.2335 kilometers" |
| E5c | Radius at the boundary (kilometres)             | Valid Saint Peters body with `?distance=40.2335&distance_unit=KM`                                       | HTTP 200 - equivalent to the 25 mile maximum                                                                         |
| E6  | Invalid distance unit                           | Valid Saint Peters body with `?distance_unit=YARDS`                                                     | HTTP 400, `INVALID_INPUT_VALUE` - "Invalid unit. The valid values are KM and MILE."                                  |
| E7  | Limit above maximum                             | Valid Saint Peters body with `?limit=500`                                                               | HTTP 400, `INVALID_INPUT_VALUE` - "Invalid limit. The maximum limit is 100"                                          |
| E8  | No merchant near the coordinates (empty result) | `{"merchantType":"paypass","latitude":"0.0","longitude":"0.0"}`                                         | HTTP 200 with `"total": 0` and an empty `merchants` array - not an error                                             |
| E9  | Unseeded merchant type for a city               | `{"merchantType":"cashback","latitude":"51.49974","longitude":"-0.163314"}` (London has `paypass` only) | HTTP 200 with `"total": 0` and an empty `merchants` array                                                            |
| E10 | Offset beyond the result set                    | Valid Saint Peters body with `?offset=1000`                                                             | HTTP 200 with a non-zero `total` and an empty `merchants` page                                                       |

#### `GET /merchants-names` - Merchant Names {#get-merchants-names---merchant-names}

|  #  |             Scenario             |                    Request                     |                                Expected outcome                                 |
|-----|----------------------------------|------------------------------------------------|---------------------------------------------------------------------------------|
| E11 | Search term below minimum length | `?merchant_name=A&merchant_type=PAYPASS`       | HTTP 400, `MISSING_REQUIRED_INPUT` - at least 2 characters, or use `ALL`        |
| E12 | Missing or invalid merchant type | `?merchant_name=CARQUEST&merchant_type=RETAIL` | HTTP 400, `MISSING_REQUIRED_INPUT` - use `PAYPASS`, `EASYSAVINGS` or `CASHBACK` |
| E13 | Valid term with no matches       | `?merchant_name=ZZZZZZ&merchant_type=PAYPASS`  | HTTP 200 with an empty list                                                     |

#### `GET /country-subdivisions` - Country Subdivisions {#get-country-subdivisions---country-subdivisions}

|  #  |            Scenario             |       Request        |                                Expected outcome                                |
|-----|---------------------------------|----------------------|--------------------------------------------------------------------------------|
| E14 | Country code wrong length       | `?country_code=GBRA` | HTTP 400, `INVALID_INPUT_VALUE` - "countryCode must be 3 characters in length" |
| E15 | Country code omitted            | `?country_code=`     | HTTP 400, `MISSING_REQUIRED_INPUT` - "countryCode is missing"                  |
| E16 | Valid code with no subdivisions | `?country_code=VAT`  | HTTP 200 with an empty subdivision list                                        |

#### `POST /customer-feedbacks` - Customer Feedback {#post-customer-feedbacks---customer-feedback}

|  #  |       Scenario       |                       Request                        |                              Expected outcome                              |
|-----|----------------------|------------------------------------------------------|----------------------------------------------------------------------------|
| E17 | Invalid problem code | `{"problemCode":"BAD_CODE","locationId":"17170838"}` | HTTP 400, `INVALID_PROBLEM_CODE` - "'BAD_CODE' is not a valid problemCode" |
| E18 | Missing problem code | `{"locationId":"17170838"}`                          | HTTP 400, `MISSING_PROBLEM_CODE` - "problemCode is missing"                |

#### `GET /feedback-problems`, `GET /countries` and `GET /categories` {#get-feedback-problems-get-countries-and-get-categories}

|  #  |                   Scenario                   |                              Request                               |                                                                                        Expected outcome                                                                                         |
|-----|----------------------------------------------|--------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| E19 | Invalid merchant type filter                 | `/feedback-problems?merchant_type=ATM`                             | HTTP 400, `INVALID_INPUT_VALUE` - merchant type must be PayPass, EasySavings or Cashback                                                                                                        |
| E20 | Unauthenticated call to a reference endpoint | `/countries` or `/categories` sent without a valid OAuth signature | HTTP 401, `UnauthorizedError` - see [Authentication Errors](https://developer.mastercard.com/locations-merchants/documentation/integration-and-testing/index.md#authentication-errors-http-401) |

Note: An empty result set is a valid HTTP 200 response, not an error. Design your client to distinguish "no merchants found" (`total: 0`) from a rejected request (HTTP 4xx with an `Errors` object).

## Troubleshooting {#troubleshooting}

For a full list of error codes and their meanings, see [Codes and Formats](https://developer.mastercard.com/locations-merchants/documentation/code-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 `Valid address or latitude and longitude must be provided` value (must be numeric).
* Invalid `Longitude must be between -180 and 180`.
* Invalid `Latitude must be between -90 and 90`.

<br />

To resolve this error, try the following:

1. Validate your JSON payload with a JSON linter.
2. Ensure either a valid address or latitude and longitude is provided in the request body.
3. Ensure `latitude` is between -90 and 90, and `longitude` is between -180 and 180.

## Environment Guidance {#environment-guidance}

For environment URLs and descriptions, see [API Basics - Environments](https://developer.mastercard.com/locations-merchants/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/locations-merchants/documentation/quick-start-guide/index.md) if you still need credentials or project setup.
* Run the workflow above with the [Postman Collection](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/postman-collection/index.md) or the [Insomnia Collection](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/insomnia-collection/index.md) for ready-to-run requests, or see all options in [Developer Tools](https://developer.mastercard.com/locations-merchants/documentation/developer-tools/index.md).
* Review the [Use Cases](https://developer.mastercard.com/locations-merchants/documentation/use-cases/index.md) for a scenario walkthrough of each endpoint you are testing.
* Check [Codes and Formats](https://developer.mastercard.com/locations-merchants/documentation/code-and-formats/index.md) for the full list of reason codes returned by these tests.
* When Sandbox testing passes, follow the [Onboarding Checklist](https://developer.mastercard.com/locations-merchants/documentation/tutorials-and-guides/onboarding-checklist/index.md) to request production access.
