@code-nl/shopify-billing
v0.3.15
Published
Shopify Billing for public apps
Downloads
15
Readme
Shopify Billing
Install
First, install this package with:npm install @code-nl/shopify-billing
Configuration dependencies
This module is dependent on several Firebase Function configuration properties. Please check the list below and make sure these are set:
shopify.app_name
: The handle (URL safe name) of the app how it is registered in Shopify. Used to visit the app directly from the apps administration panel.shopify.api_secret
: The secret resolved when creating the app entry at Shopify. This value will be used to create and verify HMAC values when communicating from function to function.functions.charge_url
: The root URL pointing to the billing app (named as "charge app" before). Used to enter the required steps in the billing procedures.functions.auth_url
: The root URL pointing to the auth app. Used to login the merchant once all billing checks are done.
Configuration billing
The Shopify Billing module is highly dependent on specific configuration data.
Here you can see an example of a Firebase Functions' configuration as you can submit.
{
"billing": {
"models": {
"recurring_application_charge": {
"default_plan": "Standard",
"trial_days": "30",
"test": "true",
"plans": {
"standard": {
"scopes": "scopeA,scopeB",
"price": "10.0"
},
"advanced": {
"scopes": "scopeA,scopeB,scopeC,scopeD",
"price": "12.0"
},
"plus": {
"scopes": "scopeA,scopeB,scopeC,scopeD,scopeE,scopeF,scopeG,scopeH",
"price": "30.0"
},
}
}
}
}
}
Currently, only recurring application charges are supported. So all data is nested under billing.models.recurring_application_charge
.
Note: Because this is a Firebase Functions configuration, only maps
and strings
are supported. So all numbers, arrays, booleans are converted to one of both.
Properties
default_plan
: The identifier of a plan you'd like to be selected by default on screen while a merchant is choosing a proper billing plan. This identifier must be one of theplans[id]
.trial_days
: The number of days a trial may last. During the trial, the merchant wouldn't have to pay the charge amount.test
: Whether or not being in testmode. Probably set"true"
when developing and once everything is set up properly, set to"false"
.plans
: A map of all available plans to show, the key inside this map is very important. Please choose wisely since this key is used as the name for the actual Shopify charge.X
: A map of a single plan where "X" is the key to identify this plan.scopes
: A list of scopes that can be used to limit functionality within the app based on the selected billing plan. These scopes are like tags and should not be shown to the merchant. Both the admin interface should translate these into a proper translation and the back-end functionality should mark certain features against these scopes without any visibility.price
: The price a merchant needs to pay every 30 days. The currency is default set to USD.
Implementation
To implement the billing module, please have a look at the following sample.
Insert the Function "billingApp"
// billing module
const { clearEnvBilling, setEnvBilling, BillingHttpController } = require("@code-nl/shopify-billing");
/**
* Enable billing for this app
*/
exports.billingApp = functions
.region('us-central1') // must be us-central1 for rewrite purposes
.runWith({
timeoutSeconds: 15,
memory: "128MB"
})
.https.onRequest((req, res) => {
// if (req.path === "/billing-setup") {
// return (
// clearEnvBilling("code-pick-up-points-dev")
// .then(() => setEnvBilling("code-pick-up-points-dev", "./billing-plans.json"))
// .then(() => res.status(200).end())
// );
// }
if (typeof req.query.shop === "undefined") {
return res.status(400).send("Missing shop parameter.");
}
// get the shop doc reference
const shopDocReference = firestore.doc(`sfyShops/${req.query.shop}`);
const redirectUrls = {
urlApp: `https://${req.query.shop}/admin/apps/${cfg.shopify.app_name}`,
urlVerify: `${cfg.functions.charge_url}/verify`, // /activate is fixed
urlCreatePlan: `${cfg.functions.charge_url}/create`, // /create is fixed
urlActivatePlan: `${cfg.functions.charge_url}/activate`, // /activate is fixed
urlAppLogin: `${cfg.functions.auth_url}/login`, // ?plan=...×tamp=...&hmac=... will get added later on
};
return BillingHttpController(req, res, shopDocReference, cfg.billing, redirectUrls, cfg.shopify.api_secret);
});
Update the Function "authApp"
@redirectToAuthorization
Update the following line, it will not go the the login page directly but will take you to the billing app first.
const callbackUrl = (onlineAccess ? cfg.functions.charge_url + '/verify' : cfg.functions.auth_url + '/install');
@handleLogin
After the claims, add this snippet. This will add a billing plan to the login URL which enables the admin interface to distinguish between having a plan and defining scopes of the admin.
Please disable or remove other existing code relating to a previous adoption of charges.
// append custom billing plan claim if a plan is given with the request
if (typeof req.query.plan !== "undefined" && req.query.plan.length > 0) {
claims["sfy_plan"] = req.query.plan;
}