Repository: prebid/prebid-server
Pull request #2225 (2022-04-18 00:39:57)

Add Original CPM and Original Bid Currency to Bid Response
This PR addresses this feature request: https://github.com/prebid/prebid-server/issues/1526

A summary of the feature request: It's difficult to track the original CPM and original currency for a bid if that price value went through currency conversions or bid conversions.

So this PR adds the original CPM/Cur to the bid response, at these paths, `seatbid.bid.ext.origbidcpm` and `seatbid.bid.ext.origbidcpm` mainly by doing the following:

- `pbsOrtbBid` struct, now has a new field of type float64 `originalBidCpm` and type string `originalBidCur`
- In the `requestBid()` function in exchange/bidder.go, after we get the bidResponse from `MakeBids()`, while we are looping over the bids in the response, right before we apply currency conversions or bid adjustments to the bid, I save the price value of the bid. And then apply that price value to the `pbsOrtbBid` object, to be used when we make the `BidExt` later on. It's also here, where we take the original currency the bid responded with, and apply it to this object here too. 
- Then these `originalBidCpm` and `originalBidCur` values are passed to the `makeBidExtJson()`, where it then gets set in the bid response JSON ext at the path `seatbid.bid.ext.origbidcpm` and `seatbid.bid.ext.origbidcur`


Patch:
diff --git a/exchange/bidder.go b/exchange/bidder.go
index 40e78e83..77558028 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -74,6 +74,8 @@ type pbsOrtbBid struct {
 	dealPriority      int
 	dealTierSatisfied bool
 	generatedBidID    string
+	originalBidCPM    float64
+	originalBidCur    string
 }
 
 // pbsOrtbSeatBid is a SeatBid returned by an adaptedBidder.
@@ -130,7 +132,6 @@ type bidderAdapterConfig struct {
 }
 
 func (bidder *bidderAdapter) requestBid(ctx context.Context, request *openrtb2.BidRequest, name openrtb_ext.BidderName, bidAdjustment float64, conversions currency.Conversions, reqInfo *adapters.ExtraRequestInfo, accountDebugAllowed, headerDebugAllowed bool) (*pbsOrtbSeatBid, []error) {
-
 	reqData, errs := bidder.Bidder.MakeRequests(request, reqInfo)
 
 	if len(reqData) == 0 {
@@ -246,15 +247,19 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, request *openrtb2.B
 				if err == nil {
 					// Conversion rate found, using it for conversion
 					for i := 0; i < len(bidResponse.Bids); i++ {
+						originalBidCpm := 0.0
 						if bidResponse.Bids[i].Bid != nil {
+							originalBidCpm = bidResponse.Bids[i].Bid.Price
 							bidResponse.Bids[i].Bid.Price = bidResponse.Bids[i].Bid.Price * bidAdjustment * conversionRate
 						}
 						seatBid.bids = append(seatBid.bids, &pbsOrtbBid{
-							bid:          bidResponse.Bids[i].Bid,
-							bidMeta:      bidResponse.Bids[i].BidMeta,
-							bidType:      bidResponse.Bids[i].BidType,
-							bidVideo:     bidResponse.Bids[i].BidVideo,
-							dealPriority: bidResponse.Bids[i].DealPriority,
+							bid:            bidResponse.Bids[i].Bid,
+							bidMeta:        bidResponse.Bids[i].BidMeta,
+							bidType:        bidResponse.Bids[i].BidType,
+							bidVideo:       bidResponse.Bids[i].BidVideo,
+							dealPriority:   bidResponse.Bids[i].DealPriority,
+							originalBidCPM: originalBidCpm,
+							originalBidCur: bidResponse.Currency,
 						})
 					}
 				} else {
diff --git a/exchange/exchange.go b/exchange/exchange.go
index af28f2bb..20527e66 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -995,7 +995,7 @@ func (e *exchange) makeBid(bids []*pbsOrtbBid, auc *auction, returnCreative bool
 			}
 		}
 
-		if bidExtJSON, err := makeBidExtJSON(bid.bid.Ext, bidExtPrebid, impExtInfoMap, bid.bid.ImpID); err != nil {
+		if bidExtJSON, err := makeBidExtJSON(bid.bid.Ext, bidExtPrebid, impExtInfoMap, bid.bid.ImpID, bid.originalBidCPM, bid.originalBidCur); err != nil {
 			errs = append(errs, err)
 		} else {
 			result = append(result, *bid.bid)
@@ -1009,7 +1009,7 @@ func (e *exchange) makeBid(bids []*pbsOrtbBid, auc *auction, returnCreative bool
 	return result, errs
 }
 
-func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impExtInfoMap map[string]ImpExtInfo, impId string) (json.RawMessage, error) {
+func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impExtInfoMap map[string]ImpExtInfo, impId string, originalBidCpm float64, originalBidCur string) (json.RawMessage, error) {
 	var extMap map[string]interface{}
 
 	if len(ext) != 0 {
@@ -1020,6 +1020,16 @@ func makeBidExtJSON(ext json.RawMessage, prebid *openrtb_ext.ExtBidPrebid, impEx
 		extMap = make(map[string]interface{})
 	}
 
+	//ext.origbidcpm
+	if originalBidCpm >= 0 {
+		extMap[openrtb_ext.OriginalBidCpmKey] = originalBidCpm
+	}
+
+	//ext.origbidcur
+	if originalBidCur != "" {
+		extMap[openrtb_ext.OriginalBidCurKey] = originalBidCur
+	}
+
 	// ext.prebid
 	if prebid.Meta == nil && maputil.HasElement(extMap, "prebid", "meta") {
 		metaContainer := struct {
diff --git a/openrtb_ext/bid.go b/openrtb_ext/bid.go
index bf6bb1c8..1b72b25b 100644
--- a/openrtb_ext/bid.go
+++ b/openrtb_ext/bid.go
@@ -170,4 +170,6 @@ func (key TargetingKey) TruncateKey(maxLength int) string {
 
 const (
 	StoredRequestAttributes = "storedrequestattributes"
+	OriginalBidCpmKey       = "origbidcpm"
+	OriginalBidCurKey       = "origbidcur"
 )


Test patch:
diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go
index 401c245d..c4998f75 100644
--- a/exchange/bidder_test.go
+++ b/exchange/bidder_test.go
@@ -138,6 +138,9 @@ func TestSingleBidder(t *testing.T) {
 		if len(seatBid.httpCalls) != test.httpCallsLen {
 			t.Errorf("The bidder shouldn't log HttpCalls when request.test == 0. Found %d", len(seatBid.httpCalls))
 		}
+		for index, bid := range seatBid.bids {
+			assert.NotEqual(t, mockBidderResponse.Bids[index].Bid.Price, bid.originalBidCPM, "The bid price was adjusted, so the originally bid CPM should be different")
+		}
 	}
 }
 
@@ -402,8 +405,9 @@ func TestConnectionClose(t *testing.T) {
 }
 
 type bid struct {
-	currency string
-	price    float64
+	currency       string
+	price          float64
+	originalBidCur string
 }
 
 // TestMultiCurrencies rate converter is set / active.
@@ -437,9 +441,9 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.1},
-				{currency: "USD", price: 1.2},
-				{currency: "USD", price: 1.3},
+				{currency: "USD", price: 1.1, originalBidCur: "USD"},
+				{currency: "USD", price: 1.2, originalBidCur: "USD"},
+				{currency: "USD", price: 1.3, originalBidCur: "USD"},
 			},
 			expectedBadCurrencyErrors: []error{},
 			description:               "Case 1 - Bidder respond with the same currency (default one) on all HTTP responses",
@@ -461,9 +465,9 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.1},
-				{currency: "USD", price: 1.2},
-				{currency: "USD", price: 1.3},
+				{currency: "USD", price: 1.1, originalBidCur: "USD"},
+				{currency: "USD", price: 1.2, originalBidCur: "USD"},
+				{currency: "USD", price: 1.3, originalBidCur: "USD"},
 			},
 			expectedBadCurrencyErrors: []error{},
 			description:               "Case 2 - Bidder respond with no currency on all HTTP responses",
@@ -485,9 +489,9 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.1 * 1.1435678764},
-				{currency: "USD", price: 1.2 * 1.1435678764},
-				{currency: "USD", price: 1.3 * 1.1435678764},
+				{currency: "USD", price: 1.1 * 1.1435678764, originalBidCur: "EUR"},
+				{currency: "USD", price: 1.2 * 1.1435678764, originalBidCur: "EUR"},
+				{currency: "USD", price: 1.3 * 1.1435678764, originalBidCur: "EUR"},
 			},
 			expectedBadCurrencyErrors: []error{},
 			description:               "Case 3 - Bidder respond with the same non default currency on all HTTP responses",
@@ -509,9 +513,9 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.1},
-				{currency: "USD", price: 1.2 * 1.1435678764},
-				{currency: "USD", price: 1.3 * 1.3050530256},
+				{currency: "USD", price: 1.1, originalBidCur: "USD"},
+				{currency: "USD", price: 1.2 * 1.1435678764, originalBidCur: "EUR"},
+				{currency: "USD", price: 1.3 * 1.3050530256, originalBidCur: "GBP"},
 			},
 			expectedBadCurrencyErrors: []error{},
 			description:               "Case 4 - Bidder respond with a mix of currencies on all HTTP responses",
@@ -533,9 +537,9 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.1},
-				{currency: "USD", price: 1.2 * 1.1435678764},
-				{currency: "USD", price: 1.3 * 1.3050530256},
+				{currency: "USD", price: 1.1, originalBidCur: "USD"},
+				{currency: "USD", price: 1.2 * 1.1435678764, originalBidCur: "EUR"},
+				{currency: "USD", price: 1.3 * 1.3050530256, originalBidCur: "GBP"},
 			},
 			expectedBadCurrencyErrors: []error{},
 			description:               "Case 5 - Bidder respond with a mix of currencies and no currency on all HTTP responses",
@@ -557,8 +561,8 @@ func TestMultiCurrencies(t *testing.T) {
 				},
 			},
 			expectedBids: []bid{
-				{currency: "USD", price: 1.2 * 1.1435678764},
-				{currency: "USD", price: 1.3 * 1.3050530256},
+				{currency: "USD", price: 1.2 * 1.1435678764, originalBidCur: "EUR"},
+				{currency: "USD", price: 1.3 * 1.3050530256, originalBidCur: "GBP"},
 			},
 			expectedBadCurrencyErrors: []error{
 				currency.ConversionNotFoundError{FromCur: "JPY", ToCur: "USD"},
@@ -683,8 +687,9 @@ func TestMultiCurrencies(t *testing.T) {
 		resultLightBids := make([]bid, len(seatBid.bids))
 		for i, b := range seatBid.bids {
 			resultLightBids[i] = bid{
-				price:    b.bid.Price,
-				currency: seatBid.currency,
+				price:          b.bid.Price,
+				currency:       seatBid.currency,
+				originalBidCur: b.originalBidCur,
 			}
 		}
 		assert.ElementsMatch(t, tc.expectedBids, resultLightBids, tc.description)
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index d304f76d..4e8b47ad 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -1606,7 +1606,7 @@ func TestBidResponseCurrency(t *testing.T) {
 		H:     250,
 		Ext:   nil,
 	}
-	aPbsOrtbBidArr := []*pbsOrtbBid{{bid: sampleBid, bidType: openrtb_ext.BidTypeBanner}}
+	aPbsOrtbBidArr := []*pbsOrtbBid{{bid: sampleBid, bidType: openrtb_ext.BidTypeBanner, originalBidCPM: 9.517803}}
 	sampleSeatBid := []openrtb2.SeatBid{
 		{
 			Seat: "appnexus",
@@ -1616,7 +1616,7 @@ func TestBidResponseCurrency(t *testing.T) {
 					Price: 9.517803,
 					W:     300,
 					H:     250,
-					Ext:   json.RawMessage(`{"prebid":{"type":"banner"}}`),
+					Ext:   json.RawMessage(`{"origbidcpm":9.517803,"prebid":{"type":"banner"}}`),
 				},
 			},
 		},
@@ -1751,7 +1751,7 @@ func TestBidResponseImpExtInfo(t *testing.T) {
 		true,
 		[]byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}
 
-	expectedBidResponseExt := `{"prebid":{"type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`
+	expectedBidResponseExt := `{"origbidcpm":0,"prebid":{"type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`
 
 	actualBidResp, err := e.buildBidResponse(context.Background(), liveAdapters, adapterBids, bidRequest, nil, nil, nil, true, impExtInfo, errList)
 	assert.NoError(t, err, fmt.Sprintf("imp ext info was not passed through correctly: %s", err))
@@ -2400,10 +2400,10 @@ func TestCategoryMapping(t *testing.T) {
 	bid3 := openrtb2.Bid{ID: "bid_id3", ImpID: "imp_id3", Price: 30.0000, Cat: cats3, W: 1, H: 1}
 	bid4 := openrtb2.Bid{ID: "bid_id4", ImpID: "imp_id4", Price: 40.0000, Cat: cats4, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30, PrimaryCategory: "AdapterOverride"}, nil, 0, false, ""}
-	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30, PrimaryCategory: "AdapterOverride"}, nil, 0, false, "", 30.0000, "USD"}
+	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 40.0000, "USD"}
 
 	innerBids := []*pbsOrtbBid{
 		&bid1_1,
@@ -2455,10 +2455,10 @@ func TestCategoryMappingNoIncludeBrandCategory(t *testing.T) {
 	bid3 := openrtb2.Bid{ID: "bid_id3", ImpID: "imp_id3", Price: 30.0000, Cat: cats3, W: 1, H: 1}
 	bid4 := openrtb2.Bid{ID: "bid_id4", ImpID: "imp_id4", Price: 40.0000, Cat: cats4, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30, PrimaryCategory: "AdapterOverride"}, nil, 0, false, ""}
-	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 50}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30, PrimaryCategory: "AdapterOverride"}, nil, 0, false, "", 30.0000, "USD"}
+	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 50}, nil, 0, false, "", 40.0000, "USD"}
 
 	innerBids := []*pbsOrtbBid{
 		&bid1_1,
@@ -2509,9 +2509,9 @@ func TestCategoryMappingTranslateCategoriesNil(t *testing.T) {
 	bid2 := openrtb2.Bid{ID: "bid_id2", ImpID: "imp_id2", Price: 20.0000, Cat: cats2, W: 1, H: 1}
 	bid3 := openrtb2.Bid{ID: "bid_id3", ImpID: "imp_id3", Price: 30.0000, Cat: cats3, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 30.0000, "USD"}
 
 	innerBids := []*pbsOrtbBid{
 		&bid1_1,
@@ -2591,9 +2591,9 @@ func TestCategoryMappingTranslateCategoriesFalse(t *testing.T) {
 	bid2 := openrtb2.Bid{ID: "bid_id2", ImpID: "imp_id2", Price: 20.0000, Cat: cats2, W: 1, H: 1}
 	bid3 := openrtb2.Bid{ID: "bid_id3", ImpID: "imp_id3", Price: 30.0000, Cat: cats3, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 40}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 30.0000, "USD"}
 
 	innerBids := []*pbsOrtbBid{
 		&bid1_1,
@@ -2643,11 +2643,11 @@ func TestCategoryDedupe(t *testing.T) {
 	bid4 := openrtb2.Bid{ID: "bid_id4", ImpID: "imp_id4", Price: 20.0000, Cat: cats4, W: 1, H: 1}
 	bid5 := openrtb2.Bid{ID: "bid_id5", ImpID: "imp_id5", Price: 20.0000, Cat: cats1, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 50}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_5 := pbsOrtbBid{&bid5, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 50}, nil, 0, false, "", 15.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_5 := pbsOrtbBid{&bid5, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
 
 	selectedBids := make(map[string]int)
 	expectedCategories := map[string]string{
@@ -2722,11 +2722,11 @@ func TestNoCategoryDedupe(t *testing.T) {
 	bid4 := openrtb2.Bid{ID: "bid_id4", ImpID: "imp_id4", Price: 20.0000, Cat: cats4, W: 1, H: 1}
 	bid5 := openrtb2.Bid{ID: "bid_id5", ImpID: "imp_id5", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_5 := pbsOrtbBid{&bid5, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 14.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 14.0000, "USD"}
+	bid1_3 := pbsOrtbBid{&bid3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_4 := pbsOrtbBid{&bid4, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_5 := pbsOrtbBid{&bid5, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
 
 	selectedBids := make(map[string]int)
 	expectedCategories := map[string]string{
@@ -2802,8 +2802,8 @@ func TestCategoryMappingBidderName(t *testing.T) {
 	bid1 := openrtb2.Bid{ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 	bid2 := openrtb2.Bid{ID: "bid_id2", ImpID: "imp_id2", Price: 10.0000, Cat: cats2, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
 
 	innerBids1 := []*pbsOrtbBid{
 		&bid1_1,
@@ -2856,8 +2856,8 @@ func TestCategoryMappingBidderNameNoCategories(t *testing.T) {
 	bid1 := openrtb2.Bid{ID: "bid_id1", ImpID: "imp_id1", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 	bid2 := openrtb2.Bid{ID: "bid_id2", ImpID: "imp_id2", Price: 12.0000, Cat: cats2, W: 1, H: 1}
 
-	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_1 := pbsOrtbBid{&bid1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_2 := pbsOrtbBid{&bid2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 12.0000, "USD"}
 
 	innerBids1 := []*pbsOrtbBid{
 		&bid1_1,
@@ -2968,7 +2968,7 @@ func TestBidRejectionErrors(t *testing.T) {
 		innerBids := []*pbsOrtbBid{}
 		for _, bid := range test.bids {
 			currentBid := pbsOrtbBid{
-				bid, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: test.duration}, nil, 0, false, ""}
+				bid, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: test.duration}, nil, 0, false, "", 10.0000, "USD"}
 			innerBids = append(innerBids, &currentBid)
 		}
 
@@ -3016,8 +3016,8 @@ func TestCategoryMappingTwoBiddersOneBidEachNoCategorySamePrice(t *testing.T) {
 	bidApn1 := openrtb2.Bid{ID: "bid_idApn1", ImpID: "imp_idApn1", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 	bidApn2 := openrtb2.Bid{ID: "bid_idApn2", ImpID: "imp_idApn2", Price: 10.0000, Cat: cats2, W: 1, H: 1}
 
-	bid1_Apn1 := pbsOrtbBid{&bidApn1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_Apn2 := pbsOrtbBid{&bidApn2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_Apn1 := pbsOrtbBid{&bidApn1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_Apn2 := pbsOrtbBid{&bidApn2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
 
 	innerBidsApn1 := []*pbsOrtbBid{
 		&bid1_Apn1,
@@ -3096,11 +3096,11 @@ func TestCategoryMappingTwoBiddersManyBidsEachNoCategorySamePrice(t *testing.T)
 	bidApn2_1 := openrtb2.Bid{ID: "bid_idApn2_1", ImpID: "imp_idApn2_1", Price: 10.0000, Cat: cats2, W: 1, H: 1}
 	bidApn2_2 := openrtb2.Bid{ID: "bid_idApn2_2", ImpID: "imp_idApn2_2", Price: 20.0000, Cat: cats2, W: 1, H: 1}
 
-	bid1_Apn1_1 := pbsOrtbBid{&bidApn1_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_Apn1_2 := pbsOrtbBid{&bidApn1_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_Apn1_1 := pbsOrtbBid{&bidApn1_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_Apn1_2 := pbsOrtbBid{&bidApn1_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
 
-	bid1_Apn2_1 := pbsOrtbBid{&bidApn2_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_Apn2_2 := pbsOrtbBid{&bidApn2_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_Apn2_1 := pbsOrtbBid{&bidApn2_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_Apn2_2 := pbsOrtbBid{&bidApn2_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
 
 	innerBidsApn1 := []*pbsOrtbBid{
 		&bid1_Apn1_1,
@@ -3178,9 +3178,9 @@ func TestRemoveBidById(t *testing.T) {
 	bidApn1_2 := openrtb2.Bid{ID: "bid_idApn1_2", ImpID: "imp_idApn1_2", Price: 20.0000, Cat: cats1, W: 1, H: 1}
 	bidApn1_3 := openrtb2.Bid{ID: "bid_idApn1_3", ImpID: "imp_idApn1_3", Price: 10.0000, Cat: cats1, W: 1, H: 1}
 
-	bid1_Apn1_1 := pbsOrtbBid{&bidApn1_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_Apn1_2 := pbsOrtbBid{&bidApn1_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
-	bid1_Apn1_3 := pbsOrtbBid{&bidApn1_3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, ""}
+	bid1_Apn1_1 := pbsOrtbBid{&bidApn1_1, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
+	bid1_Apn1_2 := pbsOrtbBid{&bidApn1_2, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 20.0000, "USD"}
+	bid1_Apn1_3 := pbsOrtbBid{&bidApn1_3, nil, "video", nil, &openrtb_ext.ExtBidPrebidVideo{Duration: 30}, nil, 0, false, "", 10.0000, "USD"}
 
 	type aTest struct {
 		desc      string
@@ -3305,7 +3305,7 @@ func TestApplyDealSupport(t *testing.T) {
 			},
 		}
 
-		bid := pbsOrtbBid{&openrtb2.Bid{ID: "123456"}, nil, "video", map[string]string{}, &openrtb_ext.ExtBidPrebidVideo{}, nil, test.dealPriority, false, ""}
+		bid := pbsOrtbBid{&openrtb2.Bid{ID: "123456"}, nil, "video", map[string]string{}, &openrtb_ext.ExtBidPrebidVideo{}, nil, test.dealPriority, false, "", 0, "USD"}
 		bidCategory := map[string]string{
 			bid.bid.ID: test.targ["hb_pb_cat_dur"],
 		}
@@ -3472,7 +3472,7 @@ func TestUpdateHbPbCatDur(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		bid := pbsOrtbBid{&openrtb2.Bid{ID: "123456"}, nil, "video", map[string]string{}, &openrtb_ext.ExtBidPrebidVideo{}, nil, test.dealPriority, false, ""}
+		bid := pbsOrtbBid{&openrtb2.Bid{ID: "123456"}, nil, "video", map[string]string{}, &openrtb_ext.ExtBidPrebidVideo{}, nil, test.dealPriority, false, "", 0, "USD"}
 		bidCategory := map[string]string{
 			bid.bid.ID: test.targ["hb_pb_cat_dur"],
 		}
@@ -3491,6 +3491,8 @@ func TestMakeBidExtJSON(t *testing.T) {
 		ext                json.RawMessage
 		extBidPrebid       openrtb_ext.ExtBidPrebid
 		impExtInfo         map[string]ImpExtInfo
+		origbidcpm         float64
+		origbidcur         string
 		expectedBidExt     string
 		expectedErrMessage string
 	}
@@ -3501,7 +3503,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"video":{"h":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video"), Meta: &openrtb_ext.ExtBidPrebidMeta{BrandName: "foo"}},
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"meta": {"brandName": "foo"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}}`,
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"meta": {"brandName": "foo"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3509,7 +3513,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"video":{"h":100},"prebid":{"meta": {"brandName": "foo"}}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"meta": {"brandName": "foo"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}}`,
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"meta": {"brandName": "foo"}, "type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3517,7 +3523,8 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                nil,
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`,
+			origbidcpm:         0,
+			expectedBidExt:     `{"origbidcpm": 0,"prebid":{"type":"video"},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3525,47 +3532,59 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"video":{"h":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
 			impExtInfo:         map[string]ImpExtInfo{"another_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}}`,
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
 			description:        "Valid extension, empty extBidPrebid and valid imp ext info",
 			ext:                json.RawMessage(`{"video":{"h":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{},
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"type":""},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}}`,
+			expectedBidExt:     `{"prebid":{"type":""},"storedrequestattributes":{"h":480,"mimes":["video/mp4"]},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
 			description:        "Valid extension, non empty extBidPrebid and empty imp ext info",
 			ext:                json.RawMessage(`{"video":{"h":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}}`,
+			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
 			description:        "Valid extension, non empty extBidPrebid and valid imp ext info without video attr",
 			ext:                json.RawMessage(`{"video":{"h":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"banner":{"h":480}}`)}},
-			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}}`,
+			expectedBidExt:     `{"prebid":{"type":"video"},"video":{"h":100}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
 			description:        "Valid extension with prebid, non empty extBidPrebid and valid imp ext info without video attr",
 			ext:                json.RawMessage(`{"prebid":{"targeting":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"banner":{"h":480}}`)}},
-			expectedBidExt:     `{"prebid":{"type":"video"}}`,
+			expectedBidExt:     `{"prebid":{"type":"video"}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
 			description:        "Valid extension with prebid, non empty extBidPrebid and valid imp ext info with video attr",
 			ext:                json.RawMessage(`{"prebid":{"targeting":100}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("video")},
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
 			impExtInfo:         map[string]ImpExtInfo{"test_imp_id": {true, []byte(`{"video":{"h":480,"mimes":["video/mp4"]}}`)}},
-			expectedBidExt:     `{"prebid":{"type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]}}`,
+			expectedBidExt:     `{"prebid":{"type":"video"}, "storedrequestattributes":{"h":480,"mimes":["video/mp4"]}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3573,7 +3592,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                nil,
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner"), Meta: &openrtb_ext.ExtBidPrebidMeta{BrandName: "foo"}},
 			impExtInfo:         map[string]ImpExtInfo{},
-			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}}`,
+			origbidcpm:         0,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3581,7 +3602,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner"), Meta: &openrtb_ext.ExtBidPrebidMeta{BrandName: "foo"}},
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}}`,
+			origbidcpm:         0,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"origbidcpm": 0,"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3589,7 +3612,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"prebid":{"meta":{"brandName":"notfoo", "brandId": 42}}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner"), Meta: &openrtb_ext.ExtBidPrebidMeta{BrandName: "foo"}},
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}}`,
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3597,7 +3622,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"prebid":{"meta":{"brandName":"foo"}}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner")},
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}}`,
+			origbidcpm:         10.0000,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcpm": 10, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3605,7 +3632,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                json.RawMessage(`{"prebid":{"meta":{"brandName":"foo","unknown":"value"}}}`),
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner")},
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}}`,
+			origbidcpm:         -1,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"prebid":{"meta":{"brandName":"foo"},"type":"banner"}, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		{
@@ -3613,7 +3642,9 @@ func TestMakeBidExtJSON(t *testing.T) {
 			ext:                nil,
 			extBidPrebid:       openrtb_ext.ExtBidPrebid{Type: openrtb_ext.BidType("banner")},
 			impExtInfo:         nil,
-			expectedBidExt:     `{"prebid":{"type":"banner"}}`,
+			origbidcpm:         0,
+			origbidcur:         "USD",
+			expectedBidExt:     `{"origbidcpm": 0,"prebid":{"type":"banner"}, "origbidcur": "USD"}`,
 			expectedErrMessage: "",
 		},
 		//Error cases
@@ -3644,7 +3675,7 @@ func TestMakeBidExtJSON(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id")
+		result, err := makeBidExtJSON(test.ext, &test.extBidPrebid, test.impExtInfo, "test_imp_id", test.origbidcpm, test.origbidcur)
 
 		if test.expectedErrMessage == "" {
 			assert.JSONEq(t, test.expectedBidExt, string(result), "Incorrect result")
@@ -3683,7 +3714,7 @@ func TestStoredAuctionResponses(t *testing.T) {
 		SeatBid: []openrtb2.SeatBid{
 			{
 				Bid: []openrtb2.Bid{
-					{ID: "bid_id", ImpID: "impression-id", Ext: json.RawMessage(`{"prebid":{"type":""}}`)},
+					{ID: "bid_id", ImpID: "impression-id", Ext: json.RawMessage(`{"origbidcpm":0,"prebid":{"type":""}}`)},
 				},
 				Seat: "appnexus",
 			},
@@ -4023,8 +4054,9 @@ func (b *validatingBidder) requestBid(ctx context.Context, request *openrtb2.Bid
 			bids := make([]*pbsOrtbBid, len(mockResponse.SeatBid.Bids))
 			for i := 0; i < len(bids); i++ {
 				bids[i] = &pbsOrtbBid{
-					bid:     mockResponse.SeatBid.Bids[i].Bid,
-					bidType: openrtb_ext.BidType(mockResponse.SeatBid.Bids[i].Type),
+					originalBidCPM: mockResponse.SeatBid.Bids[i].Bid.Price,
+					bid:            mockResponse.SeatBid.Bids[i].Bid,
+					bidType:        openrtb_ext.BidType(mockResponse.SeatBid.Bids[i].Type),
 				}
 			}
 
diff --git a/exchange/exchangetest/append-bidder-names.json b/exchange/exchangetest/append-bidder-names.json
index 507aee1a..2c0d46e4 100644
--- a/exchange/exchangetest/append-bidder-names.json
+++ b/exchange/exchangetest/append-bidder-names.json
@@ -111,6 +111,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -136,6 +137,7 @@
               ],
               "crid": "creative-3",
               "ext": {
+                "origbidcpm": 0.6,
                 "prebid": {
                   "targeting": {
                     "hb_bidder": "appnexus",
diff --git a/exchange/exchangetest/bid-consolidation-test.json b/exchange/exchangetest/bid-consolidation-test.json
index f65fd920..99a2a60a 100644
--- a/exchange/exchangetest/bid-consolidation-test.json
+++ b/exchange/exchangetest/bid-consolidation-test.json
@@ -110,6 +110,7 @@
             "h": 250,
             "crid": "creative-2",
             "ext": {
+              "origbidcpm": 0.4,
               "prebid": {
                 "type": "video"
               }
@@ -126,6 +127,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.3,
               "prebid": {
                 "type": "video"
               }
@@ -139,6 +141,7 @@
             "h": 500,
             "crid": "creative-3",
             "ext": {
+              "origbidcpm": 0.6,
               "prebid": {
                 "type": "video"
               }
diff --git a/exchange/exchangetest/bid-ext-prebid-collision.json b/exchange/exchangetest/bid-ext-prebid-collision.json
index 054671ce..3cc311ad 100644
--- a/exchange/exchangetest/bid-ext-prebid-collision.json
+++ b/exchange/exchangetest/bid-ext-prebid-collision.json
@@ -54,6 +54,7 @@
                             "crid": "creative-1",
                             "ext": {
                                 "someField": "someValue",
+                                "origbidcpm": 0.3,
                                 "prebid": {
                                     "willBeOverwritten": "by core logic"
                                 }
@@ -79,6 +80,7 @@
                     "crid": "creative-1",
                     "ext": {
                         "someField": "someValue",
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "video"
                         }
diff --git a/exchange/exchangetest/bid-ext.json b/exchange/exchangetest/bid-ext.json
index 8211ac88..c208f73c 100644
--- a/exchange/exchangetest/bid-ext.json
+++ b/exchange/exchangetest/bid-ext.json
@@ -53,6 +53,7 @@
                             "h": 250,
                             "crid": "creative-1",
                             "ext": {
+                                "origbidcpm": 0.3,
                                 "someField": "someValue"
                             }
                         },
@@ -75,6 +76,7 @@
                     "h": 250,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "someField": "someValue",
                         "prebid": {
                             "type": "video"
diff --git a/exchange/exchangetest/bid-id-invalid.json b/exchange/exchangetest/bid-id-invalid.json
index 17d3a3ec..278331d4 100644
--- a/exchange/exchangetest/bid-id-invalid.json
+++ b/exchange/exchangetest/bid-id-invalid.json
@@ -88,6 +88,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "type": "video",
                   "targeting": {
diff --git a/exchange/exchangetest/bid-id-valid.json b/exchange/exchangetest/bid-id-valid.json
index 8da6410e..f353514f 100644
--- a/exchange/exchangetest/bid-id-valid.json
+++ b/exchange/exchangetest/bid-id-valid.json
@@ -88,6 +88,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "bidid": "mock_uuid",
                   "type": "video",
diff --git a/exchange/exchangetest/debuglog_disabled.json b/exchange/exchangetest/debuglog_disabled.json
index e95b556b..c4b25a01 100644
--- a/exchange/exchangetest/debuglog_disabled.json
+++ b/exchange/exchangetest/debuglog_disabled.json
@@ -120,6 +120,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -145,6 +146,7 @@
               ],
               "crid": "creative-3",
               "ext": {
+                "origbidcpm": 0.6,
                 "prebid": {
                   "targeting": {
                     "hb_bidder": "appnexus",
diff --git a/exchange/exchangetest/debuglog_enabled.json b/exchange/exchangetest/debuglog_enabled.json
index 8475482f..0073c47c 100644
--- a/exchange/exchangetest/debuglog_enabled.json
+++ b/exchange/exchangetest/debuglog_enabled.json
@@ -122,6 +122,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -147,6 +148,7 @@
               ],
               "crid": "creative-3",
               "ext": {
+                "origbidcpm": 0.6,
                 "prebid": {
                   "targeting": {
                     "hb_bidder": "appnexus",
diff --git a/exchange/exchangetest/eidpermissions-allowed-alias.json b/exchange/exchangetest/eidpermissions-allowed-alias.json
index 24c9af7c..65287169 100644
--- a/exchange/exchangetest/eidpermissions-allowed-alias.json
+++ b/exchange/exchangetest/eidpermissions-allowed-alias.json
@@ -112,6 +112,7 @@
                     "h": 250,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "video"
                         }
diff --git a/exchange/exchangetest/eidpermissions-allowed.json b/exchange/exchangetest/eidpermissions-allowed.json
index 851c98dd..4e427cca 100644
--- a/exchange/exchangetest/eidpermissions-allowed.json
+++ b/exchange/exchangetest/eidpermissions-allowed.json
@@ -106,6 +106,7 @@
                     "h": 250,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "video"
                         }
diff --git a/exchange/exchangetest/eidpermissions-denied.json b/exchange/exchangetest/eidpermissions-denied.json
index 38127191..d834ea54 100644
--- a/exchange/exchangetest/eidpermissions-denied.json
+++ b/exchange/exchangetest/eidpermissions-denied.json
@@ -100,6 +100,7 @@
                     "h": 250,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "video"
                         }
diff --git a/exchange/exchangetest/events-bid-account-off-request-off.json b/exchange/exchangetest/events-bid-account-off-request-off.json
index 9ce23f5e..3bf1fc9e 100644
--- a/exchange/exchangetest/events-bid-account-off-request-off.json
+++ b/exchange/exchangetest/events-bid-account-off-request-off.json
@@ -71,6 +71,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "type": "banner"
                 }
@@ -84,6 +85,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "type": "banner"
                 }
diff --git a/exchange/exchangetest/events-bid-account-off-request-on.json b/exchange/exchangetest/events-bid-account-off-request-on.json
index 1dd2648e..6838ec94 100644
--- a/exchange/exchangetest/events-bid-account-off-request-on.json
+++ b/exchange/exchangetest/events-bid-account-off-request-on.json
@@ -73,6 +73,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "type": "banner",
                   "events": {
@@ -90,6 +91,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "type": "banner",
                   "events": {
diff --git a/exchange/exchangetest/events-bid-account-on-request-off.json b/exchange/exchangetest/events-bid-account-on-request-off.json
index 31e519b2..677fa21f 100644
--- a/exchange/exchangetest/events-bid-account-on-request-off.json
+++ b/exchange/exchangetest/events-bid-account-on-request-off.json
@@ -72,6 +72,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "type": "banner",
                   "events": {
@@ -89,6 +90,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "type": "banner",
                   "events": {
diff --git a/exchange/exchangetest/events-vast-account-off-request-off.json b/exchange/exchangetest/events-vast-account-off-request-off.json
index f322e7c5..9eff3e81 100644
--- a/exchange/exchangetest/events-vast-account-off-request-off.json
+++ b/exchange/exchangetest/events-vast-account-off-request-off.json
@@ -103,6 +103,7 @@
               "h": 250,
               "crid": "creative-4",
               "ext": {
+                "origbidcpm": 0.51,
                 "prebid": {
                   "type": "video"
                 }
@@ -122,6 +123,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -144,6 +146,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "type": "video"
                 }
diff --git a/exchange/exchangetest/events-vast-account-off-request-on.json b/exchange/exchangetest/events-vast-account-off-request-on.json
index 262b859a..0b30219d 100644
--- a/exchange/exchangetest/events-vast-account-off-request-on.json
+++ b/exchange/exchangetest/events-vast-account-off-request-on.json
@@ -109,6 +109,7 @@
               "h": 250,
               "crid": "creative-4",
               "ext": {
+                "origbidcpm": 0.51,
                 "prebid": {
                   "bidid": "mock_uuid",
                   "type": "video"
@@ -130,6 +131,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "bidid": "mock_uuid",
                   "type": "video",
@@ -154,6 +156,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "bidid": "mock_uuid",
                   "type": "video"
diff --git a/exchange/exchangetest/events-vast-account-on-request-off.json b/exchange/exchangetest/events-vast-account-on-request-off.json
index c5941e25..5a6d0451 100644
--- a/exchange/exchangetest/events-vast-account-on-request-off.json
+++ b/exchange/exchangetest/events-vast-account-on-request-off.json
@@ -104,6 +104,7 @@
               "h": 250,
               "crid": "creative-4",
               "ext": {
+                "origbidcpm": 0.51,
                 "prebid": {
                   "type": "video"
                 }
@@ -124,6 +125,7 @@
               "h": 250,
               "crid": "creative-1",
               "ext": {
+                "origbidcpm": 0.71,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -147,6 +149,7 @@
               "h": 250,
               "crid": "creative-2",
               "ext": {
+                "origbidcpm": 0.21,
                 "prebid": {
                   "type": "video"
                 }
diff --git a/exchange/exchangetest/firstpartydata-imp-ext-multiple-bidders.json b/exchange/exchangetest/firstpartydata-imp-ext-multiple-bidders.json
index ff88274f..c16fbc86 100644
--- a/exchange/exchangetest/firstpartydata-imp-ext-multiple-bidders.json
+++ b/exchange/exchangetest/firstpartydata-imp-ext-multiple-bidders.json
@@ -157,6 +157,7 @@
                     "h": 500,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "banner"
                         }
@@ -172,6 +173,7 @@
                     "h": 500,
                     "crid": "creative-2",
                     "ext": {
+                        "origbidcpm": 0.4,
                         "prebid": {
                             "type": "banner"
                         }
diff --git a/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json b/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json
index 0ecd3d5c..aaaac94c 100644
--- a/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json
+++ b/exchange/exchangetest/firstpartydata-imp-ext-multiple-prebid-bidders.json
@@ -161,6 +161,7 @@
                     "h": 500,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "banner"
                         }
@@ -176,6 +177,7 @@
                     "h": 500,
                     "crid": "creative-2",
                     "ext": {
+                        "origbidcpm": 0.4,
                         "prebid": {
                             "type": "banner"
                         }
diff --git a/exchange/exchangetest/firstpartydata-imp-ext-one-bidder.json b/exchange/exchangetest/firstpartydata-imp-ext-one-bidder.json
index b8a22ffd..9e42e5ae 100644
--- a/exchange/exchangetest/firstpartydata-imp-ext-one-bidder.json
+++ b/exchange/exchangetest/firstpartydata-imp-ext-one-bidder.json
@@ -99,6 +99,7 @@
                     "h": 500,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "banner"
                         }
diff --git a/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json b/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json
index e64fa787..87ff8a8a 100644
--- a/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json
+++ b/exchange/exchangetest/firstpartydata-imp-ext-one-prebid-bidder.json
@@ -103,6 +103,7 @@
                     "h": 500,
                     "crid": "creative-1",
                     "ext": {
+                        "origbidcpm": 0.3,
                         "prebid": {
                             "type": "banner"
                         }
diff --git a/exchange/exchangetest/include-brand-category.json b/exchange/exchangetest/include-brand-category.json
index 68e93e3a..38b8a7d3 100644
--- a/exchange/exchangetest/include-brand-category.json
+++ b/exchange/exchangetest/include-brand-category.json
@@ -99,6 +99,7 @@
               "crid": "creative-1",
               "cat": ["IAB1-1"],
               "ext": {
+                "origbidcpm": 0.3,
                 "prebid": {
                   "type": "video",
                   "targeting": {
@@ -122,6 +123,7 @@
               "cat": ["IAB1-2"],
               "crid": "creative-3",
               "ext": {
+                "origbidcpm": 0.6,
                 "prebid": {
                   "targeting": {
                       "hb_bidder": "appnexus",
diff --git a/exchange/exchangetest/request-multi-bidders-debug-info.json b/exchange/exchangetest/request-multi-bidders-debug-info.json
index 5061798b..18d9b1aa 100644
--- a/exchange/exchangetest/request-multi-bidders-debug-info.json
+++ b/exchange/exchangetest/request-multi-bidders-debug-info.json
@@ -121,6 +121,7 @@
                 "IAB1-1"
               ],
               "ext": {
+                "origbidcpm": 12.00,
                 "prebid": {
                   "type": "",
                   "targeting": {
diff --git a/exchange/exchangetest/request-multi-bidders-one-no-resp.json b/exchange/exchangetest/request-multi-bidders-one-no-resp.json
index b7179ccb..d46de2dc 100644
--- a/exchange/exchangetest/request-multi-bidders-one-no-resp.json
+++ b/exchange/exchangetest/request-multi-bidders-one-no-resp.json
@@ -94,6 +94,7 @@
             "crid": "creative-1",
             "cat": ["IAB1-1"],
             "ext": {
+              "origbidcpm": 12.00,
               "prebid": {
                 "type": "",
                 "targeting": {
diff --git a/exchange/exchangetest/targeting-cache-vast-banner.json b/exchange/exchangetest/targeting-cache-vast-banner.json
index 215485cc..d396abbb 100644
--- a/exchange/exchangetest/targeting-cache-vast-banner.json
+++ b/exchange/exchangetest/targeting-cache-vast-banner.json
@@ -64,6 +64,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.01,
               "prebid": {
                 "type": "banner",
                 "targeting": {
diff --git a/exchange/exchangetest/targeting-cache-vast.json b/exchange/exchangetest/targeting-cache-vast.json
index 53a48c4e..1cda3a5e 100644
--- a/exchange/exchangetest/targeting-cache-vast.json
+++ b/exchange/exchangetest/targeting-cache-vast.json
@@ -63,6 +63,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.01,
               "prebid": {
                 "cache": {
                   "bids": {
diff --git a/exchange/exchangetest/targeting-cache-zero.json b/exchange/exchangetest/targeting-cache-zero.json
index 0048ea10..3be5e630 100644
--- a/exchange/exchangetest/targeting-cache-zero.json
+++ b/exchange/exchangetest/targeting-cache-zero.json
@@ -66,6 +66,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.01,
               "prebid": {
                 "cache": {
                   "bids": {
diff --git a/exchange/exchangetest/targeting-mobile.json b/exchange/exchangetest/targeting-mobile.json
index f3962cff..4b41bc15 100644
--- a/exchange/exchangetest/targeting-mobile.json
+++ b/exchange/exchangetest/targeting-mobile.json
@@ -118,6 +118,7 @@
             "h": 250,
             "crid": "creative-4",
             "ext": {
+              "origbidcpm": 0.51,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -142,6 +143,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.71,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -169,6 +171,7 @@
             "h": 250,
             "crid": "creative-2",
             "ext": {
+              "origbidcpm": 0.21,
               "prebid": {
                 "type": "video"
               }
@@ -182,6 +185,7 @@
             "h": 500,
             "crid": "creative-3",
             "ext": {
+              "origbidcpm": 0.61,
               "prebid": {
                 "type": "video",
                 "targeting": {
diff --git a/exchange/exchangetest/targeting-no-winners.json b/exchange/exchangetest/targeting-no-winners.json
index 891ff0ff..74a67263 100644
--- a/exchange/exchangetest/targeting-no-winners.json
+++ b/exchange/exchangetest/targeting-no-winners.json
@@ -120,6 +120,7 @@
             "h": 250,
             "crid": "creative-4",
             "ext": {
+              "origbidcpm": 0.51,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -143,6 +144,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.71,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -163,6 +165,7 @@
             "h": 250,
             "crid": "creative-2",
             "ext": {
+              "origbidcpm": 0.21,
               "prebid": {
                 "type": "video"
               }
@@ -176,6 +179,7 @@
             "h": 500,
             "crid": "creative-3",
             "ext": {
+              "origbidcpm": 0.61,
               "prebid": {
                 "type": "video",
                 "targeting": {
diff --git a/exchange/exchangetest/targeting-only-winners.json b/exchange/exchangetest/targeting-only-winners.json
index 5f449af3..491ab98f 100644
--- a/exchange/exchangetest/targeting-only-winners.json
+++ b/exchange/exchangetest/targeting-only-winners.json
@@ -120,6 +120,7 @@
             "h": 250,
             "crid": "creative-4",
             "ext": {
+              "origbidcpm": 0.51,
               "prebid": {
                 "type": "video"
               }
@@ -136,6 +137,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.71,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -156,6 +158,7 @@
             "h": 250,
             "crid": "creative-2",
             "ext": {
+              "origbidcpm": 0.21,
               "prebid": {
                 "type": "video"
               }
@@ -169,6 +172,7 @@
             "h": 500,
             "crid": "creative-3",
             "ext": {
+              "origbidcpm": 0.61,
               "prebid": {
                 "type": "video",
                 "targeting": {
diff --git a/exchange/exchangetest/targeting-with-winners.json b/exchange/exchangetest/targeting-with-winners.json
index f081b7ee..faa5fbb9 100644
--- a/exchange/exchangetest/targeting-with-winners.json
+++ b/exchange/exchangetest/targeting-with-winners.json
@@ -118,6 +118,7 @@
             "h": 250,
             "crid": "creative-4",
             "ext": {
+              "origbidcpm": 0.51,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -141,6 +142,7 @@
             "h": 250,
             "crid": "creative-1",
             "ext": {
+              "origbidcpm": 0.71,
               "prebid": {
                 "type": "video",
                 "targeting": {
@@ -166,6 +168,7 @@
             "h": 250,
             "crid": "creative-2",
             "ext": {
+              "origbidcpm": 0.21,
               "prebid": {
                 "type": "video"
               }
@@ -179,6 +182,7 @@
             "h": 500,
             "crid": "creative-3",
             "ext": {
+              "origbidcpm": 0.61,
               "prebid": {
                 "type": "video",
                 "targeting": {