FX Rates

The FXRate adapter type is invoked when constructing an International Wire. It displays up-to-date exchange rate information for foreign currencies to United States Dollars.

We create an Adapter extension just as any other:

q2 create_extension
New Extension Name: ConvertToDollars
What type of extension are you creating?

    1) Online (default)
    2) SSO (Third Party Integration)
    3) Ardent (API)
    4) Q2Console (Backoffice)
    5) Central (Legacy Backoffice)
    6) Adapter <--------
    7) Audit Action
    8) Custom Health Check
    9) Message Bus
    10) Caliper API Custom Endpoint
    11) Base Extension

Please make a selection and press Return [1]: 6

Select adapter type to generate

    1) Account Details
    2) Authentication Token
    3) Check Image
    4) Domestic Wire
    5) Deposit Item Image
    6) External Authentication
    7) FX Rate  <--------
    8) Instant Payments
    9) International Wire
    10) Remote Deposit
    11) Statement Image

Please make a selection and press Return: 7

What did we get? Our extension.py has the usual boilerplate for a request handler, and a handler class definition with three methods:

async def get_fx_quote(self, currency_code, amount, group_id) -> FxRateQuoteReply:
async def book_fx_quote(self, currency_code, amount, group_id) -> FxRateExchangeDealReply:
async def cancel_fx_quote(self, currency_code, amount, group_id) -> FxRateExchangeDealReply:

That’s it? From the perspective of an extension developer, yes. By the time this code has executed, the Caliper SDK has:

  • Intercepted the request from Online

  • Checked the database for its configured destination

  • Redirected the request to this Caliper SDK extension

  • Translated the XML payload containing the request into simple parameters, currency_code, and amount, described above

What you do with these two values, is completely up to you– that’s the power and flexibility of adapters. But, whatever you return will be displayed to the end user as the equivalent amount in USD.

../../../../_images/fx_rates.png

Let’s implement a simple call to a third party that provides FOREX data:

async def get_fx_quote(self, currency_code, amount, group_id) -> FxRateQuoteReply:
    """
    Given the three letter currency code and amount, provide the conversion to USD

    :param currency_code: The 3 letter currency code as found in the Q2_CurrencyCode table
    :param amount: The amount of the currency to be converted
    """
    to = "USD"

    exchange_rate_api_url = f"https://local-dev-api.q2developer.com/projects/currencyConvert?to={to}&from={currency_code}&amount={amount}"
    rate = 0.0
    usd_amount = 0.0
    response = await q2_requests.get(
        self.logger,
        exchange_rate_api_url,
        headers={
            'apikey': 'S6TczFkiWjDZy7FElvqKYMogzdcEcoQy'
        }
    )

    response_as_dict = response.json()

    if response_as_dict.get("success"):
        usd_amount = response_as_dict.get("result")
        rate = response_as_dict.get("info").get('quote')
    else:
        self.logger.error(response_as_dict.get("message"))

    response = FxRateQuoteReply(
        status = ReplyStatus.Success,
        status_description="Success",
        quote_id = "SDF383JD-2332HDS83-332SDD", # ID to be used later during the booking process
        base_rate = rate, # (rate not including markup) - must be persisted with transaction for data extract during file creation - new field to store.
        exchange_rate = rate+.02, #  (rate including markup) - to be included in approval success message
        usd_equivalent_amount = usd_amount, # converted fx amount to usd
        expiration_date = datetime.now() + timedelta(days=1, hours=3)) # quote is good until

    return response

When the usd_amount is returned, the Caliper SDK will:

  • Translate the result back into an appropriate XML payload

  • Send the result through HQ

  • Display the result in Online banking, for example in the International Wires workflow

More details on the flow can be found in the Architecture section.

This function will be executed as the user is typing in the wire amount in the UI.

Once the user has approved the wire, the book_fx_quote function will be executed. Same behavior except this time you should actual execute the FX order.

The last function to implement is cancel_fx_quote. This function will be called if for some reason the order needs to be reversed.

For this to work, we need to install and configure our extension in the database. This is accomplished the same way as any extension type, q2 install. The appropriate tables will be updated to re-route adapter requests of the type FXRate, coming from anywhere in Q2 platform, to your running extension’s URL.