Back to Website
Show / Hide Table of Contents

Downloading artifacts for an order

  • 12 minutes to read

Let's say your customers have created personalized designs using a Customer's Canvas editor and placed an order on your online store. If your store is based on one of the e-commerce platforms we support (like Shopify, BigCommerce, WooCommerce, Magento, or nopCommerce), or if you've implemented a custom storefront integration, a project is created once the order is placed. You can easily access the project in the Customer's Canvas BackOffice app and download the print files from it.

However, downloading print files manually isn't always an option. For instance, if you don't handle order fulfillment in-house and instead use an API to send orders to your printing company.

In such a scenario, you can use the Customer's Canvas API to automatically download print files (or, speaking more widely, artifacts, which can include additional files if required) for completed orders. This article provides instructions on how to do so.

Assumptions

Here are some assumptions that we will make for this guide:

  1. Your application can receive information about orders from your e-commerce platform, and your app can differentiate between new orders and orders you have already processed.

    For example, if you're using Shopify, your app may subscribe to the orders/create webhook. Alternatively, you could request all new orders once per day and mark them as processed once you've downloaded the order artifacts (print files).

  2. An online store is integrated with Customer's Canvas, and you have its storefrontId (explained further).

  3. The processing pipelines are properly configured for the products you want to process.

  4. Your objective is to download all artifacts for the selected orders.

How we are going to achieve this goal

The diagram below illustrates the flow initiated by an e-commerce platform when a user completes an order for a product with Customer's Canvas data.

flowchart TD subgraph Processing pipeline task1(Task 1) --> task2(Task 2) task2 --> otherTasks(...) otherTasks --> finalTask(Final task) end subgraph E-commerce Platform order(Order completed) end subgraph Customer's Canvas order -- order creation webhook --> project(Project created) project -- starts processing pipeline --> task1 finalTask -- save artifact --> artifact(Artifacts saved\nin Asset Storage) end

When a user completes an order for a product with Customer's Canvas data, the e-commerce platform triggers the order creation webhook. Customer's Canvas handles this webhook and creates a project record, which starts the processing pipeline. Since the processing pipeline works asynchronously, it may take some time to complete all steps. However, once finished, the artifacts created by its tasks are saved in Asset Storage.

As soon as the project is created, Customer's Canvas saves the order ID and its number as the project metadata. This allows your app to request projects related to your orders. Once you have the project information, you can find the processing pipeline associated with it. Only one processing pipeline per project may exist. A pipeline is not created immediately with a project, but any delay is typically quite small.

The processing pipeline can have several statuses, such as pending or in progress. You need to implement a polling scheme and repeat the request at a certain time interval until the pipeline becomes complete. Note that the pipeline may fail, and in this case, you need to stop polling. You should decide what your app should do in such cases, such as saving this information to a log or attempting to restart it.

When the pipeline is successfully completed, all relevant print files and other artifacts become available to download.

The following sequence diagram illustrates the process.

sequenceDiagram participant C as Customer's Canvas participant A as Your App participant E as E-commerce Platform A ->> +E : Get new orders E ->> -A : New orders loop For each order A ->> +C : Get an order's project C ->> A : Project A ->> C : Get a project's pipeline C ->> A : Pipeline A ->> C : Get pipeline status C ->> A : Pending | Completed
| Failed Note over A: Once Pipeline is Completed A ->> C : Get artifacts C ->> A : List of URLs loop For each artifact A ->> C : Download artifact C ->> -A : Artifact binary (e.g. PDF) end A ->> E : Tag order as done end

Using the API

This guide assumes that you are familiar with the principles of how you should use the Customer's Canvas API. If not, we recommend that you take a look at these articles first.

  • API Reference - for an API overview and information about supported API Client libraries
  • C# API Client - for the guide on how you can properly integrate the C# API Client library to your .NET app

Authenticating your app

Before we start, make sure that your app has credentials to make API calls. For the scenario described above, the most relevant authentication scheme is via Client Credentials.

Register your app in your tenant and implement the authentication in your app as explained in the Authentication in Customer's Canvas Hub article.

Determining your storefrontId

Customer's Canvas allows for integrating a single tenant with multiple storefronts (i.e., online stores) simultaneously. For example, you may have two Shopify stores with different domains for different products. Or, you may have one store based on WooCommerce and another one on BigCommerce.

When you work with projects, you need to know the storefrontId, which allows you to distinguish one store from another. It is especially important considering that the uniqueness of the order numbers between different online stores is not guaranteed.

To determine the storefrontId, in your Customer's Canvas account, go to Settings > Integrations. The storefrontId is in the left column.

Settings -> Integrations, storefrontId

Searching projects for an order

You can use the Projects_GetAll endpoint of the StorefrontAPI to receive a list of projects. You need to provide at least two arguments to achieve our goal:

  1. storefrontId - obtained as explained above.
  2. orderId - an ID of an order you need to process.

Let's assume that the storefrontId is 42 and the orderId is 123.

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  GET "https://api.customerscanvashub.com/api/storefront/v1/projects?orderId=123&storefrontId=42" \
  -H  "accept: text/plain"\
  -H  "Authorization: Bearer <TOKEN>"
GET https://api.customerscanvashub.com/api/storefront/v1/projects?orderId=123&storefrontId=42
var storefrontId = 42; // Put your real storefrontId here
var order = "123"; // Put your real order ID here
var projectsPagedList = await storefrontApiClient.GetAllAsync(storefrontId, orderId: order);
var storefrontId = 42; // Put your real storefrontId here
var orderId = "123"; // Put your real order ID here
var projectsPagedList = await _storefrontApiClient.getAll(storefrontId, null, null, null, null, null, null, null, null, orderId);
$storefrontId = 42; // Put your real storefrontId here
$orderId = "123"; // Put your real order ID here
$projectsPagedList = $storefrontApiClient->projectsGetAll($storefrontId, null, null, null, null, null, null, null, null, $orderId, null);

It returns a structure containing a list of project items filtered by this order ID. Note that it is a normal scenario when a single order includes multiple projects. For example, if an order consists of several line items and these line items represent products associated with Customer's Canvas, a project per each line item is created.

You need to use the id of each project in this list as explained further.

Getting a project's artifacts directly

To simplify the process, we have introduced a dedicated endpoint that enables you to receive artifacts directly from a project without worrying about the processing pipeline. You can access this endpoint at Projects_GetProjectProcessingResults by passing the ID of each project returned in the previous step.

For example, if the project ID is 4567, the API call may look like this.

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  GET "https://api.customerscanvashub.com/api/storefront/v1/projects/4567/processing-results" \
  -H  "accept: text/plain" \
  -H  "Authorization: Bearer <TOKEN>"
GET https://api.customerscanvashub.com/api/storefront/v1/projects/4567/processing-results
var projectId = 4567; // Set a real project ID here
var processingResults = await storefrontApiClient.GetProjectProcessingResultsAsync(projectId);
var projectId = 4567; // Put your real project ID here
var processingResults = await _storefrontApiClient.getProjectProcessingResults(projectId);
$projectId = 4567; // Put your real project ID here
$processingResults = $storefrontApiClient->projectsGetProjectProcessingResults($projectId);

Once you receive the processing results, you need to check the status field, which can have one of four values: Pending, InProgress, Completed, or Failed.

  • If the status is Pending or InProgress, you should wait and retry after some interval, such as several minutes (minimum 60 seconds).
  • If the status is Failed, refer to the statusDescription field for additional details.
  • If the status is Completed, the artifacts are ready, and you can retrieve them from the outputFileDetails property.

When processing the outputFileDetails, keep in mind that depending on the processing pipeline, the results may include more than one file. For example, it may include a print-ready PDF file, a reference preview, and a JSON description of the order. It may also include multiple PDF files for a VDP scenario.

One important parameter to consider is whether artifacts can be downloaded using a direct link without authentication. An author of a processing pipeline may control whether artifacts are available anonymously or not. Your app can determine this by checking the anonymousAccess flag. If the flag is true, you can download the artifact using the url property. If it is not true, you will need to use the GET /api/storage/v1/artifacts/{id}/file endpoint of the Asset Storage API, as explained later in this article.

These steps should be sufficient to achieve your goal of downloading print files for an order. However, if you need more control over the rendering process for any reason, you may want to explore other capabilities of the API.

Restarting failed pipelines

There are several reasons why a pipeline may have a Failed status. Some of these reasons may be temporary, in which case you may want to retry the pipeline execution. There are two operations you can use to retry a failed pipeline:

  • Resume (Projects_ResumeProjectProcessing): This operation continues the pipeline from the point of the last failed task.
  • Restart (Projects_RestartProjectProcessing): This operation restarts the pipeline from the first task.

We recommend using the Resume operation to recover a failed pipeline to avoid redoing operations that have already succeeded, which can reduce overhead. Additionally, certain tasks should not be repeated without a good reason. For example, if a task purchases a photo from a stock service, and the pipeline fails on a subsequent task, restarting the pipeline would cause a second purchase of the item, which has already been paid for.

However, the Restart operation is useful in situations where you need to regenerate all temporary artifacts from scratch, such as when editing a personalized design after the user has submitted it.

When retrying a failed pipeline, it is important to use a reasonable delay between attempts. Ideally, this delay should be several minutes and should not be less than one minute.

To resume a failed pipeline, use the following API call.

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  POST "https://api.customerscanvashub.com/api/storefront/v1/projects/4567/resume-processing" \
  -H  "accept: text/plain" \
  -H  "Authorization: Bearer <TOKEN>" \
  -d  ""
POST https://api.customerscanvashub.com/api/storefront/v1/projects/4567/resume-processing
var projectId = 4567; // Set a real project ID 
await storefrontApiClient.ResumeProjectProcessingAsync(projectId);
var projectId = 4567; // Put your real project ID here
await _storefrontApiClient.resumeProjectProcessing(projectId);
$projectId = 4567; // Put your real project ID here
$storefrontApiClient->projectsResumeProjectProcessing($projectId);

A Restart operation is called in a similar manner.

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  POST "https://api.customerscanvashub.com/api/storefront/v1/projects/4567/restart-processing" \
  -H  "accept: text/plain" \
  -H  "Authorization: Bearer <TOKEN>" \
  -d  ""
POST https://api.customerscanvashub.com/api/storefront/v1/projects/4567/restart-processing
var projectId = 4567; // Set a real project ID 
await storefrontApiClient.RestartProjectProcessingAsync(projectId);
var projectId = 4567; // Put your real project ID here
await _storefrontApiClient.restartProjectProcessing(projectId);
$projectId = 4567; // Put your real project ID here
$storefrontApiClient->projectsRestartProjectProcessing($projectId);

Getting a list of artifacts

If you need to get a list of artifacts by pipeline ID, you can use the GET /api/storage/v1/artifacts endpoint of the Asset Storage API. This is useful in situations where you need to get some extended details about them compared to the approach with Projects_GetProjectProcessingResults.

To use the endpoint, pass the pipeline ID as a group parameter. This result will show only the artifacts that were generated as part of the specified pipeline. You can also filter out all temporary artifacts by specifying the type as Final.

For example, if you wanted to get a list of all final artifacts generated by a pipeline with ID 12345, you could make the following API call:

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  GET "https://api.customerscanvashub.com/api/storage/v1/artifacts?group=12345&type=Final" \
  -H  "accept: text/json"\
  -H  "Authorization: Bearer <TOKEN>"
GET https://api.customerscanvashub.com/api/storage/v1/artifacts?group=12345&type=Final
var pipelineId = 12345; // Set a real pipeline ID 
var artifacts = await artifactsApiClient.GetAllAsync(group: pipelineId, type: ArtifactType.Final);
var pipelineId = 12345; // Put your real pipeline ID here
var artifacts = await _artifactsApiClient.getAll(pipelineId, null, ArtifactType.Final);
$pipelineId = 12345; // Put your real pipeline ID here
$artifacts = $assetStorageApiClient->artifactsGetAll($pipelineId, null, Aurigma\AssetStorage\Model\ArtifactType::_FINAL);

This would return a list of all final artifacts generated by the specified pipeline.

Downloading artifacts

When using the GET /api/storage/v1/artifacts endpoint to retrieve artifacts, as explained above, the output structure contains additional fields, such as size and lastModified, in addition to the ones returned by Projects_GetProjectProcessingResults.

To download the results, you can simply use the GET /api/storage/v1/artifacts/{id}/file endpoint and provide the artifact ID. If needed, you can include the attachment flag to control whether the Content-Disposition header with the file name should be included in the API response or not.

Let's see how you can get an artifact with ID = 98765 with the attachment mode enabled.

  • cURL
  • HTTP
  • C#
  • TS
  • PHP
curl -X \
  GET "https://api.customerscanvashub.com/api/storage/v1/artifacts/98765/file?attachment=true" \
  -H  "accept: application/octet-stream" \
  -H  "Authorization: Bearer <TOKEN>"
GET https://api.customerscanvashub.com/api/storage/v1/artifacts/98765/file?attachment=true
var artifactId = 98765; // Set a real artifact ID 
var file = await artifactsApiClient.GetFileAsync(artifactId, true);
var artifactId = 98765; // Put your real artifact ID here
var file = await _artifactsApiClient.getFile(artifactId, true);
$artifactId = 98765; // Put your real artifact ID here
$file = $assetStorageApiClient->artifactsGetFile($artifactId, true);

If the processing pipeline author has enabled the ability to download artifacts via a direct link, you can access these files more easily by using the url property without requiring authentication. To ensure that direct URLs are available, check if the anonymousAccess property is set to true.

Conclusion

In this article, we have discussed the flow required to download print files and other artifacts for completed e-commerce orders, which is a crucial task in integrating Customer's Canvas with order fulfillment systems.

We have determined that the most efficient way to achieve this goal is by utilizing the Projects_GetProjectProcessingResults endpoint. However, we have also explored an additional endpoint that performs other tasks, such as recovering failed pipelines, checking the project status, and receiving the binary content of the artifacts.

By following the guidelines provided in this article, you can easily integrate Customer's Canvas into your e-commerce system and streamline your order fulfillment process.

Was this page helpful?
Thanks for your feedback!
Back to top Copyright © 2001–2024 Aurigma, Inc. All rights reserved.
Loading...
    Thank for your vote
    Your opinion is important to us. To provide details, send feedback.
    Send feedback