Sell your products online: the user picks a product & quantity and then makes a payment, all within the form.
// This is just a static JSON file for this example, but it _could_ be an interface
// to your backend inventory system, allowing you to provide availability estimates
// and up-to-date prices.
let inventoryEndpoint = `https://prod.static.formulate.dev/gallery/order-form/inventory.json`;
let menu = {
Cookware: ["Saucepan", "Sauté Pan", "Skillet", "Stock Pot"],
Bakeware: ["Cake Tin", "Cupcake Tray"],
Tools: ["Chef's Knife", "Paring Knife"],
};
let toOptions = (items, inventory) => {
return items.map((item) => ({
label: `${item}: ($${inventory[item].price / 100})`,
value: item,
image: `https://prod.static.formulate.dev/gallery/order-form/${item}.png`,
}));
};
export default async function () {
await form.statement("Welcome to our kitchen supply store!", {
buttonText: "Get started",
banner: {
full: true,
imageUrl: "https://prod.static.formulate.dev/gallery/patterns/2.png",
},
});
let response = await form.fetch(inventoryEndpoint);
let inventory = JSON.parse(response.text);
let { value: category } = await form.multi(
"Let's get started! What are you looking for?",
_.keys(menu),
{ single: true }
);
let { value: item } = await form.multi(
"Perfect, here's what we have in stock",
toOptions(menu[category], inventory),
{ single: true }
);
let { value: quantity } = await form.multi(
`**${item}**? Great choice! How many do you want to buy?`,
[1, 2, 3, 4, 5],
{ single: true, hideNumbers: true, name: "Quantity" }
);
let price = inventory[item].price;
let total = (quantity * price) / 100;
await form.statement(`Ok, that'll be $${total}. Please confirm below.`, {
buttonText: "Confirm",
});
await form.statement("Thanks! We need to collect some details from you so can we can ship this over to you as soon as possible.");
let { text: countries } = await form.fetch("https://prod.static.formulate.dev/gallery/countries.json");
let countryOptions = JSON.parse(countries).map((c) => c.Name);
await form.short("First, your email address!", { email: true });
let streetAddress = await form.short("Your street address:");
let city = await form.short("City:");
let zipCode = await form.short("ZIP code:", { number: true });
let { value: country } = await form.select("and country:", countryOptions, { single: true });
let {status} = await form.payment("Here's a final summary of your order:", {
description: `
- Item: ${item} ($${price / 100})
- Quantity: ${quantity}
- Address: ${streetAddress}, ${city} ${zipCode}, ${country}
`,
buttonText: "Purchase",
currency: "usd",
items: [{
amount: price,
name: item,
quantity: quantity,
imageUrls: [`https://prod.static.formulate.dev/gallery/order-form/${item}.png`],
}],
});
if (status === 'successful') {
await form.statement("Your payment was successful!", {
description: `We'll send you an email to confirm, and you should receive the ${item} soon.`,
buttonText: 'Submit',
});
} else {
await form.statement("Oops, looks like your payment failed! ", {
description: `Click below to submit your order anyway, someone will be in touch within 24 hours.`,
buttonText: 'Submit',
});
}
}