I am facing the same issue scribscription getting expired automatically after two days.
Can you please guide me about how could I fix this issue.
Here is the code where I have implemented the shopify billing api.
import React, { useCallback, useEffect, useState } from "react";
import { Button, Card, Frame, Page, Toast } from "@shopify/polaris";
import { authenticate, MONTHLY_PLAN } from "../shopify.server";
import { Form, useActionData } from "@remix-run/react";
import { json } from "@remix-run/node";
export async function action({ request }) {
const { billing, admin } = await authenticate.admin(request);
const result = await admin.graphql(`
#graphql
query Shop {
app {
installation {
activeSubscriptions {
status
}
}
}
}
`, { variables: {} });
const resultJson = await result.json();
const Subscriptionstatus = resultJson?resultJson.data.app.installation.activeSubscriptions[0]?.status:'';
if (Subscriptionstatus !== "ACTIVE") {
const billingCheck = await billing.require({
plans: [MONTHLY_PLAN],
isTest: false,
onFailure: async () => billing.request({
plan: MONTHLY_PLAN,
isTest: false,
returnUrl: '',
}),
});
return json(billingCheck);
}
console.log("Subscription status: ", Subscriptionstatus);
return json({ status: Subscriptionstatus });
}
const BillingComponent = () => {
const [active, setActive] = useState(false);
const data = useActionData();
const subscriptionStatus = data ? data.status : '';
useEffect(() => {
if (subscriptionStatus === "ACTIVE") {
setActive(true);
}
}, [subscriptionStatus]); // useEffect dependency
const toggleActive = useCallback(() => setActive((active) => !active), []);
const toastMarkup = active ? (
<Toast content="You already have an active subscription" onDismiss={toggleActive} />
) : null;
return (
<Page title="Manage Subscription" narrowWidth backAction={{ content: '', url: '/app' }}>
<Frame>
<Card>
<Form method="post">
<div
style={{
textAlign: "center",
display: "flex",
flexDirection: "column",
}}
>
<h1 style={{ fontSize: "33px", marginBottom: "19px" }}>
Pricing Plan
</h1>
<span style={{ fontSize: "13px" }}>No additional charges</span>
<b>$4.99/month</b>
<span style={{ fontSize: "13px" }}>7 days free trial</span>
<div>
<Button primary submit>
Choose Plan
</Button>
{toastMarkup}
</div>
</div>
</Form>
</Card>
</Frame>
</Page>
);
};
export default BillingComponent;
Here is the shopify.server.js file.
import "@shopify/shopify-app-remix/adapters/node";
import {
AppDistribution,
DeliveryMethod,
shopifyApp,
BillingInterval,
LATEST_API_VERSION,
} from "@shopify/shopify-app-remix/server";
import { PrismaSessionStorage } from "@shopify/shopify-app-session-storage-prisma";
import { restResources } from "@shopify/shopify-api/rest/admin/2023-07";
import prisma from "./db.server";
export const MONTHLY_PLAN = 'Monthly subscription';
const shopify = shopifyApp({
apiKey: process.env.SHOPIFY_API_KEY,
apiSecretKey: process.env.SHOPIFY_API_SECRET || "",
apiVersion: LATEST_API_VERSION,
scopes: process.env.SCOPES?.split(","),
appUrl: process.env.SHOPIFY_APP_URL || "",
billing: {
[MONTHLY_PLAN]: {
amount: 4.99,
currencyCode: 'USD',
trialDays: 3,
interval: BillingInterval.Every30Days,
}
},
authPathPrefix: "/auth",
sessionStorage: new PrismaSessionStorage(prisma),
distribution: AppDistribution.AppStore,
restResources,
webhooks: {
APP_UNINSTALLED: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: "/webhooks",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
...(process.env.SHOP_CUSTOM_DOMAIN
? { customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN] }
: {}),
});
export default shopify;
export const apiVersion = LATEST_API_VERSION;
export const addDocumentResponseHeaders = shopify.addDocumentResponseHeaders;
export const authenticate = shopify.authenticate;
export const unauthenticated = shopify.unauthenticated;
export const login = shopify.login;
export const registerWebhooks = shopify.registerWebhooks;
export const sessionStorage = shopify.sessionStorage;