11. Checkout
Collect email, address, shipping, and payment, then place the order.
On this page
In this step, you'll create a checkout screen where users enter their address, choose shipping and payment methods, and place their order.
The checkout screen will have three steps:
- Delivery: Enter shipping and billing addresses.
- Shipping: Choose a shipping method.
- Payment: Choose a payment method.
You'll implement first the three steps components, including their components and utilities, then the main checkout screen and navigation.
Add Address Form Component
First, you'll create an address form component to collect shipping and billing addresses.
Create the file components/checkout/address-form.tsx with the following content:
tsx
The AddressForm component receives various props for the address fields and their change handlers. It also receives a list of countries to populate the country picker.
The component renders input fields for the address and a modal picker for selecting the country. It handles input focus and country selection appropriately.
Add Delivery Step Component
Next, you'll create the delivery step component for the checkout process. It will use the AddressForm component to collect shipping and billing addresses.
Create the file components/checkout/delivery-step.tsx with the following content:
tsx
The DeliveryStep component receives the following props:
email: The email address associated with the cart.shippingAddress: The shipping address details of the cart.billingAddress: The billing address details of the cart.useSameForBilling: A boolean indicating whether to use the shipping address for billing.loading: A boolean indicating whether the form is in a loading state.onEmailChange: Callback to update the email address.onShippingAddressChange: Callback to update the shipping address fields.onBillingAddressChange: Callback to update the billing address fields.onUseSameForBillingChange: Callback to toggle the use of the same address for billing.onNext: Callback to proceed to the next step.
The component renders an email input field and uses the AddressForm component to collect shipping and billing addresses. A switch is provided to toggle whether to use the same address for billing.
Add Shipping Step Component
Next, you'll create the shipping step component for the checkout process. This step allows users to select a shipping method.
Create the file components/checkout/shipping-step.tsx with the following content:
tsx
The ShippingStep component receives the following props:
shippingOptions: An array of available shipping options.selectedShippingOption: The ID of the currently selected shipping option.currencyCode: The currency code for formatting prices.loading: A boolean indicating whether the shipping options are being loaded.onSelectOption: Callback to select a shipping option.onBack: Callback to go back to the previous step.onNext: Callback to proceed to the next step.
The component renders a list of shipping options with their names and prices. The selected option is highlighted.
Add Payment Provider Utility
Before creating the payment step component, you'll add a utility function that maps payment provider IDs to their display information.
Create the file lib/payment-providers.ts with the following content:
ts
The getPaymentProviderInfo function takes a payment provider ID and returns an object containing an icon name and a formatted title for display purposes.
The function only handles Aiminaabee's built-in manual payment provider pp_system_default. You can expand it later to include more providers that you integrate.
Add Payment Step Component
You'll now create the payment step component for the checkout process. This step allows users to select a payment method, and shows the cart's summary before placing the order.
This step will not handle actual payment processing. Instead, it will just allow users to select a payment method and place the order. If you integrate real payment providers later, you'll need to handle their specific payment flows.
Create the file components/checkout/payment-step.tsx with the following content:
tsx
The PaymentStep component receives the following props:
cart: The current cart object containing pricing details.paymentProviders: An array of available payment providers.selectedPaymentProvider: The ID of the currently selected payment provider.loading: A boolean indicating whether the payment providers are being loaded.onSelectProvider: Callback to select a payment provider.onBack: Callback to go back to the previous step.onPlaceOrder: Callback to place the order.
The component renders a list of payment providers with their icons and titles. The selected provider is highlighted.
A summary of the cart's pricing details is displayed, including subtotal, discounts, shipping, tax, and total amount.
Add Checkout Screen Component
Finally, you'll create the main checkout screen that manages the multi-step checkout process. It will use the previously created step components to guide users through entering their information, selecting shipping and payment methods, and placing their order.
Create the file app/checkout.tsx with the following content:
tsx
The CheckoutScreen component includes the following state variables:
currentStep: The current step in the checkout process.loading: A boolean indicating whether an operation is in progress.- Contact and address fields for shipping and billing.
- Shipping options and the selected shipping option.
- Payment providers and the selected payment provider.
Next, you'll handle updating the state variables when the cart changes. Replace the // TODO update state when cart changes comment with the following:
tsx
A useEffect hook populates the form fields with existing cart data when the cart changes.
Next, you'll fetch the available shipping options and payment providers when the user reaches the respective steps. Replace the // TODO fetch shipping options and payment providers comment with the following:
tsx
You add a fetchShippingOptions function that retrieves shipping options, and a fetchPaymentProviders function that retrieves payment providers from the Aiminaabee backend.
You also add a useEffect hook that calls these functions when the user navigates to the shipping or payment steps.
Next, you'll add functions that handle moving between steps and placing the order. Replace the // TODO handle step transitions and order placement comment with the following:
tsx
The following functions are added:
handleDeliveryNext: Validates the delivery information, updates the cart with the email and addresses, and moves to the shipping step.handleShippingNext: Validates the selected shipping option, adds it to the cart, and moves to the payment step.handlePlaceOrder: Validates the selected payment provider, initiates the payment session, completes the cart, and handles the order confirmation. This function should also navigate to an order confirmation screen, which you'll implement later.
Finally, you'll render the appropriate step component based on the current step. Replace the // TODO render step components comment with the following:
tsx
If the cart isn't set, a message prompts the user to add items to their cart.
Otherwise, the step indicators are rendered at the top of the screen, and the current step's component is shown.
Add Checkout Screen to Navigation
Next, you'll add the checkout screen to the app's navigation structure. You'll add it as a top-level stack screen.
In app/_layout.tsx, Replace the TODO: Add checkout and order confirmation screens comment with the following:
tsx
Update Cart Screen to Navigate to Checkout
Finally, you'll update the cart screen to navigate to the checkout screen when the user taps the "Proceed to Checkout" button.
In app/(drawer)/(tabs)/(cart)/index.tsx, find the Button at the end of the CartScreen component's return statement, and change the onPress prop to the following:
tsx
If you get a type error regarding the /checkout route, the error will be resolved when you run the app.
Test the Checkout Flow
To test the checkout flow, run your Aiminaabee application and Expo app.
Then, in your Expo app, click on the "Proceed to Checkout" button in the cart screen. You should be taken to the checkout screen with the Delivery step as the current step.
In the Delivery step, fill in the email and address fields, then click "Continue" to proceed to the Shipping step.

Then, in the Shipping step, select a shipping method and click "Continue" to proceed to the Payment step.

Finally, in the Payment step, select a payment provider. You currently can place an order, but there is no order confirmation screen yet. You'll add it in the next step.

Next: 12. Order confirmation