When a user builds a custom plan by picking individual features, the receipt metadata contains the feature details directly.
Stripe limits metadata values to 500 characters. Cuprice splits the feature JSON across multiple keys:
{
"customPlan": "true",
"featureDetails_0": "[{\"name\":\"AI Prompt\",\"type\":\"Standard\",\"price\":10},",
"featureDetails_1": "{\"name\":\"Dashboard\",\"type\":\"Standard\",\"price\":20}]"
}
Reconstructing the feature list
Join all featureDetails_* keys and parse the JSON:
const metadata = receipt.metadata;
let json = "";
Object.keys(metadata)
.filter(k => k.startsWith("featureDetails"))
.sort()
.forEach(k => json += metadata[k]);
const features = JSON.parse(json);
// => [{ name: "AI Prompt", type: "Standard", price: 10 }, ...]
Feature object shape
Each feature in the array has:
Feature name (e.g. “AI Prompt”)
Feature type: “Standard”, “Limits”, or “Usage Based”
For Limits/Usage Based features, the purchased quantity