Hi!
Please shed some light on Billing configurations for the apps in shopify-cli 3.0 node template.
-
How to create different billing plans
-
How to redirect to Shopify billing page once the merchants choose the plan from our pricing page.
-
How to redirect to our Pricing page once the app is installed.
1 Like
Hey @Sharan_oapps ,
Just wanted to share a few things after taking a closer look at the questions asked concerning app billing.
While the Shopify CLI is a great tool for quickly scaffolding apps from our various templates, generating extensions, managing theme development and even custom storefronts, the examples apps are meant to offer a staring point and likely require additional development to achieve intended functionality. Any feedback about those sample apps generated with the CLI or the corresponding API libraries (eg. Node.js, PHP, Ruby), please consider opening an issue in their official Github repos directly.
Lastly, it is always a good idea keeping an eye here in these forums for any related threads or replies back from other community members - Cheers!
2 Likes
@ShopifyDevSup Hello !
I am stuck in enabling billing. Actually, I want to enable recurring billing for my app but it does not enable yet I apply the solution you tell above by providing a link but it didn’t work for me please can you tell me how can I enable billing for Every30Days?
Node js Template contains Shopify.js file which has the following code :
import { BillingInterval, LATEST_API_VERSION, BillingReplacementBehavior } from “@shopify/shopify-api”;
import { shopifyApp } from “@shopify/shopify-app-express”;
import { SQLiteSessionStorage } from “@shopify/shopify-app-session-storage-sqlite”;
import { restResources } from “@shopify/shopify-api/rest/admin/2023-01”;
const DB_PATH = ${process.cwd()}/database.sqlite;
// The transactions with Shopify will always be marked as test transactions, unless NODE_ENV is production.
// See the ensureBilling helper to learn more about billing in this template.
const billingConfig = {
“My Shopify Charge”: {
// This is an example configuration that would do a one-time charge for $5 (only USD is currently supported)
amount: 19.0,
currencyCode: “USD”,
interval: BillingInterval.Every30Days,
replacementBehavior: BillingReplacementBehavior.ApplyImmediately,
},
};
const shopify = shopifyApp({
api: {
apiVersion: LATEST_API_VERSION,
restResources,
billing: billingConfig, //undefined or replace with billingConfig above to enable example billing
},
auth: {
path: “/api/auth”,
callbackPath: “/api/auth/callback”,
},
webhooks: {
path: “/api/webhooks”,
},
// This should be replaced with your preferred storage strategy
sessionStorage: new SQLiteSessionStorage(DB_PATH),
});
export default shopify;
Thanks in advance please help me. I will be very grateful
Hey @syedusama0786 - thanks for reaching out. Our team was able to do some testing, and your input should work to set up a recurring subscription. This guide here is for single usage charges, but the configuration should work the same way for recurring subscriptions, so I wanted to share it with you. I’d also recommend taking a look here at our md doc for billing request configs via Node.js specifically - this may help get you set up.
Could you let us know if you’re still encountering errors after you’ve reviewed the links above? If you’re still seeing errors, just respond back here with any specific error messages or an X-Request-ID you receive from any related API responses and we can investigate further.
Hope this helps!
Al | Shopify Developer Support
1 Like
@ShopifyDevSup Thanks for replying I will check this.
This works when the session is created and asks for the billing to be activated, but if the admin of the store clicks Cancel he can easily continue to use the current app session with no billing activated.
What is the fix for that? The only way I could go about this was to check in every API that the billing is accepted. Is there a better way?
2 Likes
Hi @ovidiucaramida , any news about a solution for that?
Thank for your help!
@ovidiucaramida I am also facing the same issue in this. you got any solution or not ?
@ShopifyDevSup
This works when the session is created and asks for the billing to be activated, but if the admin of the store clicks Cancel he can easily continue to use the current app session with no billing activated.
What is the fix for that? The only way I could go about this was to check in every API that the billing is accepted. Is there a better way?
1 Like
I didn’t find a solution. I just added a middleware and used that on every API request
2 Likes
Add this code to the index.js file to your backend
app.get(
shopify.config.auth.callbackPath,
shopify.auth.callback(),
// Request payment if required
async (req, res, next) => {
console.log(“BILLING CALLLED”)
const plans = Object.keys(billingConfig);
const session = res.locals.shopify.session;
const hasPayment = await shopify.api.billing.check({
session,
plans: plans,
isTest: true,
});
if (hasPayment) {
next();
} else {
res.redirect(
await shopify.api.billing.request({
session,
plan: plans[0],
isTest: true,
})
);
}
},
shopify.redirectToShopifyOrAppRoot()
);
@syedusama0786 it is not the solution to our probleme
So for me the solution is:
- Create a middleware to check actual Plan and secure some routes
const hasPayment = await shopify.api.billing.check({
session,
plans: plans,
isTest: true,
});
or
const response = await shopify.api.rest.RecurringApplicationCharge.all({
session: res.locals.shopify.session,
});
//Set Plan Metafield
const client = new shopify.api.clients.Graphql({ session })
try {
const response = await client.query({
data: {
query: `query {
currentAppInstallation {
id
}
}`
}
})
const appInstallationId = response.body.data.currentAppInstallation.id
await client.query({
data: {
query: `mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafieldsSetInput) {
metafields {
id
namespace
key
}
userErrors {
field
message
}
}
}`,
variables: {
"metafieldsSetInput": [
{
"namespace": "applicationInstallation",
"key": "hasPlan",
"type": "boolean",
"value": `${hasPlan.toString()}`,
"ownerId": `${appInstallationId}`
}
]
},
},
});
- If you use theme extension you can use available_if of schema
I tried to implement Billing in this same way but its giving me error can ypu please help me?