소스 검색

feat(payments-plugin): Export StripeService to support more payment flows (#3624)

Kristóf Kerti 6 달 전
부모
커밋
829ab2c93e

+ 2 - 2
packages/payments-plugin/e2e/fixtures/stripe-checkout-test.plugin.ts

@@ -1,9 +1,9 @@
 /* eslint-disable */
-import { Controller, Res, Get } from '@nestjs/common';
+import { Controller, Get, Res } from '@nestjs/common';
 import { PluginCommonModule, VendurePlugin } from '@vendure/core';
 import { Response } from 'express';
 
-import { clientSecret } from './stripe-dev-server';
+import { clientSecret } from '../stripe-dev-server';
 
 /**
  * This test controller returns the Stripe intent checkout page

+ 59 - 0
packages/payments-plugin/e2e/fixtures/stripe-service-export-test.plugin.ts

@@ -0,0 +1,59 @@
+import { Args, Mutation, Resolver } from '@nestjs/graphql';
+import {
+    Allow,
+    Ctx,
+    OrderService,
+    Permission,
+    PluginCommonModule,
+    RequestContext,
+    RequestContextService,
+    VendurePlugin,
+} from '@vendure/core';
+import gql from 'graphql-tag';
+
+import { StripePlugin } from '../../src/stripe';
+import { StripeService } from '../../src/stripe/stripe.service';
+
+@Resolver()
+export class CustomStripeResolver {
+    constructor(
+        private stripeService: StripeService,
+        private orderService: OrderService,
+        private requestContextService: RequestContextService,
+    ) {}
+
+    @Mutation()
+    @Allow(Permission.Owner)
+    async createCustomStripePaymentIntent(
+        @Ctx() ctx: RequestContext,
+        @Args() args: { orderCode: string; channelToken: string },
+    ): Promise<string> {
+        // By the orderCode we find the order where we assume additional payments are required.
+        // If the order is not in the request's channel context, we can use other means to lookup the order.
+        const order = await this.orderService.findOneByCode(ctx, args.orderCode);
+        // The stripe webhook handler expects: channelToken, orderId, orderCode and languageCode
+        // We can hijack those details, to support cross-channel payments and additional "non-active" order payments
+        const customCtx = await this.requestContextService.create({
+            apiType: 'shop',
+            channelOrToken: args.channelToken,
+            req: ctx.req,
+        });
+        if (!order) {
+            throw new Error('No order');
+        }
+        return this.stripeService.createPaymentIntent(customCtx, order);
+    }
+}
+
+@VendurePlugin({
+    imports: [PluginCommonModule, StripePlugin],
+    shopApiExtensions: {
+        schema: gql`
+            extend type Mutation {
+                createCustomStripePaymentIntent(orderCode: String, channelToken: String): String!
+            }
+        `,
+        resolvers: [CustomStripeResolver],
+    },
+})
+export class StripeServiceExportTestPlugin {}

+ 6 - 0
packages/payments-plugin/e2e/payment-helpers.ts

@@ -229,6 +229,12 @@ export const CREATE_STRIPE_PAYMENT_INTENT = gql`
     }
 `;
 
+export const CREATE_CUSTOM_STRIPE_PAYMENT_INTENT = gql`
+    mutation createCustomStripePaymentIntent {
+        createCustomStripePaymentIntent
+    }
+`;
+
 export const GET_MOLLIE_PAYMENT_METHODS = gql`
     query molliePaymentMethods($input: MolliePaymentMethodsInput!) {
         molliePaymentMethods(input: $input) {

+ 13 - 3
packages/payments-plugin/e2e/stripe-dev-server.ts

@@ -10,7 +10,6 @@ import {
     RequestContext,
 } from '@vendure/core';
 import { createTestEnvironment, registerInitializer, SqljsInitializer, testConfig } from '@vendure/testing';
-import gql from 'graphql-tag';
 import path from 'path';
 
 import { initialData } from '../../../e2e-common/e2e-initial-data';
@@ -18,6 +17,8 @@ import { StripePlugin } from '../src/stripe';
 import { stripePaymentMethodHandler } from '../src/stripe/stripe.handler';
 
 /* eslint-disable */
+import { StripeCheckoutTestPlugin } from './fixtures/stripe-checkout-test.plugin';
+import { StripeServiceExportTestPlugin } from './fixtures/stripe-service-export-test.plugin';
 import { CREATE_PAYMENT_METHOD } from './graphql/admin-queries';
 import {
     CreatePaymentMethodMutation,
@@ -25,8 +26,11 @@ import {
 } from './graphql/generated-admin-types';
 import { AddItemToOrderMutation, AddItemToOrderMutationVariables } from './graphql/generated-shop-types';
 import { ADD_ITEM_TO_ORDER } from './graphql/shop-queries';
-import { CREATE_STRIPE_PAYMENT_INTENT, setShipping } from './payment-helpers';
-import { StripeCheckoutTestPlugin } from './stripe-checkout-test.plugin';
+import {
+    CREATE_CUSTOM_STRIPE_PAYMENT_INTENT,
+    CREATE_STRIPE_PAYMENT_INTENT,
+    setShipping,
+} from './payment-helpers';
 
 export let clientSecret: string;
 
@@ -46,6 +50,7 @@ export let clientSecret: string;
             }),
             StripePlugin.init({}),
             StripeCheckoutTestPlugin,
+            StripeServiceExportTestPlugin,
         ],
         logger: new DefaultLogger({ level: LogLevel.Debug }),
     });
@@ -99,5 +104,10 @@ export let clientSecret: string;
     await setShipping(shopClient);
     const { createStripePaymentIntent } = await shopClient.query(CREATE_STRIPE_PAYMENT_INTENT);
     clientSecret = createStripePaymentIntent;
+
+    // Showcasing the custom intent creation
+    const { createCustomStripePaymentIntent } = await shopClient.query(CREATE_CUSTOM_STRIPE_PAYMENT_INTENT);
+    Logger.debug('Result of createCustomStripePaymentIntent:', createCustomStripePaymentIntent);
+
     Logger.info('http://localhost:3050/checkout', 'Stripe DevServer');
 })();

+ 1 - 1
packages/payments-plugin/src/stripe/stripe.plugin.ts

@@ -1,5 +1,4 @@
 import { LanguageCode, PluginCommonModule, Type, VendurePlugin } from '@vendure/core';
-import { json } from 'body-parser';
 import { gql } from 'graphql-tag';
 
 import { STRIPE_PLUGIN_OPTIONS } from './constants';
@@ -198,6 +197,7 @@ import { StripePluginOptions } from './types';
         `,
         resolvers: [StripeResolver],
     },
+    exports: [StripeService],
     compatibility: '^3.0.0',
 })
 export class StripePlugin {