"test: true", and "trialDays: number" is being ignored when calling appSubscriptionCreate

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.

HI @Liam ,

Thank you! Please check both the “trial” and “test”. :slightly_smiling_face:

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.

Hi @Liam ,

Ok, i see. Did you manage to find out yet what was the problem?