This guide provides detailed instructions to install the cartridge on Salesforce Commerce Cloud (SFCC) SiteGenesis stores.
The Klarna Payments LINK Cartridge contains two cartridges required for full functionality. Controller and SiteGenesis support are separated into two distinct cartridges, facilitating the installation and use of either model:
int_klarna_paymentsint_klarna_payments: Implements the core storefront functionality.
int_klarna_payments_controllersint_klarna_payments_controllers: Implements the storefront functionality with SG code.
Go to the main directory metadata folder, review the site-template content, and edit if needed. (The site template is prepared to set up “SiteGenesis” and “RefArch” sites. You may want to change that to your actual sites and delete the ones that are not needed.)
2.
Zip the directory to create the site-template.zip installation package.
3.
Log into the SFCC Business Manager.
4.
Click Administration > Sites Development > Site Import & Export.
5.
Browse to the directory where you saved the site-template.zip.
6.
Click Upload.
7.
Select the uploaded site zip and click Import.
Review the default service.xml file in the site-template.zip and update the configuration for Playground and Production accordingly before importing.
As of version 24.4.0, the cartridge configuration process has changed. If you are using a version older than 24.4.0, please refer to the Deprecated Features section of the Changelog for detailed information on the configuration changes.
The templates have been updated to support On-site Messaging and Address Forms for Klarna. These templates are intended for reference, but you can customize them to suit your specific needs. Please ensure that the final review and sign-off align with your project requirements and contractual agreements.
This one-time clean-up job is applicable only to merchants integrated with Klarna Payments cartridge version earlier than 19.1.6, utilizing (or previously used) virtual card-based settlement (VCN) and stored decrypted card details within Business Manager.
The job iterates over orders with status Exported and the attribute custom.kpIsVCN=true to remove sensitive details saved in fields kpVCNPAN, kpVCNCSC, kpVCNExpirationMonth, and kpVCNExpirationYear from previous releases. No parameters are passed to the script.
Upon successful run, the job logs the result of processed orders in the custom debug log located in webdav/Sites/Logs. You will receive a message indicating the processed orders count for each storefront or a message indicating that there are no orders needing update.
In case of an error, the cause of the failure (message and stack trace) will be logged in the standard error log.
Log into the SFCC Business Manager, and go to Administration > Operations > Import & Export.
Click on the Import button, and browse for the jobs.xml file and select it for import.
Job Steps
The default scope included in the XML file is for RefArch. If you have multiple sites using this functionality, you need to configure each site as a separate flow within this file.
In the newly added flow, click on the Configure a step button. When the flyout appears, search for the term script, and select the ExecuteScriptModule from the list.
ID: Provide a meaningful and unique name for this job step. Ensure that the name is unique across all flows to avoid saving errors.
ExecuteScriptModule.Module: Specify the location of the OrderCleanUpJob.js file. The default path is int_klarna_payments/cartridge/scripts/job/OrderCleanUpJob.js, but this can vary depending on where the script is placed.
ExecuteScriptModule.FunctionName: Leave this field as execute.
Click on the Assign button to save the step configuration.
**Select the Site Scope: **Click on Organization within the step configuration flyout, and choose Specific Sites from the drop-down menu.
**Assign to the Relevant Site: **From the list of sites, select the appropriate site ID (e.g., SiteGenesisGlobal), and click on Assign to apply the configuration to the selected site.
Job scope content
Repeat steps 1-5 for each site/storefront that you have using Klarna VCN and need additional configuration. This ensures that the clean-up job runs for all relevant sites and removes sensitive data as required.
The RecurringOrders job is designed to process subscription entries for all customers. The job performs the following functions:
Eligibility Check: It verifies that the subscription is enabled and that either the nextChargeDate or nextRetryDate matches the current date.
Order Creation: It creates new Salesforce Commerce Cloud (SFCC) orders for eligible subscriptions, replacing the old ones.
Trial Period Handling: It processes orders with expiring trial periods for charges.
Configuration
By default, the job is set to run on the RefArch site, as specified in the jobs.xml file. This setting can be modified either in the jobs.xml file or through the storefront configuration.
The job consists of a single step, createOrder, with the following configuration:
To integrate Klarna Payments into the minishipments.isml file, follow these steps:
Add the following code at the beginning of the minishipments.isml file. This step includes the necessary Klarna Payments modules for the mini shipments template.
After the line containing <isminicheckout_address p_address="${'{'}shipment.shippingAddress{'}'}"/>, add the code below. This step adds the Klarna Payment Address Helper, which manages the shipment and shipping address.
Update the existing getExpressKlarnaMethod() function as shown below:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
* Read and update Klarna Express Payment Method SitePreference
* @param {object} paymentMethodCategories klarna payment categories received from Klarna authorize call
* @returns {Object} paymentMethods JSON string of payment methods
*/
functiongetExpressKlarnaMethod(paymentMethodCategories) {
// Use the payment method received from Klarna authorize call. If not available, fall back to the default value from KlarnaConstantsvar paymentMethods = paymentMethodCategories ? paymentMethodCategories : KlarnaConstants.KLARNA_EXPRESS_CATEGORY_CONTENT.KEC_CONTENT;
var paymentMethod = null;
if (!empty(paymentMethods)) {
if (!empty(paymentMethods) && paymentMethods.length > 0) {
int klarna payments:cartridge:scripts:util:klarnaHelper
Update existing Klarna.Payments.finalize() (within KEC condition) to send an empty object instead of sending the paymentmethod_categories in the KEC flow finalize call, as shown below:
int klarna payments:cartridge:static:default:js:klarna-payments-finalize 1
int klarna payments:cartridge:static:default:js:klarna-payments-finalize 2
This code handles orders with a pending Klarna fraud status by calling the PendingOrder method and logs an error if it fails.
Modifications in OrderModel.js
In the placeOrder method, add the following code at the end:
JAVASCRIPT
1
2
3
4
5
if (session.privacy.customer_token) {
var SubscriptionHelper = require('*/cartridge/scripts/subscription/subscriptionHelper');
SubscriptionHelper.updateCustomerSubscriptionData(order);
}
This code updates the customer subscription data if a customer token is present in the session.
Modifications in OrderModel.js (cont.)
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
var productLineItem = cart.createProductLineItem(productListItem, shipment);
productLineItem.setQuantityValue(quantity);
if (productLineItem) {
var isSubscriptionProduct = productListItem.product.custom.kpIsSubscriptionProduct;
var isStandardProduct = !empty(productListItem.product.custom.kpIsStandardProduct) ? productListItem.product.custom.kpIsStandardProduct : true;
if (isSubscriptionProduct && !isStandardProduct) {
productLineItem.custom.kpSubscription = true;
}
}
This code checks if the product is a subscription product and updates the product line item accordingly.
In the addProductItem function, add the following code block on line 220:
JAVASCRIPT
1
2
3
4
5
6
var isSubscriptionProduct = product.custom.kpIsSubscriptionProduct;
var isStandardProduct = !empty(product.custom.kpIsStandardProduct) ? product.custom.kpIsStandardProduct : true;
if (isSubscriptionProduct && !isStandardProduct) {
productLineItem.custom.kpSubscription = true;
}
Modifications in footer.isml
This code checks if the product is a subscription product and updates the product line item accordingly.
Add the following code before the module exports section:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
functionupdateSubscriptionAjax() {
var productId = request.httpParameterMap.pid.stringValue;
var subscription = request.httpParameterMap.subscription.stringValue === 'true';
var uuid = request.httpParameterMap.uuid.stringValue;
var SubscriptionHelper = require('*/cartridge/scripts/subscription/subscriptionHelper');
let r = require('~/cartridge/scripts/util/Response');
var cart = app.getModel('Cart').goc();
if (!cart) {
This function handles AJAX requests to update the subscription status of a product in the cart.
Add the following code before the module exports section:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
functionupdateSubscriptionDetailsAjax() {
var SubscriptionHelper = require('*/cartridge/scripts/subscription/subscriptionHelper');
var selectedValue = request.httpParameterMap.selectedValue.stringValue;
var subscriptionField = request.httpParameterMap.subscriptionField.stringValue;
let r = require('~/cartridge/scripts/util/Response');
var cart = app.getModel('Cart').goc();
if (!cart) {
This function handles AJAX requests to update subscription details in the cart.
Add the following code at the end of the exposed methods section:
Add the following subscriptions function at the end of the controller:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
/**
* Renders a page with all customer's subscriptions
*/functionsubscriptions() {
var subscriptions = [];
var profile = customer.profile;
if (profile.custom.kpSubscriptions) {
subscriptions = JSON.parse(profile.custom.kpSubscriptions);
}
app.getView({
This function retrieves the customer's subscriptions from their profile and renders the subscription history page.
Order.js modifications
Add the following module export for the subscriptions function:
JAVASCRIPT
1
2
3
4
/** Renders a page with the subscriptions history of the current logged in customer.
* @see module:controllers/Order~subscriptions */
exports.Subscriptions = guard.ensure(['get', 'https', 'loggedIn'], subscriptions);
This ensures that the subscriptions function is accessible and secured.
Add the following code on line 38, after the removeAllPayments() call:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
var SubscriptionHelper = require('*/cartridge/scripts/subscription/subscriptionHelper');
var subValidation = SubscriptionHelper.validateCartProducts(Cart.goc().object);
if (subValidation && subValidation.error) {
response.redirect(URLUtils.https('Cart-Show'));
return;
}
SubscriptionHelper.updateCartSubscriptionDetails(Cart.goc().object);
This code validates the subscription products in the cart and updates the cart subscription details. If there's an error, it redirects to the cart page.
Modifications in COCustomer.js
Update app.getView on line 68 by adding following code:
Insert the following code into the handleAuthorizationResult() function, before the line handleExpressCheckoutRedirect(cart, PAYMENT_METHOD, redirectURL);
Add klarnaSignIn function after Logout() function:
JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
/**
* Logs the customer in using Klarna SignIn functionality.
* Calls the {@link module:controllers/Account~Show|Account controller Show function}.
*/functionklarnaSignIn() {
var signInHelper = require('*/cartridge/scripts/signin/klarnaSignIn');
var r = require('*/cartridge/scripts/util/Response');
var Resource = require('dw/web/Resource');
var klarnaSignInErrorMsg = Resource.msg('klarna.signin.loginerror', 'klarnaSignIn', null);
All requests to Klarna are performed through Klarna’s REST API and are encrypted using SHA-256 with the shared secret provided by Klarna. To ensure security, only HTTPS is allowed for these communications. JSON is the format used for all requests and responses, facilitating consistent and structured data exchange.
For detailed information, including the resource structure for requests and responses, please refer to Klarna Payments API.