prebid / Prebid.js

Setup and manage header bidding advertising partners without writing code or confusing line items. Prebid.js is open source and free.
https://docs.prebid.org
Apache License 2.0
1.28k stars 2.05k forks source link

Prebid 1.0 - currency support #1089

Closed bretg closed 7 years ago

bretg commented 7 years ago

Tracking issue for currency support in Prebid 1.0 as defined in Issue #891. In additional to passing the currency abbreviation to adapters, we're going to spec a system where a static currency conversion file is stored on a CDN and updated daily. This file would optionally be loaded and used to adjust bid CPMs from specified bidders.

Note: our assumption here is that conversion is only necessary from USD to the following major currencies: AUD BRL CAD CHF CLP CNY CZK DKK EUR GBP HKD HUF IDR ILS INR JPY KRW MXN MYR NOK NZD PHP PKR PLN RUB SEK SGB THB TRY TWD ZAR

Let us know if there other source or destination currencies required. Wanted to keep the list to just those likely to be needed in order to keep the file small.

bretg commented 7 years ago

Suggested mechanism for utilizing the loaded exchange rates:

pbjs.bidderSettings = {
    abc: {
      bidCpmAdjustment : function(bidCpm, bid){
          return bidCpm * getCurrencyConversion("JPY");
       }
    },
    xyz: {
      bidCpmAdjustment : function(bidCpm, bid){
          grossToNetConversion=0.85;
          return bidCpm * getCurrencyConversion("JPY") * grossToNetConversion;
       }
   }
}
AntoineJac commented 7 years ago

Hi Bret,

I have worked on something similar with a customer using the fixer.io API however it requires the price to be set up with a "Custom CPM Bucket Sizing" or a specific bidderSettings as bucket are capped. Also important to notice that as the currency rate will vary, the keyword will change and could not match the line items anymore... Best method seems to use the method with CPMs declare in a Price Buckets to pass always the same keywords.

Cheers,

mijhael3000 commented 7 years ago

Hi Bret,

It is great that you are working on this.. If you define getCurrencyConversion function, from where does it take the exchange rate? from a web service? It could increase latatency and bring a new point of failure. What happen if the web service is not available?

Cheers!

Mijhael.-

AntoineJac commented 7 years ago

Hi Mijhael,

I think the best and more stable is the solution propose by Bret to host a static currency conversion file that will be updated daily if the request is successful. So if the web service is no more available, the rate will be the one from the day before the failure. We then have to create an alert system to be informed if the API is down so we could edit it.

Cheers,

Antoine

bretg commented 7 years ago

Right - the proposed design doesn't involved a remote API. If a publisher chooses to do currency conversion, a separate javascript file would be loaded that sets up an array that would be used by an internal API. This file would be updated daily by the Prebid Org team and cachable for 24 hours, and we'd be responsible for making sure it's fresh. Since the same file will be used across the internet, browsers will only have to load it once per day across all Prebid-using sites.

For pubs that don't want to rely on a common currency conversion file, we'll allow specification of a custom file.

bretg commented 7 years ago

We're considering using fixer.io as the source of currency conversions. However, it doesn't support all the currencies listed above. Exceptions:

So the plan is that the initial public service will contain only the currencies provided by http://api.fixer.io/latest.

If a particular publisher requires currencies not on this list, they will be able to host their own conversion file and use the code.

Slind14 commented 7 years ago

Would this allow conversions to EUR? Since you were talking about USD being the only go to. I'm asking because we have DFP setup with EURO as currency.

pribeh commented 7 years ago

Not sure if this will help, but if anyone is looking for a solution in the meantime this is what we're using to convert to Canadian:

<script>
  //Run this function before the prebid setup to obtain the conversion rate.
  //Use the conversion rate to adjust the bid Responses after the bids are back.
  window.RATE;
  function getConversionRate(currency){
    var xmlHttp = new XMLHttpRequest();
      xmlHttp.onreadystatechange = function() { 
          if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
              var response = JSON.parse(xmlHttp.responseText);
            if (response){
                var conversionRate = response.rates[currency];
                window.RATE = (Number(conversionRate));
            }
      }
      xmlHttp.open("GET", "http://api.fixer.io/latest?base=USD&symbols=" + currency, true);
      xmlHttp.send(null);   
  }

  getConversionRate('CAD');
  </script>
Slind14 commented 7 years ago

@pribeh doesn't this increase the overall latency?

GLStephen commented 7 years ago

Are we sure there are no non-us currency bidders that should be accounted for?

pribeh commented 7 years ago

@Slind14 It has too but by how much I haven't confirmed. I'll take a look in a bit to see if I can measure the latency. But, if you look on fixer's home page you can see they're estimation of response time to be 5.84ms – which isn't too shabby.

http://fixer.io/

Slind14 commented 7 years ago

@pribeh yeah, I was just wondering why you aren't caching it. @GLStephen I'm pretty sure Ströer will be using EUR once they release their header bidding in Q3/Q4, I guess there are many more, its just that the local ones require more time to support header bidding.

pribeh commented 7 years ago

@Slind14 Because I'm not sure how(?).

Slind14 commented 7 years ago

I haven't worked with prebid jet and have no idea of its structure. Maybe someone who knows the source could let us know if there is already some sort of mem caching happening which could be used for this or if we would need to handle it our self.

bretg commented 7 years ago

Some details about the in-progress implementation of the Prebid currency support:

1) Currency support is optional. It'll be turned on by calling a new setConfig() routine:

pbjs.setConfig({
  "currency": {
      "adServerCurrency": "AAA",    // enables currency feature
      "conversionRateFile": "URL"   // publisher can override the default rate file
   }});

2) The conversion rate file can be created and supplied by the publisher. Prebid Org will supply a file as a service to the community. The code expects the format below.

3) Adapters will need to specify what currency the bid is in. Defaults to USD if not specified.

4) The platform will detect whether a conversion is needed from the bid currency to the AdServerCurrency and will be smart about using the rate file to do so. It will be able to find a one-hop conversion as needed. e.g. if the bid is in AUD and needs to be converted to BRL, it could convert to AUD-USD first, then USD-BRL. Or a direct conversion can be provided in the file.

5) The Prebid Org rate file will be built daily by querying fixer.io and caching the results on AWS CloudFront.

Format of the conversion rate file:


{
   "dataAsOf":"2017-04-24",
   "conversions":{
      "USD":{        // from USD to other currencies
         "AUD":1.321,
         "BRL":3.1253,
         "CAD":1.3431,
         "CHF":0.99613,
         "CNY":6.8852,
          [...]
    },
    "GPB": {         // can optionally supply direct conversions
         [...]             // from multiple currencies
    }
  }
}
bretg commented 7 years ago

Waiting for modules so this can be refactored to fit into a module.