Create a custom channel
Openship supports channel platforms out of the box like Shopify, WooCommerce, and BigCommerce, but also works with custom channels.
To create a custom channel, you must create 4 endpoints:
- requiredSearch products endpoint
- requiredCreate purchase endpoint
- requiredCreate tracking endpoint
- requiredCancel purchase endpoint
Search products endpoint
1. Let's start with a function that returns an array of products. You can fetch
these products from a CMS, Google Sheet, or any platform. Each product in the array will have 5 values:
- image:stringproduct image
- title:stringproduct title
- productId:stringproduct identifier
- variantId:stringvariant product identifier, if none send 0
- price:stringproduct price
- availableForSale:booleantrue if item is available
2. Openship will send some attributes to the endpoint:
- accessToken: access token to verify the request
- searchEntry: search products based on this value
- productId: product identifier
- variantId: product variant identifier
Let's put these values to use.
3. First, we check this access token against our .env
file to make the user has been granted access.
4. Next, let's check if the search entry parameter exists and if so, filter our products based on that value.
5. Next, let's check if the productId and variantId exist. If so, filter allProducts based on these values. If no products are found after filtering, return an error.
Search products endpoint
1. Let's start with a function that returns an array of products. You can fetch
these products from a CMS, Google Sheet, or any platform. Each product in the array will have 5 values:
- image:stringproduct image
- title:stringproduct title
- productId:stringproduct identifier
- variantId:stringvariant product identifier, if none send 0
- price:stringproduct price
- availableForSale:booleantrue if item is available
2. Openship will send some attributes to the endpoint:
- accessToken: access token to verify the request
- searchEntry: search products based on this value
- productId: product identifier
- variantId: product variant identifier
Let's put these values to use.
3. First, we check this access token against our .env
file to make the user has been granted access.
4. Next, let's check if the search entry parameter exists and if so, filter our products based on that value.
5. Next, let's check if the productId and variantId exist. If so, filter allProducts based on these values. If no products are found after filtering, return an error.
Create purchase endpoint
1. Openship will use this create purchase function to create purchases on the channel. Openship sends the following attributes to the endpoint:
- accessToken: access token to verify the request
- email: email connected to the Openship account
- metafields: channel-specific fields
- cartItems: products that need to be fulfilled
- productId: product identifier
- variantId: product variant identifier
- name: product title
- quantity: quantity of product to ship
- price: product cost
- address: shipping address
- first_name
- last_name
- streetAddress1
- streetAddress2
- city
- state
- zip
- state
- country
Let's put these values to use.
2. First, we check this access token against our .env
file to make the user has been granted access.
3. Using this information, we can create a purchase on Shopify, Google Sheets, CMS, or any existing platform. Let's keep it simple and send an email with the purchase information to our supplier:
- First, let's create the email content using the address and products from our request body
- Next, we'll use the
nodemailer
package and the ethereal.email service to send a test email. If the purchase is created successfully, we return 2 values:- purchaseId:stringpurchase ID of the newly created purchase (in this case, we just get the current time in milliseconds)
- url:stringlink to an purchase confirmation page
4. Lastly, if purchase creation fails, we return an error.
Create purchase endpoint
1. Openship will use this create purchase function to create purchases on the channel. Openship sends the following attributes to the endpoint:
- accessToken: access token to verify the request
- email: email connected to the Openship account
- metafields: channel-specific fields
- cartItems: products that need to be fulfilled
- productId: product identifier
- variantId: product variant identifier
- name: product title
- quantity: quantity of product to ship
- price: product cost
- address: shipping address
- first_name
- last_name
- streetAddress1
- streetAddress2
- city
- state
- zip
- state
- country
Let's put these values to use.
2. First, we check this access token against our .env
file to make the user has been granted access.
3. Using this information, we can create a purchase on Shopify, Google Sheets, CMS, or any existing platform. Let's keep it simple and send an email with the purchase information to our supplier:
- First, let's create the email content using the address and products from our request body
- Next, we'll use the
nodemailer
package and the ethereal.email service to send a test email. If the purchase is created successfully, we return 2 values:- purchaseId:stringpurchase ID of the newly created purchase (in this case, we just get the current time in milliseconds)
- url:stringlink to an purchase confirmation page
4. Lastly, if purchase creation fails, we return an error.
Create tracking endpoint
Once an purchase is created using the function above, the channel has to create tracking details on Openship. To do this, we must first get the API key from Openship. On the left sidebar, you'll see the key icon.
After generating a key, add this to your .env
file as OPENSHIP_KEY
. Since we'll be using Openship's GraphQL API, we'll also add OPENSHIP_DOMAIN
to the .env
file.
This is how the .env
file looks so far:
- ACCESS_TOKEN: access token to verify the request
- OPENSHIP_DOMAIN: domain where your Openship API can be accessed (normally ends in
/api/graphql
) - OPENSHIP_KEY: API key created on your Openship instance
1. Let's start creating our create-tracking function. First, we'll get these 4 values from the request body:
- accessToken:stringaccess token to verify the request
- purchaseId:stringpurchase ID of the newly created purchase
- trackingNumber:stringshipping tracking number
- trackingCompany:stringshipping tracking company
We'll check the accessToken against ACCESS_TOKEN
variable that's in our .env
file.
2. To make requests to Openship's GraphQL API, we'll use the gql
and request
imports from the graphql-request
package.
We'll use OPENSHIP_DOMAIN
as the url and pass OPENSHIP_KEY
a header named x-api-key
.
3. Let's create the mutation which will add the tracking details on Openship. We'll pass the mutation under document and pass the values from the request body as variables.
4. Lastly, if tracking creation is successful, we'll return the tracking information.
5. We'll also catch any errors if tracking creation fails.
1. Let's start creating our create-tracking function. First, we'll get these 4 values from the request body:
- accessToken:stringaccess token to verify the request
- purchaseId:stringpurchase ID of the newly created purchase
- trackingNumber:stringshipping tracking number
- trackingCompany:stringshipping tracking company
We'll check the accessToken against ACCESS_TOKEN
variable that's in our .env
file.
2. To make requests to Openship's GraphQL API, we'll use the gql
and request
imports from the graphql-request
package.
We'll use OPENSHIP_DOMAIN
as the url and pass OPENSHIP_KEY
a header named x-api-key
.
3. Let's create the mutation which will add the tracking details on Openship. We'll pass the mutation under document and pass the values from the request body as variables.
4. Lastly, if tracking creation is successful, we'll return the tracking information.
5. We'll also catch any errors if tracking creation fails.
Cancel purchase endpoint
Purchases can also be cancelled. This is useful if an item is out of stock, damaged, lost, or for any reason that would prevent a purchase order from being fulfilled. When a purchase is cancelled, the connected order will be marked as PENDING
so that it can be fulfilled again.
1. Let's start creating our cancel-purchase function. First, we'll get these 2 values from the request body:
- accessToken:stringaccess token to verify the request
- purchaseId:stringpurchase ID that needs to be cancelled
We'll check the accessToken against ACCESS_TOKEN
variable that's in our .env
file.
2. We'll use the same function as before to access Openship's GraphQL API.
3. This time, we'll call the cancelPurchase
mutation and pass the purchaseId as the variable.
4. Lastly, if the purchase cancellation is successful, we'll return the response.
5. We'll also catch any errors if purchase cancellation fails.
1. Let's start creating our cancel-purchase function. First, we'll get these 2 values from the request body:
- accessToken:stringaccess token to verify the request
- purchaseId:stringpurchase ID that needs to be cancelled
We'll check the accessToken against ACCESS_TOKEN
variable that's in our .env
file.
2. We'll use the same function as before to access Openship's GraphQL API.
3. This time, we'll call the cancelPurchase
mutation and pass the purchaseId as the variable.
4. Lastly, if the purchase cancellation is successful, we'll return the response.
5. We'll also catch any errors if purchase cancellation fails.
Deploying the channel
Now that we have our functions built, we have to deploy them. We'll keep it simple and add these functions to a Next.js application as API Routes. This is a good starting place when building your own channel. Check out the CodeSandbox below to customize it and make it your own.
When you're finished customizing, you can deploy the application to Vercel, Netlify, or any platform that supports node.js
.
We have already deployed the demo channel we just made. To test it, add the channel and choose DEMO under the channel type.
Deploy this channel yourself on Vercel: