How to sell 3D product, then send API request to print & ship

I’m looking to sell products that are 3D printed objects, but after the sale is made, an API call is made to a 3D print facility, where a REST API call sends the info needed to sell and ship the item (SKU#, shipTo name & address, etc.). Would I be able to do this using BSS Reflow?

Do I need the Pro Reflow?

Any docs and examples?

Would you be able to do this with Reflow?
Yes, in theory. You would definitely need to code your own application to sit between Reflow and your 3D printing supplier.

Would you need Reflow Pro?
Yes, according to the Reflow API docs, the API request to list orders, and to be notified of order via webhooks is a Pro feature.

Here are the API docs:

Any examples?
I haven’t seen anyone on the forums do anything this complex with Reflow, and I think your idea, which is very clever, probably hasn’t been done before. But like I say, you’ll need an application to sit between Reflow and the 3D print supplier to translate the API request from Reflow and transform it into a request your 3D print company can use.

1 Like

So where would this middle application sit? On my own server?

Yes, you’d need to write it yourself. Or hire someone.

Presumably you wouldn’t just be able to pipe the order from Reflow straight to the 3D supplier as their API will be expecting the data in a different format.

It should still be quite feasible, and it’s something I’ve done before for a different project of mine. PHP is a pretty good language to use for a script that could do this.

I wonder if there is an “API Gateway” SAAS that would work… I see Cloudflare API or (re: “This-StackOverflow” using a Docker version of https://tyk.io/https://tyk.io/docs/tyk-oss/ce-docker/)

I don’t believe you would need a SAAS product, Tyk looks to be a more complex solution than is necessary for the task and would add further costs to your project.

You wouldn’t need Cloudflares API protection services as the API request to your 3D printing company shall most likely already have authentication. And you are not actually building an API, just a service to push data to their API.

You can also just configure the middleware to only accept data from Reflow.

Tyk it appears still requires you to code yourself the processing of extracting the data sent by the Reflow webhook, to build the API request to send to the 3D printers.

You could write a script with JavaScript, TypeScript, Python or Rust and host it for free on Cloudflare’s Workers platform.

Since I don’t know anything about the 3D printing company you wish to use though, I can’t really supply specific information.

1 Like

You might want to take a look at the reflow webhook documentation rather than the api docs

@martin I know you said you didn’t want any part of this, when i was communicating with you about my idea, but it’s a perfect fit for BSS… and the future!!.. are you sure you won’t reconsider… ??

You can’t create APIs or any communication code between Reflow’s webhook, your API, and the 3D printing service using BSS. So, why is it a perfect fit for BSS?

1 Like

As @richards said, webhooks… all we’d need is a place to plug in our API key, and a properly formatted POST to the printfarm after payment received… poof. All the other pieces are there such as products, sku. payment, etc! (@martin could charge a small fee for the usage of this feature)… i know others looking for a cheap storefront… this would be perfect!

Sure, it could be more elaborate than that, but not vital for MVP!

Using Webhooks and APIs is an advanced feature, the beauty of the developers giving these options is so that users can develop and tie in their own systems with this data.

Reflow already let’s you customise the data you want sent with the webhook request, which is already going above and beyond what other services offer and really must be praised.

However, developing a “no code” feature where Reflow handles the data into the form another API is expecting and sending it to your desired service is very complex and a niche feature suggestion.

Also what you are requiring really isn’t that complex for an advanced user, who is familiar with APIs and Webhooks - and would be most likely to want to use these features, to just develop on their own.

You’re also falling into the loophole that, just because you require this feature and think it would be nice, you’re assuming others would require it too.

If you reach out to me in direct messages, I would be happy to develop the solution you are looking for for free as it won’t take anymore than half an hour tops once I have all the information.

I choose Shapeways from a quick search for 3D print suppliers who offer an API to place orders and below I created with the help of AI a PHP script that shall take the Reflow Webhook, process it and send it to Shapeways for printing.

In this example I have chosen the SKU in Reflow to specify to Shapeways the existing model (MODEL_ID) on the account.

Although not implemented here, another feature you could use in Reflow and the Shapeways API is allowing customers to specify what material their models would be printed with (MATERIAL_ID) using the personalisation options in Reflow.

Shapeways would bill you with the CREDIT_CARD on your account, so you would still be able to manage billing customers through Reflow.

<?php

// Replace with your actual Shapeways API access token
$accessToken = 'YOUR_ACCESS_TOKEN';

// Shapeways API endpoint for placing orders
$url = 'https://api.shapeways.com/orders/v1';

// Read the raw POST data from the webhook
$rawData = file_get_contents('php://input');

// Decode the JSON into an associative array
$reflowWebhook = json_decode($rawData, true);

// Initialize items list
$items = [];

// Function to split the full name from Reflow into first and last name, using LAST NAME as backup if none is found
function splitName($fullName) {
    // Check if there's a space in the name
    $nameParts = explode(' ', $fullName, 2);
    $firstName = $nameParts[0];
    $lastName = isset($nameParts[1]) ? $nameParts[1] : 'LAST NAME';
    return [$firstName, $lastName];
}

// Map Reflow webhook data to Shapeways order format
foreach ($reflowWebhook['data']['object']['line_items'] as $lineItem) {
    $items[] = [
        'materialId' => $lineItem['MATERIAL_ID'],
        'modelId' => $lineItem['sku'],  //SKU must correlate to the model ID from Shapeways
        'quantity' => $lineItem['quantity'],
    ];
}

// Extract the customer's name and split it into first and last name
list($firstName, $lastName) = splitName($reflowWebhook['data']['object']['customer']['name']);

// Prepare order data
$orderData = [
    'items' => $items,
    'firstName' => $firstName,
    'lastName' => $lastName, // Use the split last name
    'country' => $reflowWebhook['data']['object']['shipping_address']['country'],
    'state' => '',    // State not shown in the Reflow Webhook example, so leaving blank
    'city' => $reflowWebhook['data']['object']['shipping_address']['city'],
    'address1' => $reflowWebhook['data']['object']['shipping_address']['address'],
    'address2' => '', // Not provided in the Reflow Webhook example, unsure if it exists
    'zipCode' => $reflowWebhook['data']['object']['shipping_address']['postcode'],
    'phoneNumber' => $reflowWebhook['data']['object']['customer']['phone'],
    'paymentMethod' => 'credit_card', // Credit card on file with Shapeways
    'shippingOption' => 'Cheapest',   // Tells Shapeways to use the cheapest shipping option
];

// Convert order data to JSON
$postData = json_encode($orderData);

// Initialize cURL session
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $accessToken,
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Execute cURL request and handle response
$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'cURL Error: ' . curl_error($ch);
} else {
    // Handle successful response
    echo 'Order placed successfully: ' . $response;
}

// Close cURL session
curl_close($ch);

?>