mcpField
B
b2c-webservices

b2c-webservices

github.com/salesforcecommercecloudDevelopment5787 installsUpdated today
Repository

About b2c-webservices

A skill for Salesforce B2C Commerce developers implementing external integrations with the Service Framework. It covers service configuration, callbacks, error handling, log filtering, and mock testing.

Key features

  1. 01Configure HTTP, SOAP, and file transfer services
  2. 02Create services with LocalServiceRegistry
  3. 03Implement request and response callbacks
  4. 04Handle rate limits and circuit breakers
  5. 05Filter sensitive logs and mock calls

Use cases

  1. 01Connect to external REST APIs or SOAP services
  2. 02Transfer files over FTP or SFTP
  3. 03Set timeouts and rate limits for service calls
  4. 04Test integrations without calling external systems

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-webservices

After installing, type/b2c-webservicesin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

evals/
trigger-evals.json
references/
FTP-SERVICES.md
HTTP-SERVICES.md
SERVICES-XML.md
SOAP-SERVICES.md

Details

From the project README

Web Services Skill

This skill guides you through implementing web service integrations in B2C Commerce using the Service Framework.

Overview

The Service Framework provides a structured way to call external services with:

FeatureDescription
ConfigurationService settings managed in Business Manager
Rate LimitingAutomatic throttling to protect external systems
Circuit BreakerAutomatic failure handling to prevent cascade failures
LoggingCommunication logging with sensitive data filtering
MockingTest services without external calls

Service Types

TypeUse CaseProtocol
HTTPREST APIs, webhooksHTTP/HTTPS
HTTPFormForm submissionsHTTP/HTTPS with form encoding
FTPFile transfers (deprecated)FTP
SFTPSecure file transfersSFTP
SOAPSOAP web servicesHTTP/HTTPS with SOAP
GENERICCustom protocolsAny

Service Framework Components

Business Manager Configuration

Services are configured in Administration > Operations > Services:

  1. Service Configuration - General settings (enabled, logging, callbacks)
  2. Service Profile - Rate limiting and circuit breaker settings
  3. Service Credential - URL and authentication credentials
Script Components
ComponentPurpose
LocalServiceRegistryCreates service instances
ServiceCallbackDefines request/response handling
ServiceBase service with common methods
ResultResponse object with status and data

Basic Pattern

'use strict';

var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');

var myService = LocalServiceRegistry.createService('my.service.id', {
    /**
     * Configure the request before it is sent
     * @param {dw.svc.HTTPService} svc - The service instance
     * @param {Object} params - Parameters passed to service.call()
     * @returns {string} Request body
     */
    createRequest: function (svc, params) {
        svc.setRequestMethod('POST');
        svc.addHeader('Content-Type', 'application/json');
        return JSON.stringify(params);
    },

    /**
     * Parse the response after a successful call
     * @param {dw.svc.HTTPService} svc - The service instance
     * @param {dw.net.HTTPClient} client - The HTTP client with response
     * @returns {Object} Parsed response
     */
    parseResponse: function (svc, client) {
        return JSON.parse(client.text);
    },

    /**
     * Filter sensitive data from logs (required for production)
     * @param {string} msg - The message to filter
     * @returns {string} Filtered message
     */
    filterLogMessage: function (msg) {
        return msg.replace(/("api_key"\s*:\s*")[^"]+"/g, '$1***"');
    }
});

// Call the service
var result = myService.call({ key: 'value' });

if (result.ok) {
    var data = result.object;
} else {
    var error = result.errorMessage;
}

Service Callbacks

CallbackRequiredDescription
createRequestYes*Configure request, return body
parseResponseYes*Parse response, return result object
executeNoCustom execution logic (replaces default)
initServiceClientNoCreate/configure underlying client
mockCallNoReturn mock response (execute phase only)
mockFullNoReturn mock response (entire call)
filterLogMessageRecommendedFilter sensitive data from logs
getRequestLogMessageNoCustom request log message
getResponseLogMessageNoCustom response log message

*Required unless execute is implemented

Result Object

The call() method returns a dw.svc.Result:

PropertyTypeDescription
okBooleanTrue if successful
statusString"OK", "ERROR", or "SERVICE_UNAVAILABLE"
objectObjectResponse from parseResponse
errorNumberError code (e.g., HTTP status)
errorMessageStringError description
unavailableReasonStringWhy service is unavailable
mockResultBooleanTrue if from mock callback
Unavailable Reasons
ReasonDescription
TIMEOUTCall timed out
RATE_LIMITEDRate limit exceeded
CIRCUIT_BROKENCircuit breaker open
DISABLEDService disabled
CONFIG_PROBLEMConfiguration error

Error Handling

var result = myService.call(params);

if (result.ok) {
    return result.object;
}

// Handle different error types
switch (result.status) {
    case 'SERVICE_UNAVAILABLE':
        switch (result.unavailableReason) {
            case 'RATE_LIMITED':
                // Retry later
                break;
            case 'CIRCUIT_BROKEN':
                // Service is down, use fallback
                break;
            case 'TIMEOUT':
                // Request timed out
                break;
        }
        break;
    case 'ERROR':
        // Check HTTP status code
        if (result.error === 401) {
            // Authentication error
        } else if (result.error === 404) {
            // Resource not found
        }
        break;
}

throw new Error('Service error: ' + result.errorMessage);

Log Filtering

Production environments require log filtering to prevent sensitive data exposure:

var myService = LocalServiceRegistry.createService('my.service', {
    createRequest: function (svc, params) {
        // ... configure request
    },

    parseResponse: function (svc, client) {
        return JSON.parse(client.text);
    },

    /**
     * Filter sensitive data from all log messages
     */
    filterLogMessage: function (msg) {
        // Filter API keys
        msg = msg.replace(/api_key=[^&]+/g, 'api_key=***');
        // Filter authorization headers
        msg = msg.replace(/Authorization:\s*[^\r\n]+/gi, 'Authorization: ***');
        // Filter passwords in JSON
        msg = msg.replace(/("password"\s*:\s*")[^"]+"/g, '$1***"');
        return msg;
    },

    /**
     * Custom request log message (optional)
     */
    getRequestLogMessage: function (request) {
        // Return custom message or null for default
        return 'Request: ' + request.substring(0, 100) + '...';
    },

    /**
     * Custom response log message (optional)
     */
    getResponseLogMessage: function (response) {
        // Return custom message or null for default
        return 'Response received';
    }
});

Mocking Services

Use mock callbacks for testing without external calls:

var myService = LocalServiceRegistry.createService('my.service', {
    createRequest: function (svc, params) {
        svc.setRequestMethod('GET');
        svc.addParam('id', params.id);
        return null;
    },

    parseResponse: function (svc, client) {
        return JSON.parse(client.text);
    },

    /**
     * Mock the execute phase only (createRequest and parseResponse still run)
     */
    mockCall: function (svc, request) {
        return {
            statusCode: 200,
            text: JSON.stringify({ id: 1, name: 'Mock Data' })
        };
    },

    /**
     * Or mock the entire call (replaces all phases)
     */
    mockFull: function (svc, params) {
        return { id: params.id, name: 'Full Mock Data' };
    }
});

// Force mock mode
myService.setMock();
var result = myService.call({ id: 123 });

Service Configuration in Business Manager

Creating a Service
  1. Go to Administration > Operations > Services
  2. Click New under Service Configurations
  3. Fill in:
    • Service ID: Unique identifier (e.g., my.api.service)
    • Service Type: HTTP, FTP, SOAP, etc.
    • Enabled: Check to enable
    • Profile: Select or create a profile
    • Credential: Select or create credentials
    • Communication Log: Enable for debugging
Service Profile Settings
SettingDescription
TimeoutMaximum wait time in milliseconds
Rate LimitMaximum calls per time unit
Circuit Breaker EnabledEnable automatic failure handling
Max Circuit Breaker CallsCalls before circuit opens
Circuit Breaker IntervalTime window for tracking failures
Service Credential Settings
SettingDescription
IDCredential identifier
URLBase URL for the service
UserUsername for authentication
PasswordPassword for authentication

Detailed References

Script API Classes

ClassDescription
dw.svc.LocalServiceRegistryCreate service instances
dw.svc.ServiceBase service class
dw.svc.HTTPServiceHTTP service methods
dw.svc.FTPServiceFTP/SFTP service methods
dw.svc.SOAPServiceSOAP service methods
dw.svc.ResultService call result
dw.svc.ServiceConfigService configuration
dw.svc.ServiceProfileRate limit/circuit breaker config
dw.svc.ServiceCredentialAuthentication credentials
dw.net.HTTPClientUnderlying HTTP client
dw.net.FTPClientUnderlying FTP client
dw.net.SFTPClientUnderlying SFTP client

Comments

Markdown supported