How to Implement Multi-Currency Support in the Adyen Salesforce Commerce Cloud Integration
The Adyen Salesforce Commerce Cloud integration handles multi-currency support automatically through the AdyenHelper utility class, which detects active currencies, applies correct fraction digits, and converts SFCC Money objects to the integer format required by the Adyen Checkout API.
The adyen/adyen-salesforce-commerce-cloud repository provides built-in mechanisms to implement multi-currency support without requiring custom conversion logic. At the core of this implementation is the adyenHelper.js file, which standardizes how monetary values are processed across all payment flows including checkout, payment methods, and gift card handling.
Core Currency Handling Architecture
The multi-currency architecture centers on src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js. This utility ensures that every payment-related script processes amounts consistently according to the shopper's selected currency and the specific decimal precision requirements of that currency.
Currency Detection and Fallback Logic
The getCurrencyValueForApi method determines the active currency by first checking the currencyCode property of the amount object. If this property is missing, the system falls back to session.currency.currencyCode.
// src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js (lines 736-744)
getCurrencyValueForApi(amount) {
const currencyCode =
Currency.getCurrency(amount.currencyCode) ||
session.currency.currencyCode; // ← fallback
const digitsNumber = adyenHelperObj.getFractionDigits(
currencyCode.toString(),
);
const value = Math.round(amount.multiply(10 ** digitsNumber).value);
return new dw.value.Money(value, currencyCode);
}
This approach ensures that basket-level currency selections override session defaults when present, while maintaining a reliable fallback for scenarios where explicit currency codes are not provided.
Fraction Digit Handling for Global Currencies
Different currencies require different decimal precisions. The getFractionDigits method (lines 749-783) encodes this mapping to ensure amounts are converted correctly for the Adyen API:
- Zero-decimal currencies: JPY, IDR (0 digits)
- Three-decimal currencies: BHD, KWD (3 digits)
- Standard currencies: USD, EUR, GBP (2 digits)
// src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js
getFractionDigits(currencyCode) {
let format;
const currency = currencyCode || session.currency.currencyCode;
switch (currency) {
case 'JPY': case 'IDR': /* … zero-decimal list */ format = 0; break;
case 'BHD': case 'KWD': /* … three-decimal list */ format = 3; break;
default: format = 2;
}
return format;
}
The conversion formula value = amount × 10^fractionDigits transforms SFCC Money objects into the integer format expected by Adyen's Checkout API.
Implementation Flow Across Payment Components
When implementing multi-currency support in custom controllers or scripts, follow this architectural pattern used throughout the integration:
- Basket Currency Selection: The shopper selects a currency through the storefront, updating the basket's
currencyCodevia standard SFCC mechanisms (configured in Business Manager). - Amount Conversion: Payment scripts call
AdyenHelper.getCurrencyValueForApito convert order totals, shipping costs, taxes, and line items. - API Payload Construction: Converted values are inserted into JSON payloads sent to Adyen via
AdyenHelper.getService. - Response Processing: Returned amounts are converted back using helper methods like
getDivisorForCurrencyfor shopper-facing displays.
Practical Code Examples
Converting Basket Totals for Payment Requests
When assembling payment requests in adyenCheckout.js, always convert the basket total using the helper method:
// src/cartridges/int_adyen_SFRA/cartridge/adyen/scripts/payments/adyenCheckout.js
var AdyenHelper = require('*/cartridge/adyen/utils/adyenHelper');
function createPaymentRequest(basket) {
var amount = AdyenHelper.getCurrencyValueForApi(basket.getTotalGrossPrice());
return {
amount: {
currency: amount.getCurrencyCode(),
value: amount.getValue()
},
// … additional fields …
};
}
This pattern appears consistently in getCheckoutPaymentMethods.js and other payment scripts, ensuring the amount object contains the correctly scaled integer value and currency code.
Handling Zero-Decimal Currencies
For zero-decimal currencies like JPY, the helper automatically prevents incorrect division:
// Example: Converting a gift-card balance in JPY
var balance = new dw.value.Money(5000, 'JPY'); // JPY uses 0 decimals
var apiBalance = AdyenHelper.getCurrencyValueForApi(balance);
// apiBalance.value === 5000 (remains unchanged)
Without this handling, a value of ¥5000 would be incorrectly sent as 50 (5000/100), causing significant payment discrepancies.
Programmatic Currency Switching
To implement multi-currency support that allows shoppers to switch currencies mid-session, modify the basket currency in a controller:
// In a custom controller extending CheckoutServices.js
var Currency = require('dw/util/Currency');
var BasketMgr = require('dw/order/BasketMgr');
var Transaction = require('dw/system/Transaction');
function changeBasketCurrency(newCurrencyCode) {
var basket = BasketMgr.getCurrentBasket();
if (Currency.getCurrency(newCurrencyCode) && basket) {
Transaction.wrap(function () {
basket.setCurrencyCode(newCurrencyCode);
});
}
}
This approach leverages the existing CheckoutServices.js pattern while ensuring subsequent Adyen API calls automatically pick up the new currency through the helper's fallback logic.
Key Source Files for Multi-Currency Implementation
| File | Role | Key Functions |
|---|---|---|
adyenHelper.js |
Central utility for currency conversion | getCurrencyValueForApi, getFractionDigits, getDivisorForCurrency |
adyenCheckout.js |
Assembles final payment payloads | Uses getCurrencyValueForApi for all amount fields |
getCheckoutPaymentMethods.js |
Retrieves available payment methods | Includes basket currency in eligibility requests |
CheckoutServices.js |
Controls basket lifecycle | Handles currency code updates |
adyenConfigs.js |
Reads site preferences | Exposes supported currencies from Business Manager |
Summary
- The
AdyenHelperclass inadyenHelper.jsprovides centralized currency conversion that automatically detects the active currency and applies correct fraction digits. - Use
getCurrencyValueForApito convert any SFCCMoneyobject to the integer format required by Adyen's API, handling zero-decimal (JPY) and three-decimal (BHD) currencies correctly. - The integration falls back from
amount.currencyCodetosession.currency.currencyCode, ensuring robust currency detection across different payment scenarios. - All payment scripts—including checkout, payment methods, and gift card handling—utilize these helper methods, providing consistent multi-currency support throughout the transaction lifecycle.
- Extend
getFractionDigitsinadyenHelper.jsonly if you need custom rounding rules for specific regional requirements.
Frequently Asked Questions
How does the Adyen integration handle currencies with no decimal places?
The integration automatically detects zero-decimal currencies like JPY and IDR through the getFractionDigits method in adyenHelper.js. When these currencies are identified, the multiplier uses 10^0 (equals 1), ensuring the amount is sent to Adyen as a whole number without division. This prevents the API from receiving incorrect fractional values for currencies that do not support decimal denominations.
Can shoppers change currencies after adding items to their basket?
Yes, you can implement multi-currency support that allows mid-session currency switching by updating the basket's currencyCode property within a transaction wrapper. The CheckoutServices.js controller demonstrates this pattern, and once updated, all subsequent calls to AdyenHelper.getCurrencyValueForApi automatically use the new currency for payment processing and amount conversion.
Where is the currency conversion logic centralized in the codebase?
All currency conversion logic is centralized in src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js, specifically within the getCurrencyValueForApi method (lines 736-744) and the getFractionDigits method (lines 749-783). This centralization ensures consistent handling across checkout, payment methods, partial payments, and gift card functionality without requiring duplicate conversion code in individual controllers.
Do I need to modify the Adyen service configuration for each currency?
No, the service configuration in AdyenHelper.getService remains currency-agnostic. The integration passes the currency code and converted amount values dynamically in each API request payload. As long as the currencies are configured in your Adyen merchant account and enabled in SFCC Business Manager, the existing service setup handles all supported currencies automatically.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →