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
Sometimes customers ask for refunds for individual meals due to a variety of reasons and customer service reps must check manually to see where the order was processed and manually create a refund - and sometimes they must also manually calculate the refund amount (somtimes there is a discount code and depending on the subscription level a refund for a single meal has varying value)
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.
Now, using Zenaton, refunds can be issued by customer service representatives directly in shopify by entering the refund amount and reason or manually 'in mass' by using a CSV file containing order IDs and the meal quantity to refund for each one.
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);
}
Watch David show what this workflow does in a live demo at the Zenaton user conference in January 2020.
Sample Projects
Start building workflows
Sign-up and run a sample project Learn more