用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/majiayu000/claude-skill-registry --skill b2c-custom-api-development命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
LLM token logprobs and calibration. Per-decision confidence, ECE, Brier, reliability diagrams, low-confidence triage.
Analyze LLM token logprobs and calibration. Use for per-decision confidence, ECE, Brier scores, reliability diagrams, and low-confidence triage.
回顾最近 N 天的 Claude Code 使用记录——扫描原始会话数据,按主题分组汇总"我都做了什么",并从个人操作系统视角输出模式、风险与增删建议。当用户说 /recap、"看看我这几天做了什么"、"回顾一下我最近的会话"、"这两天我用 claude 干了啥"、"活动回顾" 时使用。
基于 SOC 职业分类
正在显示 SKILL.md
| name | b2c-custom-api-development |
| description | Guide for developing SCAPI Custom APIs on Salesforce B2C Commerce |
This skill guides you through developing Custom APIs for Salesforce B2C Commerce. Custom APIs let you expose custom script code as REST endpoints under the SCAPI framework.
A Custom API URL has this structure:
https://{shortCode}.api.commercecloud.salesforce.com/custom/{apiName}/{apiVersion}/organizations/{organizationId}/{endpointPath}
Three components are required to create a Custom API:
api.json file binding endpoints to implementationsCustom APIs are defined within cartridges. Create a rest-apis folder in the cartridge directory with subdirectories for each API:
/my-cartridge
/cartridge
package.json
/rest-apis
/my-api-name # API name (lowercase alphanumeric and hyphens only)
api.json # Mapping file
schema.yaml # OAS 3.0 contract
script.js # Implementation
/scripts
/controllers
Important: API directory names can only contain alphanumeric lowercase characters and hyphens.
The API contract defines endpoints using OAS 3.0 format:
openapi: 3.0.0
info:
version: 1.0.0 # API version (1.0.0 becomes v1 in URL)
title: My Custom API
components:
securitySchemes:
ShopperToken: # For Shopper APIs (requires siteId)
type: oauth2
flows:
clientCredentials:
tokenUrl: https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{organizationId}/oauth2/token
scopes:
c_my_scope: Description of my scope
AmOAuth2: # For Admin APIs (no siteId)
type: oauth2
flows:
clientCredentials:
tokenUrl: https://account.demandware.com/dwsso/oauth2/access_token
scopes:
c_my_admin_scope: Description of my admin scope
parameters:
siteId:
name: siteId
in: query
required: true
schema:
type: string
minLength: 1
locale:
name: locale
in: query
required: false
schema:
type: string
minLength: 1
paths:
/my-endpoint:
get:
summary: Get something
operationId: getMyData # Must match function name in script
parameters:
- $ref: '#/components/parameters/siteId'
- in: query
name: c_my_param # Custom params must start with c_
required: true
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
security:
- ShopperToken: ['c_my_scope'] # Global security (or per-operation)
info.version, transformed to URL version (e.g., 1.0.1 becomes v1)ShopperToken for Shopper APIs or AmOAuth2 for Admin APIsc_, contain only alphanumeric/hyphen/period/underscore, max 25 charsc_ prefixsiteId and locale must have type: string and minLength: 1additionalProperties attribute is not allowed in request body schemas| Aspect | Shopper API | Admin API |
|---|---|---|
| Security Scheme | ShopperToken | AmOAuth2 |
siteId Parameter | Required | Must omit |
| Max Runtime | 10 seconds | 60 seconds |
| Max Request Body | 5 MiB | 20 MB |
| Activity Type | STOREFRONT | BUSINESS_MANAGER |
The implementation script exports functions matching operationId values:
var RESTResponseMgr = require('dw/system/RESTResponseMgr');
exports.getMyData = function() {
// Get query parameters
var myParam = request.getHttpParameterMap().get('c_my_param').getStringValue();
// Get path parameters (for paths like /items/{itemId})
var itemId = request.getSCAPIPathParameters().get('itemId');
// Get request body (for POST/PUT/PATCH)
var requestBody = JSON.parse(request.httpParameterMap.requestBodyAsString);
// Business logic here...
var result = {
data: 'my data',
param: myParam
};
// Return success response
RESTResponseMgr.createSuccess(result).render();
};
exports.getMyData.public = true; // Required: mark function as public
// Error response example
exports.getMyDataWithError = function() {
RESTResponseMgr
.createError(404, , , )
.();
};
.. = ;
type field.public = trueEnable Page Caching for the site, then use:
// Cache for 60 seconds
response.setExpires(Date.now() + 60000);
// Personalized caching
response.setVaryBy('price_promotion');
Include responses from other SCAPI endpoints:
var include = dw.system.RESTResponseMgr.createScapiRemoteInclude(
'custom', 'other-api', 'v1', 'endpointPath',
dw.web.URLParameter('siteId', 'MySite')
);
var response = {
data: 'my data',
included: [include]
};
RESTResponseMgr.createSuccess(response).render();
The mapping file binds endpoints to implementations:
{
"endpoints": [
{
"endpoint": "getMyData",
"schema": "schema.yaml",
"implementation": "script"
},
{
"endpoint": "getMyDataV2",
"schema": "schema_v2.yaml",
"implementation": "script_v2"
}
]
}
Important:
Endpoints are registered when activating the code version containing the API definitions. After uploading your cartridge:
For Shopper APIs, the cartridge must be in the site's cartridge path. For Admin APIs, the cartridge must be in the Business Manager site's cartridge path.
Custom APIs have a circuit breaker that blocks requests when error rate exceeds 50%:
Prevention: Write robust code with error handling and avoid long-running remote calls.
When endpoints return 404 or fail to register:
rest-apis/{api-name}/ contains all filesCustomApiRegistry| Error | Cause | Solution |
|---|---|---|
| 400 Bad Request | Contract violation (unknown/invalid params) | Define all params in schema |
| 401 Unauthorized | Invalid/missing token | Check token validity and header |
| 403 Forbidden | Missing scope | Verify scope in token matches contract |
| 404 Not Found | Endpoint not registered | Check status report, verify structure |
| 500 Internal Error | Script error | Check logs for CustomApiInvocationException |
| 503 Service Unavailable | Circuit breaker open | Fix script errors, wait for reset |
b2c slas client create --default-scopes --scopes "c_my_scope" to create a test clientb2c-cli:b2c-slas skill for full client management optionssiteId in all requestssiteId from requestsTo query the Custom API status report, use an Account Manager token with scope:
sfcc.custom-apis (read-only)sfcc.custom-apis.rw (read-write)rest-apis/{api-name}/ structureDeploy your cartridge and activate to trigger Custom API registration:
# Deploy cartridge and reload (re-activate) to register endpoints
b2c code deploy ./my-cartridge --reload
# Or deploy then activate separately
b2c code deploy ./my-cartridge
b2c code activate my-code-version
See the b2c-cli:b2c-code skill for more deployment options.
After deployment, verify your endpoints are registered:
# Check Custom API registration status
# Tenant ID: derive from hostname (e.g., zzpq-013 → zzpq_013)
b2c scapi custom status --tenant-id zzpq_013
# Filter to see only failed registrations
b2c scapi custom status --tenant-id zzpq_013 --status not_registered
# Show error reasons for failed registrations
b2c scapi custom status --tenant-id zzpq_013 --status not_registered --columns apiName,endpointPath,errorReason
See the b2c-cli:b2c-scapi-custom skill for more status options.
| Issue | Solution |
|---|---|
Endpoint shows not_registered | Check errorReason column, verify schema.yaml syntax |
| Endpoint not appearing | Verify cartridge is in site's cartridge path, re-activate code version |
| 404 on requests | Endpoint not registered or wrong URL path |
Test your Custom API endpoints using curl after deployment.
Before testing a Shopper API with custom scopes, ensure you have a SLAS client configured with those scopes:
# Create a test client with your custom scope (replace c_my_scope with your scope)
b2c slas client create \
--tenant-id zzpq_013 \
--channels RefArch \
--default-scopes \
--scopes "c_my_scope" \
--redirect-uri http://localhost:3000/callback \
--json
# Save the client_id and client_secret from the output
Warning: Use --scopes (plural) for client scopes, NOT --scope (singular).
See b2c-cli:b2c-slas skill for more options.
Using a private SLAS client with client credentials grant:
# Set your credentials
SHORTCODE="your-short-code"
ORG="f_ecom_xxxx_xxx"
SLAS_CLIENT_ID="your-client-id"
SLAS_CLIENT_SECRET="your-client-secret"
SITE="RefArch"
# Get access token
TOKEN=$(curl -s "https://$SHORTCODE.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/$ORG/oauth2/token" \
-u "$SLAS_CLIENT_ID:$SLAS_CLIENT_SECRET" \
-d "grant_type=client_credentials&channel_id=$SITE" | jq -r '.access_token')
echo $TOKEN
# Call the Custom API endpoint
curl -s "https://$SHORTCODE.api.commercecloud.salesforce.com/custom/my-api/v1/organizations/$ORG/my-endpoint?siteId=$SITE" \
-H "Authorization: Bearer $TOKEN" | jq
b2c slas client list to find existing SLAS clientsb2c slas client create --default-scopes --scopes "c_my_scope" to create a test clientb2c webdav get from the logs root if requests failWhen your Custom API calls external services via LocalServiceRegistry.createService(), you must configure the service in Business Manager or import it via site archive.
See the b2c:b2c-webservices skill for:
var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');
var service = LocalServiceRegistry.createService('my.external.api', {
createRequest: function(svc, args) {
svc.setRequestMethod('GET');
svc.addHeader('Authorization', 'Bearer ' + args.token);
return null;
},
parseResponse: function(svc, client) {
return JSON.parse(client.text);
}
});
var result = service.call({ token: 'my-token' });
For simple HTTP services:
<?xml version="1.0" encoding="UTF-8"?>
<services xmlns="http://www.demandware.com/xml/impex/services/2014-09-26">
<service-credential service-credential-id="my.external.api">
<url>https://api.example.com/v1</url>
</service-credential>
<service-profile service-profile-id="my.external.api.profile">
<timeout-millis>5000</timeout-millis>
<rate-limit-enabled>false</rate-limit-enabled>
<rate-limit-calls>0</rate-limit-calls>
<rate-limit-millis>0</rate-limit-millis>
<cb-enabled>true</cb-enabled>
<cb-calls>5</cb-calls>
<cb-millis>10000</cb-millis>
</service-profile>
<service service-id="my.external.api">
<service-type>HTTP
true
MYAPI
true
false
false
my.external.api.profile
my.external.api
Common XML element name mistakes:
service-credential-id, NOT iduser-id, NOT userforce-prd-enabled, NOT force-prd-comm-log-enabledImport with: b2c job import ./my-services-folder
See b2c:b2c-webservices skill for complete schema documentation, or run b2c docs schema services for the XSD.
b2c-cli:b2c-code - Deploying cartridges and activating code versionsb2c-cli:b2c-scapi-custom - Checking Custom API registration statusb2c-cli:b2c-slas - Creating SLAS clients for testing Shopper APIs with custom scopesb2c:b2c-webservices - Service configuration, HTTP/FTP/SOAP clients, services.xml formatb2c-cli:b2c-job - Running jobs and importing site archivesadditionalProperties is not allowed$ref references supported in schemas (no remote/URL refs)c_ prefix