Skip to content

Building Embedded Apps on YouCan

This guide will walk you through the process of creating and deploying an embedded app within the YouCan platform. We'll focus on building an app that displays orders and sends SMS alerts when a new order is placed. We'll use the YouCan CLI's starter template to streamline the development process.

App Overview

The purpose of this app is to enhance the merchant experience. It listens for new order notifications via webhooks and alerts the merchant through SMS. The app's backend handles webhook events, while the frontend displays order information.

Learning Objectives

By the end of this tutorial, you'll be able to:

  • Build and integrate embedded apps for YouCan.
  • Set up your development environment.
  • Authenticate your app with the YouCan platform
  • Use YouCan APIs for data integration.
  • Implement real-time SMS notifications using Twilio.

Requirements

To start building our app, we'll need to set up our working environment first.

  • Create a YouCan Partner Account and set a development store.
  • Ensure Required Software: You must have NodeJs, a package manager (either npm or pnpm), and git installed.
  • Familiarity with JavaScript: To get you started, YouCan provides an app template based on Nuxt.
  • Select a Code Editor for managing the codebase.

Let’s Get Started!

Initialize The Project

When we're building a YouCan app, we don't need to install YouCan CLI globally. Instead, these packages should be added as dependencies of our app.

Run the following command using pnpm to install all the dependencies needed - including YouCan CLI itself.

bash
pnpm create @youcan/app@latest

or you can use npm

bash
npm init @youcan/app@latest
app-structure

After initialization, choose a name for this app that reflects its purpose. For this example, let's name it "order-tracker".

Next, select the “Start with Nuxt” option as a starting template.

Set Up the Application

The setup process will place all necessary files in the app's directory.

  1. Let's navigate to our newly created app's directory:
bash
cd order-tracker
  1. Inside the app's directory, we'll make sure all dependencies are installed using pnpm:
bash
pnpm install

This command installs all the required dependencies listed in the package.json file.

App Structure

As a starting point, the generated app's directory includes a Nuxt template with some preset configurations. Let's see what each folder and file does:

app-structure
  • layouts: Defines the structure of our app's UI.

  • pages: Vue components that correspond to the routes of our app. index.vue is the default landing page.

  • prisma: Contains Prisma schema and migration files, used to define and manage the app's database models.

  • public: Static assets like images and fonts go here.

  • server: server-side logic is defined here, including API routes and middleware

  • youcan: This directory is specific to the YouCan platform that contains custom configurations and code that interfaces with YouCan APIs.

  • app.vue: The main Vue component that acts as the entry point for our app.

  • .env and .env.example: Environment configuration files. We'll duplicate .env.example to create a .env file, then fill it with the private keys and settings (more details are provided in the next step)

  • youcan.app.json and youcan.web.json: Configuration files specific to our app, such as OAuth settings.

Start the Development Server

We'll get our development server up by running the following command in our app's directory:

bash
pnpm dev

This command initiates our app's local development server. If you haven't logged in to your YouCan development store yet, the YouCan CLI will prompt you for authentication.

Authentication and Environment Configuration

Once the server is up and running, we'll have to establish a secure session and authenticate our app with the YouCan platform.

The YouCan CLI's app template simplifies this process with a pre-configured OAuth flow, but you can dive deeper into customization by checking the Authentication Setup Process.

App Settings

When running a local server (e.g port 3000), we must make it publicly accessible for features like Webhooks to work correctly. Here's how to set it up:

1. Making Our Local Server Public:

  • We'll use ngrok to expose our local server, providing us with a public URL for receiving webhooks from YouCan.
bash
ngrok http 3000
set up ngrok url

2. Accessing OAuth Credentials:

  • Navigate to your YouCan Partner dashboard and locate the app we're creating.
  • Click on "details" to view our OAuth client details.
youcan partner client details

3. Updating .env File:

  • We'll create a .env file based on the .env.example template.
  • Fill in our OAuth credentials, making sure the NUXT_YOUCAN_API_KEY matches the Client ID and the NUXT_YOUCAN_API_SECRET matches the Client Secret.
  • Set NUXT_YOUCAN_API_REDIRECT to our ngrok URL followed by the path to the auth callback endpoint.
  • Add NUXT_YOUCAN_WEBHOOK_URL with our ngrok URL to prepare for setting up webhooks.
javascript
//.env

NUXT_YOUCAN_API_KEY=45
NUXT_YOUCAN_API_SECRET=[Client Secret]
NUXT_YOUCAN_API_SCOPES=*
NUXT_YOUCAN_API_REDIRECT=https://39fb-102-50-248-53.ngrok-free.app/auth/callback
NUXT_YOUCAN_WEBHOOK_URL=https://39fb-102-50-248-53.ngrok-free.app/youcan/webhook
DATABASE_URL="file:./dev.db"
env config

4. Updating youcan.app.json file:

  • In the youcan.app.json file, we'll confirm the name and id of our app.
  • Replace the app_url with our ngrok URL (e.g https://39fb-102-50-248-53.ngrok-free.app).
  • Update the redirect_urls to include our ngrok redirect URI.
  • Make sure the oauth object contains the correct scopes and client_id.
JSON
 //youcan.app.json

{
    "name": "order-tracker",
    "id": "dapp_2b8zbj5B7mswKEMkq7H2d2TEv44",
    "app_url": "https://39fb-102-50-248-53.ngrok-free.app",
    "redirect_urls": [
        "https://39fb-102-50-248-53.ngrok-free.app/auth/callback",
    ],
    "oauth": {
        "scopes": [
            "*"
        ],
        "client_id": "45"
    }
}
youcan oauth server

By following these steps, we'll have a secure, authenticated app ready to be installed on our development store.

Install the App on a Development Store

To see our app in action, we need to install it on our development store. Run:

bash
pnpm youcan app install

YouCan prompts us to authorize the app within our development store.

Verify the App Installation and Authentication

Once our app is installed, we'll be able to see it within the YouCan seller-area dashboard. We'll verify that everything is set up correctly by using a URL parser to inspect the callback URL for essential authentication elements, it should include the following:

  • hmac: A hash of all the request params using our OAuth client secret.
  • timestamp: It shows when the request was made.
  • session: The user's session ID.
  • store: The store ID within YouCan.
  • seller: A unique ID for the seller's account on YouCan.
app dashboard

App Dashboard Implementation

To display orders from the YouCan store in our app, we implement a Vue component for the front end and a server route to handle data fetching.

Frontend

In the index.vue file located in the pages directory, we use the useFetch API to request order data from our backend:

jsx
// pages/index.vue

<script setup lang="ts">
const {data: orders} = useFetch<{data: Record<string, {id:string}>}>('/orders');

if (process.client) {
  useQantra().toast.show({
    title: "Hello World",
    description: "This is a toast message"
  });
}
</script>

<template>
  <div v-for="order in orders?.data">
    {{ order.id }}
  </div>
</template>

<style>
html {
  background-color: white;
  font: var(--text-sm-regular);
}
</style>

This component fetches and displays the id of each order.

Backend: Server Route

We create a server route to query the YouCan API for order data, using the session's access token for authorization.

jsx
// server/routes/orders.ts

export default defineEventHandler(async (event) => {
    const session = event.context.session;
  
    const response = await fetch('https://api.youcanshop.dev/orders', {
        headers: {
            Authorization: 'Bearer ' + session.accessToken
        }
    });
    const orders = await response.json();

    return orders;
});

WARNING

While the documentation lists https://api.youcan.shop as the API Base URL, for local development purposes, switch to using https://api.youcanshop.dev. Post app approval, revert to the documented URL for production deployment.

Webhook Logic and SMS Notifications

After displaying orders on the dashboard, we’ll focus on how to integrate webhook handling for real-time notifications and set up SMS alerts for new orders.

Understanding Webhooks

Webhooks are notifications sent by YouCan to OAuth client when an event occur on a store. In our case, YouCan sends a webhook to our "Order Tracker" app when a new order is created.

Refer to the REST Hooks documentation to see the available events.

Webhook Flow

Here's how our app handles a webhook:

  1. Webhook Triggered: When a new order is placed on YouCan, it triggers a order.create webhook event.
  2. App Receives Webhook: Our app's server listens for this event.
  3. Process and Respond: Once the webhook is received, the app processes the order details then sends an SMS alert.

Set Up Webhooks

To register a webhook, we need to make a POST request to the YouCan API. This is typically done in the callback.get.ts file within our server's routes directory. Here's how to register a webhook for the order.create event:

typescript
// callback.get.ts

// ... Your existing code

  const r = await fetch('https://api.youcanshop.dev/resthooks/subscribe', {
    method: "POST",
    headers: {
      Authorization: `Bearer ${access_token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      target_url: process.env.YOUCAN_WEBHOOK_URL,
      event: 'order.create',
    })
  });

Implement Webhook Handling

In the app's server logic, we set up a route specifically to listen for and handle incoming webhooks:

typescript
// server/routes/youcan/webhooks.ts

export default defineEventHandler(async (event) => {
    const body = await readBody(event);

    console.log('Webhook processed:', body);

    await sendSMS();
});

In this code snippet:

  • readBody(event)parses the incoming webhook request to extract its content.
  • We check if the event is order.create and proceed to call sendSMS.

Integrate SMS Notification with Webhook

For the SMS notification functionality, we use Twilio.

  1. Add the Twilio SDK to our project
bash
pnpm install twilio
  1. Set Twilio credentials in the .env file:
typescript
TWILIO_ACCOUNT_SID=YourTwilioAccountSID
TWILIO_AUTH_TOKEN=YourTwilioAuthToken
  1. Implement the sendSMS function:
typescript
import twilio from 'twilio';

const accountSid = process.env.TWILIO_ACCOUNT_SID; 
const authToken = process.env.TWILIO_AUTH_TOKEN; 
const client = twilio(accountSid, authToken);

async function sendSMS() {
    try {
        const message = await client.messages.create({
            body: 'New order received',
            from: '+12404665161',
            to: '+212600600600'  
        });
        console.log('SMS sent:', message.sid);
        return message.sid;
    } catch (error) {
        console.error('Error sending SMS:', error);
        throw error; 
    }
}

With this setup, whenever a new order is created, our app will send an SMS notification, making the merchant aware of the new order in real-time.

Testing and Validation

  • After setting up the webhook and SMS notifications, let's create an order in the YouCan Seller Area dashboard to trigger the webhook. create order

  • Check our server logs or use tools like ngrok's inspection interface to see incoming POST requests to /youcan/webhook.

  • Verify that these requests contain the order data.

  • Confirm that the SMS notifications are being sent out.

webhook post request

Customization and Enhancement Opportunities

Note

Before we proceed to the final step of publishing our app, it's important to note that this guide is a basic introduction to the key functionalities of building an app on the YouCan platform. The “Order Tracker” app we created serves as a starting point.
Consider improving the visual appeal and usability of this app with Youcan UI.

For instance, we can refine the order listing by integrating the YouCan UI Table component. Let's see how we can display order's data more clearly, as shown below.

webhook post request

Here's a code snippet demonstrating how Youcan UI can be implemented:

typescript
<script setup lang="ts">
import { Table } from '@youcan/ui-vue3';
import type { TableColumn, TableData } from '@youcan/ui-vue3/dist/types/components/Table/types';
import type { StaticStatusDefinition } from '@youcan/ui-vue3/dist/types/components/Status/types';

// Define table columns
const columns: TableColumn[] = [
  { label: 'ID', accessor: 'id' },
  { label: 'Total', accessor: 'total' },
  { label: 'Payment Status', accessor: 'payment_status_new' }
];

// Define status colors
const paymentStatuses: { [status: string]: StaticStatusDefinition } = {
  unpaid: {
    color: '#EE0200',
    label: 'Unpaid',
    labelColor: '#f8dcdc',
  },
  paid: {
    color: '#52E2C0',
    label: 'Paid',
    labelColor: '#2d4236',
  }
};

// Fetch orders and transform them into TableData format
const {data: orders} = useFetch('/orders');

const ordersTableData = computed((): TableData[] => {
  return orders.value?.data.map(order => ({
    row: {
      id: order.id,
      total: order.total,
      payment_status_new: {
        variant: 'static-status',
        data: {
          status: paymentStatuses[order.payment_status_new.toLowerCase()] || {}
        },
      },
    }
  }));
});

</script>

<template>
  <Table
    :columns="columns"
    :data="ordersTableData"
  />
</template>

<style>
html {
  background-color: white;
  font: var(--text-sm-regular);
}

</style>

Publish your app

To publish our embedded app, we head to the YouCan partner dashboard, and submit our app for review.

  1. Navigate to the "Apps" section and locate our app.
  2. Click on "Push For Review".
  3. Wait for the YouCan team to review and approve our app.
  4. Once approved, our app will be published on the YouCan platform, available for any YouCan merchant to install.

Important

Please note that after submitting your app for review, the app is locked for changes. It's important to finalize all modifications before submission.

Conclusion

Congratulations! You have successfully navigated through the process of creating an embedded app for the YouCan platform. By following these steps, you're now equipped to transform your innovative ideas into functional tools that can enhance the online store experience.

Additional Ressources

Order Tracker Github Repository

YouCan Developer Documentation.