Solicit API
Embeddable service configurator with plans, add-ons, and real-time pricing. Solicit sits between item selection (ShopLift or custom) and payment processing (Swipe) to handle complex service configuration. The professional way to solicit services online.
What You Can Build
- Service marketplaces - Let users configure and purchase services
- Plan/tier selection - Radio-style plan picking with pricing
- Add-on upsells - Toggle additional services with real-time price updates
- Custom pricing logic - Implement any pricing model via callbacks
- External item display - Show selected items from ShopLift or custom sources
The Solicitation Flow
ShopLift Solicit Swipe (Products) -> (Services) -> (Payment) | | | v v v Cart Items Plan + Add-ons Checkout Selection Configuration Processing
Live Demo
Try the Solicit configurator. Gary's coping mechanisms are included.
Configure services for the newly single documentation writer
Sara, if you're reading this...
Quickstart
Start soliciting in under 2 minutes.
1. Include the SDK
<!-- Load Solicit Core --> <script src="https://solicit.vagibond.com/solicit-core.js"></script> <!-- Also load Swipe for payment processing --> <script src="https://swipe.vagibond.com/swipe-core.js"></script>
2. Initialize with your config
SolicitCore.init({
merchantId: 'your-merchant',
merchantName: 'Your Business',
plans: [
{ id: 'basic', name: 'Basic', price: 49, description: 'Entry tier' },
{ id: 'pro', name: 'Professional', price: 149, popular: true },
{ id: 'enterprise', name: 'Enterprise', price: 499 }
],
addons: [
{ id: 'priority', name: 'Priority Support', price: 29 }
]
});
// Initialize Swipe for payment
SwipeCore.init({ companyName: 'Your Business' });
3. Open the drawer
// Trigger on button click, CTA, etc. document.querySelector('.cta-button').addEventListener('click', () => { SolicitCore.open(); });
Authentication
Solicit is a client-side SDK - no API keys required. For server-side validation, configure webhooks through your Swipe integration.
Rate Limits
| Tier | Solicitations/mo | Notes |
|---|---|---|
| Free | Unlimited | Client-side only, no limits |
SDK Initialization
Configure Solicit with your merchant settings and service options.
SolicitCore.init({
// Required
merchantId: 'your-merchant-id',
merchantName: 'Your Business Name',
// Service tiers (radio selection)
plans: [...],
// Custom form fields
fields: [...],
// Add-on toggles
addons: [...],
// External items callback
getExternalItems: () => [...],
// Custom pricing logic
calculatePricing: (state) => {...},
// Theme customization
theme: {...},
// Labels customization
labels: {...},
// Callbacks
onSubmit: (data) => {...},
onClose: () => {...}
});
Plans Configuration
Define service tiers with radio-style selection.
plans: [ { id: 'starter', name: 'Starter', price: 49, description: 'Up to 3 solicitations/month' }, { id: 'professional', name: 'Professional', price: 149, description: 'Unlimited solicitations', popular: true // Shows "Popular" badge }, { id: 'enterprise', name: 'Enterprise', price: 499, description: 'Custom solutions' } ]
Custom Fields
Add form fields for service configuration.
fields: [ // Select dropdown { name: 'service_type', type: 'select', label: 'Service Type', options: [ { value: '', label: 'Select...', disabled: true }, { value: 'hourly', label: 'Hourly' }, { value: 'daily', label: 'Daily', price: 50 } // Shows +$50 ] }, // Text input { name: 'company', type: 'text', label: 'Company Name', placeholder: 'Your company' }, // Textarea { name: 'notes', type: 'textarea', label: 'Special Requests', rows: 4 }, // Number input { name: 'quantity', type: 'number', label: 'Quantity', min: 1, max: 100, defaultValue: 1 } ]
Add-ons
Toggle-able add-on services with pricing.
addons: [ { id: 'priority', name: 'Priority Support', price: 29, description: '24/7 dedicated support line' }, { id: 'insurance', name: 'Service Insurance', price: 99, description: 'Full refund if unsatisfied' } ]
Custom Pricing
Implement complex pricing logic with the calculatePricing callback.
calculatePricing: (state) => { // state contains: // - selectedPlan: { id, name, price, ... } // - selectedAddons: Set of addon IDs // - externalItems: Array from getExternalItems() // - fieldValues: { fieldName: value, ... } // - plans: Full plans array // - addons: Full addons array const planPrice = state.selectedPlan?.price || 0; const itemCount = state.externalItems.length || 1; const quantity = state.fieldValues.quantity || 1; // Calculate add-ons let addonsTotal = 0; state.selectedAddons.forEach(id => { const addon = state.addons.find(a => a.id === id); if (addon) addonsTotal += addon.price; }); const total = (planPrice * itemCount * quantity) + addonsTotal; return { lineItems: [ { label: 'Items', value: `${itemCount} selected` }, { label: 'Plan', value: `$${planPrice}` }, { label: 'Add-ons', value: `$${addonsTotal}` } ], total: total, frequency: '/mo' // or '', '/hr', 'one-time' }; }
Theming
Customize colors to match your brand.
theme: { accent: '#8B0000', // Primary accent color background: '#ffffff', // Drawer background headerBackground: '#f9fafb', text: '#111111', textMuted: '#666666', border: '#e5e7eb', inputBackground: '#ffffff', inputBorder: '#d1d5db', buttonBackground: '#8B0000', // Falls back to accent buttonText: '#ffffff', buttonHover: '#6B0000', borderRadius: '10px' }
open()
Opens the Solicit drawer. Resets state and renders fresh content.
SolicitCore.open();
close()
Closes the drawer. Triggers onClose callback if configured.
SolicitCore.close();
getState()
Returns current selection state.
const state = SolicitCore.getState(); // { // selectedPlan: { id: 'pro', name: 'Professional', price: 149 }, // selectedAddons: ['priority', 'insurance'], // externalItems: [...], // fieldValues: { service_type: 'hourly', notes: '...' } // }
configure()
Update configuration after initialization.
SolicitCore.configure({
plans: newPlans,
theme: { accent: '#00FF00' }
});
ShopLift Integration
Display cart items from ShopLift in the Solicit drawer.
SolicitCore.init({
// Get items from ShopLift cart
getExternalItems: () => {
return ShopLiftCore.getCart().map(item => ({
id: item.id,
name: item.name,
subtitle: item.subtitle,
image: item.image
}));
}
});
Swipe Handoff
By default, Solicit hands off to SwipeCore for payment processing.
// Default behavior (automatic) // When user clicks submit, Solicit: // 1. Builds order items from state // 2. Closes the Solicit drawer // 3. Calls SwipeCore.showCheckout(items, total) // Custom submit handling SolicitCore.init({ onSubmit: (orderData) => { // orderData contains full state // Handle custom payment flow console.log(orderData.pricing.total); myPaymentProcessor.checkout(orderData); } });
Custom Selection
Integrate with any selection UI (hobos, executives, pets, convicts, etc.).
// Track selected items in your own state let selectedItems = []; // Toggle selection function toggleItem(item) { const idx = selectedItems.findIndex(i => i.id === item.id); if (idx > -1) { selectedItems.splice(idx, 1); } else { selectedItems.push(item); } } // Configure Solicit to read from your state SolicitCore.init({ getExternalItems: () => selectedItems.map(item => ({ id: item.id, name: item.name, subtitle: `$${item.rate}/hr`, image: item.photo })) });
Testimoney Integration
Configure paid executive testimonials.
SolicitCore.init({
merchantId: 'testi',
merchantName: 'Testimoney',
plans: [
{ id: 'starter', name: 'Starter', price: 49, description: 'Up to 3 endorsers' },
{ id: 'growth', name: 'Growth', price: 149, description: 'Up to 10 endorsers', popular: true },
{ id: 'enterprise', name: 'Enterprise', price: 499, description: 'Unlimited' }
],
addons: [
{ id: 'ai-quotes', name: 'AI Quote Suggestions', price: 29 },
{ id: 'insurance', name: 'Testimonial Insurance', price: 99 }
],
getExternalItems: () => selectedExecutives,
calculatePricing: (state) => {
// Platform fee + executive rates
const platformFee = state.selectedPlan?.price || 0;
const execTotal = state.externalItems.reduce((sum, e) => sum + e.rate, 0);
// ...
}
});
Changelog
- Initial release
- Plans, fields, add-ons configuration
- Custom pricing callbacks
- ShopLift integration
- Swipe handoff
- Full theming support