For discussing the development and integration of subscription-enabled shops using Shopify's Subscription APIs.
Hi, i am calling appSubscriptionCreate when users visit my admin panel and dont have a subscription. Even though i am passing `test:true`, and `trialDays: 10`, the response from calling that mutation is returning `{ test: false, trialDays: 0 }`.
So when i get redirected to the `/charges` page by Shopify, i cant click on Cancel button, as well as its not showing that its in test mode.
Can you please help me fix it:
shopify.server.ts
export const MONTHLY_PLAN = {
NAME: "Monthly subscription",
AMOUNT: 3,
CURRENCY: "USD",
TRIAL_DAYS: 14,
};
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 || "",
authPathPrefix: "/auth",
sessionStorage: new PrismaSessionStorage(prisma),
distribution: AppDistribution.AppStore,
restResources,
billing: {
[MONTHLY_PLAN.NAME]: {
amount: MONTHLY_PLAN.AMOUNT,
currencyCode: MONTHLY_PLAN.CURRENCY,
interval: BillingInterval.Every30Days,
},
},
webhooks: {
APP_UNINSTALLED: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: "/webhooks",
},
APP_SUBSCRIPTIONS_UPDATE: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: "/webhooks",
},
},
hooks: {
afterAuth: async ({ session }) => {
shopify.registerWebhooks({ session });
},
},
future: {
v3_webhookAdminContext: true,
v3_authenticatePublic: true,
},
...(process.env.SHOP_CUSTOM_DOMAIN
? { customShopDomains: [process.env.SHOP_CUSTOM_DOMAIN] }
: {}),
});
payment.server.ts
export async function createSubscription(
graphql: GraphQLClient,
shopUrl: string
) {
const returnUrl = getReturlUrl(shopUrl);
const response = await graphql(
`
mutation appSubscriptionCreate(
$lineItems: [AppSubscriptionLineItemInput!]!
$name: String!
$returnUrl: URL!
) {
appSubscriptionCreate(
lineItems: $lineItems
name: $name
returnUrl: $returnUrl
) {
appSubscription {
createdAt
currentPeriodEnd
id
name
returnUrl
status
test
trialDays
}
confirmationUrl
userErrors {
field
message
}
}
}
`,
{
variables: {
name: MONTHLY_PLAN.NAME,
returnUrl: returnUrl,
trialDays: MONTHLY_PLAN.TRIAL_DAYS,
test: true,
lineItems: [
{
plan: {
appRecurringPricingDetails: {
price: {
amount: MONTHLY_PLAN.AMOUNT,
currencyCode: MONTHLY_PLAN.CURRENCY,
},
},
},
},
],
},
}
);
const {
data: { appSubscriptionCreate },
} = await response.json();
return appSubscriptionCreate;
}
const getReturlUrl = (shopUrl: string) => {
if (shopUrl.startsWith("https://") || shopUrl.startsWith("http://")) {
return shopUrl;
} else {
// returnUrl is generated by appending `https://` to the `session.shop` var which is `quickstore-uniqueid.myshopify.com`. in this case will become `https://quickstore-uniqueid.myshopify.com
return "https://" + shopUrl;
}
};
When i am logging the `appSubscriptionCreate` i am receiving the following
appSubscriptionCreate: {
appSubscription: {
createdAt: '2023-12-08T07:45:19Z',
currentPeriodEnd: null,
id: 'gid://shopify/AppSubscription/24758550573',
name: 'Monthly subscription',
returnUrl: 'https://quickstore-uniqueid.myshopify.com/',
status: 'PENDING',
test: false,
trialDays: 0
},
confirmationUrl: 'https://quickstore-uniqueid.myshopify.com/admin/charges/73990176769/24758550573/RecurringApplicationCharge/confirm_recurring_application_charge?signature=someSignature',
userErrors: []
}
So the trialDays and test, is being ignore completely.
app.payment.tsx
export async function loader({ request }: LoaderFunctionArgs) {
const {
session,
admin: { graphql },
redirect,
} = await authenticate.admin(request);
const subscription = await createSubscription(graphql, session.shop);
if (
subscription.appSubscription.currentPeriodEnd === null &&
subscription.confirmationUrl
) {
return redirect(subscription.confirmationUrl, { target: "_parent" });
}
return null
}
And when i get redirected to the `/changes` page, it looks like this (together with the error when i click Cancel button":
Hi Ertanb,
It does look like you're following the correct structure from our docs for this mutation, so it's surprising the trialDays are being set to 0. I've gotten in touch with our internal devs though so will take a deeper look into this.
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
Could that by any way be permission issues? I have the current access scope in `shopify.app.toml`:
[access_scopes]
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
scopes = "write_products"
For permissions, I believe you just need to be able to make authenticated calls to the Admin API. Still looking into this internally.
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