Browse Source

feat(payments-plugin): Add support for opting-out of Braintree vault

Relates to #1651. This commit makes it possible to not send the `customerId` when generating
the Braintree client token.
Michael Bromley 3 years ago
parent
commit
faeef6d3cc

+ 30 - 2
packages/payments-plugin/src/braintree/braintree.plugin.ts

@@ -37,7 +37,8 @@ import { BraintreePluginOptions } from './types';
  *       BraintreePlugin.init({
  *         environment: Environment.Sandbox,
  *         // This allows saving customer payment
- *         // methods with Braintree
+ *         // methods with Braintree (see "vaulting"
+ *         // section below for details)
  *         storeCustomersInBraintree: true,
  *       }),
  *     ]
@@ -187,6 +188,33 @@ import { BraintreePluginOptions } from './types';
  *   }
  * }
  * ```
+ *
+ * ## Storing payment details (vaulting)
+ *
+ * Braintree has a [vault feature](https://developer.paypal.com/braintree/articles/control-panel/vault/overview) which allows the secure storage
+ * of customer's payment information. Using the vault allows you to offer a faster checkout for repeat customers without needing to worry about
+ * how to securely store payment details.
+ *
+ * To enable this feature, set the `storeCustomersInBraintree` option to `true`.
+ *
+ * ```TypeScript
+ * BraintreePlugin.init({
+ *   environment: Environment.Sandbox,
+ *   storeCustomersInBraintree: true,
+ * }),
+ * ```
+ *
+ * Since v1.8, it is possible to override vaulting on a per-payment basis by passing `includeCustomerId: false` to the `generateBraintreeClientToken`
+ * mutation:
+ *
+ * ```GraphQL
+ * const { generateBraintreeClientToken } = await graphQlClient.query(gql`
+ *   query GenerateBraintreeClientToken($includeCustomerId: Boolean) {
+ *     generateBraintreeClientToken(includeCustomerId: $includeCustomerId)
+ *   }
+ * `, { includeCustomerId: false });
+ * ```
+ *
  * @docsCategory payments-plugin
  * @docsPage BraintreePlugin
  */
@@ -215,7 +243,7 @@ import { BraintreePluginOptions } from './types';
     shopApiExtensions: {
         schema: gql`
             extend type Query {
-                generateBraintreeClientToken(orderId: ID): String!
+                generateBraintreeClientToken(orderId: ID, includeCustomerId: Boolean): String!
             }
         `,
         resolvers: [BraintreeResolver],

+ 7 - 2
packages/payments-plugin/src/braintree/braintree.resolver.ts

@@ -27,7 +27,10 @@ export class BraintreeResolver {
     ) {}
 
     @Query()
-    async generateBraintreeClientToken(@Ctx() ctx: RequestContext, @Args() { orderId }: { orderId?: ID }) {
+    async generateBraintreeClientToken(
+        @Ctx() ctx: RequestContext,
+        @Args() { orderId, includeCustomerId }: { orderId?: ID; includeCustomerId?: boolean },
+    ) {
         if (orderId) {
             Logger.warn(
                 `The orderId argument to the generateBraintreeClientToken mutation has been deprecated and may be omitted.`,
@@ -45,7 +48,9 @@ export class BraintreeResolver {
             const args = await this.getPaymentMethodArgs(ctx);
             const gateway = getGateway(args, this.options);
             try {
-                const result = await gateway.clientToken.generate({ customerId });
+                const result = await gateway.clientToken.generate({
+                    customerId: includeCustomerId === false ? undefined : customerId,
+                });
                 return result.clientToken;
             } catch (e) {
                 Logger.error(

+ 4 - 1
packages/payments-plugin/src/braintree/types.ts

@@ -33,10 +33,13 @@ export interface BraintreePluginOptions {
     /**
      * @description
      * If set to `true`, a [Customer](https://developer.paypal.com/braintree/docs/guides/customers) object
-     * will be created in Braintree, which allows the secure storage of previously-used payment methods.
+     * will be created in Braintree, which allows the secure storage ("vaulting") of previously-used payment methods.
      * This is done by adding a custom field to the Customer entity to store the Braintree customer ID,
      * so switching this on will require a database migration / synchronization.
      *
+     * Since v1.8, it is possible to override vaulting on a per-payment basis by passing `includeCustomerId: false` to the
+     * `generateBraintreeClientToken` mutation.
+     *
      * @default false
      */
     storeCustomersInBraintree?: boolean;