-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added ep payment gateway setup command
- Loading branch information
Showing
11 changed files
with
452 additions
and
0 deletions.
There are no files selected for viewing
202 changes: 202 additions & 0 deletions
202
packages/composable-cli/src/commands/payments/ep-payments/ep-payments-command.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
import yargs from "yargs" | ||
import { | ||
EPPaymentsCommandArguments, | ||
EPPaymentsCommandData, | ||
EPPaymentsCommandError, | ||
} from "./ep-payments-integration.types" | ||
import { CommandContext, CommandHandlerFunction } from "../../../types/command" | ||
import { handleErrors } from "../../../util/error-handler" | ||
import { trackCommandHandler } from "../../../util/track-command-handler" | ||
import { | ||
createActiveStoreMiddleware, | ||
createAuthenticationCheckerMiddleware, | ||
} from "../../generate/generate-command" | ||
import { PaymentsCommandArguments } from "../payments.types" | ||
import * as ansiColors from "ansi-colors" | ||
import inquirer from "inquirer" | ||
import { isTTY } from "../../../util/is-tty" | ||
import boxen from "boxen" | ||
import ora from "ora" | ||
import { logging } from "@angular-devkit/core" | ||
import { setupEPPaymentsPaymentGateway } from "./util/setup-epcc-ep-payment" | ||
import { | ||
EPPaymentsSetup, | ||
epPaymentsSetupSchema, | ||
} from "./util/setup-ep-payments-schema" | ||
|
||
export function createEPPaymentsCommand( | ||
ctx: CommandContext, | ||
): yargs.CommandModule<PaymentsCommandArguments, EPPaymentsCommandArguments> { | ||
return { | ||
command: "ep-payments", | ||
describe: | ||
"setup EP Payment gateway for your Elastic Path powered storefront", | ||
builder: async (yargs) => { | ||
return yargs | ||
.middleware(createAuthenticationCheckerMiddleware(ctx)) | ||
.middleware(createActiveStoreMiddleware(ctx)) | ||
.option("account-id", { | ||
type: "string", | ||
description: "EP Payments account ID", | ||
}) | ||
.option("publishable-key", { | ||
type: "string", | ||
description: "EP Payments publishable key", | ||
}) | ||
.fail(false) | ||
.help() | ||
}, | ||
handler: handleErrors( | ||
trackCommandHandler(ctx, createEPPaymentsCommandHandler), | ||
), | ||
} | ||
} | ||
|
||
export function createEPPaymentsCommandHandler( | ||
ctx: CommandContext, | ||
): CommandHandlerFunction< | ||
EPPaymentsCommandData, | ||
EPPaymentsCommandError, | ||
EPPaymentsCommandArguments | ||
> { | ||
return async function epPaymentsCommandHandler(args) { | ||
const spinner = ora() | ||
|
||
try { | ||
if (!ctx.epClient) { | ||
spinner.fail(`Failed to setup EP Payments.`) | ||
return { | ||
success: false, | ||
error: { | ||
code: "missing_ep_client", | ||
message: "Failed to setup EP Payments - missing EP client", | ||
}, | ||
} | ||
} | ||
|
||
const options = await resolveOptions(args, ctx.logger, ansiColors) | ||
|
||
spinner.start(`Setting up EP Payments...`) | ||
const result = await setupEPPaymentsPaymentGateway( | ||
{ | ||
epPaymentsStripeAccountId: options.accountId, | ||
epPaymentsStripePublishableKey: options.publishableKey, | ||
}, | ||
ctx.epClient, | ||
ctx.logger, | ||
) | ||
|
||
if (!result.success) { | ||
spinner.fail(`Failed to setup EP Payments.`) | ||
return { | ||
success: false, | ||
error: { | ||
code: "ep_payments_setup_failed", | ||
message: "Failed to setup EP Payments", | ||
}, | ||
} | ||
} | ||
|
||
spinner.succeed(`EP Payments setup successfully.`) | ||
return { | ||
success: true, | ||
data: {}, | ||
} | ||
} catch (e) { | ||
spinner.fail(`Failed to setup Algolia integration`) | ||
return { | ||
success: false, | ||
error: { | ||
code: "ALGOLIA_INTEGRATION_SETUP_FAILED", | ||
message: "Failed to setup Algolia integration", | ||
}, | ||
} | ||
} | ||
} | ||
} | ||
|
||
async function resolveOptions( | ||
args: EPPaymentsCommandArguments, | ||
logger: logging.Logger, | ||
colors: typeof ansiColors, | ||
): Promise<EPPaymentsSetup> { | ||
if (args.interactive && isTTY()) { | ||
return epPaymentsOptionsPrompts(args, logger, colors) | ||
} | ||
|
||
const parsed = epPaymentsSetupSchema.safeParse({ | ||
accountId: args.accountId, | ||
publishableKey: args.publishableKey, | ||
}) | ||
|
||
if (!parsed.success) { | ||
throw new Error(`Invalid arguments: ${JSON.stringify(parsed.error)}`) | ||
} | ||
|
||
return parsed.data | ||
} | ||
|
||
async function epPaymentsOptionsPrompts( | ||
args: EPPaymentsCommandArguments, | ||
logger: logging.Logger, | ||
_colors: typeof ansiColors, | ||
): Promise<EPPaymentsSetup> { | ||
const { accountId: argsAccountId, publishableKey: argsPublishableKey } = args | ||
|
||
if (!argsAccountId && !argsPublishableKey) { | ||
logger.info( | ||
boxen( | ||
`If you don't have an EP payments account setup reach out to us \nhttps://www.elasticpath.com/products/payments`, | ||
{ | ||
padding: 1, | ||
margin: 1, | ||
}, | ||
), | ||
) | ||
} | ||
|
||
let gatheredOptions = {} | ||
|
||
if (!argsAccountId) { | ||
const { algoliaApplicationId } = await inquirer.prompt([ | ||
{ | ||
type: "string", | ||
name: "accountId", | ||
message: "What is your EP Payments account ID?", | ||
}, | ||
]) | ||
|
||
gatheredOptions = { | ||
...gatheredOptions, | ||
appId: algoliaApplicationId, | ||
} | ||
} else { | ||
gatheredOptions = { | ||
...gatheredOptions, | ||
accountId: argsAccountId, | ||
} | ||
} | ||
|
||
if (!argsPublishableKey) { | ||
const { algoliaAdminApiKey } = await inquirer.prompt([ | ||
{ | ||
type: "password", | ||
name: "algoliaAdminApiKey", | ||
message: "What is your Algolia Admin API Key?", | ||
mask: "*", | ||
}, | ||
]) | ||
|
||
gatheredOptions = { | ||
...gatheredOptions, | ||
adminApiKey: algoliaAdminApiKey, | ||
} | ||
} else { | ||
gatheredOptions = { | ||
...gatheredOptions, | ||
publishableKey: argsPublishableKey, | ||
} | ||
} | ||
|
||
return gatheredOptions as any | ||
} |
15 changes: 15 additions & 0 deletions
15
packages/composable-cli/src/commands/payments/ep-payments/ep-payments-integration.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { PaymentsCommandArguments } from "../payments.types" | ||
|
||
export type EPPaymentsCommandData = { | ||
indexName?: string | ||
} | ||
|
||
export type EPPaymentsCommandError = { | ||
code: string | ||
message: string | ||
} | ||
|
||
export type EPPaymentsCommandArguments = { | ||
accountId?: string | ||
publishableKey?: string | ||
} & PaymentsCommandArguments |
10 changes: 10 additions & 0 deletions
10
packages/composable-cli/src/commands/payments/ep-payments/util/ep-payments-schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { z } from "zod" | ||
|
||
export const epPaymentGatewaySettingsSchema = z.object({ | ||
epPaymentsStripeAccountId: z.string().min(1), | ||
epPaymentsStripePublishableKey: z.string().min(1), | ||
}) | ||
|
||
export type EpPaymentGatewaySettings = z.TypeOf< | ||
typeof epPaymentGatewaySettingsSchema | ||
> |
8 changes: 8 additions & 0 deletions
8
packages/composable-cli/src/commands/payments/ep-payments/util/setup-ep-payments-schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { z } from "zod" | ||
|
||
export const epPaymentsSetupSchema = z.object({ | ||
accountId: z.string(), | ||
publishableKey: z.string(), | ||
}) | ||
|
||
export type EPPaymentsSetup = z.TypeOf<typeof epPaymentsSetupSchema> |
56 changes: 56 additions & 0 deletions
56
packages/composable-cli/src/commands/payments/ep-payments/util/setup-epcc-ep-payment.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { logging } from "@angular-devkit/core" | ||
import type { Gateway, Moltin } from "@moltin/sdk" | ||
import { checkGateway, OperationResult } from "@elasticpath/composable-common" | ||
import { updateEpPaymentGateway } from "./update-gateway" | ||
import { EpPaymentGatewaySettings } from "./ep-payments-schema" | ||
|
||
export async function setupEPPaymentsPaymentGateway( | ||
sourceInput: EpPaymentGatewaySettings, | ||
epccClient: Moltin, | ||
logger: logging.LoggerApi, | ||
): Promise<OperationResult<Gateway>> { | ||
try { | ||
const { epPaymentsStripeAccountId } = sourceInput | ||
|
||
/** | ||
* Check if EP payments is enabled and do nothing if it is | ||
*/ | ||
const checkGatewayResult = await checkGateway( | ||
epccClient, | ||
"elastic_path_payments_stripe", | ||
) | ||
|
||
if (checkGatewayResult.success) { | ||
logger.debug(`EP Payment gateway is already enabled`) | ||
return checkGatewayResult | ||
} | ||
|
||
/** | ||
* Update ep payment gateway to be enabled with test mode on | ||
*/ | ||
const updateResult = await updateEpPaymentGateway( | ||
epccClient, | ||
epPaymentsStripeAccountId, | ||
) | ||
|
||
if (!updateResult.success) { | ||
logger.debug(`Failed to update ep payment gateway.`) | ||
return updateResult | ||
} | ||
|
||
return updateResult | ||
} catch (err: unknown) { | ||
const errorStr = `An unknown error occurred: ${ | ||
err instanceof Error | ||
? `${err.name} = ${err.message}` | ||
: JSON.stringify(err) | ||
}` | ||
|
||
logger.error(errorStr) | ||
|
||
return { | ||
success: false, | ||
error: new Error(errorStr), | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
packages/composable-cli/src/commands/payments/ep-payments/util/update-gateway.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { Gateway, Moltin as EpccClient } from "@moltin/sdk" | ||
import { OperationResult } from "@elasticpath/composable-common" | ||
|
||
const errMsg = "Failed to enable elastic_path_payments_stripe gateway." | ||
|
||
export async function updateEpPaymentGateway( | ||
client: EpccClient, | ||
accountId: string, | ||
): Promise<OperationResult<Gateway>> { | ||
try { | ||
const updatedGateway = await client.Gateways.Update( | ||
"elastic_path_payments_stripe", | ||
{ enabled: true, stripe_account: accountId, test: true }, | ||
) | ||
|
||
if (updatedGateway.data) { | ||
return { | ||
success: true, | ||
data: updatedGateway.data, | ||
} | ||
} | ||
|
||
return { | ||
success: false, | ||
error: new Error(`${errMsg} ${JSON.stringify(updatedGateway)}`), | ||
} | ||
} catch (err: unknown) { | ||
return { | ||
success: false, | ||
error: new Error( | ||
`${errMsg} An unknown error occurred ${ | ||
err instanceof Error | ||
? `${err.name} - ${err.message}` | ||
: "Failed to render error." | ||
}`, | ||
), | ||
} | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
packages/composable-cli/src/commands/payments/payments-command.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import yargs from "yargs" | ||
import { | ||
CommandContext, | ||
CommandHandlerFunction, | ||
RootCommandArguments, | ||
} from "../../types/command" | ||
import { handleErrors } from "../../util/error-handler" | ||
|
||
import { trackCommandHandler } from "../../util/track-command-handler" | ||
import { createEPPaymentsCommand } from "./ep-payments/ep-payments-command" | ||
import { | ||
PaymentsCommandArguments, | ||
PaymentsCommandData, | ||
PaymentsCommandError, | ||
} from "./payments.types" | ||
import { createActiveStoreMiddleware } from "../generate/generate-command" | ||
|
||
export function createPaymentsCommand( | ||
ctx: CommandContext, | ||
): yargs.CommandModule<RootCommandArguments, PaymentsCommandArguments> { | ||
return { | ||
command: "payments", | ||
aliases: ["p"], | ||
describe: "setup Elastic Path payment gateways for your storefront", | ||
builder: (yargs) => { | ||
return yargs | ||
.middleware(createActiveStoreMiddleware(ctx)) | ||
.command(createEPPaymentsCommand(ctx)) | ||
.help() | ||
.demandCommand(1) | ||
.strict() | ||
}, | ||
handler: handleErrors( | ||
trackCommandHandler(ctx, createPaymentsCommandHandler), | ||
), | ||
} | ||
} | ||
|
||
export function createPaymentsCommandHandler( | ||
_ctx: CommandContext, | ||
): CommandHandlerFunction< | ||
PaymentsCommandData, | ||
PaymentsCommandError, | ||
PaymentsCommandArguments | ||
> { | ||
return async function integrationCommandHandler(_args) { | ||
return { | ||
success: false, | ||
error: { | ||
code: "missing-positional-argument", | ||
message: | ||
'missing positional argument did you mean to run "ep-payments" command?', | ||
}, | ||
} | ||
} | ||
} |
Oops, something went wrong.