UNPKG

@shopify/shopify-api

Version:

Shopify API Library for Node - accelerate development with support for authentication, graphql proxy, webhooks

1 lines 14.3 kB
{"version":3,"file":"request.mjs","sources":["../../../../../../lib/billing/request.ts"],"sourcesContent":["import {ConfigInterface, ConfigParams} from '../base-types';\nimport {BillingInterval} from '../types';\nimport {BillingError} from '../error';\nimport {buildEmbeddedAppUrl} from '../auth/get-embedded-app-url';\nimport {GraphqlClient, graphqlClientClass} from '../clients/admin';\nimport {hashString} from '../../runtime/crypto';\nimport {HashFormat} from '../../runtime/crypto/types';\nimport {FutureFlagOptions} from '../../future/flags';\n\nimport {\n BillingConfigOneTimePlan,\n BillingRequestParams,\n BillingRequestResponse,\n RecurringPaymentResponse,\n RequestResponseData,\n SinglePaymentResponse,\n BillingConfigSubscriptionLineItemPlan,\n RequestConfigLineItemOverrides,\n BillingRequest,\n APP_SUBSCRIPTION_FRAGMENT,\n} from './types';\n\nconst RECURRING_PURCHASE_MUTATION = `\n ${APP_SUBSCRIPTION_FRAGMENT}\n mutation AppSubscriptionCreate(\n $name: String!\n $returnUrl: URL!\n $test: Boolean\n $trialDays: Int\n $replacementBehavior: AppSubscriptionReplacementBehavior\n $lineItems: [AppSubscriptionLineItemInput!]!\n ) {\n appSubscriptionCreate(\n name: $name\n returnUrl: $returnUrl\n test: $test\n trialDays: $trialDays\n replacementBehavior: $replacementBehavior\n lineItems: $lineItems\n ) {\n appSubscription {\n ...AppSubscriptionFragment\n }\n confirmationUrl\n userErrors {\n field\n message\n }\n }\n }\n`;\n\nconst ONE_TIME_PURCHASE_MUTATION = `\n mutation test(\n $name: String!\n $price: MoneyInput!\n $returnUrl: URL!\n $test: Boolean\n ) {\n appPurchaseOneTimeCreate(\n name: $name\n price: $price\n returnUrl: $returnUrl\n test: $test\n ) {\n appPurchaseOneTime {\n id\n name\n test\n }\n confirmationUrl\n userErrors {\n field\n message\n }\n }\n }\n`;\n\ninterface RequestInternalParams {\n client: GraphqlClient;\n plan: string;\n returnUrl: string;\n isTest: boolean;\n}\n\ninterface RequestOneTimePaymentInternalParams extends RequestInternalParams {\n billingConfig: BillingConfigOneTimePlan;\n}\n\ninterface RequestSubscriptionParams extends RequestInternalParams {\n billingConfig: BillingConfigSubscriptionLineItemPlan;\n}\n\nexport function request<\n Config extends ConfigInterface<Params>,\n Params extends ConfigParams<any, Future>,\n Future extends FutureFlagOptions,\n>(config: Config): BillingRequest {\n return async function <Params extends BillingRequestParams>({\n session,\n plan,\n isTest = true,\n returnUrl: returnUrlParam,\n returnObject = false,\n ...overrides\n }: Params): Promise<BillingRequestResponse<Params>> {\n if (!config.billing || !config.billing[plan]) {\n throw new BillingError({\n message: `Could not find plan ${plan} in billing settings`,\n errorData: [],\n });\n }\n\n const billingConfig = {\n ...config.billing[plan],\n };\n const filteredOverrides = Object.fromEntries(\n Object.entries(overrides).filter(([_key, value]) => value !== undefined),\n );\n\n const cleanShopName = session.shop.replace('.myshopify.com', '');\n const embeddedAppUrl = buildEmbeddedAppUrl(config)(\n hashString(`admin.shopify.com/store/${cleanShopName}`, HashFormat.Base64),\n );\n\n const appUrl = `${config.hostScheme}://${config.hostName}?shop=${session.shop}`;\n\n // if provided a return URL, use it, otherwise use the embedded app URL or hosted app URL\n const returnUrl =\n returnUrlParam || (config.isEmbeddedApp ? embeddedAppUrl : appUrl);\n\n const GraphqlClient = graphqlClientClass({config});\n const client = new GraphqlClient({session});\n\n function isLineItemPlan(\n billingConfig: any,\n ): billingConfig is BillingConfigSubscriptionLineItemPlan {\n return 'lineItems' in billingConfig;\n }\n\n function isOneTimePlan(\n billingConfig: any,\n ): billingConfig is BillingConfigOneTimePlan {\n return billingConfig.interval === BillingInterval.OneTime;\n }\n\n let data: RequestResponseData;\n if (isLineItemPlan(billingConfig)) {\n const mergedBillingConfigs = mergeBillingConfigs(\n billingConfig,\n filteredOverrides,\n );\n const mutationRecurringResponse = await requestSubscriptionPayment({\n billingConfig: mergedBillingConfigs,\n plan,\n client,\n returnUrl,\n isTest,\n });\n\n data = mutationRecurringResponse.appSubscriptionCreate!;\n } else if (isOneTimePlan(billingConfig)) {\n const mutationOneTimeResponse = await requestSinglePayment({\n billingConfig: {...billingConfig, ...filteredOverrides},\n plan,\n client,\n returnUrl,\n isTest,\n });\n data = mutationOneTimeResponse.appPurchaseOneTimeCreate!;\n } else {\n throw new BillingError({\n message: `Invalid billing configuration for plan ${plan}. Must be either a one-time plan or a subscription plan with line items.`,\n errorData: [],\n });\n }\n\n if (data.userErrors?.length) {\n throw new BillingError({\n message: 'Error while billing the store',\n errorData: data.userErrors,\n });\n }\n\n if (returnObject) {\n return data as Omit<\n RequestResponseData,\n 'userErrors'\n > as BillingRequestResponse<Params>;\n } else {\n return data.confirmationUrl as BillingRequestResponse<Params>;\n }\n };\n}\n\nasync function requestSubscriptionPayment({\n billingConfig,\n plan,\n client,\n returnUrl,\n isTest,\n}: RequestSubscriptionParams): Promise<RecurringPaymentResponse> {\n const lineItems = billingConfig.lineItems.map((item) => {\n if (\n item.interval === BillingInterval.Every30Days ||\n item.interval === BillingInterval.Annual\n ) {\n const appRecurringPricingDetails: any = {\n interval: item.interval,\n price: {\n amount: item.amount,\n currencyCode: item.currencyCode,\n },\n };\n\n if (item.discount) {\n appRecurringPricingDetails.discount = {\n durationLimitInIntervals: item.discount.durationLimitInIntervals,\n value: {\n amount: item.discount.value.amount,\n percentage: item.discount.value.percentage,\n },\n };\n }\n\n return {\n plan: {\n appRecurringPricingDetails,\n },\n };\n } else if (item.interval === BillingInterval.Usage) {\n const appUsagePricingDetails = {\n terms: item.terms,\n cappedAmount: {\n amount: item.amount,\n currencyCode: item.currencyCode,\n },\n };\n\n return {\n plan: {\n appUsagePricingDetails,\n },\n };\n } else {\n throw new BillingError({\n message: 'Invalid interval provided',\n errorData: [item],\n });\n }\n });\n\n const mutationResponse = await client.request<RecurringPaymentResponse>(\n RECURRING_PURCHASE_MUTATION,\n {\n variables: {\n name: plan,\n trialDays: billingConfig.trialDays,\n replacementBehavior: billingConfig.replacementBehavior,\n returnUrl,\n test: isTest,\n lineItems,\n },\n },\n );\n\n if (mutationResponse.errors) {\n throw new BillingError({\n message: 'Error while billing the store',\n errorData: mutationResponse.errors,\n });\n }\n\n return mutationResponse.data!;\n}\n\nasync function requestSinglePayment({\n billingConfig,\n plan,\n client,\n returnUrl,\n isTest,\n}: RequestOneTimePaymentInternalParams): Promise<SinglePaymentResponse> {\n const mutationResponse = await client.request<SinglePaymentResponse>(\n ONE_TIME_PURCHASE_MUTATION,\n {\n variables: {\n name: plan,\n returnUrl,\n test: isTest,\n price: {\n amount: billingConfig.amount,\n currencyCode: billingConfig.currencyCode,\n },\n },\n },\n );\n\n if (mutationResponse.errors) {\n throw new BillingError({\n message: 'Error while billing the store',\n errorData: mutationResponse.errors,\n });\n }\n\n return mutationResponse.data!;\n}\n\nfunction mergeBillingConfigs(\n billingConfig: BillingConfigSubscriptionLineItemPlan,\n overrides: RequestConfigLineItemOverrides,\n): BillingConfigSubscriptionLineItemPlan {\n const mergedConfig = {...billingConfig, ...overrides};\n const mergedLineItems = [];\n\n if (billingConfig.lineItems && overrides.lineItems) {\n for (const i of billingConfig.lineItems) {\n let found = false;\n\n for (const j of overrides.lineItems) {\n if (i.interval === j!.interval) {\n mergedLineItems.push({...i, ...j});\n found = true;\n break;\n }\n }\n\n if (!found) {\n mergedLineItems.push(i);\n }\n }\n\n mergedConfig.lineItems = mergedLineItems;\n }\n\n return mergedConfig as BillingConfigSubscriptionLineItemPlan;\n}\n"],"names":[],"mappings":"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"}