A place to discuss charging merchants for your apps and services using the billing API.
Hi
Is there a working example of "shopify remix app template" where recurring charge is used and checking if the customer has any plan associated ?
(I am new to entire node thing and trying to convert on of my dotnet app to node/remix )
thanks
Solved! Go to the solution
This is an accepted solution.
Hi Ishahrier,
We don't currently have recurring charges and customer plan checks in this example app (it was just released last week), but I've passed on this request to our product team. Hopefully other developers in this community will be able to share advice on how to implement these features though 🙂
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
This is an accepted solution.
Hi Ishahrier,
We don't currently have recurring charges and customer plan checks in this example app (it was just released last week), but I've passed on this request to our product team. Hopefully other developers in this community will be able to share advice on how to implement these features though 🙂
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
@Liam Hey hope u r doing good.
can you please kindly guide me how to add billing in remix template?
For anyone stumbling to this post looking for a walkthrough I created a video walkthrough for this on my YouTube channel https://www.youtube.com/watch?v=Z3vLfOaLX-o
In case if someone is finding the answer for this question, I wrote an article regarding App Billing with Shopify Remix Template. Read it here. https://medium.com/breaktheloop/mastering-billing-with-shopify-app-remix-template-5fccca26ac56
Any chance you can post the details here instead of on medium locked behind a paywall?
This medium blog is a fairly a big one. Refer to https://github.com/DanojaDias/remix-billing-api-example-app. It has all the things explained in the blog. Main changes are in shopify.server.ts and app._index.tsx. Hope This helps.
Thanks for the example app. It's a good starting point.
To clarify, how does the app handle the following scenario: A shop installs, uses, then uninstalls the app before the trial ends. If the shop reinstalls it later, does the trial period restart? How do you prevent unlimited free use in this case?
I have implemented a solution for this issue. While I’m not entirely certain if it is the optimal approach, it is functioning as expected.
Within the shopify.server.js file, I included a function that retrieves the current active subscriptions using GraphQL, as follows:
/// .... more things on shopify.server.js
export const sessionStorage = shopify.sessionStorage;
const CACHED_SUBSCRIPTIONS: {
[key: string]: {
plan: string;
timestamp: number;
}
} = {};
export const getPlan = async (session: Session) => {
// get cached charge if it exists and it is not expired
if (
CACHED_SUBSCRIPTIONS[session.shop] &&
Date.now() - CACHED_SUBSCRIPTIONS[session.shop].timestamp < 1000 * 60 * 5) {
return CACHED_SUBSCRIPTIONS[session.shop];
}
// get the active subscription from graphql
const query = `#graphql
{
currentAppInstallation {
activeSubscriptions {
name
}
}
}
`;
const {data} = await performQuery(session, query, {});
// if there are no active subscriptions then return false
if (data.currentAppInstallation.activeSubscriptions.length === 0) return false;
// save current subscription in cache
const subscription = {
plan: data.currentAppInstallation.activeSubscriptions[0].name,
timestamp: Date.now()
}
CACHED_SUBSCRIPTIONS[session.shop] = subscription;
// return the current subscription
return subscription;
}
Subsequently, in the app.jsx file, I perform a check to verify if there is an active subscription plan. If no active plan is found, the user is redirected to the managed charges page provided by Shopify:
export const loader = async ({ request }) => {
const { session, redirect } = await authenticate.admin(request);
const currentPlan = await getPlan(session);
if (!currentPlan)
throw redirect(
`https://admin.shopify.com/store/${session.shop.replace(".myshopify.com", "")}/charges/${process.env.APP_HANDLE}/pricing_plans`,
{ target: "_parent" }
);
return json({ apiKey: process.env.SHOPIFY_API_KEY || "" });
};
Please note that the redirect I am utilizing comes from authenticate.admin, rather than directly from Remix.
I hope this information is helpful.