Repository: prebid/prebid-server
Pull request #2394 (2022-09-28 11:39:09)

Update sspBC adapter to v5.7
- adapter now writes integrationType (inver) into creative body. This helps us to distinct between impressions from prebid.js and prebid-server adapters
- increment version number
- update tests

wojciech-bialy-wpm: Please note sspBC adapter suffers from a bug introduced in  0.227.0 (regarding adapter names)

Patch:
diff --git a/adapters/grid/grid.go b/adapters/grid/grid.go
index b9ca47e8..7eafcf0b 100644
--- a/adapters/grid/grid.go
+++ b/adapters/grid/grid.go
@@ -21,6 +21,7 @@ type GridAdapter struct {
 
 type GridBid struct {
 	*openrtb2.Bid
+	AdmNative   json.RawMessage     `json:"adm_native,omitempty"`
 	ContentType openrtb_ext.BidType `json:"content_type"`
 }
 
@@ -282,6 +283,35 @@ func setImpExtData(imp openrtb2.Imp) openrtb2.Imp {
 	return imp
 }
 
+func fixNative(req json.RawMessage) (json.RawMessage, error) {
+	var gridReq map[string]interface{}
+	var parsedRequest map[string]interface{}
+
+	if err := json.Unmarshal(req, &gridReq); err != nil {
+		return req, nil
+	}
+	if imps, exists := maputil.ReadEmbeddedSlice(gridReq, "imp"); exists {
+		for _, imp := range imps {
+			if gridImp, ok := imp.(map[string]interface{}); ok {
+				native, hasNative := maputil.ReadEmbeddedMap(gridImp, "native")
+				if hasNative {
+					request, hasRequest := maputil.ReadEmbeddedString(native, "request")
+					if hasRequest {
+						delete(native, "request")
+						if err := json.Unmarshal([]byte(request), &parsedRequest); err == nil {
+							native["request_native"] = parsedRequest
+						} else {
+							native["request_native"] = request
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return json.Marshal(gridReq)
+}
+
 // MakeRequests makes the HTTP requests which should be made to fetch bids.
 func (a *GridAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
 	var errors = make([]error, 0)
@@ -312,6 +342,14 @@ func (a *GridAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapte
 	request.Imp = validImps
 
 	reqJSON, err := json.Marshal(request)
+
+	if err != nil {
+		errors = append(errors, err)
+		return nil, errors
+	}
+
+	fixedReqJSON, err := fixNative(reqJSON)
+
 	if err != nil {
 		errors = append(errors, err)
 		return nil, errors
@@ -323,7 +361,7 @@ func (a *GridAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapte
 	return []*adapters.RequestData{{
 		Method:  "POST",
 		Uri:     a.endpoint,
-		Body:    reqJSON,
+		Body:    fixedReqJSON,
 		Headers: headers,
 	}}, errors
 }
@@ -357,6 +395,11 @@ func (a *GridAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalReq
 		for i := range sb.Bid {
 			bidMeta, err := getBidMeta(sb.Bid[i].Ext)
 			bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp, sb.Bid[i])
+			if sb.Bid[i].AdmNative != nil && sb.Bid[i].AdM == "" {
+				if bytes, err := json.Marshal(sb.Bid[i].AdmNative); err == nil {
+					sb.Bid[i].AdM = string(bytes)
+				}
+			}
 			if err != nil {
 				return nil, []error{err}
 			}
@@ -411,6 +454,10 @@ func getMediaTypeForImp(impID string, imps []openrtb2.Imp, bidWithType GridBid)
 					return openrtb_ext.BidTypeVideo, nil
 				}
 
+				if imp.Native != nil {
+					return openrtb_ext.BidTypeNative, nil
+				}
+
 				return "", &errortypes.BadServerResponse{
 					Message: fmt.Sprintf("Unknown impression type for ID: \"%s\"", impID),
 				}
diff --git a/adapters/huaweiads/huaweiads.go b/adapters/huaweiads/huaweiads.go
index c1b97fdf..b8cc9f47 100644
--- a/adapters/huaweiads/huaweiads.go
+++ b/adapters/huaweiads/huaweiads.go
@@ -282,7 +282,7 @@ func (a *adapter) MakeRequests(openRTBRequest *openrtb2.BidRequest,
 			return nil, []error{errors.New("Unmarshal ExtImpHuaweiAds failed: huaweiAdsImpExt is nil.")}
 		}
 
-		adslot30, err := getReqAdslot30(huaweiAdsImpExt, &openRTBRequest.Imp[index], openRTBRequest)
+		adslot30, err := getReqAdslot30(huaweiAdsImpExt, &openRTBRequest.Imp[index])
 		if err != nil {
 			return nil, []error{err}
 		}
@@ -457,12 +457,16 @@ func getReqJson(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidRequest,
 }
 
 func getReqAdslot30(huaweiAdsImpExt *openrtb_ext.ExtImpHuaweiAds,
-	openRTBImp *openrtb2.Imp, openRTBRequest *openrtb2.BidRequest) (adslot30, error) {
+	openRTBImp *openrtb2.Imp) (adslot30, error) {
 	adtype := convertAdtypeStringToInteger(strings.ToLower(huaweiAdsImpExt.Adtype))
+	testStatus := 0
+	if huaweiAdsImpExt.IsTestAuthorization == "true" {
+		testStatus = 1
+	}
 	var adslot30 = adslot30{
 		Slotid: huaweiAdsImpExt.SlotId,
 		Adtype: adtype,
-		Test:   int32(openRTBRequest.Test),
+		Test:   int32(testStatus),
 	}
 	if err := checkAndExtractOpenrtbFormat(&adslot30, adtype, huaweiAdsImpExt.Adtype, openRTBImp); err != nil {
 		return adslot30, err
@@ -700,7 +704,6 @@ func getClientTime(clientTime string) (newClientTime string) {
 // getReqDeviceInfo: get device information for HuaweiAds request
 func getReqDeviceInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidRequest) (err error) {
 	var device device
-	var isGetGaidSuccess = false
 	if openRTBRequest.Device != nil {
 		device.Type = int32(openRTBRequest.Device.DeviceType)
 		device.Useragent = openRTBRequest.Device.UA
@@ -718,12 +721,12 @@ func getReqDeviceInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidReq
 		var country = getCountryCode(openRTBRequest)
 		device.BelongCountry = country
 		device.LocaleCountry = country
-		device.Gaid, isGetGaidSuccess = getGaidFromDeviceIFA(openRTBRequest.Device.OS, openRTBRequest.Device.IFA)
 		device.Ip = openRTBRequest.Device.IP
+		device.Gaid = openRTBRequest.Device.IFA
 	}
 
 	// get oaid gaid imei in openRTBRequest.User.Ext.Data
-	if err = getDeviceIDFromUserExt(&device, isGetGaidSuccess, openRTBRequest); err != nil {
+	if err = getDeviceIDFromUserExt(&device, openRTBRequest); err != nil {
 		return err
 	}
 
@@ -741,26 +744,13 @@ func getReqDeviceInfo(request *huaweiAdsRequest, openRTBRequest *openrtb2.BidReq
 	return nil
 }
 
-// getGaidFromDeviceIFA: get gaid from IFA if os is android
-// gaid example: e4fe9bde-caa0-47b6-908d-ffba3fa184f2
-func getGaidFromDeviceIFA(os string, ifa string) (gaid string, isGetGaidSuccess bool) {
-	if !strings.Contains(strings.ToLower(os), "android") {
-		return "", false
-	}
-
-	gaid = strings.ToLower(ifa)
-	if gaid == "" {
-		return "", false
-	}
-
-	return gaid, true
-}
-
 func getCountryCode(openRTBRequest *openrtb2.BidRequest) string {
 	if openRTBRequest.Device != nil && openRTBRequest.Device.Geo != nil && openRTBRequest.Device.Geo.Country != "" {
 		return convertCountryCode(openRTBRequest.Device.Geo.Country)
 	} else if openRTBRequest.User != nil && openRTBRequest.User.Geo != nil && openRTBRequest.User.Geo.Country != "" {
 		return convertCountryCode(openRTBRequest.User.Geo.Country)
+	} else if openRTBRequest.Device != nil && openRTBRequest.Device.MCCMNC != "" {
+		return getCountryCodeFromMCC(openRTBRequest.Device.MCCMNC)
 	} else {
 		return defaultCountryName
 	}
@@ -788,39 +778,60 @@ func convertCountryCode(country string) (out string) {
 	return defaultCountryName
 }
 
+func getCountryCodeFromMCC(MCC string) (out string) {
+	var countryMCC = strings.Split(MCC, "-")[0]
+	intVar, err := strconv.Atoi(countryMCC)
+
+	if err != nil {
+		return defaultCountryName
+	} else {
+		if result, found := MccList[intVar]; found {
+			return strings.ToUpper(result)
+		} else {
+			return defaultCountryName
+		}
+	}
+}
+
 // getDeviceID include oaid gaid imei. In prebid mobile, use TargetingParams.addUserData("imei", "imei-test");
 // When ifa: gaid exists, other device id can be passed by TargetingParams.addUserData("oaid", "oaid-test");
-// When getGaidFromDeviceIFA success, getDeviceIDFromUserExt failed, no error will be reported.
-func getDeviceIDFromUserExt(device *device, isGetGaidSuccess bool, openRTBRequest *openrtb2.BidRequest) (err error) {
+func getDeviceIDFromUserExt(device *device, openRTBRequest *openrtb2.BidRequest) (err error) {
+	var userObjExist = true
 	if openRTBRequest.User == nil || openRTBRequest.User.Ext == nil {
-		if isGetGaidSuccess {
-			return nil
-		}
-		return errors.New("get gaid from openrtb Device.IFA failed, and get device id failed: openRTBRequest.User.Ext is nil.")
+		userObjExist = false
 	}
-	var extUserDataHuaweiAds openrtb_ext.ExtUserDataHuaweiAds
-	if err := json.Unmarshal(openRTBRequest.User.Ext, &extUserDataHuaweiAds); err != nil {
-		if isGetGaidSuccess {
-			return nil
+	if userObjExist {
+		var extUserDataHuaweiAds openrtb_ext.ExtUserDataHuaweiAds
+		if err := json.Unmarshal(openRTBRequest.User.Ext, &extUserDataHuaweiAds); err != nil {
+			return errors.New("get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds. Error: " + err.Error())
+		}
+
+		var deviceId = extUserDataHuaweiAds.Data
+		isValidDeviceId := false
+
+		if len(deviceId.Oaid) > 0 {
+			device.Oaid = deviceId.Oaid[0]
+			isValidDeviceId = true
+		}
+		if len(deviceId.Gaid) > 0 {
+			device.Gaid = deviceId.Gaid[0]
+			isValidDeviceId = true
+		}
+		if len(deviceId.Imei) > 0 {
+			device.Imei = deviceId.Imei[0]
+			isValidDeviceId = true
+		}
+
+		if !isValidDeviceId {
+			return errors.New("getDeviceID: Imei ,Oaid, Gaid are all empty.")
+		}
+		if len(deviceId.ClientTime) > 0 {
+			device.ClientTime = getClientTime(deviceId.ClientTime[0])
+		}
+	} else {
+		if len(device.Gaid) == 0 {
+			return errors.New("getDeviceID: openRTBRequest.User.Ext is nil and device.Gaid is not specified.")
 		}
-		return errors.New("get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds.")
-	}
-	var deviceId = extUserDataHuaweiAds.Data
-	if !isGetGaidSuccess && len(deviceId.Imei) == 0 && len(deviceId.Gaid) == 0 && len(deviceId.Oaid) == 0 {
-		return errors.New("get gaid from openrtb Device.IFA failed, and get device id failed: Imei ,Oaid, Gaid are all empty.")
-	}
-	if len(deviceId.Oaid) > 0 {
-		device.Oaid = deviceId.Oaid[0]
-	}
-	// when getGaidFromDeviceIFA failed
-	if len(deviceId.Gaid) > 0 && !isGetGaidSuccess {
-		device.Gaid = deviceId.Gaid[0]
-	}
-	if len(deviceId.Imei) > 0 {
-		device.Imei = deviceId.Imei[0]
-	}
-	if len(deviceId.ClientTime) > 0 {
-		device.ClientTime = getClientTime(deviceId.ClientTime[0])
 	}
 	return nil
 }
diff --git a/adapters/huaweiads/mcc_list.go b/adapters/huaweiads/mcc_list.go
new file mode 100644
index 00000000..fff92013
--- /dev/null
+++ b/adapters/huaweiads/mcc_list.go
@@ -0,0 +1,243 @@
+package huaweiads
+
+var MccList = map[int]string{
+	202: "gr", //Greece
+	204: "nl", //Netherlands (Kingdom of the)
+	206: "be", //Belgium
+	208: "fr", //France
+	212: "mc", //Monaco (Principality of)
+	213: "ad", //Andorra (Principality of)
+	214: "es", //Spain
+	216: "hu", //Hungary (Republic of)
+	218: "ba", //Bosnia and Herzegovina
+	219: "hr", //Croatia (Republic of)
+	220: "rs", //Serbia and Montenegro
+	222: "it", //Italy
+	225: "va", //Vatican City State
+	226: "ro", //Romania
+	228: "ch", //Switzerland (Confederation of)
+	230: "cz", //Czech Republic
+	231: "sk", //Slovak Republic
+	232: "at", //Austria
+	234: "gb", //United Kingdom of Great Britain and Northern Ireland
+	235: "gb", //United Kingdom of Great Britain and Northern Ireland
+	238: "dk", //Denmark
+	240: "se", //Sweden
+	242: "no", //Norway
+	244: "fi", //Finland
+	246: "lt", //Lithuania (Republic of)
+	247: "lv", //Latvia (Republic of)
+	248: "ee", //Estonia (Republic of)
+	250: "ru", //Russian Federation
+	255: "ua", //Ukraine
+	257: "by", //Belarus (Republic of)
+	259: "md", //Moldova (Republic of)
+	260: "pl", //Poland (Republic of)
+	262: "de", //Germany (Federal Republic of)
+	266: "gi", //Gibraltar
+	268: "pt", //Portugal
+	270: "lu", //Luxembourg
+	272: "ie", //Ireland
+	274: "is", //Iceland
+	276: "al", //Albania (Republic of)
+	278: "mt", //Malta
+	280: "cy", //Cyprus (Republic of)
+	282: "ge", //Georgia
+	283: "am", //Armenia (Republic of)
+	284: "bg", //Bulgaria (Republic of)
+	286: "tr", //Turkey
+	288: "fo", //Faroe Islands
+	289: "ge", //Abkhazia (Georgia)
+	290: "gl", //Greenland (Denmark)
+	292: "sm", //San Marino (Republic of)
+	293: "si", //Slovenia (Republic of)
+	294: "mk", //The Former Yugoslav Republic of Macedonia
+	295: "li", //Liechtenstein (Principality of)
+	297: "me", //Montenegro (Republic of)
+	302: "ca", //Canada
+	308: "pm", //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
+	310: "us", //United States of America
+	311: "us", //United States of America
+	312: "us", //United States of America
+	313: "us", //United States of America
+	314: "us", //United States of America
+	315: "us", //United States of America
+	316: "us", //United States of America
+	330: "pr", //Puerto Rico
+	332: "vi", //United States Virgin Islands
+	334: "mx", //Mexico
+	338: "jm", //Jamaica
+	340: "gp", //Guadeloupe (French Department of)
+	342: "bb", //Barbados
+	344: "ag", //Antigua and Barbuda
+	346: "ky", //Cayman Islands
+	348: "vg", //British Virgin Islands
+	350: "bm", //Bermuda
+	352: "gd", //Grenada
+	354: "ms", //Montserrat
+	356: "kn", //Saint Kitts and Nevis
+	358: "lc", //Saint Lucia
+	360: "vc", //Saint Vincent and the Grenadines
+	362: "ai", //Netherlands Antilles
+	363: "aw", //Aruba
+	364: "bs", //Bahamas (Commonwealth of the)
+	365: "ai", //Anguilla
+	366: "dm", //Dominica (Commonwealth of)
+	368: "cu", //Cuba
+	370: "do", //Dominican Republic
+	372: "ht", //Haiti (Republic of)
+	374: "tt", //Trinidad and Tobago
+	376: "tc", //Turks and Caicos Islands
+	400: "az", //Azerbaijani Republic
+	401: "kz", //Kazakhstan (Republic of)
+	402: "bt", //Bhutan (Kingdom of)
+	404: "in", //India (Republic of)
+	405: "in", //India (Republic of)
+	406: "in", //India (Republic of)
+	410: "pk", //Pakistan (Islamic Republic of)
+	412: "af", //Afghanistan
+	413: "lk", //Sri Lanka (Democratic Socialist Republic of)
+	414: "mm", //Myanmar (Union of)
+	415: "lb", //Lebanon
+	416: "jo", //Jordan (Hashemite Kingdom of)
+	417: "sy", //Syrian Arab Republic
+	418: "iq", //Iraq (Republic of)
+	419: "kw", //Kuwait (State of)
+	420: "sa", //Saudi Arabia (Kingdom of)
+	421: "ye", //Yemen (Republic of)
+	422: "om", //Oman (Sultanate of)
+	423: "ps", //Palestine
+	424: "ae", //United Arab Emirates
+	425: "il", //Israel (State of)
+	426: "bh", //Bahrain (Kingdom of)
+	427: "qa", //Qatar (State of)
+	428: "mn", //Mongolia
+	429: "np", //Nepal
+	430: "ae", //United Arab Emirates
+	431: "ae", //United Arab Emirates
+	432: "ir", //Iran (Islamic Republic of)
+	434: "uz", //Uzbekistan (Republic of)
+	436: "tj", //Tajikistan (Republic of)
+	437: "kg", //Kyrgyz Republic
+	438: "tm", //Turkmenistan
+	440: "jp", //Japan
+	441: "jp", //Japan
+	450: "kr", //Korea (Republic of)
+	452: "vn", //Viet Nam (Socialist Republic of)
+	454: "hk", //"Hong Kong, China"
+	455: "mo", //"Macao, China"
+	456: "kh", //Cambodia (Kingdom of)
+	457: "la", //Lao People's Democratic Republic
+	460: "cn", //China (People's Republic of)
+	461: "cn", //China (People's Republic of)
+	466: "tw", //"Taiwan, China"
+	467: "kp", //Democratic People's Republic of Korea
+	470: "bd", //Bangladesh (People's Republic of)
+	472: "mv", //Maldives (Republic of)
+	502: "my", //Malaysia
+	505: "au", //Australia
+	510: "id", //Indonesia (Republic of)
+	514: "tl", //Democratic Republic of Timor-Leste
+	515: "ph", //Philippines (Republic of the)
+	520: "th", //Thailand
+	525: "sg", //Singapore (Republic of)
+	528: "bn", //Brunei Darussalam
+	530: "nz", //New Zealand
+	534: "mp", //Northern Mariana Islands (Commonwealth of the)
+	535: "gu", //Guam
+	536: "nr", //Nauru (Republic of)
+	537: "pg", //Papua New Guinea
+	539: "to", //Tonga (Kingdom of)
+	540: "sb", //Solomon Islands
+	541: "vu", //Vanuatu (Republic of)
+	542: "fj", //Fiji (Republic of)
+	543: "wf", //Wallis and Futuna (Territoire franais d'outre-mer)
+	544: "as", //American Samoa
+	545: "ki", //Kiribati (Republic of)
+	546: "nc", //New Caledonia (Territoire franais d'outre-mer)
+	547: "pf", //French Polynesia (Territoire franais d'outre-mer)
+	548: "ck", //Cook Islands
+	549: "ws", //Samoa (Independent State of)
+	550: "fm", //Micronesia (Federated States of)
+	551: "mh", //Marshall Islands (Republic of the)
+	552: "pw", //Palau (Republic of)
+	553: "tv", //Tuvalu
+	555: "nu", //Niue
+	602: "eg", //Egypt (Arab Republic of)
+	603: "dz", //Algeria (People's Democratic Republic of)
+	604: "ma", //Morocco (Kingdom of)
+	605: "tn", //Tunisia
+	606: "ly", //Libya (Socialist People's Libyan Arab Jamahiriya)
+	607: "gm", //Gambia (Republic of the)
+	608: "sn", //Senegal (Republic of)
+	609: "mr", //Mauritania (Islamic Republic of)
+	610: "ml", //Mali (Republic of)
+	611: "gn", //Guinea (Republic of)
+	612: "ci", //Côte d'Ivoire (Republic of)
+	613: "bf", //Burkina Faso
+	614: "ne", //Niger (Republic of the)
+	615: "tg", //Togolese Republic
+	616: "bj", //Benin (Republic of)
+	617: "mu", //Mauritius (Republic of)
+	618: "lr", //Liberia (Republic of)
+	619: "sl", //Sierra Leone
+	620: "gh", //Ghana
+	621: "ng", //Nigeria (Federal Republic of)
+	622: "td", //Chad (Republic of)
+	623: "cf", //Central African Republic
+	624: "cm", //Cameroon (Republic of)
+	625: "cv", //Cape Verde (Republic of)
+	626: "st", //Sao Tome and Principe (Democratic Republic of)
+	627: "gq", //Equatorial Guinea (Republic of)
+	628: "ga", //Gabonese Republic
+	629: "cg", //Congo (Republic of the)
+	630: "cg", //Democratic Republic of the Congo
+	631: "ao", //Angola (Republic of)
+	632: "gw", //Guinea-Bissau (Republic of)
+	633: "sc", //Seychelles (Republic of)
+	634: "sd", //Sudan (Republic of the)
+	635: "rw", //Rwanda (Republic of)
+	636: "et", //Ethiopia (Federal Democratic Republic of)
+	637: "so", //Somali Democratic Republic
+	638: "dj", //Djibouti (Republic of)
+	639: "ke", //Kenya (Republic of)
+	640: "tz", //Tanzania (United Republic of)
+	641: "ug", //Uganda (Republic of)
+	642: "bi", //Burundi (Republic of)
+	643: "mz", //Mozambique (Republic of)
+	645: "zm", //Zambia (Republic of)
+	646: "mg", //Madagascar (Republic of)
+	647: "re", //Reunion (French Department of)
+	648: "zw", //Zimbabwe (Republic of)
+	649: "na", //Namibia (Republic of)
+	650: "mw", //Malawi
+	651: "ls", //Lesotho (Kingdom of)
+	652: "bw", //Botswana (Republic of)
+	653: "sz", //Swaziland (Kingdom of)
+	654: "km", //Comoros (Union of the)
+	655: "za", //South Africa (Republic of)
+	657: "er", //Eritrea
+	658: "sh", //Saint Helena, Ascension and Tristan da Cunha
+	659: "ss", //South Sudan (Republic of)
+	702: "bz", //Belize
+	704: "gt", //Guatemala (Republic of)
+	706: "sv", //El Salvador (Republic of)
+	708: "hn", //Honduras (Republic of)
+	710: "ni", //Nicaragua
+	712: "cr", //Costa Rica
+	714: "pa", //Panama (Republic of)
+	716: "pe", //Peru
+	722: "ar", //Argentine Republic
+	724: "br", //Brazil (Federative Republic of)
+	730: "cl", //Chile
+	732: "co", //Colombia (Republic of)
+	734: "ve", //Venezuela (Bolivarian Republic of)
+	736: "bo", //Bolivia (Republic of)
+	738: "gy", //Guyana
+	740: "ec", //Ecuador
+	742: "gf", //French Guiana (French Department of)
+	744: "py", //Paraguay (Republic of)
+	746: "sr", //Suriname (Republic of)
+	748: "uy", //Uruguay (Eastern Republic of)
+	750: "fk", //Falkland Islands (Malvinas)
+}
diff --git a/adapters/infoawarebidder.go b/adapters/infoawarebidder.go
index 5dfd4dd0..b019b01c 100644
--- a/adapters/infoawarebidder.go
+++ b/adapters/infoawarebidder.go
@@ -13,12 +13,12 @@ import (
 // media types defined in the static/bidder-info/{bidder}.yaml file.
 //
 // It adjusts incoming requests in the following ways:
-//   1. If App or Site traffic is not supported by the info file, then requests from
-//      those sources will be rejected before the delegate is called.
-//   2. If a given MediaType is not supported for the platform, then it will be set
-//      to nil before the request is forwarded to the delegate.
-//   3. Any Imps which have no MediaTypes left will be removed.
-//   4. If there are no valid Imps left, the delegate won't be called at all.
+//  1. If App or Site traffic is not supported by the info file, then requests from
+//     those sources will be rejected before the delegate is called.
+//  2. If a given MediaType is not supported for the platform, then it will be set
+//     to nil before the request is forwarded to the delegate.
+//  3. Any Imps which have no MediaTypes left will be removed.
+//  4. If there are no valid Imps left, the delegate won't be called at all.
 type InfoAwareBidder struct {
 	Bidder
 	info parsedBidderInfo
@@ -37,13 +37,13 @@ func (i *InfoAwareBidder) MakeRequests(request *openrtb2.BidRequest, reqInfo *Ex
 
 	if request.Site != nil {
 		if !i.info.site.enabled {
-			return nil, []error{&errortypes.BadInput{Message: "this bidder does not support site requests"}}
+			return nil, []error{&errortypes.Warning{Message: "this bidder does not support site requests"}}
 		}
 		allowedMediaTypes = i.info.site
 	}
 	if request.App != nil {
 		if !i.info.app.enabled {
-			return nil, []error{&errortypes.BadInput{Message: "this bidder does not support app requests"}}
+			return nil, []error{&errortypes.Warning{Message: "this bidder does not support app requests"}}
 		}
 		allowedMediaTypes = i.info.app
 	}
@@ -57,7 +57,7 @@ func (i *InfoAwareBidder) MakeRequests(request *openrtb2.BidRequest, reqInfo *Ex
 
 	// If all imps in bid request come with unsupported media types, exit
 	if numToFilter == len(request.Imp) {
-		return nil, append(errs, &errortypes.BadInput{Message: "Bid request didn't contain media types supported by the bidder"})
+		return nil, append(errs, &errortypes.Warning{Message: "Bid request didn't contain media types supported by the bidder"})
 	}
 
 	if numToFilter != 0 {
@@ -78,19 +78,19 @@ func pruneImps(imps []openrtb2.Imp, allowedTypes parsedSupports) (int, []error)
 	for i := 0; i < len(imps); i++ {
 		if !allowedTypes.banner && imps[i].Banner != nil {
 			imps[i].Banner = nil
-			errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("request.imp[%d] uses banner, but this bidder doesn't support it", i)})
+			errs = append(errs, &errortypes.Warning{Message: fmt.Sprintf("request.imp[%d] uses banner, but this bidder doesn't support it", i)})
 		}
 		if !allowedTypes.video && imps[i].Video != nil {
 			imps[i].Video = nil
-			errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("request.imp[%d] uses video, but this bidder doesn't support it", i)})
+			errs = append(errs, &errortypes.Warning{Message: fmt.Sprintf("request.imp[%d] uses video, but this bidder doesn't support it", i)})
 		}
 		if !allowedTypes.audio && imps[i].Audio != nil {
 			imps[i].Audio = nil
-			errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("request.imp[%d] uses audio, but this bidder doesn't support it", i)})
+			errs = append(errs, &errortypes.Warning{Message: fmt.Sprintf("request.imp[%d] uses audio, but this bidder doesn't support it", i)})
 		}
 		if !allowedTypes.native && imps[i].Native != nil {
 			imps[i].Native = nil
-			errs = append(errs, &errortypes.BadInput{Message: fmt.Sprintf("request.imp[%d] uses native, but this bidder doesn't support it", i)})
+			errs = append(errs, &errortypes.Warning{Message: fmt.Sprintf("request.imp[%d] uses native, but this bidder doesn't support it", i)})
 		}
 		if !hasAnyTypes(&imps[i]) {
 			numToFilter = numToFilter + 1
diff --git a/adapters/sspBC/sspbc.go b/adapters/sspBC/sspbc.go
index 4fe8a2eb..71cf3da7 100644
--- a/adapters/sspBC/sspbc.go
+++ b/adapters/sspBC/sspbc.go
@@ -19,7 +19,7 @@ import (
 )
 
 const (
-	adapterVersion              = "5.6"
+	adapterVersion              = "5.7"
 	impFallbackSize             = "1x1"
 	requestTypeStandard         = 1
 	requestTypeOneCode          = 2
@@ -55,6 +55,7 @@ type templatePayload struct {
 	Page    string `json:"page"`
 	Referer string `json:"referer"`
 	McAd    string `json:"mcad"`
+	Inver   string `json:"inver"`
 }
 
 // requestImpExt represents the ext field of the request imp field.
@@ -83,10 +84,11 @@ func Builder(_ openrtb_ext.BidderName, config config.Adapter) (adapters.Bidder,
 		`width=device-width, initial-scale=1.0"><style> body { background-color: transparent; margin: 0;` +
 		` padding: 0; }</style><script> window.rekid = {{.SiteId}}; window.slot = {{.SlotId}}; window.ad` +
 		`label = '{{.AdLabel}}'; window.pubid = '{{.PubId}}'; window.wp_sn = 'sspbc_go'; window.page = '` +
-		`{{.Page}}'; window.ref = '{{.Referer}}'; window.mcad = JSON.parse(atob('{{.McAd}}'));</script><` +
-		`/head><body><div id="c"></div><script async crossorigin nomodule src="//std.wpcdn.pl/wpjslib/wp` +
-		`jslib-inline.js" id="wpjslib"></script><script async crossorigin type="module" src="//std.wpcdn` +
-		`.pl/wpjslib6/wpjslib-inline.js" id="wpjslib6"></script></body></html>`
+		`{{.Page}}'; window.ref = '{{.Referer}}'; window.mcad = JSON.parse(atob('{{.McAd}}')); window.in` +
+		`ver = '{{.Inver}}'; </script></head><body><div id="c"></div><script async c` +
+		`rossorigin nomodule src="//std.wpcdn.pl/wpjslib/wpjslib-inline.js" id="wpjslib"></script><scrip` +
+		`t async crossorigin type="module" src="//std.wpcdn.pl/wpjslib6/wpjslib-inline.js" id="wpjslib6"` +
+		`></script></body></html>`
 
 	bannerTemplate, err := template.New("banner").Parse(bannerHTML)
 	if err != nil {
@@ -254,6 +256,7 @@ func (a *adapter) createBannerAd(bid openrtb2.Bid, ext responseExt, request *ope
 		Page:    request.Site.Page,
 		Referer: request.Site.Ref,
 		McAd:    base64.URLEncoding.EncodeToString(mcMarshalled),
+		Inver:   prebidServerIntegrationType,
 	}
 
 	var filledTemplate bytes.Buffer
diff --git a/config/accounts.go b/config/accounts.go
index e5bae8af..75319001 100644
--- a/config/accounts.go
+++ b/config/accounts.go
@@ -1,8 +1,6 @@
 package config
 
 import (
-	"fmt"
-
 	"github.com/prebid/go-gdpr/consentconstants"
 	"github.com/prebid/prebid-server/openrtb_ext"
 )
@@ -20,18 +18,18 @@ const (
 
 // Account represents a publisher account configuration
 type Account struct {
-	ID                      string               `mapstructure:"id" json:"id"`
-	Disabled                bool                 `mapstructure:"disabled" json:"disabled"`
-	CacheTTL                DefaultTTLs          `mapstructure:"cache_ttl" json:"cache_ttl"`
-	EventsEnabled           bool                 `mapstructure:"events_enabled" json:"events_enabled"`
-	CCPA                    AccountCCPA          `mapstructure:"ccpa" json:"ccpa"`
-	GDPR                    AccountGDPR          `mapstructure:"gdpr" json:"gdpr"`
-	DebugAllow              bool                 `mapstructure:"debug_allow" json:"debug_allow"`
-	DefaultIntegration      string               `mapstructure:"default_integration" json:"default_integration"`
-	CookieSync              CookieSync           `mapstructure:"cookie_sync" json:"cookie_sync"`
-	Events                  Events               `mapstructure:"events" json:"events"` // Don't enable this feature. It is still under developmment - https://github.com/prebid/prebid-server/issues/1725
-	TruncateTargetAttribute *int                 `mapstructure:"truncate_target_attr" json:"truncate_target_attr"`
-	AlternateBidderCodes    AlternateBidderCodes `mapstructure:"alternatebiddercodes" json:"alternatebiddercodes"`
+	ID                      string                               `mapstructure:"id" json:"id"`
+	Disabled                bool                                 `mapstructure:"disabled" json:"disabled"`
+	CacheTTL                DefaultTTLs                          `mapstructure:"cache_ttl" json:"cache_ttl"`
+	EventsEnabled           bool                                 `mapstructure:"events_enabled" json:"events_enabled"`
+	CCPA                    AccountCCPA                          `mapstructure:"ccpa" json:"ccpa"`
+	GDPR                    AccountGDPR                          `mapstructure:"gdpr" json:"gdpr"`
+	DebugAllow              bool                                 `mapstructure:"debug_allow" json:"debug_allow"`
+	DefaultIntegration      string                               `mapstructure:"default_integration" json:"default_integration"`
+	CookieSync              CookieSync                           `mapstructure:"cookie_sync" json:"cookie_sync"`
+	Events                  Events                               `mapstructure:"events" json:"events"` // Don't enable this feature. It is still under developmment - https://github.com/prebid/prebid-server/issues/1725
+	TruncateTargetAttribute *int                                 `mapstructure:"truncate_target_attr" json:"truncate_target_attr"`
+	AlternateBidderCodes    *openrtb_ext.ExtAlternateBidderCodes `mapstructure:"alternatebiddercodes" json:"alternatebiddercodes"`
 }
 
 // CookieSync represents the account-level defaults for the cookie sync endpoint.
@@ -223,51 +221,3 @@ func (a *AccountIntegration) GetByIntegrationType(integrationType IntegrationTyp
 
 	return integrationEnabled
 }
-
-type AlternateBidderCodes struct {
-	Enabled bool                                   `mapstructure:"enabled" json:"enabled"`
-	Bidders map[string]AdapterAlternateBidderCodes `mapstructure:"bidders" json:"bidders"`
-}
-
-type AdapterAlternateBidderCodes struct {
-	Enabled            bool     `mapstructure:"enabled" json:"enabled"`
-	AllowedBidderCodes []string `mapstructure:"allowedbiddercodes" json:"allowedbiddercodes"`
-}
-
-func (bidderCodes *AlternateBidderCodes) IsValidBidderCode(bidder, alternateBidder string) (bool, error) {
-	const ErrAlternateBidderNotDefined = "alternateBidderCodes not defined for adapter %q, rejecting bids for %q"
-
-	if alternateBidder == "" || bidder == alternateBidder {
-		return true, nil
-	}
-
-	if !bidderCodes.Enabled {
-		return false, nil
-	}
-
-	if bidderCodes.Bidders == nil {
-		return false, fmt.Errorf(ErrAlternateBidderNotDefined, bidder, alternateBidder)
-	}
-
-	adapterCfg, ok := bidderCodes.Bidders[bidder]
-	if !ok {
-		return false, fmt.Errorf(ErrAlternateBidderNotDefined, bidder, alternateBidder)
-	}
-
-	if !adapterCfg.Enabled {
-		// config has bidder entry but is not enabled, report it
-		return false, fmt.Errorf("alternateBidderCodes disabled for %q, rejecting bids for %q", bidder, alternateBidder)
-	}
-
-	if adapterCfg.AllowedBidderCodes == nil || (len(adapterCfg.AllowedBidderCodes) == 1 && adapterCfg.AllowedBidderCodes[0] == "*") {
-		return true, nil
-	}
-
-	for _, code := range adapterCfg.AllowedBidderCodes {
-		if alternateBidder == code {
-			return true, nil
-		}
-	}
-
-	return false, fmt.Errorf("invalid biddercode %q sent by adapter %q", alternateBidder, bidder)
-}
diff --git a/config/bidderinfo.go b/config/bidderinfo.go
index 74122bdf..70e1f89f 100644
--- a/config/bidderinfo.go
+++ b/config/bidderinfo.go
@@ -9,6 +9,7 @@ import (
 	"github.com/prebid/prebid-server/util/sliceutil"
 	"io/ioutil"
 	"log"
+	"path/filepath"
 	"strings"
 	"text/template"
 
@@ -170,38 +171,66 @@ func (bi BidderInfo) IsEnabled() bool {
 	return !bi.Disabled
 }
 
-// LoadBidderInfo parses all static/bidder-info/{bidder}.yaml files from the file system.
-func LoadBidderInfo(path string) (BidderInfos, error) {
-	bidderConfigs, err := ioutil.ReadDir(path)
+type InfoReader interface {
+	Read() (map[string][]byte, error)
+}
+
+type InfoReaderFromDisk struct {
+	Path string
+}
+
+func (r InfoReaderFromDisk) Read() (map[string][]byte, error) {
+	bidderConfigs, err := ioutil.ReadDir(r.Path)
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	infos := BidderInfos{}
-
+	bidderInfos := make(map[string][]byte)
 	for _, bidderConfig := range bidderConfigs {
 		if bidderConfig.IsDir() {
 			continue //ignore directories
 		}
 		fileName := bidderConfig.Name()
-		filePath := fmt.Sprintf("%v/%v", path, fileName)
+		filePath := filepath.Join(r.Path, fileName)
 		data, err := ioutil.ReadFile(filePath)
 		if err != nil {
 			return nil, err
 		}
+		bidderInfos[fileName] = data
+	}
+	return bidderInfos, nil
+}
 
-		info := BidderInfo{}
-		if err := yaml.Unmarshal(data, &info); err != nil {
-			return nil, fmt.Errorf("error parsing yaml for bidder %s: %v", fileName, err)
-		}
+func LoadBidderInfoFromDisk(path string) (BidderInfos, error) {
+	bidderInfoReader := InfoReaderFromDisk{Path: path}
+	return LoadBidderInfo(bidderInfoReader)
+}
 
+func LoadBidderInfo(reader InfoReader) (BidderInfos, error) {
+	return processBidderInfos(reader, openrtb_ext.NormalizeBidderName)
+}
+
+func processBidderInfos(reader InfoReader, normalizeBidderName func(string) (openrtb_ext.BidderName, bool)) (BidderInfos, error) {
+	bidderConfigs, err := reader.Read()
+	if err != nil {
+		return nil, fmt.Errorf("error loading bidders data")
+	}
+
+	infos := BidderInfos{}
+
+	for fileName, data := range bidderConfigs {
 		bidderName := strings.Split(fileName, ".")
 		if len(bidderName) == 2 && bidderName[1] == "yaml" {
-			// all bidder names loaded from the file system should be in lowercase
-			// to match bidder names in Viper config bidder infos
-			// this will prevent from missing bidder config overrides
-			// in func applyBidderInfoConfigOverrides
-			infos[(strings.ToLower(bidderName[0]))] = info
+			normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName[0])
+			if !bidderNameExists {
+				return nil, fmt.Errorf("error parsing config for bidder %s: unknown bidder", fileName)
+			}
+			info := BidderInfo{}
+			if err := yaml.Unmarshal(data, &info); err != nil {
+				return nil, fmt.Errorf("error parsing config for bidder %s: %v", fileName, err)
+			}
+
+			infos[string(normalizedBidderName)] = info
 		}
 	}
 	return infos, nil
@@ -349,9 +378,13 @@ func validateSyncer(bidderInfo BidderInfo) error {
 	return nil
 }
 
-func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos BidderInfos) (BidderInfos, error) {
+func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos BidderInfos, normalizeBidderName func(string) (openrtb_ext.BidderName, bool)) (BidderInfos, error) {
 	for bidderName, bidderInfo := range configBidderInfos {
-		if fsBidderCfg, exists := fsBidderInfos[bidderName]; exists {
+		normalizedBidderName, bidderNameExists := normalizeBidderName(bidderName)
+		if !bidderNameExists {
+			return nil, fmt.Errorf("error setting configuration for bidder %s: unknown bidder", bidderName)
+		}
+		if fsBidderCfg, exists := fsBidderInfos[string(normalizedBidderName)]; exists {
 			bidderInfo.Syncer = bidderInfo.Syncer.Override(fsBidderCfg.Syncer)
 
 			if bidderInfo.Endpoint == "" && len(fsBidderCfg.Endpoint) > 0 {
@@ -436,7 +469,9 @@ func applyBidderInfoConfigOverrides(configBidderInfos BidderInfos, fsBidderInfos
 				glog.Warningf("adapters.%s.usersync_url is deprecated and will be removed in a future version, please update to the latest user sync config values", strings.ToLower(bidderName))
 			}
 
-			fsBidderInfos[bidderName] = bidderInfo
+			fsBidderInfos[string(normalizedBidderName)] = bidderInfo
+		} else {
+			return nil, fmt.Errorf("error finding configuration for bidder %s: unknown bidder", bidderName)
 		}
 	}
 	return fsBidderInfos, nil
diff --git a/config/config.go b/config/config.go
index a424a3f1..fc57bdc7 100644
--- a/config/config.go
+++ b/config/config.go
@@ -617,7 +617,7 @@ func (cfg *TimeoutNotification) validate(errs []error) []error {
 }
 
 // New uses viper to get our server configurations.
-func New(v *viper.Viper, bidderInfos BidderInfos) (*Configuration, error) {
+func New(v *viper.Viper, bidderInfos BidderInfos, normalizeBidderName func(string) (openrtb_ext.BidderName, bool)) (*Configuration, error) {
 	var c Configuration
 	if err := v.Unmarshal(&c); err != nil {
 		return nil, fmt.Errorf("viper failed to unmarshal app config: %v", err)
@@ -700,7 +700,7 @@ func New(v *viper.Viper, bidderInfos BidderInfos) (*Configuration, error) {
 	// Migrate combo stored request config to separate stored_reqs and amp stored_reqs configs.
 	resolvedStoredRequestsConfig(&c)
 
-	mergedBidderInfos, err := applyBidderInfoConfigOverrides(c.BidderInfos, bidderInfos)
+	mergedBidderInfos, err := applyBidderInfoConfigOverrides(c.BidderInfos, bidderInfos, normalizeBidderName)
 	if err != nil {
 		return nil, err
 	}
diff --git a/config/test/bidder-info/someBidder.yaml b/config/test/bidder-info-valid/stroeerCore.yaml
similarity index 100%
rename from config/test/bidder-info/someBidder.yaml
rename to config/test/bidder-info-valid/stroeerCore.yaml
diff --git a/exchange/bidder.go b/exchange/bidder.go
index 479c0256..a9fe874e 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -54,7 +54,7 @@ type AdaptedBidder interface {
 	//
 	// Any errors will be user-facing in the API.
 	// Error messages should help publishers understand what might account for "bad" bids.
-	requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) ([]*pbsOrtbSeatBid, []error)
+	requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) ([]*pbsOrtbSeatBid, []error)
 }
 
 // bidRequestOptions holds additional options for bid request execution to maintain clean code and reasonable number of parameters
@@ -154,7 +154,7 @@ type bidderAdapterConfig struct {
 	EndpointCompression string
 }
 
-func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
+func (bidder *bidderAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
 
 	var reqData []*adapters.RequestData
 	var errs []error
diff --git a/exchange/bidder_validate_bids.go b/exchange/bidder_validate_bids.go
index 504b2cf3..d48c3e8f 100644
--- a/exchange/bidder_validate_bids.go
+++ b/exchange/bidder_validate_bids.go
@@ -8,9 +8,9 @@ import (
 
 	"github.com/mxmCherry/openrtb/v16/openrtb2"
 	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/currency"
 	"github.com/prebid/prebid-server/experiment/adscert"
+	"github.com/prebid/prebid-server/openrtb_ext"
 	goCurrency "golang.org/x/text/currency"
 )
 
@@ -29,7 +29,7 @@ type validatedBidder struct {
 	bidder AdaptedBidder
 }
 
-func (v *validatedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
+func (v *validatedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
 	seatBids, errs := v.bidder.requestBid(ctx, bidderRequest, conversions, reqInfo, adsCertSigner, bidRequestOptions, alternateBidderCodes)
 	for _, seatBid := range seatBids {
 		if validationErrors := removeInvalidBids(bidderRequest.BidRequest, seatBid); len(validationErrors) > 0 {
diff --git a/exchange/exchange.go b/exchange/exchange.go
index f1a9a7b8..40fc4a2a 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -286,7 +286,16 @@ func (e *exchange) HoldAuction(ctx context.Context, r AuctionRequest, debugLog *
 	} else {
 		// List of bidders we have requests for.
 		liveAdapters = listBiddersWithRequests(bidderRequests)
-		adapterBids, adapterExtra, anyBidsReturned = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, r.Account.AlternateBidderCodes, requestExt.Prebid.Experiment)
+
+		//This will be used validate bids
+		var alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes
+		if requestExt != nil && requestExt.Prebid.AlternateBidderCodes != nil {
+			alternateBidderCodes = *requestExt.Prebid.AlternateBidderCodes
+		} else if r.Account.AlternateBidderCodes != nil {
+			alternateBidderCodes = *r.Account.AlternateBidderCodes
+		}
+
+		adapterBids, adapterExtra, anyBidsReturned = e.getAllBids(auctionCtx, bidderRequests, bidAdjustmentFactors, conversions, accountDebugAllow, r.GlobalPrivacyControlHeader, debugLog.DebugOverride, alternateBidderCodes, requestExt.Prebid.Experiment)
 	}
 
 	var auc *auction
@@ -494,7 +503,7 @@ func (e *exchange) getAllBids(
 	accountDebugAllowed bool,
 	globalPrivacyControlHeader string,
 	headerDebugAllowed bool,
-	alternateBidderCodes config.AlternateBidderCodes,
+	alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes,
 	experiment *openrtb_ext.Experiment) (
 	map[openrtb_ext.BidderName]*pbsOrtbSeatBid,
 	map[openrtb_ext.BidderName]*seatResponseExtra, bool) {
diff --git a/exchange/utils.go b/exchange/utils.go
index 96e5e2a9..9007e20e 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -237,7 +237,7 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest,
 
 		sChainWriter.Write(&reqCopy, bidder)
 
-		reqCopy.Ext, err = buildRequestExtForBidder(bidder, req.BidRequest.Ext, requestExt, bidderParamsInReqExt)
+		reqCopy.Ext, err = buildRequestExtForBidder(bidder, req.BidRequest.Ext, requestExt, bidderParamsInReqExt, auctionRequest.Account.AlternateBidderCodes)
 		if err != nil {
 			return nil, []error{err}
 		}
@@ -273,8 +273,15 @@ func getAuctionBidderRequests(auctionRequest AuctionRequest,
 	return bidderRequests, errs
 }
 
-func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, requestExtParsed *openrtb_ext.ExtRequest, bidderParamsInReqExt map[string]json.RawMessage) (json.RawMessage, error) {
-	if len(requestExt) == 0 || requestExtParsed == nil {
+func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, requestExtParsed *openrtb_ext.ExtRequest, bidderParamsInReqExt map[string]json.RawMessage, cfgABC *openrtb_ext.ExtAlternateBidderCodes) (json.RawMessage, error) {
+	// Resolve alternatebiddercode for current bidder
+	var reqABC *openrtb_ext.ExtAlternateBidderCodes
+	if len(requestExt) != 0 && requestExtParsed != nil && requestExtParsed.Prebid.AlternateBidderCodes != nil {
+		reqABC = requestExtParsed.Prebid.AlternateBidderCodes
+	}
+	alternateBidderCodes := buildRequestExtAlternateBidderCodes(bidder, cfgABC, reqABC)
+
+	if (len(requestExt) == 0 || requestExtParsed == nil) && alternateBidderCodes == nil {
 		return json.RawMessage(``), nil
 	}
 
@@ -287,11 +294,15 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request
 	// Copy Allowed Fields
 	// Per: https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#prebid-server-ortb2-extension-summary
 	prebid := openrtb_ext.ExtRequestPrebid{
-		Integration:         requestExtParsed.Prebid.Integration,
-		Channel:             requestExtParsed.Prebid.Channel,
-		Debug:               requestExtParsed.Prebid.Debug,
-		CurrencyConversions: requestExtParsed.Prebid.CurrencyConversions,
-		BidderParams:        bidderParams,
+		BidderParams:         bidderParams,
+		AlternateBidderCodes: alternateBidderCodes,
+	}
+
+	if requestExtParsed != nil {
+		prebid.CurrencyConversions = requestExtParsed.Prebid.CurrencyConversions
+		prebid.Integration = requestExtParsed.Prebid.Integration
+		prebid.Channel = requestExtParsed.Prebid.Channel
+		prebid.Debug = requestExtParsed.Prebid.Debug
 	}
 
 	// Marshal New Prebid Object
@@ -302,14 +313,44 @@ func buildRequestExtForBidder(bidder string, requestExt json.RawMessage, request
 
 	// Update Ext With Prebid Json
 	extMap := make(map[string]json.RawMessage)
-	if err := json.Unmarshal(requestExt, &extMap); err != nil {
-		return nil, err
+	if len(requestExt) != 0 {
+		if err := json.Unmarshal(requestExt, &extMap); err != nil {
+			return nil, err
+		}
 	}
 	extMap["prebid"] = prebidJson
 
 	return json.Marshal(extMap)
 }
 
+func buildRequestExtAlternateBidderCodes(bidder string, accABC *openrtb_ext.ExtAlternateBidderCodes, reqABC *openrtb_ext.ExtAlternateBidderCodes) *openrtb_ext.ExtAlternateBidderCodes {
+	if reqABC != nil {
+		alternateBidderCodes := &openrtb_ext.ExtAlternateBidderCodes{
+			Enabled: reqABC.Enabled,
+		}
+		if bidderCodes, ok := reqABC.Bidders[bidder]; ok {
+			alternateBidderCodes.Bidders = map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+				bidder: bidderCodes,
+			}
+		}
+		return alternateBidderCodes
+	}
+
+	if accABC != nil {
+		alternateBidderCodes := &openrtb_ext.ExtAlternateBidderCodes{
+			Enabled: accABC.Enabled,
+		}
+		if bidderCodes, ok := accABC.Bidders[bidder]; ok {
+			alternateBidderCodes.Bidders = map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+				bidder: bidderCodes,
+			}
+		}
+		return alternateBidderCodes
+	}
+
+	return nil
+}
+
 // extractBuyerUIDs parses the values from user.ext.prebid.buyeruids, and then deletes those values from the ext.
 // This prevents a Bidder from using these values to figure out who else is involved in the Auction.
 func extractBuyerUIDs(user *openrtb2.User) (map[string]string, error) {
diff --git a/main.go b/main.go
index bdd79f11..a8326666 100644
--- a/main.go
+++ b/main.go
@@ -10,6 +10,7 @@ import (
 
 	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/currency"
+	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prebid/prebid-server/router"
 	"github.com/prebid/prebid-server/server"
 	"github.com/prebid/prebid-server/util/task"
@@ -30,7 +31,7 @@ func main() {
 		glog.Exitf("Unable to build configuration directory path: %v", err)
 	}
 
-	bidderInfos, err := config.LoadBidderInfo(bidderInfoPath)
+	bidderInfos, err := config.LoadBidderInfoFromDisk(bidderInfoPath)
 	if err != nil {
 		glog.Exitf("Unable to load bidder configurations: %v", err)
 	}
@@ -59,7 +60,7 @@ const infoDirectory = "./static/bidder-info"
 func loadConfig(bidderInfos config.BidderInfos) (*config.Configuration, error) {
 	v := viper.New()
 	config.SetupViper(v, configFileName, bidderInfos)
-	return config.New(v, bidderInfos)
+	return config.New(v, bidderInfos, openrtb_ext.NormalizeBidderName)
 }
 
 func serve(cfg *config.Configuration) error {
diff --git a/openrtb_ext/alternatebiddercodes.go b/openrtb_ext/alternatebiddercodes.go
new file mode 100644
index 00000000..49291a3e
--- /dev/null
+++ b/openrtb_ext/alternatebiddercodes.go
@@ -0,0 +1,58 @@
+package openrtb_ext
+
+import "fmt"
+
+// ExtAlternateBidderCodes defines list of alternate bidder codes allowed by adatpers. This overrides host level configs.
+type ExtAlternateBidderCodes struct {
+	Enabled bool                                      `mapstructure:"enabled" json:"enabled"`
+	Bidders map[string]ExtAdapterAlternateBidderCodes `mapstructure:"bidders" json:"bidders"`
+}
+
+type ExtAdapterAlternateBidderCodes struct {
+	Enabled            bool     `mapstructure:"enabled" json:"enabled"`
+	AllowedBidderCodes []string `mapstructure:"allowedbiddercodes" json:"allowedbiddercodes"`
+}
+
+func (bidderCodes *ExtAlternateBidderCodes) IsValidBidderCode(bidder, alternateBidder string) (bool, error) {
+	if alternateBidder == "" || bidder == alternateBidder {
+		return true, nil
+	}
+
+	if !bidderCodes.Enabled {
+		return false, alternateBidderDisabledError(bidder, alternateBidder)
+	}
+
+	if bidderCodes.Bidders == nil {
+		return false, alternateBidderNotDefinedError(bidder, alternateBidder)
+	}
+
+	adapterCfg, ok := bidderCodes.Bidders[bidder]
+	if !ok {
+		return false, alternateBidderNotDefinedError(bidder, alternateBidder)
+	}
+
+	if !adapterCfg.Enabled {
+		// config has bidder entry but is not enabled, report it
+		return false, alternateBidderDisabledError(bidder, alternateBidder)
+	}
+
+	if adapterCfg.AllowedBidderCodes == nil || (len(adapterCfg.AllowedBidderCodes) == 1 && adapterCfg.AllowedBidderCodes[0] == "*") {
+		return true, nil
+	}
+
+	for _, code := range adapterCfg.AllowedBidderCodes {
+		if alternateBidder == code {
+			return true, nil
+		}
+	}
+
+	return false, fmt.Errorf("invalid biddercode %q sent by adapter %q", alternateBidder, bidder)
+}
+
+func alternateBidderDisabledError(bidder, alternateBidder string) error {
+	return fmt.Errorf("alternateBidderCodes disabled for %q, rejecting bids for %q", bidder, alternateBidder)
+}
+
+func alternateBidderNotDefinedError(bidder, alternateBidder string) error {
+	return fmt.Errorf("alternateBidderCodes not defined for adapter %q, rejecting bids for %q", bidder, alternateBidder)
+}
diff --git a/openrtb_ext/request.go b/openrtb_ext/request.go
index b3807c5d..cb33b0bb 100644
--- a/openrtb_ext/request.go
+++ b/openrtb_ext/request.go
@@ -58,6 +58,9 @@ type ExtRequestPrebid struct {
 	// passing of personally identifiable information doesn't constitute a sale per CCPA law.
 	// The array may contain a single sstar ('*') entry to represent all bidders.
 	NoSale []string `json:"nosale,omitempty"`
+
+	//AlternateBidderCodes is populated with host's AlternateBidderCodes config if not defined in request
+	AlternateBidderCodes *ExtAlternateBidderCodes `json:"alternatebiddercodes,omitempty"`
 }
 
 // Experiment defines if experimental features are available for the request
diff --git a/static/bidder-info/grid.yaml b/static/bidder-info/grid.yaml
index 409bad60..bf1832c9 100644
--- a/static/bidder-info/grid.yaml
+++ b/static/bidder-info/grid.yaml
@@ -7,10 +7,12 @@ capabilities:
     mediaTypes:
       - banner
       - video
+      - native
   site:
     mediaTypes:
       - banner
       - video
+      - native
 userSync:
   redirect:
     url: "https://x.bidswitch.net/check_uuid/{{.RedirectURL}}?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}"


Test patch:
diff --git a/adapters/grid/gridtest/exemplary/multitype-native.json b/adapters/grid/gridtest/exemplary/multitype-native.json
new file mode 100644
index 00000000..2a142938
--- /dev/null
+++ b/adapters/grid/gridtest/exemplary/multitype-native.json
@@ -0,0 +1,110 @@
+{
+    "mockBidRequest": {
+        "id": "test-request-id",
+        "site": {
+            "page": "https://good.site/url"
+        },
+        "imp": [{
+            "id": "test-imp-id",
+            "banner": {
+                "format": [{
+                    "w": 300,
+                    "h": 250
+                }]
+            },
+            "video": {
+                "mimes": ["video/mp4"],
+                "protocols": [2, 5],
+                "w": 300,
+                "h": 250
+            },
+            "native": {
+                "ver": "1.1",
+                "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}"
+            },
+            "ext": {
+                "bidder": {
+                    "uid": 1
+                }
+            }
+        }]
+    },
+
+    "httpCalls": [{
+        "expectedRequest": {
+            "uri": "http://localhost/prebid",
+            "body": {
+                "id": "test-request-id",
+                "site": {
+                    "page": "https://good.site/url"
+                },
+                "imp": [{
+                    "id": "test-imp-id",
+                    "banner": {
+                        "format": [{
+                            "w": 300,
+                            "h": 250
+                        }]
+                    },
+                    "video": {
+                        "mimes": ["video/mp4"],
+                        "protocols": [2, 5],
+                        "w": 300,
+                        "h": 250
+                    },
+                    "native": {
+                        "ver": "1.1",
+                            "request_native": {"ver":"1.0","layout":1,"adunit":1,"plcmttype":1,"plcmtcnt":1,"seq":0,"assets":[{"id":1,"required":1,"title":{"len":75}},{"id":2,"required":1,"img":{"type":3,"wmin":60,"hmin":60,"mimes":["image/jpeg","image/jpg","image/png"]}},{"id":3,"required":0,"data":{"type":2,"len":75}},{"id":4,"required":0,"data":{"type":6,"len":1000}},{"id":5,"required":0,"data":{"type":7,"len":1000}},{"id":6,"required":0,"data":{"type":11,"len":1000}}]}
+                    },
+                    "ext": {
+                        "bidder": {
+                            "uid": 1
+                        }
+                    }
+                }]
+            }
+        },
+        "mockResponse": {
+            "status": 200,
+            "body": {
+                "id": "test-request-id",
+                "seatbid": [{
+                    "seat": "grid",
+                    "bid": [{
+                        "id": "randomid",
+                        "impid": "test-imp-id",
+                        "price": 0.500000,
+                        "adid": "12345678",
+                        "adm_native": {
+                            "some_native_key": "native_value"
+                        },
+                        "cid": "987",
+                        "crid": "12345678",
+                        "content_type": "native",
+                        "h": 250,
+                        "w": 300
+                    }]
+                }],
+                "cur": "USD"
+            }
+        }
+    }],
+
+    "expectedBidResponses": [{
+        "currency": "USD",
+        "bids": [{
+            "bid": {
+                "id": "randomid",
+                "impid": "test-imp-id",
+                "price": 0.5,
+                "adm": "{\"some_native_key\":\"native_value\"}",
+                "adid": "12345678",
+                "cid": "987",
+                "crid": "12345678",
+                "w": 300,
+                "h": 250
+            },
+            "type": "native"
+        }]
+    }]
+}
diff --git a/adapters/grid/gridtest/exemplary/native-as-string.json b/adapters/grid/gridtest/exemplary/native-as-string.json
new file mode 100644
index 00000000..3ad66b98
--- /dev/null
+++ b/adapters/grid/gridtest/exemplary/native-as-string.json
@@ -0,0 +1,85 @@
+{
+    "mockBidRequest": {
+        "id": "test-request-id",
+        "site": {
+            "page": "https://good.site/url"
+        },
+        "imp": [{
+            "id": "test-imp-id",
+            "native": {
+                "ver": "1.1",
+                "request": "request string"
+            },
+            "ext": {
+                "bidder": {
+                    "uid": 1
+                }
+            }
+        }]
+    },
+
+    "httpCalls": [{
+        "expectedRequest": {
+            "uri": "http://localhost/prebid",
+            "body": {
+                "id": "test-request-id",
+                "site": {
+                    "page": "https://good.site/url"
+                },
+                "imp": [{
+                    "id": "test-imp-id",
+                    "native": {
+                        "ver": "1.1",
+                        "request_native": "request string"
+                    },
+                    "ext": {
+                        "bidder": {
+                            "uid": 1
+                        }
+                    }
+                }]
+            }
+        },
+        "mockResponse": {
+            "status": 200,
+            "body": {
+                "id": "test-request-id",
+                "seatbid": [{
+                    "seat": "grid",
+                    "bid": [{
+                        "id": "randomid",
+                        "impid": "test-imp-id",
+                        "price": 0.500000,
+                        "adid": "12345678",
+                        "adm_native": {
+                            "some_native_key": "native_value"
+                        },
+                        "cid": "987",
+                        "crid": "12345678",
+                        "h": 250,
+                        "w": 300
+                    }]
+                }],
+                "cur": "USD"
+            }
+        }
+    }],
+
+    "expectedBidResponses": [{
+        "currency": "USD",
+        "bids": [{
+            "bid": {
+                "id": "randomid",
+                "impid": "test-imp-id",
+                "price": 0.5,
+                "adm": "{\"some_native_key\":\"native_value\"}",
+                "adid": "12345678",
+                "cid": "987",
+                "crid": "12345678",
+                "w": 300,
+                "h": 250
+            },
+            "type": "native"
+        }]
+    }]
+}
diff --git a/adapters/grid/gridtest/exemplary/simple-native.json b/adapters/grid/gridtest/exemplary/simple-native.json
new file mode 100644
index 00000000..be7c17f7
--- /dev/null
+++ b/adapters/grid/gridtest/exemplary/simple-native.json
@@ -0,0 +1,85 @@
+{
+    "mockBidRequest": {
+        "id": "test-request-id",
+        "site": {
+            "page": "https://good.site/url"
+        },
+        "imp": [{
+            "id": "test-imp-id",
+            "native": {
+                "ver": "1.1",
+                "request": "{\"ver\":\"1.0\",\"layout\":1,\"adunit\":1,\"plcmttype\":1,\"plcmtcnt\":1,\"seq\":0,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":75}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"wmin\":60,\"hmin\":60,\"mimes\":[\"image/jpeg\",\"image/jpg\",\"image/png\"]}},{\"id\":3,\"required\":0,\"data\":{\"type\":2,\"len\":75}},{\"id\":4,\"required\":0,\"data\":{\"type\":6,\"len\":1000}},{\"id\":5,\"required\":0,\"data\":{\"type\":7,\"len\":1000}},{\"id\":6,\"required\":0,\"data\":{\"type\":11,\"len\":1000}}]}"
+            },
+            "ext": {
+                "bidder": {
+                    "uid": 1
+                }
+            }
+        }]
+    },
+
+    "httpCalls": [{
+        "expectedRequest": {
+            "uri": "http://localhost/prebid",
+            "body": {
+                "id": "test-request-id",
+                "site": {
+                    "page": "https://good.site/url"
+                },
+                "imp": [{
+                    "id": "test-imp-id",
+                    "native": {
+                        "ver": "1.1",
+                        "request_native": {"ver":"1.0","layout":1,"adunit":1,"plcmttype":1,"plcmtcnt":1,"seq":0,"assets":[{"id":1,"required":1,"title":{"len":75}},{"id":2,"required":1,"img":{"type":3,"wmin":60,"hmin":60,"mimes":["image/jpeg","image/jpg","image/png"]}},{"id":3,"required":0,"data":{"type":2,"len":75}},{"id":4,"required":0,"data":{"type":6,"len":1000}},{"id":5,"required":0,"data":{"type":7,"len":1000}},{"id":6,"required":0,"data":{"type":11,"len":1000}}]}
+                    },
+                    "ext": {
+                        "bidder": {
+                            "uid": 1
+                        }
+                    }
+                }]
+            }
+        },
+        "mockResponse": {
+            "status": 200,
+            "body": {
+                "id": "test-request-id",
+                "seatbid": [{
+                    "seat": "grid",
+                    "bid": [{
+                        "id": "randomid",
+                        "impid": "test-imp-id",
+                        "price": 0.500000,
+                        "adid": "12345678",
+                        "adm_native": {
+                            "some_native_key": "native_value"
+                        },
+                        "cid": "987",
+                        "crid": "12345678",
+                        "h": 250,
+                        "w": 300
+                    }]
+                }],
+                "cur": "USD"
+            }
+        }
+    }],
+
+    "expectedBidResponses": [{
+        "currency": "USD",
+        "bids": [{
+            "bid": {
+                "id": "randomid",
+                "impid": "test-imp-id",
+                "price": 0.5,
+                "adm": "{\"some_native_key\":\"native_value\"}",
+                "adid": "12345678",
+                "cid": "987",
+                "crid": "12345678",
+                "w": 300,
+                "h": 250
+            },
+            "type": "native"
+        }]
+    }]
+}
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner1.json b/adapters/huaweiads/huaweiadstest/exemplary/banner1.json
index da88a6b7..ffcc704f 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/banner1.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner1.json
@@ -47,6 +47,7 @@
       "ip": "ip",
       "ifa": "e4fe9bde-caa0-47b6-908d-ffba3fa184f2",
       "pxratio": 23.01,
+      "mccmnc": "460",
       "geo": {
         "country": "CHN"
       }
@@ -103,7 +104,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
@@ -125,7 +126,7 @@
             "pxratio": 23.01,
             "width": 1080,
             "clientTime": "2018-11-02 16:34:07.981+1300",
-            "gaid": "e4fe9bde-caa0-47b6-908d-ffba3fa184f2",
+            "gaid": "gaid",
             "useragent": "useragent",
             "version": "10.0.0",
             "maker": "huawei",
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner2.json b/adapters/huaweiads/huaweiadstest/exemplary/banner2.json
index 44324d8c..4f1cc6b4 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/banner2.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner2.json
@@ -126,7 +126,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner3.json b/adapters/huaweiads/huaweiadstest/exemplary/banner3.json
new file mode 100644
index 00000000..d012dd8e
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner3.json
@@ -0,0 +1,271 @@
+{
+  "mockBidRequest": {
+    "id": "a3b18c5b-6708-4bb7-b41b-40ed37d89561",
+    "source": {
+      "tid": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+    },
+    "imp": [
+      {
+        "id": "PrebidMobile",
+        "secure": 1,
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "api": [
+            5
+          ]
+        },
+        "ext": {
+          "prebid": {
+            "storedrequest": {
+              "id": "1001-1"
+            }
+          },
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "device": {
+      "make": "HUAWEI",
+      "model": "LYA-AL00",
+      "ua": "ua",
+      "lmt": 0,
+      "os": "android",
+      "osv": "29",
+      "language": "za",
+      "w": 360,
+      "h": 755,
+      "pxratio": 3,
+      "mccmnc": "424-3",
+      "carrier": "carrier",
+      "connectiontype": 1,
+      "geo": {
+      }
+    },
+    "app": {
+      "bundle": "com.example.p10",
+      "ver": "1.11",
+      "name": "API1.0Demo",
+      "publisher": {
+        "id": "1001"
+      },
+      "ext": {
+        "prebid": {
+          "source": "prebid-mobile",
+          "version": "1.11"
+        }
+      }
+    },
+    "user": {
+      "gender": "O",
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        }
+      }
+    },
+    "ext": {
+      "prebid": {
+        "storedrequest": {
+          "id": "1001"
+        },
+        "cache": {
+          "bids": {}
+        },
+        "targeting": {}
+      }
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://adx-dra.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "ua"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "en",
+            "country": "AE",
+            "name": "API1.0Demo",
+            "pkgname": "com.example.pkgname2",
+            "version": "1.11"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "device": {
+            "height": 755,
+            "language": "za",
+            "oaid": "oaid",
+            "os": "android",
+            "localeCountry": "AE",
+            "pxratio": 3,
+            "width": 360,
+            "model": "LYA-AL00",
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "useragent": "ua",
+            "version": "29",
+            "maker": "HUAWEI",
+            "belongCountry": "AE"
+          },
+          "geo": {
+          },
+          "network": {
+            "carrier": 99,
+            "cellInfo": [
+              {
+                "mcc": "424",
+                "mnc": "3"
+              }
+            ],
+            "type": 1
+          },
+          "regs": {
+          },
+          "version": "3.4",
+          "clientAdRequestId": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 250,
+                        "imageType": "img",
+                        "sha256": "",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 300
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click"
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='300' height='250'/> </a> <script type=\"text/javascript\">var dspClickTrackings = [];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "h": 250,
+            "w": 300,
+            "crid": "58025103",
+            "id": "PrebidMobile",
+            "impid": "PrebidMobile",
+            "price": 2.8
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner4_mccmnc.json b/adapters/huaweiads/huaweiadstest/exemplary/banner4_mccmnc.json
new file mode 100644
index 00000000..d72cdb19
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner4_mccmnc.json
@@ -0,0 +1,269 @@
+{
+  "mockBidRequest": {
+    "id": "a3b18c5b-6708-4bb7-b41b-40ed37d89561",
+    "source": {
+      "tid": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+    },
+    "imp": [
+      {
+        "id": "PrebidMobile",
+        "secure": 1,
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "api": [
+            5
+          ]
+        },
+        "ext": {
+          "prebid": {
+            "storedrequest": {
+              "id": "1001-1"
+            }
+          },
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "device": {
+      "make": "HUAWEI",
+      "model": "LYA-AL00",
+      "ua": "ua",
+      "lmt": 0,
+      "os": "android",
+      "osv": "29",
+      "language": "zh",
+      "w": 360,
+      "h": 755,
+      "pxratio": 3,
+      "mccmnc": "655-1",
+      "carrier": "carrier",
+      "connectiontype": 1
+    },
+    "app": {
+      "bundle": "com.example.p10",
+      "ver": "1.11",
+      "name": "API1.0Demo",
+      "publisher": {
+        "id": "1001"
+      },
+      "ext": {
+        "prebid": {
+          "source": "prebid-mobile",
+          "version": "1.11"
+        }
+      }
+    },
+    "user": {
+      "gender": "O",
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        }
+      }
+    },
+    "ext": {
+      "prebid": {
+        "storedrequest": {
+          "id": "1001"
+        },
+        "cache": {
+          "bids": {}
+        },
+        "targeting": {}
+      }
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://adx-dra.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "ua"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "en",
+            "country": "ZA",
+            "name": "API1.0Demo",
+            "pkgname": "com.example.pkgname2",
+            "version": "1.11"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "device": {
+            "height": 755,
+            "language": "zh",
+            "oaid": "oaid",
+            "os": "android",
+            "localeCountry": "ZA",
+            "pxratio": 3,
+            "width": 360,
+            "model": "LYA-AL00",
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "useragent": "ua",
+            "version": "29",
+            "maker": "HUAWEI",
+            "belongCountry": "ZA"
+          },
+          "geo": {
+          },
+          "network": {
+            "carrier": 99,
+            "cellInfo": [
+              {
+                "mcc": "655",
+                "mnc": "1"
+              }
+            ],
+            "type": 1
+          },
+          "regs": {
+          },
+          "version": "3.4",
+          "clientAdRequestId": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 250,
+                        "imageType": "img",
+                        "sha256": "",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 300
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click"
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='300' height='250'/> </a> <script type=\"text/javascript\">var dspClickTrackings = [];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "h": 250,
+            "w": 300,
+            "crid": "58025103",
+            "id": "PrebidMobile",
+            "impid": "PrebidMobile",
+            "price": 2.8
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner5_user_geo.json b/adapters/huaweiads/huaweiadstest/exemplary/banner5_user_geo.json
new file mode 100644
index 00000000..987d157e
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner5_user_geo.json
@@ -0,0 +1,272 @@
+{
+  "mockBidRequest": {
+    "id": "a3b18c5b-6708-4bb7-b41b-40ed37d89561",
+    "source": {
+      "tid": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+    },
+    "imp": [
+      {
+        "id": "PrebidMobile",
+        "secure": 1,
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "api": [
+            5
+          ]
+        },
+        "ext": {
+          "prebid": {
+            "storedrequest": {
+              "id": "1001-1"
+            }
+          },
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "device": {
+      "make": "HUAWEI",
+      "model": "LYA-AL00",
+      "ua": "ua",
+      "lmt": 0,
+      "os": "android",
+      "osv": "29",
+      "language": "zh",
+      "w": 360,
+      "h": 755,
+      "pxratio": 3,
+      "mccmnc": "655-1",
+      "carrier": "carrier",
+      "connectiontype": 1
+    },
+    "app": {
+      "bundle": "com.example.p10",
+      "ver": "1.11",
+      "name": "API1.0Demo",
+      "publisher": {
+        "id": "1001"
+      },
+      "ext": {
+        "prebid": {
+          "source": "prebid-mobile",
+          "version": "1.11"
+        }
+      }
+    },
+    "user": {
+      "gender": "O",
+      "geo": {
+        "country": "ZAF"
+      },
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        }
+      }
+    },
+    "ext": {
+      "prebid": {
+        "storedrequest": {
+          "id": "1001"
+        },
+        "cache": {
+          "bids": {}
+        },
+        "targeting": {}
+      }
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://adx-dra.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "ua"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "en",
+            "country": "ZA",
+            "name": "API1.0Demo",
+            "pkgname": "com.example.pkgname2",
+            "version": "1.11"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "device": {
+            "height": 755,
+            "language": "zh",
+            "oaid": "oaid",
+            "os": "android",
+            "localeCountry": "ZA",
+            "pxratio": 3,
+            "width": 360,
+            "model": "LYA-AL00",
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "useragent": "ua",
+            "version": "29",
+            "maker": "HUAWEI",
+            "belongCountry": "ZA"
+          },
+          "geo": {
+          },
+          "network": {
+            "carrier": 99,
+            "cellInfo": [
+              {
+                "mcc": "655",
+                "mnc": "1"
+              }
+            ],
+            "type": 1
+          },
+          "regs": {
+          },
+          "version": "3.4",
+          "clientAdRequestId": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 250,
+                        "imageType": "img",
+                        "sha256": "",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 300
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click"
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='300' height='250'/> </a> <script type=\"text/javascript\">var dspClickTrackings = [];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "h": 250,
+            "w": 300,
+            "crid": "58025103",
+            "id": "PrebidMobile",
+            "impid": "PrebidMobile",
+            "price": 2.8
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/banner6_imei.json b/adapters/huaweiads/huaweiadstest/exemplary/banner6_imei.json
new file mode 100644
index 00000000..4de8fa7e
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/banner6_imei.json
@@ -0,0 +1,262 @@
+{
+  "mockBidRequest": {
+    "id": "test-req-id",
+    "imp": [
+      {
+        "id": "test-imp-id",
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "w": 300,
+          "h": 250
+        },
+        "ext": {
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "app": {
+      "bundle": "com.example.p1",
+      "name": "Huawei Browser",
+      "ver": "9.1.0.301",
+      "content": {
+        "language": "zh"
+      }
+    },
+    "device": {
+      "ua": "useragent",
+      "h": 1920,
+      "language": "zh",
+      "model": "COL-TEST",
+      "os": "android",
+      "osv": "10.0.0",
+      "devicetype": 4,
+      "make": "huawei",
+      "w": 1080,
+      "ip": "ip",
+      "ifa": "e4fe9bde-caa0-47b6-908d-ffba3fa184f2",
+      "pxratio": 23.01,
+      "mccmnc": "460",
+      "geo": {
+        "country": "CHN"
+      }
+    },
+    "user": {
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "imei": [
+            "354347048908641"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        },
+        "consent": "CPaYLJBPaYLJBIPAAAENCSCgAPAAAAAAAAAAGsQAQGsAAAAA.YAAAAAAAAAA"
+      }
+    },
+    "regs": {
+      "coppa": 1
+    },
+    "ext": {
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://acd.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "useragent"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "zh",
+            "country": "CN",
+            "name": "Huawei Browser",
+            "pkgname": "com.example.pkgname1",
+            "version": "9.1.0.301"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ],
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "device": {
+            "height": 1920,
+            "language": "zh",
+            "oaid": "oaid",
+            "os": "android",
+            "type": 4,
+            "ip": "ip",
+            "localeCountry": "CN",
+            "pxratio": 23.01,
+            "width": 1080,
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "imei": "354347048908641",
+            "useragent": "useragent",
+            "version": "10.0.0",
+            "maker": "huawei",
+            "model": "COL-TEST",
+            "belongCountry": "CN"
+          },
+          "geo": {
+          },
+          "network": {
+            "type": 0
+          },
+          "regs": {
+            "coppa": 1
+          },
+          "consent": "CPaYLJBPaYLJBIPAAAENCSCgAPAAAAAAAAAAGsQAQGsAAAAA.YAAAAAAAAAA",
+          "version": "3.4",
+          "clientAdRequestId": "test-req-id"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "ctrlSwitchs": "001011001001010112",
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 300,
+                        "imageType": "img",
+                        "sha256": "f5d8487cddaecec45b73fc078649478c80ec646bfec8ed7da4ff931f90eab232",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 250
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click",
+                      "url": [
+                        "http://test/click1",
+                        "http://test/click2",
+                        "http://test/click3"
+                      ]
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                        "http://test/imp1",
+                        "http://test/imp2",
+                        "http://test/imp3"
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='250' height='300'/> </a> <img height=\"1\" width=\"1\" src='http://test/imp1' >  <img height=\"1\" width=\"1\" src='http://test/imp2' >  <img height=\"1\" width=\"1\" src='http://test/imp3' >  <script type=\"text/javascript\">var dspClickTrackings = [\"http://test/click1\",\"http://test/click2\",\"http://test/click3\"];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "crid": "58025103",
+            "id": "test-imp-id",
+            "impid": "test-imp-id",
+            "price": 2.8,
+            "h": 300,
+            "w": 250
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerAppPromotionType.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerAppPromotionType.json
index b7ad2dbf..685a5235 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/bannerAppPromotionType.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerAppPromotionType.json
@@ -101,7 +101,7 @@
             {
               "adtype": 8,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerNonIntegerMccmnc.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerNonIntegerMccmnc.json
new file mode 100644
index 00000000..8cb6ca92
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerNonIntegerMccmnc.json
@@ -0,0 +1,269 @@
+{
+  "mockBidRequest": {
+    "id": "a3b18c5b-6708-4bb7-b41b-40ed37d89561",
+    "source": {
+      "tid": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+    },
+    "imp": [
+      {
+        "id": "PrebidMobile",
+        "secure": 1,
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "api": [
+            5
+          ]
+        },
+        "ext": {
+          "prebid": {
+            "storedrequest": {
+              "id": "1001-1"
+            }
+          },
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "device": {
+      "make": "HUAWEI",
+      "model": "LYA-AL00",
+      "ua": "ua",
+      "lmt": 0,
+      "os": "android",
+      "osv": "29",
+      "language": "zh",
+      "w": 360,
+      "h": 755,
+      "pxratio": 3,
+      "mccmnc": "test-1",
+      "carrier": "carrier",
+      "connectiontype": 1
+    },
+    "app": {
+      "bundle": "com.example.p10",
+      "ver": "1.11",
+      "name": "API1.0Demo",
+      "publisher": {
+        "id": "1001"
+      },
+      "ext": {
+        "prebid": {
+          "source": "prebid-mobile",
+          "version": "1.11"
+        }
+      }
+    },
+    "user": {
+      "gender": "O",
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        }
+      }
+    },
+    "ext": {
+      "prebid": {
+        "storedrequest": {
+          "id": "1001"
+        },
+        "cache": {
+          "bids": {}
+        },
+        "targeting": {}
+      }
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://adx-dra.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "ua"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "en",
+            "country": "ZA",
+            "name": "API1.0Demo",
+            "pkgname": "com.example.pkgname2",
+            "version": "1.11"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "device": {
+            "height": 755,
+            "language": "zh",
+            "oaid": "oaid",
+            "os": "android",
+            "localeCountry": "ZA",
+            "pxratio": 3,
+            "width": 360,
+            "model": "LYA-AL00",
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "useragent": "ua",
+            "version": "29",
+            "maker": "HUAWEI",
+            "belongCountry": "ZA"
+          },
+          "geo": {
+          },
+          "network": {
+            "carrier": 99,
+            "cellInfo": [
+              {
+                "mcc": "test",
+                "mnc": "1"
+              }
+            ],
+            "type": 1
+          },
+          "regs": {
+          },
+          "version": "3.4",
+          "clientAdRequestId": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 250,
+                        "imageType": "img",
+                        "sha256": "",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 300
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click"
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='300' height='250'/> </a> <script type=\"text/javascript\">var dspClickTrackings = [];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "h": 250,
+            "w": 300,
+            "crid": "58025103",
+            "id": "PrebidMobile",
+            "impid": "PrebidMobile",
+            "price": 2.8
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerNotAppPromotionType.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerNotAppPromotionType.json
index e19b3c65..ec1ace1d 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/bannerNotAppPromotionType.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerNotAppPromotionType.json
@@ -101,7 +101,7 @@
             {
               "adtype": 8,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo1.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo1.json
index e70fd009..6010fdcf 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo1.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo1.json
@@ -101,7 +101,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo2.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo2.json
index 1528e2c0..43e540f3 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo2.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo2.json
@@ -126,7 +126,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo3.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo3.json
index 10032ae6..65f47015 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo3.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerTestExtraInfo3.json
@@ -126,7 +126,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/bannerWrongMccmnc.json b/adapters/huaweiads/huaweiadstest/exemplary/bannerWrongMccmnc.json
new file mode 100644
index 00000000..52962e45
--- /dev/null
+++ b/adapters/huaweiads/huaweiadstest/exemplary/bannerWrongMccmnc.json
@@ -0,0 +1,269 @@
+{
+  "mockBidRequest": {
+    "id": "a3b18c5b-6708-4bb7-b41b-40ed37d89561",
+    "source": {
+      "tid": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+    },
+    "imp": [
+      {
+        "id": "PrebidMobile",
+        "secure": 1,
+        "banner": {
+          "format": [
+            {
+              "w": 300,
+              "h": 250
+            }
+          ],
+          "api": [
+            5
+          ]
+        },
+        "ext": {
+          "prebid": {
+            "storedrequest": {
+              "id": "1001-1"
+            }
+          },
+          "bidder": {
+            "slotid": "m8x9x3rzff",
+            "adtype": "banner",
+            "publisherid": "123",
+            "signkey": "signkey",
+            "keyid": "41",
+            "isTestAuthorization": "true"
+          }
+        }
+      }
+    ],
+    "device": {
+      "make": "HUAWEI",
+      "model": "LYA-AL00",
+      "ua": "ua",
+      "lmt": 0,
+      "os": "android",
+      "osv": "29",
+      "language": "zh",
+      "w": 360,
+      "h": 755,
+      "pxratio": 3,
+      "mccmnc": "203-1",
+      "carrier": "carrier",
+      "connectiontype": 1
+    },
+    "app": {
+      "bundle": "com.example.p10",
+      "ver": "1.11",
+      "name": "API1.0Demo",
+      "publisher": {
+        "id": "1001"
+      },
+      "ext": {
+        "prebid": {
+          "source": "prebid-mobile",
+          "version": "1.11"
+        }
+      }
+    },
+    "user": {
+      "gender": "O",
+      "ext": {
+        "data": {
+          "gaid": [
+            "gaid"
+          ],
+          "oaid": [
+            "oaid"
+          ],
+          "clientTime": [
+            "2018-11-02 16:34:07.981+1300"
+          ]
+        }
+      }
+    },
+    "ext": {
+      "prebid": {
+        "storedrequest": {
+          "id": "1001"
+        },
+        "cache": {
+          "bids": {}
+        },
+        "targeting": {}
+      }
+    }
+  },
+  "httpcalls": [
+    {
+      "expectedRequest": {
+        "uri": "https://adx-dra.op.hicloud.com/ppsadx/getResult",
+        "headers": {
+          "Accept": [
+            "application/json"
+          ],
+          "Content-Type": [
+            "application/json;charset=utf-8"
+          ],
+          "User-Agent": [
+            "ua"
+          ],
+          "Authorization": [
+            "Digest username=123,realm=ppsadx/getResult,nonce=1629473330823,response=d1d61a13a83e1468aa4dff5c8a6cee0b8b381173ca3eb6fa9b313937684d87c0,algorithm=HmacSHA256,usertype=1,keyid=41"
+          ]
+        },
+        "body": {
+          "app": {
+            "lang": "en",
+            "country": "ZA",
+            "name": "API1.0Demo",
+            "pkgname": "com.example.pkgname2",
+            "version": "1.11"
+          },
+          "multislot": [
+            {
+              "adtype": 8,
+              "slotid": "m8x9x3rzff",
+              "test": 1,
+              "format": [
+                {
+                  "w": 300,
+                  "h": 250
+                }
+              ]
+            }
+          ],
+          "device": {
+            "height": 755,
+            "language": "zh",
+            "oaid": "oaid",
+            "os": "android",
+            "localeCountry": "ZA",
+            "pxratio": 3,
+            "width": 360,
+            "model": "LYA-AL00",
+            "clientTime": "2018-11-02 16:34:07.981+1300",
+            "gaid": "gaid",
+            "useragent": "ua",
+            "version": "29",
+            "maker": "HUAWEI",
+            "belongCountry": "ZA"
+          },
+          "geo": {
+          },
+          "network": {
+            "carrier": 99,
+            "cellInfo": [
+              {
+                "mcc": "203",
+                "mnc": "1"
+              }
+            ],
+            "type": 1
+          },
+          "regs": {
+          },
+          "version": "3.4",
+          "clientAdRequestId": "a3b18c5b-6708-4bb7-b41b-40ed37d89561"
+        }
+      },
+      "mockResponse": {
+        "status": 200,
+        "body": {
+          "ctrlSwitchs": "0",
+          "dsp1cost": 61,
+          "dspcost": 108,
+          "multiad": [
+            {
+              "adtype": 8,
+              "brsetting": "Y",
+              "content": [
+                {
+                  "clickActionList": [
+                    1
+                  ],
+                  "contentid": "58025103",
+                  "creativetype": 2,
+                  "endtime": 1621428898335,
+                  "filterList": [
+                    3
+                  ],
+                  "interactiontype": 1,
+                  "landingTitle": 1,
+                  "metaData": {
+                    "adSign": "2",
+                    "appPromotionChannel": "401721412",
+                    "clickUrl": "https://ads.huawei.com/usermgtportal/home/index.html#/",
+                    "imageInfo": [
+                      {
+                        "checkSha256Flag": 1,
+                        "height": 250,
+                        "imageType": "img",
+                        "sha256": "",
+                        "url": "https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg",
+                        "width": 300
+                      }
+                    ],
+                    "label": "Banner_API",
+                    "landingPageType": "3"
+                  },
+                  "monitor": [
+                    {
+                      "eventType": "click"
+                    },
+                    {
+                      "eventType": "imp",
+                      "url": [
+                      ]
+                    }
+                  ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
+                  "price": 2.8,
+                  "starttime": 1621267200000,
+                  "taskid": "48017658"
+                }
+              ],
+              "retcode30": 200,
+              "slotid": "m8x9x3rzff"
+            }
+          ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
+          "retcode": 200,
+          "totalCacheSize": 300
+        }
+      }
+    }
+  ],
+  "expectedBidResponses": [
+    {
+      "currency": "USD",
+      "bids": [
+        {
+          "bid": {
+            "adm": "<style> html, body  { margin: 0; padding: 0; width: 100%; height: 100%; vertical-align: middle; }  html  { display: table; }  body { display: table-cell; vertical-align: middle; text-align: center; -webkit-text-size-adjust: none; }  </style> <span class=\"title-link advertiser_label\"></span> <a href='https://ads.huawei.com/usermgtportal/home/index.html#/' style=\"text-decoration:none\" onclick=sendGetReq()> <img src='https://ads.huawei.com/usermgtportal/home/img/huawei_logo_black.aaec817d.svg' width='300' height='250'/> </a> <script type=\"text/javascript\">var dspClickTrackings = [];function sendGetReq() {sendSomeGetReq(dspClickTrackings)}function sendOneGetReq(url) {var req = new XMLHttpRequest();req.open('GET', url, true);req.send(null);}function sendSomeGetReq(urls) {for (var i = 0; i < urls.length; i++) {sendOneGetReq(urls[i]);}}</script>",
+            "adomain": [
+              "huaweiads"
+            ],
+            "h": 250,
+            "w": 300,
+            "crid": "58025103",
+            "id": "PrebidMobile",
+            "impid": "PrebidMobile",
+            "price": 2.8
+          },
+          "type": "banner"
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/interstitialBannerType.json b/adapters/huaweiads/huaweiadstest/exemplary/interstitialBannerType.json
index 7b66b283..be7366a4 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/interstitialBannerType.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/interstitialBannerType.json
@@ -101,7 +101,7 @@
             {
               "adtype": 12,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/interstitialVideoType.json b/adapters/huaweiads/huaweiadstest/exemplary/interstitialVideoType.json
index ed74e147..d48e8abf 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/interstitialVideoType.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/interstitialVideoType.json
@@ -102,7 +102,7 @@
               "slotid": "testslotid",
               "h": 250,
               "w": 300,
-              "test": 0
+              "test": 1
             }
           ],
           "device": {
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
index f04262d7..8297d11b 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeIncludeVideo.json
@@ -96,7 +96,7 @@
                 "903"
               ],
               "h": 200,
-              "test": 0,
+              "test": 1,
               "w": 200
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
index 57c46336..1af8abc5 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeSingleImage.json
@@ -94,7 +94,7 @@
                 "901"
               ],
               "h": 200,
-              "test": 0,
+              "test": 1,
               "w": 200
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
index 558a4410..7b5c9a54 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImage.json
@@ -93,7 +93,7 @@
                 "904"
               ],
               "h": 200,
-              "test": 0,
+              "test": 1,
               "w": 200
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
index 0e2dbbef..e72f5f59 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/nativeThreeImageIncludeIcon.json
@@ -94,7 +94,7 @@
                 "904"
               ],
               "h": 200,
-              "test": 0,
+              "test": 1,
               "w": 200
             }
           ],
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo.json
index d6b55af3..77308a62 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo.json
@@ -100,7 +100,7 @@
             {
               "adtype": 7,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo1.json b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo1.json
index 9a0d8564..1f5b8b9b 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo1.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo1.json
@@ -100,7 +100,7 @@
             {
               "adtype": 7,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo2.json b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo2.json
index a2a9c176..61ff7fa0 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo2.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo2.json
@@ -100,7 +100,7 @@
             {
               "adtype": 7,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo3.json b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo3.json
index b1317c93..4e72f089 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo3.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo3.json
@@ -100,7 +100,7 @@
             {
               "adtype": 7,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo4.json b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo4.json
index 9f3af0fd..0045e5cd 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo4.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rewardedVideo4.json
@@ -100,7 +100,7 @@
             {
               "adtype": 7,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/rollVideo.json b/adapters/huaweiads/huaweiadstest/exemplary/rollVideo.json
index 5252b6b8..f0429670 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/rollVideo.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/rollVideo.json
@@ -102,7 +102,7 @@
               "adtype": 60,
               "slotid": "testslotid",
               "totalDuration": 10,
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
diff --git a/adapters/huaweiads/huaweiadstest/exemplary/video.json b/adapters/huaweiads/huaweiadstest/exemplary/video.json
index be1f51bc..acc572c7 100644
--- a/adapters/huaweiads/huaweiadstest/exemplary/video.json
+++ b/adapters/huaweiads/huaweiadstest/exemplary/video.json
@@ -100,7 +100,7 @@
             {
               "adtype": 12,
               "slotid": "m8x9x3roll",
-              "test": 0,
+              "test": 1,
               "w": 300,
               "h": 250
             }
@@ -140,6 +140,7 @@
           "multiad": [
             {
               "adtype": 60,
+              "brsetting": "Y",
               "content": [
                 {
                   "contentid": "58001445",
@@ -286,6 +287,11 @@
                       ]
                     }
                   ],
+                  "paramfromserver": {
+                    "a": "1||test",
+                    "sig": "",
+                    "t": "99990101235959"
+                  },
                   "price": 2.8,
                   "starttime": 1620230400000,
                   "taskid": "48016632"
@@ -295,6 +301,14 @@
               "slotid": "m8x9x3roll"
             }
           ],
+          "noReportAdTypeEventList": [
+            {
+              "adType": 8,
+              "eventTypeList": [
+                "exception_6"
+              ]
+            }
+          ],
           "retcode": 200,
           "totalCacheSize": 300
         }
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response.json
index 9a6648ba..92f5e8b6 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_400.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_400.json
index 1decfb04..b860e57c 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_400.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_400.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_503.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_503.json
index 45f5c6c4..8261a13f 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_503.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_503.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_dont_find_impid.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_dont_find_impid.json
index abc1f087..e94e5fb7 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_dont_find_impid.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_dont_find_impid.json
@@ -119,7 +119,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzf1",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
@@ -132,7 +132,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzf2",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_incorrect_huawei_adtype.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_incorrect_huawei_adtype.json
index a663a538..a0a93bda 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_incorrect_huawei_adtype.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_incorrect_huawei_adtype.json
@@ -101,7 +101,7 @@
             {
               "adtype": 8,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_intent.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_intent.json
index 3a93e372..d801946d 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_intent.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_intent.json
@@ -101,7 +101,7 @@
             {
               "adtype": 8,
               "slotid": "testslotid",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "w": 300,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
index eaa726fa..c38bc9f6 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_not_native.json
@@ -90,7 +90,7 @@
             {
               "adtype": 3,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "detailedCreativeTypeList": [
                 "903"
               ],
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode30_204.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode30_204.json
index 9b15351d..466209d9 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode30_204.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode30_204.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_210.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_210.json
index dd081676..4d9543d2 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_210.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_210.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_408.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_408.json
index 3e550d4a..c7cc4d05 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_408.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_408.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_500.json b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_500.json
index e9b4cec3..f0fdeb66 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_500.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/bad_response_retcode_500.json
@@ -96,7 +96,7 @@
             {
               "adtype": 8,
               "slotid": "m8x9x3rzff",
-              "test": 0,
+              "test": 1,
               "format": [
                 {
                   "h": 250,
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid.json b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid.json
index 6db3de62..83b69b48 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid.json
@@ -70,7 +70,7 @@
   ],
   "expectedMakeRequestsErrors": [
     {
-      "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Imei ,Oaid, Gaid are all empty.",
+      "value": "getDeviceID: Imei ,Oaid, Gaid are all empty.",
       "comparison": "literal"
     }
   ]
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid1.json b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid1.json
index c32c3e24..170132be 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid1.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid1.json
@@ -59,7 +59,7 @@
   ],
   "expectedMakeRequestsErrors": [
     {
-      "value": "get gaid from openrtb Device.IFA failed, and get device id failed: openRTBRequest.User.Ext is nil.",
+      "value": "getDeviceID: openRTBRequest.User.Ext is nil and device.Gaid is not specified.",
       "comparison": "literal"
     }
   ]
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json
index dbc9edee..13328223 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid2.json
@@ -68,7 +68,7 @@
   ],
   "expectedMakeRequestsErrors": [
     {
-      "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds.",
+      "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Unmarshal openRTBRequest.User.Ext -> extUserDataHuaweiAds. Error: json: cannot unmarshal object into Go struct field ExtUserDataDeviceIdHuaweiAds.data.gaid of type []string",
       "comparison": "literal"
     }
   ]
diff --git a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid3.json b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid3.json
index 76a076a5..b1c4396f 100644
--- a/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid3.json
+++ b/adapters/huaweiads/huaweiadstest/supplemental/missing_deviceid3.json
@@ -38,7 +38,6 @@
       "geoCountry": "CH",
       "model": "COL-TEST",
       "os": "ios",
-      "ifa": "test-ifa",
       "osv": "10.0.0",
       "devicetype": 4,
       "make": "huawei",
@@ -71,7 +70,7 @@
   ],
   "expectedMakeRequestsErrors": [
     {
-      "value": "get gaid from openrtb Device.IFA failed, and get device id failed: Imei ,Oaid, Gaid are all empty.",
+      "value": "getDeviceID: Imei ,Oaid, Gaid are all empty.",
       "comparison": "literal"
     }
   ]
diff --git a/adapters/infoawarebidder_test.go b/adapters/infoawarebidder_test.go
index b3ac07f5..41ae05df 100644
--- a/adapters/infoawarebidder_test.go
+++ b/adapters/infoawarebidder_test.go
@@ -30,7 +30,7 @@ func TestAppNotSupported(t *testing.T) {
 		return
 	}
 	assert.EqualError(t, errs[0], "this bidder does not support app requests")
-	assert.IsType(t, &errortypes.BadInput{}, errs[0])
+	assert.IsType(t, &errortypes.Warning{}, errs[0])
 	assert.Len(t, bids, 0)
 }
 
@@ -52,7 +52,7 @@ func TestSiteNotSupported(t *testing.T) {
 		return
 	}
 	assert.EqualError(t, errs[0], "this bidder does not support site requests")
-	assert.IsType(t, &errortypes.BadInput{}, errs[0])
+	assert.IsType(t, &errortypes.Warning{}, errs[0])
 	assert.Len(t, bids, 0)
 }
 
diff --git a/adapters/sspBC/sspbctest/exemplary/banner-fromtemplate.json b/adapters/sspBC/sspbctest/exemplary/banner-fromtemplate.json
index 9346540c..cba21f00 100644
--- a/adapters/sspBC/sspbctest/exemplary/banner-fromtemplate.json
+++ b/adapters/sspBC/sspbctest/exemplary/banner-fromtemplate.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -129,7 +129,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoic29tZS10ZXN0LWFkIiwiYWRvbWFpbiI6WyJzc3BiYy10ZXN0Il0sImNyaWQiOiIxMjM0IiwidyI6MzAwLCJoIjoyNTAsImV4dCI6eyJhZGxhYmVsIjoiUmVrbGFtYSIsInB1YmlkIjoiNDMxIiwic2l0ZWlkIjoiMjM3NTAzIiwic2xvdGlkIjoiMDA1IiwidGFnaWQiOiJzbG90In19XX1dfQ=='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoic29tZS10ZXN0LWFkIiwiYWRvbWFpbiI6WyJzc3BiYy10ZXN0Il0sImNyaWQiOiIxMjM0IiwidyI6MzAwLCJoIjoyNTAsImV4dCI6eyJhZGxhYmVsIjoiUmVrbGFtYSIsInB1YmlkIjoiNDMxIiwic2l0ZWlkIjoiMjM3NTAzIiwic2xvdGlkIjoiMDA1IiwidGFnaWQiOiJzbG90In19XX1dfQ==')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/exemplary/banner-preformatted-multiple-imps.json b/adapters/sspBC/sspbctest/exemplary/banner-preformatted-multiple-imps.json
index 80b78364..8ec162bb 100644
--- a/adapters/sspBC/sspbctest/exemplary/banner-preformatted-multiple-imps.json
+++ b/adapters/sspBC/sspbctest/exemplary/banner-preformatted-multiple-imps.json
@@ -59,7 +59,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/exemplary/banner-preformatted-onecode.json b/adapters/sspBC/sspbctest/exemplary/banner-preformatted-onecode.json
index 77999e40..abc0c100 100644
--- a/adapters/sspBC/sspbctest/exemplary/banner-preformatted-onecode.json
+++ b/adapters/sspBC/sspbctest/exemplary/banner-preformatted-onecode.json
@@ -36,7 +36,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/exemplary/banner-preformatted.json b/adapters/sspBC/sspbctest/exemplary/banner-preformatted.json
index ea3b9ca4..422bda68 100644
--- a/adapters/sspBC/sspbctest/exemplary/banner-preformatted.json
+++ b/adapters/sspBC/sspbctest/exemplary/banner-preformatted.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/bad_response.json b/adapters/sspBC/sspbctest/supplemental/bad_response.json
index b91b8cc2..6036413d 100644
--- a/adapters/sspBC/sspbctest/supplemental/bad_response.json
+++ b/adapters/sspBC/sspbctest/supplemental/bad_response.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/bad_response_with_incorrect_impid.json b/adapters/sspBC/sspbctest/supplemental/bad_response_with_incorrect_impid.json
index 31da1162..fc28e33b 100644
--- a/adapters/sspBC/sspbctest/supplemental/bad_response_with_incorrect_impid.json
+++ b/adapters/sspBC/sspbctest/supplemental/bad_response_with_incorrect_impid.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/bad_response_without_adm.json b/adapters/sspBC/sspbctest/supplemental/bad_response_without_adm.json
index a1f1fd2b..95dbb647 100644
--- a/adapters/sspBC/sspbctest/supplemental/bad_response_without_adm.json
+++ b/adapters/sspBC/sspbctest/supplemental/bad_response_without_adm.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/request_with_diffrent_siteid.json b/adapters/sspBC/sspbctest/supplemental/request_with_diffrent_siteid.json
index ecc8bb8d..6597408d 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_with_diffrent_siteid.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_with_diffrent_siteid.json
@@ -42,7 +42,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -130,7 +130,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_bidder_ext.json b/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_bidder_ext.json
index 66fd5e12..242d1beb 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_bidder_ext.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_bidder_ext.json
@@ -38,7 +38,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -125,7 +125,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_ext.json b/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_ext.json
index f3ed6f2a..0eb38616 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_ext.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_with_incorrect_imp_ext.json
@@ -36,7 +36,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -123,7 +123,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_with_standard_and_onecode_imp.json b/adapters/sspBC/sspbctest/supplemental/request_with_standard_and_onecode_imp.json
index e967aa09..0c94df1d 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_with_standard_and_onecode_imp.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_with_standard_and_onecode_imp.json
@@ -54,7 +54,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/request_with_test.json b/adapters/sspBC/sspbctest/supplemental/request_with_test.json
index 5d9b2f16..dd27f0f9 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_with_test.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_with_test.json
@@ -43,7 +43,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -132,7 +132,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_without_banner_format.json b/adapters/sspBC/sspbctest/supplemental/request_without_banner_format.json
index e3301ab1..9e6f7a70 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_without_banner_format.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_without_banner_format.json
@@ -37,7 +37,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -118,7 +118,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_without_ext_id.json b/adapters/sspBC/sspbctest/supplemental/request_without_ext_id.json
index 694b03b7..1e715444 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_without_ext_id.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_without_ext_id.json
@@ -40,7 +40,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -127,7 +127,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/request_without_ext_site_id.json b/adapters/sspBC/sspbctest/supplemental/request_without_ext_site_id.json
index 0725b4ad..e8bd2f13 100644
--- a/adapters/sspBC/sspbctest/supplemental/request_without_ext_site_id.json
+++ b/adapters/sspBC/sspbctest/supplemental/request_without_ext_site_id.json
@@ -41,7 +41,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
@@ -128,7 +128,7 @@
                         "id": "response-005",
                         "impid": "slot",
                         "price": 20,
-                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0='));<\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
+                        "adm": "<html><head><title><\/title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style> body { background-color: transparent; margin: 0; padding: 0; }<\/style><script> window.rekid = \"237503\"; window.slot = \"005\"; window.adlabel = 'Reklama'; window.pubid = '431'; window.wp_sn = 'sspbc_go'; window.page = 'https:\\\/\\\/test.page\\\/'; window.ref = 'https:\\\/\\\/test.referer\\\/'; window.mcad = JSON.parse(atob('eyJpZCI6InRlc3QtcmVxdWVzdCIsInNlYXQiOiJzc3BiYy10ZXN0Iiwic2VhdGJpZCI6W3siYmlkIjpbeyJpZCI6InJlc3BvbnNlLTAwNSIsImltcGlkIjoic2xvdCIsInByaWNlIjoyMCwiYWRtIjoie1wiYnVuY2hcIjpcIjIzNzUwM1wiLFwiY2FwcGluZ1wiOlwiXCIsXCJzZXJ2ZXJcIjpcInNcIixcImNhbXBhaWduXCI6XCJjXCIsXCJzY29yZVwiOlwiMVwiLFwiY3JlYXRpb25zXCI6W3tcInR5cGVcIjpcImltYWdlXCIsXCJzcmNcIjpcImh0dHBzOi8vYmRyLndwY2RuLnBsL3Rlc3RzL3Rlc3QtMzAweDI1MC5wbmdcIixcInRyYWNrZXJzXCI6e30sXCJ3aWR0aFwiOjMwMCxcImhlaWdodFwiOjI1MH1dLFwiY29kZVwiOlwiMVwiLFwiYWFiVmVuZG9yc1wiOmZhbHNlLFwic2xvdFwiOlwiMDA1XCIsXCJyZWRpclwiOlwiaHR0cHM6Ly93d3cud3AucGxcIixcIndwY2xpZFwiOlwiMVwifSIsImFkb21haW4iOlsic3NwYmMtdGVzdCJdLCJjcmlkIjoiMTIzNCIsInciOjMwMCwiaCI6MjUwLCJleHQiOnsiYWRsYWJlbCI6IlJla2xhbWEiLCJwdWJpZCI6IjQzMSIsInNpdGVpZCI6IjIzNzUwMyIsInNsb3RpZCI6IjAwNSIsInRhZ2lkIjoic2xvdCJ9fV19XX0=')); window.inver = '4'; <\/script><\/head><body><div id=\"c\"><\/div><script async crossorigin nomodule src=\"\/\/std.wpcdn.pl\/wpjslib\/wpjslib-inline.js\" id=\"wpjslib\"><\/script><script async crossorigin type=\"module\" src=\"\/\/std.wpcdn.pl\/wpjslib6\/wpjslib-inline.js\" id=\"wpjslib6\"><\/script><\/body><\/html>",
                         "adomain": [
                             "sspbc-test"
                         ],
diff --git a/adapters/sspBC/sspbctest/supplemental/status_204.json b/adapters/sspBC/sspbctest/supplemental/status_204.json
index f53581b8..54d25c4f 100644
--- a/adapters/sspBC/sspbctest/supplemental/status_204.json
+++ b/adapters/sspBC/sspbctest/supplemental/status_204.json
@@ -42,7 +42,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/adapters/sspBC/sspbctest/supplemental/status_400.json b/adapters/sspBC/sspbctest/supplemental/status_400.json
index 4e058f1c..249768c2 100644
--- a/adapters/sspBC/sspbctest/supplemental/status_400.json
+++ b/adapters/sspBC/sspbctest/supplemental/status_400.json
@@ -42,7 +42,7 @@
     "httpCalls": [
         {
             "expectedRequest": {
-                "uri": "http://ssp.wp.test/bidder/?bdver=5.6&inver=4",
+                "uri": "http://ssp.wp.test/bidder/?bdver=5.7&inver=4",
                 "body": {
                     "id": "test-request",
                     "imp": [
diff --git a/config/accounts_test.go b/config/accounts_test.go
index be9f69d2..7a78c8ed 100644
--- a/config/accounts_test.go
+++ b/config/accounts_test.go
@@ -1,7 +1,6 @@
 package config
 
 import (
-	"errors"
 	"testing"
 
 	"github.com/prebid/go-gdpr/consentconstants"
@@ -711,174 +710,3 @@ func TestBasicEnforcementVendor(t *testing.T) {
 		assert.Equal(t, tt.wantBasicVendorSet, present, tt.description)
 	}
 }
-
-func TestAlternateBidderCodes_IsValidBidderCode(t *testing.T) {
-	type fields struct {
-		Enabled bool
-		Bidders map[string]AdapterAlternateBidderCodes
-	}
-	type args struct {
-		bidder          string
-		alternateBidder string
-	}
-	tests := []struct {
-		name        string
-		fields      fields
-		args        args
-		wantIsValid bool
-		wantErr     error
-	}{
-		{
-			name:        "alternateBidder is not set/blank (default non-extra bid case)",
-			wantIsValid: true,
-		},
-		{
-			name: "alternateBidder and bidder are same (default non-extra bid case with seat's alternateBidder explicitly set)",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "pubmatic",
-			},
-			wantIsValid: true,
-		},
-		{
-			name: "account.alternatebiddercodes config not defined (default, reject bid)",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			wantIsValid: false,
-		},
-		{
-			name: "account.alternatebiddercodes config enabled but adapter config not defined",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields:      fields{Enabled: true},
-			wantIsValid: false,
-			wantErr:     errors.New(`alternateBidderCodes not defined for adapter "pubmatic", rejecting bids for "groupm"`),
-		},
-		{
-			name: "account.alternatebiddercodes config enabled but adapter config is not available",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"appnexus": {},
-				},
-			},
-			wantIsValid: false,
-			wantErr:     errors.New(`alternateBidderCodes not defined for adapter "pubmatic", rejecting bids for "groupm"`),
-		},
-		{
-			name: "account.alternatebiddercodes config enabled but adapter config is disabled",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {Enabled: false},
-				},
-			},
-			wantIsValid: false,
-			wantErr:     errors.New(`alternateBidderCodes disabled for "pubmatic", rejecting bids for "groupm"`),
-		},
-		{
-			name: "account.alternatebiddercodes and adapter config enabled but adapter config does not have allowedBidderCodes defined",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {Enabled: true},
-				},
-			},
-			wantIsValid: true,
-		},
-		{
-			name: "allowedBidderCodes is *",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {
-						Enabled:            true,
-						AllowedBidderCodes: []string{"*"},
-					},
-				},
-			},
-			wantIsValid: true,
-		},
-		{
-			name: "allowedBidderCodes is in the list",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {
-						Enabled:            true,
-						AllowedBidderCodes: []string{"groupm"},
-					},
-				},
-			},
-			wantIsValid: true,
-		},
-		{
-			name: "allowedBidderCodes is not in the list",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {
-						Enabled:            true,
-						AllowedBidderCodes: []string{"xyz"},
-					},
-				},
-			},
-			wantIsValid: false,
-			wantErr:     errors.New(`invalid biddercode "groupm" sent by adapter "pubmatic"`),
-		},
-		{
-			name: "account.alternatebiddercodes and adapter config enabled but adapter config has allowedBidderCodes list empty",
-			args: args{
-				bidder:          "pubmatic",
-				alternateBidder: "groupm",
-			},
-			fields: fields{
-				Enabled: true,
-				Bidders: map[string]AdapterAlternateBidderCodes{
-					"pubmatic": {Enabled: true, AllowedBidderCodes: []string{}},
-				},
-			},
-			wantIsValid: false,
-			wantErr:     errors.New(`invalid biddercode "groupm" sent by adapter "pubmatic"`),
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			a := &AlternateBidderCodes{
-				Enabled: tt.fields.Enabled,
-				Bidders: tt.fields.Bidders,
-			}
-			gotIsValid, gotErr := a.IsValidBidderCode(tt.args.bidder, tt.args.alternateBidder)
-			assert.Equal(t, tt.wantIsValid, gotIsValid)
-			assert.Equal(t, tt.wantErr, gotErr)
-		})
-	}
-}
diff --git a/config/bidderinfo_test.go b/config/bidderinfo_test.go
index 85e15323..462e920f 100644
--- a/config/bidderinfo_test.go
+++ b/config/bidderinfo_test.go
@@ -10,7 +10,12 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-const testInfoFilesPath = "./test/bidder-info"
+const testInfoFilesPathValid = "./test/bidder-info-valid"
+const testSimpleYAML = `
+maintainer:
+  email: "some-email@domain.com"
+gvlVendorID: 42
+`
 const fullBidderYAMLConfig = `
 maintainer:
   email: "some-email@domain.com"
@@ -36,14 +41,14 @@ endpointCompression: "GZIP"
 `
 
 func TestLoadBidderInfoFromDisk(t *testing.T) {
-	// should appear in result in lowercase
-	bidder := "somebidder"
+	// should appear in result in mixed case
+	bidder := "stroeerCore"
 	trueValue := true
 
 	adapterConfigs := make(map[string]Adapter)
 	adapterConfigs[strings.ToLower(bidder)] = Adapter{}
 
-	infos, err := LoadBidderInfo(testInfoFilesPath)
+	infos, err := LoadBidderInfoFromDisk(testInfoFilesPathValid)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -84,6 +89,80 @@ func TestLoadBidderInfoFromDisk(t *testing.T) {
 	assert.Equal(t, expected, infos)
 }
 
+func TestProcessBidderInfo(t *testing.T) {
+	testCases := []struct {
+		description         string
+		bidderInfos         map[string][]byte
+		expectedBidderInfos BidderInfos
+		expectError         string
+	}{
+		{
+			description: "Valid bidder info",
+			bidderInfos: map[string][]byte{
+				"bidderA.yaml": []byte(testSimpleYAML),
+			},
+			expectedBidderInfos: BidderInfos{
+				"bidderA": BidderInfo{
+					Maintainer: &MaintainerInfo{
+						Email: "some-email@domain.com",
+					},
+					GVLVendorID: 42,
+				},
+			},
+			expectError: "",
+		},
+		{
+			description: "Bidder doesn't exist in bidder info list",
+			bidderInfos: map[string][]byte{
+				"unknown.yaml": []byte(testSimpleYAML),
+			},
+			expectedBidderInfos: nil,
+			expectError:         "error parsing config for bidder unknown.yaml",
+		},
+		{
+			description: "Invalid bidder config",
+			bidderInfos: map[string][]byte{
+				"bidderA.yaml": []byte("invalid bidder config"),
+			},
+			expectedBidderInfos: nil,
+			expectError:         "error parsing config for bidder bidderA.yaml",
+		},
+	}
+	for _, test := range testCases {
+		reader := StubInfoReader{test.bidderInfos}
+		bidderInfos, err := processBidderInfos(reader, mockNormalizeBidderName)
+		if test.expectError != "" {
+			assert.ErrorContains(t, err, test.expectError, "")
+		} else {
+			assert.Equal(t, test.expectedBidderInfos, bidderInfos, "incorrect bidder infos for test case: %s", test.description)
+		}
+
+	}
+
+}
+
+type StubInfoReader struct {
+	mockBidderInfos map[string][]byte
+}
+
+func (r StubInfoReader) Read() (map[string][]byte, error) {
+	return r.mockBidderInfos, nil
+}
+
+var testBidderNames = map[string]openrtb_ext.BidderName{
+	"biddera": openrtb_ext.BidderName("bidderA"),
+	"bidderb": openrtb_ext.BidderName("bidderB"),
+	"bidder1": openrtb_ext.BidderName("bidder1"),
+	"bidder2": openrtb_ext.BidderName("bidder2"),
+	"a":       openrtb_ext.BidderName("a"),
+}
+
+func mockNormalizeBidderName(name string) (openrtb_ext.BidderName, bool) {
+	nameLower := strings.ToLower(name)
+	bidderName, exists := testBidderNames[nameLower]
+	return bidderName, exists
+}
+
 func TestToGVLVendorIDMap(t *testing.T) {
 	givenBidderInfos := BidderInfos{
 		"bidderA": BidderInfo{Disabled: false, GVLVendorID: 0},
@@ -105,7 +184,7 @@ const bidderInfoRelativePath = "../static/bidder-info"
 // TestBidderInfoFiles ensures each bidder has a valid static/bidder-info/bidder.yaml file. Validation is performed directly
 // against the file system with separate yaml unmarshalling from the LoadBidderInfo func.
 func TestBidderInfoFiles(t *testing.T) {
-	_, err := LoadBidderInfo(bidderInfoRelativePath)
+	_, err := LoadBidderInfoFromDisk(bidderInfoRelativePath)
 	if err != nil {
 		assert.Fail(t, err.Error(), "Errors in bidder info files")
 	}
@@ -687,7 +766,7 @@ func TestApplyBidderInfoConfigSyncerOverrides(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos)
+		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
 		if test.expectedError == "" {
 			assert.NoError(t, resultErr, test.description+":err")
 			assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result")
@@ -849,17 +928,43 @@ func TestApplyBidderInfoConfigOverrides(t *testing.T) {
 		},
 	}
 	for _, test := range testCases {
-		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos)
+		bidderInfos, resultErr := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
 		assert.NoError(t, resultErr, test.description+":err")
 		assert.Equal(t, test.expectedBidderInfos, bidderInfos, test.description+":result")
 	}
 }
 
+func TestApplyBidderInfoConfigOverridesInvalid(t *testing.T) {
+	var testCases = []struct {
+		description            string
+		givenFsBidderInfos     BidderInfos
+		givenConfigBidderInfos BidderInfos
+		expectedError          string
+		expectedBidderInfos    BidderInfos
+	}{
+		{
+			description:            "Bidder doesn't exists in bidder list",
+			givenConfigBidderInfos: BidderInfos{"unknown": {Syncer: &Syncer{Key: "override"}}},
+			expectedError:          "error setting configuration for bidder unknown: unknown bidder",
+		},
+		{
+			description:            "Bidder doesn't exists in file system",
+			givenFsBidderInfos:     BidderInfos{"unknown": {Endpoint: "original"}},
+			givenConfigBidderInfos: BidderInfos{"bidderA": {Syncer: &Syncer{Key: "override"}}},
+			expectedError:          "error finding configuration for bidder bidderA: unknown bidder",
+		},
+	}
+	for _, test := range testCases {
+		_, err := applyBidderInfoConfigOverrides(test.givenConfigBidderInfos, test.givenFsBidderInfos, mockNormalizeBidderName)
+		assert.ErrorContains(t, err, test.expectedError, test.description+":err")
+	}
+}
+
 func TestReadFullYamlBidderConfig(t *testing.T) {
-	bidder := "someBidder"
+	bidder := "bidderA"
 	bidderInf := BidderInfo{}
 	err := yaml.Unmarshal([]byte(fullBidderYAMLConfig), &bidderInf)
-	actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}})
+	actualBidderInfo, err := applyBidderInfoConfigOverrides(BidderInfos{bidder: bidderInf}, BidderInfos{bidder: {Syncer: &Syncer{Supports: []string{"iframe"}}}}, mockNormalizeBidderName)
 
 	assert.NoError(t, err, "Error wasn't expected")
 
diff --git a/config/config_test.go b/config/config_test.go
index 27077ad7..e2a97180 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -442,7 +442,7 @@ func TestFullConfig(t *testing.T) {
 	SetupViper(v, "", bidderInfos)
 	v.SetConfigType("yaml")
 	v.ReadConfig(bytes.NewBuffer(fullConfig))
-	cfg, err := New(v, bidderInfos)
+	cfg, err := New(v, bidderInfos, mockNormalizeBidderName)
 	assert.NoError(t, err, "Setting up config should work but it doesn't")
 	cmpStrings(t, "cookie domain", cfg.HostCookie.Domain, "cookies.prebid.org")
 	cmpStrings(t, "cookie name", cfg.HostCookie.CookieName, "userid")
@@ -691,7 +691,7 @@ func TestMigrateConfig(t *testing.T) {
 	v.SetConfigType("yaml")
 	v.ReadConfig(bytes.NewBuffer(oldStoredRequestsConfig))
 	migrateConfig(v)
-	cfg, err := New(v, bidderInfos)
+	cfg, err := New(v, bidderInfos, mockNormalizeBidderName)
 	assert.NoError(t, err, "Setting up config should work but it doesn't")
 	cmpBools(t, "stored_requests.filesystem.enabled", true, cfg.StoredRequests.Files.Enabled)
 	cmpStrings(t, "stored_requests.filesystem.path", "/somepath", cfg.StoredRequests.Files.Path)
@@ -1753,7 +1753,7 @@ func TestNewCallsRequestValidation(t *testing.T) {
 			`request_validation:
     ipv4_private_networks: ` + test.privateIPNetworks)))
 
-		result, resultErr := New(v, bidderInfos)
+		result, resultErr := New(v, bidderInfos, mockNormalizeBidderName)
 
 		if test.expectedError == "" {
 			assert.NoError(t, resultErr, test.description+":err")
@@ -1788,7 +1788,7 @@ func newDefaultConfig(t *testing.T) (*Configuration, *viper.Viper) {
 	SetupViper(v, "", bidderInfos)
 	v.Set("gdpr.default_value", "0")
 	v.SetConfigType("yaml")
-	cfg, err := New(v, bidderInfos)
+	cfg, err := New(v, bidderInfos, mockNormalizeBidderName)
 	assert.NoError(t, err, "Setting up config should work but it doesn't")
 	return cfg, v
 }
@@ -1858,7 +1858,7 @@ func TestSpecialFeature1VendorExceptionMap(t *testing.T) {
 		SetupViper(v, "", bidderInfos)
 		v.SetConfigType("yaml")
 		v.ReadConfig(bytes.NewBuffer(config))
-		cfg, err := New(v, bidderInfos)
+		cfg, err := New(v, bidderInfos, mockNormalizeBidderName)
 		assert.NoError(t, err, "Setting up config error", tt.description)
 
 		assert.Equal(t, tt.wantVendorExceptions, cfg.GDPR.TCF2.SpecialFeature1.VendorExceptions, tt.description)
diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go
index d6a74ac7..47f68b60 100644
--- a/exchange/bidder_test.go
+++ b/exchange/bidder_test.go
@@ -106,7 +106,7 @@ func TestSingleBidder(t *testing.T) {
 			addCallSignHeader:   false,
 			bidAdjustments:      bidAdjustments,
 		}
-		seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+		seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 		assert.Len(t, seatBids, 1)
 		seatBid := seatBids[0]
 
@@ -228,7 +228,7 @@ func TestSingleBidderGzip(t *testing.T) {
 			addCallSignHeader:   false,
 			bidAdjustments:      bidAdjustments,
 		}
-		seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+		seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 		assert.Len(t, seatBids, 1)
 		seatBid := seatBids[0]
 
@@ -328,7 +328,7 @@ func TestRequestBidRemovesSensitiveHeaders(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	expectedHttpCalls := []*openrtb_ext.ExtHttpCall{
 		{
@@ -380,7 +380,7 @@ func TestSetGPCHeader(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	expectedHttpCall := []*openrtb_ext.ExtHttpCall{
 		{
@@ -430,7 +430,7 @@ func TestSetGPCHeaderNil(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{GlobalPrivacyControlHeader: "1"}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	expectedHttpCall := []*openrtb_ext.ExtHttpCall{
 		{
@@ -500,7 +500,7 @@ func TestMultiBidder(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	if len(seatBids) != 1 {
 		t.Fatalf("SeatBid should exist, because bids exist.")
@@ -879,7 +879,7 @@ func TestMultiCurrencies(t *testing.T) {
 				addCallSignHeader:   false,
 				bidAdjustments:      bidAdjustments,
 			},
-			config.AlternateBidderCodes{},
+			openrtb_ext.ExtAlternateBidderCodes{},
 		)
 		assert.Len(t, seatBids, 1)
 		seatBid := seatBids[0]
@@ -1037,7 +1037,7 @@ func TestMultiCurrencies_RateConverterNotSet(t *testing.T) {
 				addCallSignHeader:   false,
 				bidAdjustments:      bidAdjustments,
 			},
-			config.AlternateBidderCodes{},
+			openrtb_ext.ExtAlternateBidderCodes{},
 		)
 		assert.Len(t, seatBids, 1)
 		seatBid := seatBids[0]
@@ -1214,7 +1214,7 @@ func TestMultiCurrencies_RequestCurrencyPick(t *testing.T) {
 				addCallSignHeader:   false,
 				bidAdjustments:      bidAdjustments,
 			},
-			config.AlternateBidderCodes{},
+			openrtb_ext.ExtAlternateBidderCodes{},
 		)
 		assert.Len(t, seatBids, 1)
 		seatBid := seatBids[0]
@@ -1530,7 +1530,7 @@ func TestMobileNativeTypes(t *testing.T) {
 				addCallSignHeader:   false,
 				bidAdjustments:      bidAdjustments,
 			},
-			config.AlternateBidderCodes{},
+			openrtb_ext.ExtAlternateBidderCodes{},
 		)
 		assert.Len(t, seatBids, 1)
 
@@ -1648,7 +1648,7 @@ func TestRequestBidsStoredBidResponses(t *testing.T) {
 				addCallSignHeader:   false,
 				bidAdjustments:      bidAdjustments,
 			},
-			config.AlternateBidderCodes{},
+			openrtb_ext.ExtAlternateBidderCodes{},
 		)
 		assert.Len(t, seatBids, 1)
 
@@ -1675,7 +1675,7 @@ func TestErrorReporting(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	bids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	bids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 	if bids != nil {
 		t.Errorf("There should be no seatbid if no http requests are returned.")
 	}
@@ -1907,7 +1907,7 @@ func TestCallRecordAdapterConnections(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	_, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	_, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	// Assert no errors
 	assert.Equal(t, 0, len(errs), "bidder.requestBid returned errors %v \n", errs)
@@ -2150,7 +2150,7 @@ func TestRequestBidsWithAdsCertsSigner(t *testing.T) {
 		addCallSignHeader:   true,
 		bidAdjustments:      bidAdjustments,
 	}
-	_, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	_, errs := bidder.requestBid(ctx, bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 
 	assert.Empty(t, errs, "no errors should be returned")
 }
@@ -2365,9 +2365,9 @@ func TestExtraBid(t *testing.T) {
 	}
 
 	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions,
-		config.AlternateBidderCodes{
+		openrtb_ext.ExtAlternateBidderCodes{
 			Enabled: true,
-			Bidders: map[string]config.AdapterAlternateBidderCodes{
+			Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
 				string(openrtb_ext.BidderPubmatic): {
 					Enabled:            true,
 					AllowedBidderCodes: []string{"groupm"},
@@ -2477,9 +2477,9 @@ func TestExtraBidWithAlternateBidderCodeDisabled(t *testing.T) {
 	}
 
 	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions,
-		config.AlternateBidderCodes{
+		openrtb_ext.ExtAlternateBidderCodes{
 			Enabled: true,
-			Bidders: map[string]config.AdapterAlternateBidderCodes{
+			Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
 				string(openrtb_ext.BidderPubmatic): {
 					Enabled:            true,
 					AllowedBidderCodes: []string{"groupm-allowed"},
@@ -2586,9 +2586,9 @@ func TestExtraBidWithBidAdjustments(t *testing.T) {
 	}
 
 	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions,
-		config.AlternateBidderCodes{
+		openrtb_ext.ExtAlternateBidderCodes{
 			Enabled: true,
-			Bidders: map[string]config.AdapterAlternateBidderCodes{
+			Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
 				string(openrtb_ext.BidderPubmatic): {
 					Enabled:            true,
 					AllowedBidderCodes: []string{"groupm"},
@@ -2697,9 +2697,9 @@ func TestExtraBidWithBidAdjustmentsUsingAdapterCode(t *testing.T) {
 	}
 
 	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currencyConverter.Rates(), &adapters.ExtraRequestInfo{}, &MockSigner{}, bidReqOptions,
-		config.AlternateBidderCodes{
+		openrtb_ext.ExtAlternateBidderCodes{
 			Enabled: true,
-			Bidders: map[string]config.AdapterAlternateBidderCodes{
+			Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
 				string(openrtb_ext.BidderPubmatic): {
 					Enabled:            true,
 					AllowedBidderCodes: []string{"groupm"},
diff --git a/exchange/bidder_validate_bids_test.go b/exchange/bidder_validate_bids_test.go
index 21ffa298..71d34334 100644
--- a/exchange/bidder_validate_bids_test.go
+++ b/exchange/bidder_validate_bids_test.go
@@ -6,7 +6,6 @@ import (
 
 	"github.com/mxmCherry/openrtb/v16/openrtb2"
 	"github.com/prebid/prebid-server/adapters"
-	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/currency"
 	"github.com/prebid/prebid-server/experiment/adscert"
 	"github.com/prebid/prebid-server/openrtb_ext"
@@ -64,7 +63,7 @@ func TestAllValidBids(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 	assert.Len(t, seatBids, 1)
 	assert.Len(t, seatBids[0].bids, 4)
 	assert.Len(t, errs, 0)
@@ -134,7 +133,7 @@ func TestAllBadBids(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 	assert.Len(t, seatBids, 1)
 	assert.Len(t, seatBids[0].bids, 0)
 	assert.Len(t, errs, 7)
@@ -215,7 +214,7 @@ func TestMixedBids(t *testing.T) {
 		addCallSignHeader:   false,
 		bidAdjustments:      bidAdjustments,
 	}
-	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+	seatBids, errs := bidder.requestBid(context.Background(), bidderReq, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 	assert.Len(t, seatBids, 1)
 	assert.Len(t, seatBids[0].bids, 3)
 	assert.Len(t, errs, 5)
@@ -344,7 +343,7 @@ func TestCurrencyBids(t *testing.T) {
 			addCallSignHeader:   false,
 			bidAdjustments:      bidAdjustments,
 		}
-		seatBids, errs := bidder.requestBid(context.Background(), bidderRequest, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, config.AlternateBidderCodes{})
+		seatBids, errs := bidder.requestBid(context.Background(), bidderRequest, currency.NewConstantRates(), &adapters.ExtraRequestInfo{}, &adscert.NilSigner{}, bidReqOptions, openrtb_ext.ExtAlternateBidderCodes{})
 		assert.Len(t, seatBids, 1)
 		assert.Len(t, seatBids[0].bids, expectedValidBids)
 		assert.Len(t, errs, expectedErrs)
@@ -356,6 +355,6 @@ type mockAdaptedBidder struct {
 	errorResponse []error
 }
 
-func (b *mockAdaptedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
+func (b *mockAdaptedBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) ([]*pbsOrtbSeatBid, []error) {
 	return b.bidResponse, b.errorResponse
 }
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index 866e4d77..3bf42333 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -56,7 +56,7 @@ func TestNewExchange(t *testing.T) {
 		},
 	}
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -80,7 +80,7 @@ func TestNewExchange(t *testing.T) {
 	e := NewExchange(adapters, nil, cfg, map[string]usersync.Syncer{}, &metricsConf.NilMetricsEngine{}, biddersInfo, gdprPermsBuilder, tcf2ConfigBuilder, currencyConverter, nilCategoryFetcher{}, &adscert.NilSigner{}).(*exchange)
 	for _, bidderName := range knownAdapters {
 		if _, ok := e.adapterMap[bidderName]; !ok {
-			if biddersInfo[strings.ToLower(string(bidderName))].IsEnabled() {
+			if biddersInfo[string(bidderName)].IsEnabled() {
 				t.Errorf("NewExchange produced an Exchange without bidder %s", bidderName)
 			}
 		}
@@ -1239,7 +1239,7 @@ func TestGetBidCacheInfoEndToEnd(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer))
 	defer server.Close()
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1602,7 +1602,7 @@ func TestBidResponseCurrency(t *testing.T) {
 	server := httptest.NewServer(http.HandlerFunc(handlerNoBidServer))
 	defer server.Close()
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1846,7 +1846,7 @@ func TestRaceIntegration(t *testing.T) {
 
 	cfg := &config.Configuration{}
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1955,7 +1955,7 @@ func TestPanicRecovery(t *testing.T) {
 		},
 	}
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -2024,7 +2024,7 @@ func TestPanicRecoveryHighLevel(t *testing.T) {
 
 	cfg := &config.Configuration{}
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -4083,7 +4083,7 @@ func TestPassExperimentConfigsToHoldAuction(t *testing.T) {
 
 	cfg := &config.Configuration{}
 
-	biddersInfo, err := config.LoadBidderInfo("../static/bidder-info")
+	biddersInfo, err := config.LoadBidderInfoFromDisk("../static/bidder-info")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -4195,6 +4195,185 @@ func TestCallSignHeader(t *testing.T) {
 
 }
 
+/*
+	TestOverrideConfigAlternateBidderCodesWithRequestValues makes sure that the correct alternabiddercodes list is forwarded to the adapters and only the approved bids are returned in auction response.
+
+	1. request.ext.prebid.alternatebiddercodes has priority over the content of config.Account.Alternatebiddercodes.
+
+	2. request is updated with config.Account.Alternatebiddercodes values if request.ext.prebid.alternatebiddercodes is empty or not specified.
+
+	3. request.ext.prebid.alternatebiddercodes is given priority over config.Account.Alternatebiddercodes if both are specified.
+*/
+func TestOverrideConfigAlternateBidderCodesWithRequestValues(t *testing.T) {
+	type testIn struct {
+		config     config.Configuration
+		requestExt json.RawMessage
+	}
+	type testResults struct {
+		expectedSeats []string
+	}
+
+	testCases := []struct {
+		desc     string
+		in       testIn
+		expected testResults
+	}{
+		{
+			desc: "alternatebiddercode defined neither in config nor in the request",
+			in: testIn{
+				config: config.Configuration{},
+			},
+			expected: testResults{
+				expectedSeats: []string{"pubmatic"},
+			},
+		},
+		{
+			desc: "alternatebiddercode defined in config and not in request",
+			in: testIn{
+				config: config.Configuration{
+					AccountDefaults: config.Account{
+						AlternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{
+							Enabled: true,
+							Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+								"pubmatic": {
+									Enabled:            true,
+									AllowedBidderCodes: []string{"groupm"},
+								},
+							},
+						},
+					},
+				},
+				requestExt: json.RawMessage(`{}`),
+			},
+			expected: testResults{
+				expectedSeats: []string{"pubmatic", "groupm"},
+			},
+		},
+		{
+			desc: "alternatebiddercode defined in request and not in config",
+			in: testIn{
+				requestExt: json.RawMessage(`{"prebid": {"alternatebiddercodes": {"enabled": true, "bidders": {"pubmatic": {"enabled": true, "allowedbiddercodes": ["appnexus"]}}}}}`),
+			},
+			expected: testResults{
+				expectedSeats: []string{"pubmatic", "appnexus"},
+			},
+		},
+		{
+			desc: "alternatebiddercode defined in both config and in request",
+			in: testIn{
+				config: config.Configuration{
+					AccountDefaults: config.Account{
+						AlternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{
+							Enabled: true,
+							Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+								"pubmatic": {
+									Enabled:            true,
+									AllowedBidderCodes: []string{"groupm"},
+								},
+							},
+						},
+					},
+				},
+				requestExt: json.RawMessage(`{"prebid": {"alternatebiddercodes": {"enabled": true, "bidders": {"pubmatic": {"enabled": true, "allowedbiddercodes": ["ix"]}}}}}`),
+			},
+			expected: testResults{
+				expectedSeats: []string{"pubmatic", "ix"},
+			},
+		},
+	}
+
+	// Init an exchange to run an auction from
+	noBidServer := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) }
+	mockPubMaticBidService := httptest.NewServer(http.HandlerFunc(noBidServer))
+	defer mockPubMaticBidService.Close()
+
+	categoriesFetcher, error := newCategoryFetcher("./test/category-mapping")
+	if error != nil {
+		t.Errorf("Failed to create a category Fetcher: %v", error)
+	}
+
+	mockBidderRequestResponse := &goodSingleBidder{
+		httpRequest: &adapters.RequestData{
+			Method:  "POST",
+			Uri:     mockPubMaticBidService.URL,
+			Body:    []byte("{\"key\":\"val\"}"),
+			Headers: http.Header{},
+		},
+		bidResponse: &adapters.BidderResponse{
+			Bids: []*adapters.TypedBid{
+				{Bid: &openrtb2.Bid{ID: "1"}, Seat: ""},
+				{Bid: &openrtb2.Bid{ID: "2"}, Seat: "pubmatic"},
+				{Bid: &openrtb2.Bid{ID: "3"}, Seat: "appnexus"},
+				{Bid: &openrtb2.Bid{ID: "4"}, Seat: "groupm"},
+				{Bid: &openrtb2.Bid{ID: "5"}, Seat: "ix"},
+			},
+			Currency: "USD",
+		},
+	}
+
+	e := new(exchange)
+	e.cache = &wellBehavedCache{}
+	e.me = &metricsConf.NilMetricsEngine{}
+	e.gdprPermsBuilder = fakePermissionsBuilder{
+		permissions: &permissionsMock{
+			allowAllBidders: true,
+		},
+	}.Builder
+	e.tcf2ConfigBuilder = fakeTCF2ConfigBuilder{
+		cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+	}.Builder
+	e.currencyConverter = currency.NewRateConverter(&http.Client{}, "", time.Duration(0))
+	e.categoriesFetcher = categoriesFetcher
+	e.bidIDGenerator = &mockBidIDGenerator{false, false}
+
+	// Define mock incoming bid requeset
+	mockBidRequest := &openrtb2.BidRequest{
+		ID: "some-request-id",
+		Imp: []openrtb2.Imp{{
+			ID:     "some-impression-id",
+			Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
+			Ext:    json.RawMessage(`{"pubmatic": {"publisherId": 1}}`),
+		}},
+		Site: &openrtb2.Site{Page: "prebid.org", Ext: json.RawMessage(`{"amp":0}`)},
+	}
+
+	// Run tests
+	for _, test := range testCases {
+		e.adapterMap = map[openrtb_ext.BidderName]AdaptedBidder{
+			openrtb_ext.BidderPubmatic: AdaptBidder(mockBidderRequestResponse, mockPubMaticBidService.Client(), &test.in.config, &metricsConfig.NilMetricsEngine{}, openrtb_ext.BidderPubmatic, nil, ""),
+		}
+
+		mockBidRequest.Ext = test.in.requestExt
+
+		auctionRequest := AuctionRequest{
+			BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: mockBidRequest},
+			Account:           test.in.config.AccountDefaults,
+			UserSyncs:         &emptyUsersync{},
+		}
+
+		// Run test
+		outBidResponse, err := e.HoldAuction(context.Background(), auctionRequest, &DebugLog{})
+
+		// Assertions
+		assert.NoErrorf(t, err, "%s. HoldAuction error: %v \n", test.desc, err)
+		assert.NotNil(t, outBidResponse)
+
+		// So 2 seatBids are expected as,
+		// the default "" and "pubmatic" bids will be in one seat and the extra-bids "groupm"/"appnexus"/"ix" in another seat.
+		assert.Len(t, outBidResponse.SeatBid, len(test.expected.expectedSeats), "%s. seatbid count miss-match\n", test.desc)
+
+		for i, seatBid := range outBidResponse.SeatBid {
+			assert.Contains(t, test.expected.expectedSeats, seatBid.Seat, "%s. unexpected seatbid\n", test.desc)
+
+			if seatBid.Seat == string(openrtb_ext.BidderPubmatic) {
+				assert.Len(t, outBidResponse.SeatBid[i].Bid, 2, "%s. unexpected bid count\n", test.desc)
+			} else {
+				assert.Len(t, outBidResponse.SeatBid[i].Bid, 1, "%s. unexpected bid count\n", test.desc)
+			}
+		}
+	}
+}
+
 type MockSigner struct {
 	data string
 }
@@ -4286,7 +4465,7 @@ type validatingBidder struct {
 	mockResponses map[string]bidderResponse
 }
 
-func (b *validatingBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) (seatBids []*pbsOrtbSeatBid, errs []error) {
+func (b *validatingBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) (seatBids []*pbsOrtbSeatBid, errs []error) {
 	if expectedRequest, ok := b.expectations[string(bidderRequest.BidderName)]; ok {
 		if expectedRequest != nil {
 			if !reflect.DeepEqual(expectedRequest.BidAdjustments, bidRequestOptions.bidAdjustments) {
@@ -4343,7 +4522,7 @@ type capturingRequestBidder struct {
 	req *openrtb2.BidRequest
 }
 
-func (b *capturingRequestBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) (seatBid []*pbsOrtbSeatBid, errs []error) {
+func (b *capturingRequestBidder) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestOptions bidRequestOptions, alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes) (seatBid []*pbsOrtbSeatBid, errs []error) {
 	b.req = bidderRequest.BidRequest
 	return []*pbsOrtbSeatBid{{}}, nil
 }
@@ -4449,7 +4628,7 @@ func (e *emptyUsersync) HasAnyLiveSyncs() bool {
 
 type panicingAdapter struct{}
 
-func (panicingAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes config.AlternateBidderCodes) (posb []*pbsOrtbSeatBid, errs []error) {
+func (panicingAdapter) requestBid(ctx context.Context, bidderRequest BidderRequest, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, adsCertSigner adscert.Signer, bidRequestMetadata bidRequestOptions, alternateBidderCodes openrtb_ext.ExtAlternateBidderCodes) (posb []*pbsOrtbSeatBid, errs []error) {
 	panic("Panic! Panic! The world is ending!")
 }
 
diff --git a/exchange/exchangetest/extra-bids.json b/exchange/exchangetest/extra-bids.json
index 5dc3da15..84a4cffd 100644
--- a/exchange/exchangetest/extra-bids.json
+++ b/exchange/exchangetest/extra-bids.json
@@ -40,6 +40,15 @@
           "targeting": {
             "includewinners": true,
             "includebidderkeys": true
+          },
+          "alternatebiddercodes": {
+            "enabled": true,
+            "bidders": {
+              "pubmatic": {
+                "enabled": true,
+                "allowedbiddercodes": ["groupm"]
+              }
+            }
           }
         }
       }
@@ -47,6 +56,51 @@
   },
   "outgoingRequests": {
     "pubmatic": {
+      "expectRequest": {
+        "ortbRequest": {
+          "id": "some-request-id",
+          "site": {
+            "page": "test.somepage.com"
+          },
+          "imp": [
+            {
+              "id": "my-imp-id",
+              "video": {
+                "mimes": ["video/mp4"]
+              },
+              "ext": {
+                "bidder": {
+                  "publisherId": 5890
+                }
+              }
+            },
+            {
+              "id": "imp-id-2",
+              "video": {
+                "mimes": ["video/mp4"]
+              },
+              "ext": {
+                "bidder": {
+                  "publisherId": 5890
+                }
+              }
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "alternatebiddercodes": {
+                "enabled": true,
+                "bidders": {
+                  "pubmatic": {
+                    "enabled": true,
+                    "allowedbiddercodes": ["groupm"]
+                  }
+                }
+              }
+            }
+          }
+        }
+      },
       "mockResponse": {
         "pbsSeatBids": [{
           "pbsBids": [
@@ -117,6 +171,46 @@
       }
     },
     "appnexus": {
+      "expectRequest": {
+        "ortbRequest": {
+          "id": "some-request-id",
+          "site": {
+            "page": "test.somepage.com"
+          },
+          "imp": [
+            {
+              "id": "my-imp-id",
+              "video": {
+                "mimes": ["video/mp4"]
+              },
+              "ext": {
+                "bidder": {
+                  "placementId": 1
+                }
+              }
+            },
+            {
+              "id": "imp-id-2",
+              "video": {
+                "mimes": ["video/mp4"]
+              },
+              "ext": {
+                "bidder": {
+                  "placementId": 1
+                }
+              }
+            }
+          ],
+          "ext": {
+            "prebid": {
+              "alternatebiddercodes": {
+                "enabled": true,
+                "bidders": null
+              }
+            }
+          }
+        }
+      },
       "mockResponse": {
         "pbsSeatBids": [{
           "pbsBids": [
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index 4ff2aa0a..ae60d42d 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -5,6 +5,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"sort"
 	"testing"
 
 	"github.com/mxmCherry/openrtb/v16/openrtb2"
@@ -2419,8 +2420,7 @@ func TestCleanOpenRTBRequestsGDPRBlockBidRequest(t *testing.T) {
 			privacyConfig,
 			gdprPermissionsBuilder,
 			tcf2ConfigBuilder,
-			nil,
-		)
+			nil)
 
 		// extract bidder name from each request in the results
 		bidders := []openrtb_ext.BidderName{}
@@ -2445,46 +2445,95 @@ func TestBuildRequestExtForBidder(t *testing.T) {
 	bidderParams := json.RawMessage(`"bar"`)
 
 	testCases := []struct {
-		description  string
-		requestExt   json.RawMessage
-		bidderParams map[string]json.RawMessage
-		expectedJson json.RawMessage
+		description          string
+		requestExt           json.RawMessage
+		bidderParams         map[string]json.RawMessage
+		alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes
+		expectedJson         json.RawMessage
 	}{
 		{
-			description:  "Nil",
-			bidderParams: nil,
-			requestExt:   nil,
-			expectedJson: json.RawMessage(``),
+			description:          "Nil",
+			bidderParams:         nil,
+			requestExt:           nil,
+			alternateBidderCodes: nil,
+			expectedJson:         json.RawMessage(``),
+		},
+		{
+			description:          "Empty",
+			bidderParams:         nil,
+			alternateBidderCodes: nil,
+			requestExt:           json.RawMessage(`{}`),
+			expectedJson:         json.RawMessage(`{"prebid":{}}`),
+		},
+		{
+			description:          "Prebid - Allowed Fields Only",
+			bidderParams:         nil,
+			alternateBidderCodes: nil,
+			requestExt:           json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+			expectedJson:         json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+		},
+		{
+			description:          "Prebid - Allowed Fields + Bidder Params",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: nil,
+			requestExt:           json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+			expectedJson:         json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`),
+		},
+		{
+			description:          "Other",
+			bidderParams:         nil,
+			alternateBidderCodes: nil,
+			requestExt:           json.RawMessage(`{"other":"foo"}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{}}`),
+		},
+		{
+			description:          "Prebid + Other + Bider Params",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: nil,
+			requestExt:           json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`),
 		},
 		{
-			description:  "Empty",
-			bidderParams: nil,
-			requestExt:   json.RawMessage(`{}`),
-			expectedJson: json.RawMessage(`{"prebid":{}}`),
+			description:          "Prebid + AlternateBidderCodes in pbs config (default explicitly defined)",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{},
+			requestExt:           json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null},"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`),
 		},
 		{
-			description:  "Prebid - Allowed Fields Only",
-			bidderParams: nil,
-			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
-			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
+			description:          "Prebid + AlternateBidderCodes in pbs config",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"foo": {Enabled: true, AllowedBidderCodes: []string{"*"}}}},
+			requestExt:           json.RawMessage(`{"other":"foo"}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["*"]}}},"bidderparams":"bar"}}`),
 		},
 		{
-			description:  "Prebid - Allowed Fields + Bidder Params",
-			bidderParams: map[string]json.RawMessage{bidder: bidderParams},
-			requestExt:   json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
-			expectedJson: json.RawMessage(`{"prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`),
+			description:          "Prebid + AlternateBidderCodes in pbs config but current bidder not in AlternateBidderCodes config",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"bar": {Enabled: true, AllowedBidderCodes: []string{"*"}}}},
+			requestExt:           json.RawMessage(`{"other":"foo"}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null},"bidderparams":"bar"}}`),
 		},
 		{
-			description:  "Other",
-			bidderParams: nil,
-			requestExt:   json.RawMessage(`{"other":"foo"}`),
-			expectedJson: json.RawMessage(`{"other":"foo","prebid":{}}`),
+			description:          "Prebid + AlternateBidderCodes in request",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{},
+			requestExt:           json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]},"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}},"bidderparams":"bar"}}`),
 		},
 		{
-			description:  "Prebid + Other + Bider Params",
-			bidderParams: map[string]json.RawMessage{bidder: bidderParams},
-			requestExt:   json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true}}}`),
-			expectedJson: json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"bidderparams":"bar"}}`),
+			description:          "Prebid + AlternateBidderCodes in request but current bidder not in AlternateBidderCodes config",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{},
+			requestExt:           json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":null},"bidderparams":"bar"}}`),
+		},
+		{
+			description:          "Prebid + AlternateBidderCodes in both pbs config and in the request",
+			bidderParams:         map[string]json.RawMessage{bidder: bidderParams},
+			alternateBidderCodes: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true, Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{"foo": {Enabled: true, AllowedBidderCodes: []string{"*"}}}},
+			requestExt:           json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]},"bar":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+			expectedJson:         json.RawMessage(`{"other":"foo","prebid":{"integration":"a","channel":{"name":"b","version":"c"},"debug":true,"currency":{"rates":{"FOO":{"BAR":42}},"usepbsrates":true},"alternatebiddercodes":{"enabled":true,"bidders":{"foo":{"enabled":true,"allowedbiddercodes":["foo2"]}}},"bidderparams":"bar"}}`),
 		},
 	}
 
@@ -2497,7 +2546,7 @@ func TestBuildRequestExtForBidder(t *testing.T) {
 			}
 		}
 
-		actualJson, actualErr := buildRequestExtForBidder(bidder, test.requestExt, requestExtParsed, test.bidderParams)
+		actualJson, actualErr := buildRequestExtForBidder(bidder, test.requestExt, requestExtParsed, test.bidderParams, test.alternateBidderCodes)
 		if len(test.expectedJson) > 0 {
 			assert.JSONEq(t, string(test.expectedJson), string(actualJson), test.description+":json")
 		} else {
@@ -2509,26 +2558,28 @@ func TestBuildRequestExtForBidder(t *testing.T) {
 
 func TestBuildRequestExtForBidder_RequestExtParsedNil(t *testing.T) {
 	var (
-		bidder           = "foo"
-		requestExt       = json.RawMessage(`{}`)
-		requestExtParsed *openrtb_ext.ExtRequest
-		bidderParams     map[string]json.RawMessage
+		bidder               = "foo"
+		requestExt           = json.RawMessage(`{}`)
+		requestExtParsed     *openrtb_ext.ExtRequest
+		bidderParams         map[string]json.RawMessage
+		alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes
 	)
 
-	actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams)
+	actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams, alternateBidderCodes)
 	assert.Equal(t, json.RawMessage(``), actualJson)
 	assert.NoError(t, actualErr)
 }
 
 func TestBuildRequestExtForBidder_RequestExtMalformed(t *testing.T) {
 	var (
-		bidder           = "foo"
-		requestExt       = json.RawMessage(`malformed`)
-		requestExtParsed = &openrtb_ext.ExtRequest{}
-		bidderParams     map[string]json.RawMessage
+		bidder               = "foo"
+		requestExt           = json.RawMessage(`malformed`)
+		requestExtParsed     = &openrtb_ext.ExtRequest{}
+		bidderParams         map[string]json.RawMessage
+		alternateBidderCodes *openrtb_ext.ExtAlternateBidderCodes
 	)
 
-	actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams)
+	actualJson, actualErr := buildRequestExtForBidder(bidder, requestExt, requestExtParsed, bidderParams, alternateBidderCodes)
 	assert.Equal(t, json.RawMessage(nil), actualJson)
 	assert.EqualError(t, actualErr, "invalid character 'm' looking for beginning of value")
 }
@@ -3272,3 +3323,189 @@ func TestBuildExtData(t *testing.T) {
 		assert.JSONEq(t, test.expectedRes, string(actualRes), "Incorrect result data")
 	}
 }
+
+func TestCleanOpenRTBRequestsFilterBidderRequestExt(t *testing.T) {
+	testCases := []struct {
+		desc      string
+		inExt     json.RawMessage
+		inCfgABC  *openrtb_ext.ExtAlternateBidderCodes
+		wantExt   []json.RawMessage
+		wantError bool
+	}{
+		{
+			desc:     "Nil request ext, default account alternatebiddercodes config (nil)",
+			inExt:    nil,
+			inCfgABC: nil,
+			wantExt: []json.RawMessage{
+				json.RawMessage(""),
+				json.RawMessage(""),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "Nil request ext, default account alternatebiddercodes config (explicity defined)",
+			inExt:    nil,
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: false},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext, default account alternatebiddercodes config (explicity defined)",
+			inExt:    json.RawMessage(`{"prebid":{}}`),
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: false},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:  "Nil request ext, account alternatebiddercodes config disabled with biddercodes defined",
+			inExt: nil,
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{
+				Enabled: false,
+				Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+					"pubmatic": {Enabled: true},
+				},
+			},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":null}}}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:  "Nil request ext, account alternatebiddercodes config disabled with biddercodes defined (not participant bidder)",
+			inExt: nil,
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{
+				Enabled: false,
+				Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+					"ix": {Enabled: true},
+				},
+			},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "Nil request ext, alternatebiddercodes config enabled but bidder not present",
+			inExt:    nil,
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: true},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext with default alternatebiddercodes values (nil)",
+			inExt:    json.RawMessage(`{"prebid":{}}`),
+			inCfgABC: nil,
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{}}`),
+				json.RawMessage(`{"prebid":{}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext w/o alternatebiddercodes",
+			inExt:    json.RawMessage(`{"prebid":{}}`),
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":false,"bidders":null}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext having alternatebiddercodes for only one bidder",
+			inExt:    json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`),
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: false},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext having alternatebiddercodes for multiple bidder",
+			inExt:    json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]},"appnexus":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: false},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"appnexus":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:     "request ext having alternatebiddercodes for multiple bidder (config alternatebiddercodes not defined)",
+			inExt:    json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]},"appnexus":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{Enabled: false},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"appnexus":{"enabled":true,"allowedbiddercodes":["ix"]}}}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`),
+			},
+			wantError: false,
+		},
+		{
+			desc:  "Nil request ext, alternatebiddercodes config enabled with bidder code for only one bidder",
+			inExt: nil,
+			inCfgABC: &openrtb_ext.ExtAlternateBidderCodes{
+				Enabled: true,
+				Bidders: map[string]openrtb_ext.ExtAdapterAlternateBidderCodes{
+					"pubmatic": {
+						Enabled:            true,
+						AllowedBidderCodes: []string{"groupm"},
+					},
+				},
+			},
+			wantExt: []json.RawMessage{
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":null}}}`),
+				json.RawMessage(`{"prebid":{"alternatebiddercodes":{"enabled":true,"bidders":{"pubmatic":{"enabled":true,"allowedbiddercodes":["groupm"]}}}}}`),
+			},
+			wantError: false,
+		},
+	}
+
+	for _, test := range testCases {
+		req := newBidRequestWithBidderParams(t)
+		req.Ext = nil
+		var extRequest *openrtb_ext.ExtRequest
+		if test.inExt != nil {
+			req.Ext = test.inExt
+			unmarshaledExt, err := extractBidRequestExt(req)
+			assert.NoErrorf(t, err, test.desc+":Error unmarshaling inExt")
+			extRequest = unmarshaledExt
+		}
+
+		auctionReq := AuctionRequest{
+			BidRequestWrapper: &openrtb_ext.RequestWrapper{BidRequest: req},
+			UserSyncs:         &emptyUsersync{},
+			Account:           config.Account{AlternateBidderCodes: test.inCfgABC},
+		}
+		gdprPermissionsBuilder := fakePermissionsBuilder{
+			permissions: &permissionsMock{
+				allowAllBidders: true,
+			},
+		}.Builder
+		tcf2ConfigBuilder := fakeTCF2ConfigBuilder{
+			cfg: gdpr.NewTCF2Config(config.TCF2{}, config.AccountGDPR{}),
+		}.Builder
+		bidderToSyncerKey := map[string]string{}
+		metrics := metrics.MetricsEngineMock{}
+
+		bidderRequests, _, errs := cleanOpenRTBRequests(context.Background(), auctionReq, extRequest, bidderToSyncerKey, &metrics, gdpr.SignalNo, config.Privacy{}, gdprPermissionsBuilder, tcf2ConfigBuilder, nil)
+		assert.Equal(t, test.wantError, len(errs) != 0, test.desc)
+		sort.Slice(bidderRequests, func(i, j int) bool {
+			return bidderRequests[i].BidderCoreName < bidderRequests[j].BidderCoreName
+		})
+		for i, wantBidderRequest := range test.wantExt {
+			assert.Equal(t, wantBidderRequest, bidderRequests[i].BidRequest.Ext, test.desc+" : "+string(bidderRequests[i].BidderCoreName)+"\n\t\tGotRequestExt : "+string(bidderRequests[i].BidRequest.Ext))
+		}
+	}
+}
diff --git a/openrtb_ext/alternatebiddercodes_test.go b/openrtb_ext/alternatebiddercodes_test.go
new file mode 100644
index 00000000..438aebad
--- /dev/null
+++ b/openrtb_ext/alternatebiddercodes_test.go
@@ -0,0 +1,180 @@
+package openrtb_ext
+
+import (
+	"errors"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestAlternateBidderCodes_IsValidBidderCode(t *testing.T) {
+	type fields struct {
+		Enabled bool
+		Bidders map[string]ExtAdapterAlternateBidderCodes
+	}
+	type args struct {
+		bidder          string
+		alternateBidder string
+	}
+	tests := []struct {
+		name        string
+		fields      fields
+		args        args
+		wantIsValid bool
+		wantErr     error
+	}{
+		{
+			name:        "alternateBidder is not set/blank (default non-extra bid case)",
+			wantIsValid: true,
+		},
+		{
+			name: "alternateBidder and bidder are same (default non-extra bid case with seat's alternateBidder explicitly set)",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "pubmatic",
+			},
+			wantIsValid: true,
+		},
+		{
+			name: "account.alternatebiddercodes config not defined (default, reject bid)",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			wantIsValid: false,
+			wantErr:     errors.New(`alternateBidderCodes disabled for "pubmatic", rejecting bids for "groupm"`),
+		},
+		{
+			name: "account.alternatebiddercodes config enabled but adapter config not defined",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields:      fields{Enabled: true},
+			wantIsValid: false,
+			wantErr:     errors.New(`alternateBidderCodes not defined for adapter "pubmatic", rejecting bids for "groupm"`),
+		},
+		{
+			name: "account.alternatebiddercodes config enabled but adapter config is not available",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"appnexus": {},
+				},
+			},
+			wantIsValid: false,
+			wantErr:     errors.New(`alternateBidderCodes not defined for adapter "pubmatic", rejecting bids for "groupm"`),
+		},
+		{
+			name: "account.alternatebiddercodes config enabled but adapter config is disabled",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {Enabled: false},
+				},
+			},
+			wantIsValid: false,
+			wantErr:     errors.New(`alternateBidderCodes disabled for "pubmatic", rejecting bids for "groupm"`),
+		},
+		{
+			name: "account.alternatebiddercodes and adapter config enabled but adapter config does not have allowedBidderCodes defined",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {Enabled: true},
+				},
+			},
+			wantIsValid: true,
+		},
+		{
+			name: "allowedBidderCodes is *",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {
+						Enabled:            true,
+						AllowedBidderCodes: []string{"*"},
+					},
+				},
+			},
+			wantIsValid: true,
+		},
+		{
+			name: "allowedBidderCodes is in the list",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {
+						Enabled:            true,
+						AllowedBidderCodes: []string{"groupm"},
+					},
+				},
+			},
+			wantIsValid: true,
+		},
+		{
+			name: "allowedBidderCodes is not in the list",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {
+						Enabled:            true,
+						AllowedBidderCodes: []string{"xyz"},
+					},
+				},
+			},
+			wantIsValid: false,
+			wantErr:     errors.New(`invalid biddercode "groupm" sent by adapter "pubmatic"`),
+		},
+		{
+			name: "account.alternatebiddercodes and adapter config enabled but adapter config has allowedBidderCodes list empty",
+			args: args{
+				bidder:          "pubmatic",
+				alternateBidder: "groupm",
+			},
+			fields: fields{
+				Enabled: true,
+				Bidders: map[string]ExtAdapterAlternateBidderCodes{
+					"pubmatic": {Enabled: true, AllowedBidderCodes: []string{}},
+				},
+			},
+			wantIsValid: false,
+			wantErr:     errors.New(`invalid biddercode "groupm" sent by adapter "pubmatic"`),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			a := &ExtAlternateBidderCodes{
+				Enabled: tt.fields.Enabled,
+				Bidders: tt.fields.Bidders,
+			}
+			gotIsValid, gotErr := a.IsValidBidderCode(tt.args.bidder, tt.args.alternateBidder)
+			assert.Equal(t, tt.wantIsValid, gotIsValid)
+			assert.Equal(t, tt.wantErr, gotErr)
+		})
+	}
+}