This workflow is used by a meal delivery service that uses shopify for all of their order processing and recharge for monthly subscriptions.
Customers can purchase a one time meal which is processed through shopify or they can buy a monthly subscription for a quantity of meals per month which is processed and managed through recharge (different payment gateway) for subscriptions.
Recharge is a recurring billing app native to Shopify
In one month, due to unexpected high demand, they were unable to provide meals to all of their customers and needed to issue refunds for a large quantity of orders that were not delivered. They created this workflow to be able to automate the refund process - checking to see where the charge originated, calculating the amount and issuing the refund to save time and insure that there are no manual errors.
Using Zenaton, refunds can be issued by customer service representatives directly in shopify or 'in mass' by using a CSV file containing order IDs and the meal quantity to refund for each one.
David Turton shows us how he used Zenaton to write a workflow to automate a refund process for a shopify store with 1500 refunds and saved hours of work and errors from manually calculating and issuing refunds.
Launch: A workflow instance can be launched automatically through a private shopify app that allows a customer sales rep to issue a refund to a customer through the shopify dashboard or manually using a CSV file with a list of order IDs and meal quantities to refund.
Depending on how the workflow is launched (from inside shopify or manually via a CSV file) the input will either contain the meal quantity OR amount to refund (but not both)
{
"orderId": 1073459984,
"orderName": null,
"mealQty": 3,
"amount": 35.90,
}
module.exports.hande = function*({ orderId, orderName, mealQty, amount } = object) {
this.orderId = orderId;
this.orderName = orderName;
this.amountToRefund = amount;
this.mealQtyToRefund = mealQty;
// Get the shopify order by name or id
if (this.orderName) {
this.shopifyOrder = (yield this.run.task("GetShopifyOrder", orderName)).orders[0];
if (parseInt(this.orderName) !== parseInt(this.shopifyOrder.name)) {
return false;
}
} else if (orderId) {
this.shopifyOrder = (yield this.run.task( "GetShopifyOrderById", orderId )).order;
}
this.orderId = this.shopifyOrder.id;
this.sku = this.shopifyOrder.line_items[0].sku;
this.totalPrice = this.shopifyOrder.total_price;
this.totalMealsQty = yield this.run.task("GetMealsQty", this.sku);
// Calculate the amount of refund
this.totalRefund = this.amountToRefund
? this.amountToRefund
: yield this.run.task(
"CalculateRefund",
this.mealQtyToRefund,
this.totalMealsQty,
this.totalPrice
);
//Check to see if its a recharge order
if (this.shopifyOrder.source_name === "294517") {
this.charges = (yield this.run.task("GetRechargeCharge", this.orderId)).charges;
//check to see if its a real run and that it doesnt have previous refunds
if (!test && this.shopifyOrder.refunds.length === 0) {
this.refund = yield this.run.task("CreateRefund", this.charges[0].id, this.totalRefund);
this.processed = true;
}
//if order is from shopify
} else if (
this.shopifyOrder.source_name === "web" &&
!test &&
this.shopifyOrder.refunds.length === 0
) {
//check to see if its a real run and that it doesnt have previous refunds
this.shopifyTransactions = (yield this.run.task( "GetShopifyTransaction", this.shopifyOrder.id )).transactions;
this.refund = yield this.run.task( "CreateShopifyRefund", this.orderId, this.shopifyTransactions[0].id, this.totalRefund, this.shopifyOrder.gateway );
this.processed = true;
}
// Save to the database
const record = {
etail_order_id: this.orderId,
shopify_order: this.shopifyOrder.name,
charge_id: this.charges ? this.charges[0].id : "",
refund_amount: this.totalRefund,
total_price: this.totalPrice,
total_meals: this.totalMealsQty,
total_meals_shorted: this.mealQtyToRefund,
sku: this.sku,
email: this.shopifyOrder.email
};
this.dbInsert = yield this.run.task("LogToDb", record);
}
Real-world Examples
Start building workflows
Sign-up and run a sample project Learn more