prebid / prebid-server

Open-source solution for running real-time advertising auctions in the cloud.
https://prebid.org/product-suite/prebid-server/
Apache License 2.0
433 stars 741 forks source link

Feature: pub-supplied currency rates #1140

Closed LukaszSawicki closed 3 years ago

LukaszSawicki commented 4 years ago

Hi,

We have a problem with currency exchanging on prebid-server biddings. In our project we have combined server and client side requests and we have also included Currency module (https://github.com/prebid/Prebid.js/blob/master/modules/currency.js) in our Prebid.js build.

On client-side requests it works perfectly, but we found that Prebid Server is not including bidder currency param in any response, and because of that PrebidServerBidAdapter module (https://github.com/prebid/Prebid.js/blob/master/modules/prebidServerBidAdapter/index.js) sets currency always to USD, no matter what currency was given in response by bidder.

Here's an example on AdForm bid request. From https://prebid.adnxs.com/pbs/v1/openrtb2/auction we got that response:

{
  'id': '92871ddc-4e43-45bd-a2c8-f44870f091fc',
  'seatbid': [
    {
      'bid': [
        {
          'id': '9_112572',
          'impid': '9_112572',
          'price': 1.3734983170865096,
          'adm': '<script type=\'text/javascript\' src=\'https://track.adform.net/adfscript/?bn=34491113;rtbwp=0KdaFcCiY3YmUyrrKGm-BqzboUFQG3yp0;rtbdata=it3RNFYhxAzOdPpaRMCCIFjfL8dg0YrQTeqV-sEYjj6WPtMk4MFFL8mLstqXBt4V_H3zk3u66vFRhLWuSucc1xM73nLbpN-L6p4yY98_CQLFpImxpSJnDEuRK2Lzwr4HkUI9cLo8nmgfAUQyRAgod1fZOibZAeYf51-zJQPhYt0e1VUrJozfAH88PRYWiBYdcKnOS8tqjjzHJbbjjzKUTQx-WdyqLr5aRX8KgYH6sJWCrY1mv2tVw5yC_BU2llrlOwRSiA1It9Y8-rycztUMAcZvoPLq1akiXxCg5K_dDaYVodJSP-Diq4ScAp6vtaEklSXLtAJ-l86UA9Ix39DZbZyCArKcKByXYGi1BM8KZ9liy9coZxWKSiit7pJuZmv08JEc-uPRGWak37C5r9q8P070cZM8UC2aK6795bbid_rFq6z2Q40769GxFa_ggM5AL9eDYEw5AE5AUOaX9jaoe0Li0jV9AX0LpO5xEO-Z99DrrrNxWz0_SjOpEfEh8c5OEoG1Oe2xOHP7UcmhXVlnXN5BDaGN0EwkEpHZtjbfNUUr3ImfS10nHdBUdXywct_RZQ_AsLI2Aei_sfY3BKmsE1nnkzfGlEdyRRG73NTMH7SfoQ7aW2mmTWa8iSNdlU8Wl9BxHDFgFus1;csid=5134;adxcmd=QTwuOIuaMWxxWXp_eBE_5w2;adxvars=GvDfTI7SdKF42u1ywTJ-2s8aMsJi-PinijXHDtlJHH9OKroK4iShVJG4dWAZeGGwH2n6-cmF9PIIgRpgcR1YYW2hgZrY1TAfNlIRt_VCwZgyIF8FtP6J3j_xjHrCymTm_H3zk3u66vFRhLWuSucc1xM73nLbpN-LpbO2y2IdnHz93iT1He7T2xWq1lutpOSdruyl-v8gtqeIyq8by4rx2MWjAexNyLOV0;icid=5314392475118560546;icidt=637116649571265903;\'></script><script src="https://s1.adform.net/banners/scripts/adx.js"></script><i style="display: none" id="93b67f7953f342d9a8fb88f6140b3e74"></i><script>(_fscope = window._fscope || []).push(function (fscope) {fscope.register({"AdSlotId":"93b67f7953f342d9a8fb88f6140b3e74","CookieId":"5314392475118560546","Width":160,"Height":600,"TestId":null,"SerializedAdxVars":"GvDfTI7SdKF42u1ywTJ-2s8aMsJi-PinijXHDtlJHH9OKroK4iShVJG4dWAZeGGwH2n6-cmF9PIIgRpgcR1YYW2hgZrY1TAfNlIRt_VCwZgyIF8FtP6J3j_xjHrCymTm_H3zk3u66vFRhLWuSucc1xM73nLbpN-LpbO2y2IdnHz93iT1He7T2xWq1lutpOSdruyl-v8gtqeIyq8by4rx2MWjAexNyLOV0","PublisherVisibilityTime":1,"PublisherVisibilityArea":50,"UnloadHandlerUrl":"https://adx.adform.net/adx/unload/?","Gdpr":true,"GdprConsent":"BOpSRdzOrWHcLAKAbBPLCy-AAAAtBr_7__7-_9_-_f__9uj3Or_v_f__30ccL59v_h_zv-_5fi_20nV4u_1vft9yfk1-5ctDztp505iakivHmqNeb9v_mz3_5pxP78k89r7337Ew_v8_v8b7JCKN6A","IsMobile":false});});</script><img src="https://x.bidswitch.net/sync?ssp=adform" alt=" " style="display: none !important; width: 1px !important; height: 1px !important;" /><img src="https://d5p.de17a.com/getuid/adform?url=https%3a%2f%2fcm.adform.net%2fpixel%3fadform_pid%3d7%26adform_pc%3d" alt=" " style="display: none !important; width: 1px !important; height: 1px !important;" /><iframe src="https://s1.adform.net/banners/scripts/dt/digitrust.html" width="1" height="1" style="display: none !important; width: 1px !important; height: 1px !important;"></iframe>',
          'crid': '34491113',
          'w': 160,
          'h': 600,
          'ext': {
            'prebid': {
              'targeting': {'hb_bidder': 'adform', 'hb_pb': '1.30', 'hb_size': '160x600'},
              'type': 'banner'
            }
          }
        }
      ],
      'seat': 'adform'
    }
  ]
}

As you can see - there is no 'Currency' key in the response, but when we launch debug mode, in response object we are also getting original response from bidder, which looks that:

{
  'response': 'banner',
  'banner': '\u003cscript type=\u0027text/javascript\u0027 src=\u0027https://track.adform.net/adfscript/?bn=34491113;rtbwp=0KdaFcCiY3YmUyrrKGm-BqzboUFQG3yp0;rtbdata=it3RNFYhxAzOdPpaRMCCIFjfL8dg0YrQTeqV-sEYjj6WPtMk4MFFL8mLstqXBt4V_H3zk3u66vFRhLWuSucc1xM73nLbpN-L6p4yY98_CQLFpImxpSJnDEuRK2Lzwr4HkUI9cLo8nmgfAUQyRAgod1fZOibZAeYf51-zJQPhYt0e1VUrJozfAH88PRYWiBYdcKnOS8tqjjzHJbbjjzKUTQx-WdyqLr5aRX8KgYH6sJWCrY1mv2tVw5yC_BU2llrlOwRSiA1It9Y8-rycztUMAcZvoPLq1akiXxCg5K_dDaYVodJSP-Diq4ScAp6vtaEklSXLtAJ-l86UA9Ix39DZbZyCArKcKByXYGi1BM8KZ9liy9coZxWKSiit7pJuZmv08JEc-uPRGWak37C5r9q8P070cZM8UC2aK6795bbid_rFq6z2Q40769GxFa_ggM5AL9eDYEw5AE5AUOaX9jaoe0Li0jV9AX0LpO5xEO-Z99DrrrNxWz0_SjOpEfEh8c5OEoG1Oe2xOHP7UcmhXVlnXN5BDaGN0EwkEpHZtjbfNUUr3ImfS10nHdBUdXywct_RZQ_AsLI2Aei_sfY3BKmsE1nnkzfGlEdyRRG73NTMH7SfoQ7aW2mmTWa8iSNdlU8Wl9BxHDFgFus1;csid=5134;adxcmd=QTwuOIuaMWxxWXp_eBE_5w2;adxvars=GvDfTI7SdKF42u1ywTJ-2s8aMsJi-PinijXHDtlJHH9OKroK4iShVJG4dWAZeGGwH2n6-cmF9PIIgRpgcR1YYW2hgZrY1TAfNlIRt_VCwZgyIF8FtP6J3j_xjHrCymTm_H3zk3u66vFRhLWuSucc1xM73nLbpN-LpbO2y2IdnHz93iT1He7T2xWq1lutpOSdruyl-v8gtqeIyq8by4rx2MWjAexNyLOV0;icid=5314392475118560546;icidt=637116649571265903;\u0027\u003e\u003c/script\u003e\u003cscript src="https://s1.adform.net/banners/scripts/adx.js"\u003e\u003c/script\u003e\u003ci style="display: none" id="93b67f7953f342d9a8fb88f6140b3e74"\u003e\u003c/i\u003e\u003cscript\u003e(_fscope = window._fscope || []).push(function (fscope) {fscope.register({"AdSlotId":"93b67f7953f342d9a8fb88f6140b3e74","CookieId":"5314392475118560546","Width":160,"Height":600,"TestId":null,"SerializedAdxVars":"GvDfTI7SdKF42u1ywTJ-2s8aMsJi-PinijXHDtlJHH9OKroK4iShVJG4dWAZeGGwH2n6-cmF9PIIgRpgcR1YYW2hgZrY1TAfNlIRt_VCwZgyIF8FtP6J3j_xjHrCymTm_H3zk3u66vFRhLWuSucc1xM73nLbpN-LpbO2y2IdnHz93iT1He7T2xWq1lutpOSdruyl-v8gtqeIyq8by4rx2MWjAexNyLOV0","PublisherVisibilityTime":1,"PublisherVisibilityArea":50,"UnloadHandlerUrl":"https://adx.adform.net/adx/unload/?","Gdpr":true,"GdprConsent":"BOpSRdzOrWHcLAKAbBPLCy-AAAAtBr_7__7-_9_-_f__9uj3Or_v_f__30ccL59v_h_zv-_5fi_20nV4u_1vft9yfk1-5ctDztp505iakivHmqNeb9v_mz3_5pxP78k89r7337Ew_v8_v8b7JCKN6A","IsMobile":false});});\u003c/script\u003e\u003cimg src="https://x.bidswitch.net/sync?ssp=adform" alt=" " style="display: none !important; width: 1px !important; height: 1px !important;" /\u003e\u003cimg src="https://d5p.de17a.com/getuid/adform?url=https%3a%2f%2fcm.adform.net%2fpixel%3fadform_pid%3d7%26adform_pc%3d" alt=" " style="display: none !important; width: 1px !important; height: 1px !important;" /\u003e\u003ciframe src="https://s1.adform.net/banners/scripts/dt/digitrust.html" width="1" height="1" style="display: none !important; width: 1px !important; height: 1px !important;"\u003e\u003c/iframe\u003e',
  'win_bid': 1.3734983170865095227278813422,
  'win_cur': 'PLN',
  'width': 160,
  'height': 600,
  'deal_id': null,
  'win_crid': '34491113'
};

Original bidder response contains a key win_cur with a value of PLN. When you look at Prebid Server AdForm Bid Adapter (https://github.com/prebid/prebid-server/blob/master/adapters/adform/adform.go) you can see that the value of the win_cur field is correctly added to bidResponse object as the currency key. There is also a win_bid key which stores the CPM value. So now CPM value is 1.3735 PLN.

But after that Prebid Server code is probably ignoring currency field, because in Prebid Server response code we don't have any currency key. So, when Prebid.js gets the response it parses it to this form: Image1

Prebid.js Server Module set response original currency to USD and after that currency module converted it to PLN. And now we have the cpm value set to 5.2583 PLN

moteus commented 4 years ago

I also saw the same. According ORTB 2.5 missing currency means USD (both in reques and respose), so I think this is bug on the server side

SyntaxNode commented 4 years ago

Marked as a bug for now. We'll look into it, probably early next week.. unless a community contributor takes it on first. :)

SyntaxNode commented 4 years ago

We're looking at it now.

SyntaxNode commented 4 years ago

The issue is merged into version 0.97.0 and has been released to AppNexus/Xandr servers. Can you please verify the issue has been resolved?

onaydenov commented 4 years ago

It looks properly now. Server currency: "RUB", conversion "USD" "RUB"

LukaszSawicki commented 4 years ago

Works for me too.

I have one more question. Is it possible to tell Prebid Server from where it should get currency rates? Because in Prebid.js I can set flag 'conversionRateFile' to my own currency rate file, but on Prebid Server it takes currencies from https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json

SyntaxNode commented 4 years ago

It's not possible to pass a currency rate file to Prebid Server for a specific request. The host can override the default url (which you listed) if they would like. This approach allows the server to cache the conversion rates and use network connections for bids.

Why do you choose to use your own conversion rates? Is there an issue with the ones published by Prebid.org?

bretg commented 4 years ago

FWIW - PBS-Java supports passing in the currency rates on the request:

"ext": {
  "prebid": {
      "currency": {
          "rates": {
              "USD": { "UAH": 24.47, "ETB": 32.04 }
          }
      }
  }
}
SyntaxNode commented 4 years ago

This issue was discussed at the Prebid.org Server Group meeting on 2/21/2020. I asked about the use cases for when a publisher would want to supply their own conversion rates and was given the following circumstances:

With this context, I believe it makes sense to allow the publisher to provide their own currency conversions. I propose two distinct modes:

  1. Override The publisher may override existing conversion pairs or add new conversion pairs that Prebid Server would look at before the default ones (if available). This is a good choice if the publisher generally trusts the defaults in Prebid Server and wants to expand the currencies available or would like to provide more updated intraday pricing.

  2. Replace The publisher may provide conversion pairs which will be used without regard for whatever defaults Prebid Server may have. This is a good choice for publishers who want full control over their currency conversions. I feel this is important because the default currency conversion rates are unknown to the publisher and may still be used even with overrides provided through implicit conversion rates (the server knows A -> B and B -> C and could infer A -> C). This may cause issues the publisher would not expect.

Thoughts? Is this similar to the options already provided by PrebidJS?

bretg commented 4 years ago

Prebid.js supports two modes:

Please describe what would happen technically in your proposed scenarios. They seem the same to me: "use this value instead of what PBS already has". Are you suggesting a flag that tells PBS to ignore its own conversion rates? Like a usePbsRates flag?

"ext": {
    "prebid": {
      "currency": {
          "rates": {
              "USD": { "UAH": 24.47, "ETB": 32.04, "EUR": 0.92, ... }
          },
                  "usepbsrates": false // defaults to true
      }
  }
}
SyntaxNode commented 4 years ago

Are you suggesting a flag that tells PBS to ignore its own conversion rates? Like a usePbsRates flag?

Yes.

If true, PBS would use it's rates and the publisher override rates as you describe it works today in the Java app. If false, PBS would only use the publisher rates giving the publisher full control and confidence over the calculations.

bretg commented 4 years ago

ok - are you good with the proposed usepbsrates flag? We've been rather inconsistent about our attribute syntax. Looking over the extensions, all lowercase is the most common format.

bretg commented 4 years ago

Since the bug portion of this ticket is fixed, changing this to an enhancement to track the usepbsrates feature.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

bretg commented 4 years ago

This has been implemented in PBS-Java.

SyntaxNode commented 3 years ago

Implemented in PBS-Go 0.163.0.