Phone number ordering
A step-by-step flow for adding new phone numbers to the account: search by area code or ZIP code, pick numbers from the results, review the cost, choose where their calls go, and place the order.
Usage
- React
- Web Component
import { PhoneNumberOrdering } from '@dialstack/sdk-react/phone-number-ordering';
function OrderNumbersPage() {
return <PhoneNumberOrdering />;
}
<dialstack-phone-number-ordering></dialstack-phone-number-ordering>
<script>
// `dialstack` is your initialized instance (see Setup)
document.querySelector('dialstack-phone-number-ordering').setInstance(dialstack);
</script>
Enable the phone_number_ordering component when you mint the account session. It covers everything the flow does: searching for numbers, reading the account's per-number rate, placing and checking the order, and listing and setting call routing for the new numbers. See Sessions.
The ordering flow
A progress bar across the top shows which of the five steps the user is on.
- Search. The user picks Area Code or ZIP Code, types a value, and sets how many results to show (1 to 100, 10 by default).
- Select. Available numbers are listed with their state. The user clicks rows to select them, or uses the header checkbox to select them all. Search results are not reserved, so another buyer can take a number before the order goes in.
- Confirm. The selected numbers are listed with what they add to the account's bill. A live account sees the monthly total at its per-number rate, or a note that the numbers are billable when it has no rate set. A sandbox account sees that ordering costs nothing.
- Route. The user picks where the new numbers send calls once they activate: a user, dial plan, voice app, queue, ring group or shared voicemail box. Set up routing later is selected by default. Place Order submits the order, and the routing is applied as soon as the order is placed. If it can't be applied to a number, that number is left without routing and the order still goes ahead.
- Done. The component shows the result and checks on a pending order every 2 seconds, up to five times. If the order is still pending after that, it says the order is taking longer than usual and that the numbers will appear once it completes. Order More Numbers starts over.
All the numbers in an order are acquired together: if any one of them can't be, the order fails. An order is also rejected when it would take the account past its phone number limit, or when some of the selected numbers have been taken since the search. In each case the component shows an Order Failed screen with a message the user can act on, such as contacting support to raise the limit, and a Try Again button that returns to the search.
If the search itself fails, the component shows a Search Failed screen instead. When no numbers can be searched for the ZIP code entered, it names the ZIP code and suggests a nearby one or an area code search. When the search was otherwise rejected, it asks the user to check the area code or ZIP code. When search is unavailable, it asks them to try again later.
To order numbers from your own backend instead, see New numbers.
Options
These are specific to phone number ordering. The common options (locale, formatting, icons, layout variant, classes, load callbacks) apply too.
| React prop | Web Component method | Type | Default | Description |
|---|---|---|---|---|
searchTypes | setSearchTypes(types) | ('area_code' | 'zip')[] | ['area_code', 'zip'] | Which search modes to offer, in this order |
onOrderComplete | setOnOrderComplete(cb) | (event: { orderId: string; order: NumberOrder }) => void | — | Called when an order finishes |
onOrderError | setOnOrderError(cb) | (event: PhoneNumberOrderErrorEvent) => void | — | Called when an order is rejected or fails |
onOrderPending | setOnOrderPending(cb) | (event: { orderId: string; order: NumberOrder }) => void | — | Called when the component stops checking a pending order |
classes | setClasses(classes) | PhoneNumberOrderingClasses | — | Extra CSS classes (see Styling) |
An empty searchTypes array is ignored. onLoadError fires when a search fails, with the API's error message for your logs. A failed search doesn't fire onOrderError.
Search modes
To offer ZIP code search only:
- React
- Web Component
<PhoneNumberOrdering searchTypes={['zip']} />
ordering.setSearchTypes(['zip']);
Order events
Each order ends in exactly one of these callbacks:
onOrderCompletefires once the order is no longer pending, with the order's ID and the order itself. Apartialorder lands here too; checkfailed_numbers.onOrderErrorfires when the API rejects the order or the carrier fails it.onOrderPendingfires when the order is still pending after the component's last check, with the order's ID and the order as last seen. The component also fires it when it can't check on the order. The order carries on without the component. Fetch it by its ID later to see how it ended (see New numbers).
An order usually completes within seconds, so onOrderPending is rare.
PhoneNumberOrderErrorEvent
interface PhoneNumberOrderErrorEvent {
error: string; // the message the component shows, in its locale
message?: string; // the underlying error text, for your logs
code?: string; // the API's error code, when it sent one
status?: number; // HTTP status of the rejected request
details?: Record<string, unknown>; // the API's details for that code
order?: NumberOrder; // the order, when it was placed and then failed
}
error is written for the user, so you can show it as is. message is the API's message for a refused order, or the carrier's reason for a failed one. It is in English and can be technical, so log it rather than show it. To react to a specific failure, branch on code rather than on the text. When the order would take the account past its phone number limit, code is phone_number_limit_exceeded. When some of the numbers were taken since the search, it is phone_numbers_already_claimed. See Error codes for the full list.
- React
- Web Component
<PhoneNumberOrdering
onOrderComplete={(event) => {
console.log(`Order ${event.orderId}: ${event.order.completed_numbers.length} numbers added`);
router.push('/phone-numbers');
}}
onOrderError={(event) => console.error('Order failed:', event.code ?? event.error)}
onOrderPending={(event) => console.log(`Order ${event.orderId} is still in progress`)}
/>
const ordering = document.querySelector('dialstack-phone-number-ordering');
ordering.setOnOrderComplete((event) => {
console.log(`Order ${event.orderId}: ${event.order.completed_numbers.length} numbers added`);
window.location.href = '/phone-numbers';
});
ordering.setOnOrderError((event) => console.error('Order failed:', event.code ?? event.error));
ordering.setOnOrderPending((event) => console.log(`Order ${event.orderId} is still in progress`));
NumberOrder
interface NumberOrder {
id: string;
order_type: 'purchase' | 'disconnect';
status: 'pending' | 'complete' | 'partial' | 'failed';
phone_numbers: string[]; // the numbers requested, E.164
completed_numbers: string[];
failed_numbers: string[];
error_message: string | null;
created_at: string; // ISO 8601
updated_at: string;
}
Styling
classes adds your own CSS class names to parts of the component. For colors, fonts and spacing, see Theming.
| Key | Applied to |
|---|---|
base | The component's container |
searchForm | The search step |
resultsTable | The results step |
resultRow | Each result row |
resultRowSelected | A selected result row |
confirmPanel | The confirm step |
orderComplete | The step shown once the order is placed |
- React
- Web Component
<PhoneNumberOrdering
classes={{ resultRow: 'hover:bg-gray-50', resultRowSelected: 'font-semibold' }}
/>
ordering.setClasses({ resultRow: 'hover:bg-gray-50', resultRowSelected: 'font-semibold' });
Next steps
- Phone numbers — list the account's numbers, including orders in progress
- New numbers — search and order numbers through the API
- Theming — customize appearance