Explorar el Código

Merge branch 'master' into minor

Michael Bromley hace 2 años
padre
commit
6e441e7d2e
Se han modificado 31 ficheros con 337 adiciones y 56 borrados
  1. 15 0
      CHANGELOG.md
  2. 3 1
      docs/content/deployment/_index.md
  3. BIN
      docs/content/deployment/deploy-to-northflank/01-create-template-screen.webp
  4. BIN
      docs/content/deployment/deploy-to-northflank/02-paste-config.webp
  5. BIN
      docs/content/deployment/deploy-to-northflank/03-run-template.webp
  6. BIN
      docs/content/deployment/deploy-to-northflank/04-find-project.webp
  7. BIN
      docs/content/deployment/deploy-to-northflank/05-server-service.webp
  8. BIN
      docs/content/deployment/deploy-to-northflank/06-find-url.webp
  9. BIN
      docs/content/deployment/deploy-to-northflank/deploy-to-northflank.webp
  10. 241 0
      docs/content/deployment/deploy-to-northflank/index.md
  11. 3 1
      docs/content/developer-guide/importing-product-data.md
  12. 2 2
      docs/data/build.json
  13. 1 1
      lerna.json
  14. 3 3
      packages/admin-ui-plugin/package.json
  15. 2 2
      packages/admin-ui/package.json
  16. 1 1
      packages/admin-ui/src/lib/core/src/common/version.ts
  17. 3 3
      packages/asset-server-plugin/package.json
  18. 1 1
      packages/common/package.json
  19. 2 2
      packages/core/package.json
  20. 1 1
      packages/core/src/service/services/product-variant.service.ts
  21. 3 3
      packages/create/package.json
  22. 9 9
      packages/dev-server/package.json
  23. 3 3
      packages/elasticsearch-plugin/package.json
  24. 3 3
      packages/email-plugin/package.json
  25. 3 3
      packages/harden-plugin/package.json
  26. 3 3
      packages/job-queue-plugin/package.json
  27. 4 4
      packages/payments-plugin/package.json
  28. 1 1
      packages/payments-plugin/src/braintree/braintree.plugin.ts
  29. 23 2
      packages/payments-plugin/src/braintree/braintree.resolver.ts
  30. 3 3
      packages/testing/package.json
  31. 4 4
      packages/ui-devkit/package.json

+ 15 - 0
CHANGELOG.md

@@ -1,3 +1,18 @@
+## <small>1.9.3 (2023-02-15)</small>
+
+
+#### Fixes
+
+* **admin-ui** Fix UI for long channel list tab on Administrator detail page (#2018) ([7fdd875](https://github.com/vendure-ecommerce/vendure/commit/7fdd875)), closes [#2018](https://github.com/vendure-ecommerce/vendure/issues/2018)
+* **admin-ui** Redirect to loginUrl if configured on Forbidden GraphQL error (#2012) ([53b78d2](https://github.com/vendure-ecommerce/vendure/commit/53b78d2)), closes [#2012](https://github.com/vendure-ecommerce/vendure/issues/2012)
+* **core** Fix auth of admin and customer users with the same email (#2016) ([3c76b2f](https://github.com/vendure-ecommerce/vendure/commit/3c76b2f)), closes [#2016](https://github.com/vendure-ecommerce/vendure/issues/2016)
+* **core** Fix deletion of product options (#2017) ([a3698b5](https://github.com/vendure-ecommerce/vendure/commit/a3698b5)), closes [#2017](https://github.com/vendure-ecommerce/vendure/issues/2017)
+* **payments-plugin** Improve handling of Braintree customerId errors ([4d9f49e](https://github.com/vendure-ecommerce/vendure/commit/4d9f49e))
+
+#### Features
+
+* **asset-server-plugin** Add configurable Cache-Control header (#2005) ([316d04d](https://github.com/vendure-ecommerce/vendure/commit/316d04d)), closes [#2005](https://github.com/vendure-ecommerce/vendure/issues/2005)
+
 ## <small>1.9.2 (2023-01-18)</small>
 
 

+ 3 - 1
docs/content/deployment/_index.md

@@ -8,4 +8,6 @@ showtoc: false
 
 This section contains guides for deploying a Vendure application to production.
 
-We are planning to publish specific guides for popular platforms soon. For now, you can find platform-specific information in our [Deployment discussion category](https://github.com/vendure-ecommerce/vendure/discussions/categories/deployment).
+For a quick and simple deployment, we recommend following the [Deploying to Northflank guide]({{< relref "deploy-to-northflank" >}}).
+
+Community-contributed information about deploying to other platforms can be found in our [Deployment discussion category](https://github.com/vendure-ecommerce/vendure/discussions/categories/deployment).

BIN
docs/content/deployment/deploy-to-northflank/01-create-template-screen.webp


BIN
docs/content/deployment/deploy-to-northflank/02-paste-config.webp


BIN
docs/content/deployment/deploy-to-northflank/03-run-template.webp


BIN
docs/content/deployment/deploy-to-northflank/04-find-project.webp


BIN
docs/content/deployment/deploy-to-northflank/05-server-service.webp


BIN
docs/content/deployment/deploy-to-northflank/06-find-url.webp


BIN
docs/content/deployment/deploy-to-northflank/deploy-to-northflank.webp


+ 241 - 0
docs/content/deployment/deploy-to-northflank/index.md

@@ -0,0 +1,241 @@
+---
+title: "Deploying to Northflank"
+showtoc: true
+images: 
+    - "/docs/deployment/deploy-to-northflank/deploy-to-northflank.webp"
+---
+
+{{< figure src="./deploy-to-northflank.webp" >}}
+
+[Northflank](https://northflank.com) is a comprehensive developer platform to build and scale your apps. It has an outstanding developer experience and has a free tier for small projects, and is well-suited for deploying and scaling Vendure applications.
+
+This guide will walk you through the steps to deploy [a sample Vendure application](https://github.com/vendure-ecommerce/one-click-deploy) to Northflank.
+
+## Set up your free Northflank account
+
+Go to the Northflank [sign up page](https://app.northflank.com/signup) to create a new account. As part of the sign-up you'll be asked for credit card details, but you won't be charged unless you upgrade to a paid plan.
+
+## Create a custom template
+
+A template defines the infrastructure that is needed to run your Vendure server. Namely, a **server**, a **worker**, and a **Postgres database**.
+
+Click the templates menu item in the left sidebar and click the "Create template" button.
+
+{{< figure src="./01-create-template-screen.webp" >}}
+
+Fill in the name of the template (though note that the name will be replaced by the name "Vendure Template" based on the configuration below).
+
+Now paste the following configuration into the "Template" code editor:
+
+{{< figure src="./02-paste-config.webp" >}}
+
+
+```json
+{
+  "name": "Vendure Template",
+  "description": "Vendure is a modern, open-source headless commerce framework built with TypeScript & Node.js.",
+  "apiVersion": "v1",
+  "project": {
+    "spec": {
+      "name": "Vendure Template",
+      "description": "Vendure is a modern, open-source headless commerce framework built with TypeScript & Node.js.",
+      "region": "europe-west",
+      "color": "#57637A"
+    }
+  },
+  "spec": {
+    "kind": "Workflow",
+    "spec": {
+      "type": "sequential",
+      "steps": [
+        {
+          "kind": "Addon",
+          "spec": {
+            "name": "database",
+            "type": "postgres",
+            "version": "latest",
+            "billing": {
+              "deploymentPlan": "nf-compute-10",
+              "storageClass": "ssd",
+              "storage": 4096,
+              "replicas": 1
+            },
+            "tlsEnabled": false,
+            "externalAccessEnabled": false
+          }
+        },
+        {
+          "kind": "SecretGroup",
+          "spec": {
+            "name": "secrets",
+            "secretType": "environment-arguments",
+            "priority": 10,
+            "secrets": {
+              "variables": {
+                "APP_ENV": "production",
+                "COOKIE_SECRET": "${fn.randomSecret(32)}",
+                "SUPERADMIN_USERNAME": "superadmin",
+                "SUPERADMIN_PASSWORD": "superadmin",
+                "DB_SCHEMA": "public"
+              }
+            },
+            "addonDependencies": [
+              {
+                "addonId": "database",
+                "keys": [
+                  {
+                    "keyName": "HOST",
+                    "aliases": ["DB_HOST"]
+                  },
+                  {
+                    "keyName": "PORT",
+                    "aliases": ["DB_PORT"]
+                  },
+                  {
+                    "keyName": "DATABASE",
+                    "aliases": ["DB_NAME"]
+                  },
+                  {
+                    "keyName": "USERNAME",
+                    "aliases": ["DB_USERNAME"]
+                  },
+                  {
+                    "keyName": "PASSWORD",
+                    "aliases": ["DB_PASSWORD"]
+                  }
+                ]
+              }
+            ]
+          }
+        },
+        {
+          "kind": "BuildService",
+          "spec": {
+            "name": "build",
+            "billing": {
+              "deploymentPlan": "nf-compute-10"
+            },
+            "vcsData": {
+              "projectUrl": "https://github.com/vendure-ecommerce/one-click-deploy",
+              "projectType": "github"
+            },
+            "buildSettings": {
+              "dockerfile": {
+                "buildEngine": "kaniko",
+                "dockerFilePath": "/Dockerfile",
+                "dockerWorkDir": "/",
+                "useCache": false
+              }
+            }
+          }
+        },
+        {
+          "kind": "Workflow",
+          "spec": {
+            "type": "parallel",
+            "steps": [
+              {
+                "kind": "DeploymentService",
+                "spec": {
+                  "name": "server",
+                  "billing": {
+                    "deploymentPlan": "nf-compute-10"
+                  },
+                  "deployment": {
+                    "instances": 1,
+                    "docker": {
+                      "configType": "customCommand",
+                      "customCommand": "yarn start:server"
+                    },
+                    "internal": {
+                      "id": "build",
+                      "branch": "master",
+                      "buildSHA": "latest"
+                    }
+                  },
+                  "ports": [
+                    {
+                      "name": "p01",
+                      "internalPort": 3000,
+                      "public": true,
+                      "protocol": "HTTP"
+                    }
+                  ]
+                }
+              },
+              {
+                "kind": "DeploymentService",
+                "spec": {
+                  "name": "worker",
+                  "billing": {
+                    "deploymentPlan": "nf-compute-10"
+                  },
+                  "deployment": {
+                    "instances": 1,
+                    "docker": {
+                      "configType": "customCommand",
+                      "customCommand": "yarn start:worker"
+                    },
+                    "internal": {
+                      "id": "build",
+                      "branch": "master",
+                      "buildSHA": "latest"
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        },
+        {
+          "kind": "Build",
+          "spec": {
+            "id": "build",
+            "type": "service",
+            "branch": "master"
+          }
+        }
+      ]
+    }
+  }
+}
+```
+
+Then click the "Create template" button.
+
+## Run the template
+
+Next, click the "run template" button to start the deployment process.
+
+{{< figure src="./03-run-template.webp" >}}
+
+Once the template run has completed, you should be able to see the newly-created project in the project selector.
+
+{{< figure src="./04-find-project.webp" >}}
+
+## Find the public URL
+
+Click the "Services" menu item in the left sidebar and then click the "Server" service.
+
+{{< figure src="./05-server-service.webp" >}}
+
+In the top right corner you'll see the public URL of your new Vendure server!
+
+Note that it may take a few minutes for the server to start up and populate all the test data because the free tier has limited CPU and memory resources.
+
+Once it is ready, you can navigate to the public URL and append `/admin` to the end of the URL to access the admin panel.
+
+{{< figure src="./06-find-url.webp" >}}
+
+
+Congratulations on deploying your Vendure server!
+
+
+## Next steps
+
+Now that you have a basic Vendure server up and running, you can explore some of the other features offered by Northflank that you might need for a full production setup:
+
+- [Set up a MinIO instance](https://northflank.com/docs/v1/application/databases-and-persistence/deploy-databases-on-northflank/deploy-minio-on-northflank) for storing assets using our [S3 asset storage integration]({{< relref "s3asset-storage-strategy" >}}#configures3assetstorage).
+- [Set up a Redis instance](https://northflank.com/docs/v1/application/databases-and-persistence/deploy-databases-on-northflank/deploy-redis-on-northflank) so that you can take advantage of our highly performant [BullMQJobQueuePlugin]({{< relref "bull-mqjob-queue-plugin" >}}) and set up [Redis-based session caching]({{< relref "session-cache-strategy" >}}) to handle multi-instance deployments.
+- With the above in place, you can safely start to [scale your server instances](https://northflank.com/docs/v1/application/scale/scaling-replicas) to handle more traffic. 
+- [Add a custom domain](https://northflank.com/docs/v1/application/domains/add-a-domain-to-your-account) using Northflank's powerful DNS management system.

+ 3 - 1
docs/content/developer-guide/importing-product-data.md

@@ -174,7 +174,7 @@ export const initialData: InitialData = {
 * `defaultZone`: Sets the default shipping & tax zone for the default Channel. The zone must correspond to a value of `zone` set in the `countries` array. 
 * `taxRates`: For each item, a new [TaxCategory]({{< relref "tax-category" >}}) is created, and then a [TaxRate]({{< relref "tax-rate" >}}) is created for each unique zone defined in the `countries` array. 
 * `shippingMethods`: Allows simple flat-rate [ShippingMethods]({{< relref "shipping-method" >}}) to be defined.
-* `collections`: Allows Collections to be created. Currently, only collections based on facet values can be created (`code: 'facet-value-filter'`). The `assetPaths` and `facetValueNames` value must correspond to a values specified in the products csv file. The name should match the value specified in the product csv file (or can be a normalized - lower-case & hyphenated - version thereof). If there are FacetValues in multiple Facets with the same name, the facet may be specified with a colon delimiter, e.g. `brand:apple`, `flavour: apple`.
+* `collections`: Allows Collections to be created. Currently, only collections based on facet values can be created (`code: 'facet-value-filter'`). The `assetPaths` and `facetValueNames` values must correspond to a value specified in the products csv file. The name should match the value specified in the product csv file (or can be a normalized - lower-case & hyphenated - version thereof). If there are FacetValues in multiple Facets with the same name, the facet may be specified with a colon delimiter, e.g. `brand:apple`, `flavour: apple`.
 
 ## Populating The Server
 
@@ -218,6 +218,8 @@ populate(
   },
 );
 ```
+**Attention:** When removing the `DefaultJobQueuePlugin` from the plugins list as in the code snippet above, one should manually rebuild the search index in order for the newly added products to appear.
+In the Admin UI this can be done by navigating to the Products page and clicking the gear icon next to the search input.
 
 ### Custom populate scripts
 

+ 2 - 2
docs/data/build.json

@@ -1,4 +1,4 @@
 {
-  "version": "1.8.5",
-  "commit": "f4f977bb2"
+  "version": "1.9.3",
+  "commit": "02513db6d"
 }

+ 1 - 1
lerna.json

@@ -2,7 +2,7 @@
   "packages": [
     "packages/*"
   ],
-  "version": "1.9.2",
+  "version": "1.9.3",
   "npmClient": "yarn",
   "useWorkspaces": true,
   "command": {

+ 3 - 3
packages/admin-ui-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/admin-ui-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "files": [
@@ -21,8 +21,8 @@
   "devDependencies": {
     "@types/express": "^4.17.8",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
     "express": "^4.17.1",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"

+ 2 - 2
packages/admin-ui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/admin-ui",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "scripts": {
     "ng": "ng",
@@ -39,7 +39,7 @@
     "@ng-select/ng-select": "^7.2.0",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
-    "@vendure/common": "^1.9.2",
+    "@vendure/common": "^1.9.3",
     "@webcomponents/custom-elements": "^1.4.3",
     "apollo-angular": "^2.6.0",
     "apollo-upload-client": "^16.0.0",

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/version.ts

@@ -1,2 +1,2 @@
 // Auto-generated by the set-version.js script.
-export const ADMIN_UI_VERSION = '1.9.2';
+export const ADMIN_UI_VERSION = '1.9.3';

+ 3 - 3
packages/asset-server-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/asset-server-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "files": [
@@ -24,8 +24,8 @@
     "@types/fs-extra": "^9.0.8",
     "@types/node-fetch": "^2.5.8",
     "@types/sharp": "^0.30.4",
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
     "aws-sdk": "^2.856.0",
     "express": "^4.17.1",
     "node-fetch": "^2.6.1",

+ 1 - 1
packages/common/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/common",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "main": "index.js",
   "license": "MIT",
   "scripts": {

+ 2 - 2
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/core",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "description": "A modern, headless ecommerce framework",
   "repository": {
     "type": "git",
@@ -49,7 +49,7 @@
     "@nestjs/testing": "7.6.17",
     "@nestjs/typeorm": "7.1.5",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^1.9.2",
+    "@vendure/common": "^1.9.3",
     "apollo-server-express": "2.24.1",
     "bcrypt": "^5.1.0",
     "body-parser": "^1.19.0",

+ 1 - 1
packages/core/src/service/services/product-variant.service.ts

@@ -741,7 +741,7 @@ export class ProductVariantService {
         if (
             !samplesEach(
                 optionIds,
-                optionGroups.map(g => g.options.map(o => o.id)),
+                activeOptions.map(g => g.options.map(o => o.id)),
             )
         ) {
             this.throwIncompatibleOptionsError(optionGroups);

+ 3 - 3
packages/create/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/create",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "bin": {
     "create": "./index.js"
@@ -28,13 +28,13 @@
     "@types/handlebars": "^4.1.0",
     "@types/listr": "^0.14.2",
     "@types/semver": "^6.2.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/core": "^1.9.3",
     "rimraf": "^3.0.2",
     "ts-node": "^10.2.1",
     "typescript": "4.3.5"
   },
   "dependencies": {
-    "@vendure/common": "^1.9.2",
+    "@vendure/common": "^1.9.3",
     "chalk": "^4.1.0",
     "commander": "^7.1.0",
     "cross-spawn": "^7.0.3",

+ 9 - 9
packages/dev-server/package.json

@@ -1,6 +1,6 @@
 {
   "name": "dev-server",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "main": "index.js",
   "license": "MIT",
   "private": true,
@@ -14,18 +14,18 @@
     "load-test:100k": "node -r ts-node/register load-testing/run-load-test.ts 100000"
   },
   "dependencies": {
-    "@vendure/admin-ui-plugin": "^1.9.2",
-    "@vendure/asset-server-plugin": "^1.9.2",
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
-    "@vendure/elasticsearch-plugin": "^1.9.2",
-    "@vendure/email-plugin": "^1.9.2",
+    "@vendure/admin-ui-plugin": "^1.9.3",
+    "@vendure/asset-server-plugin": "^1.9.3",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
+    "@vendure/elasticsearch-plugin": "^1.9.3",
+    "@vendure/email-plugin": "^1.9.3",
     "typescript": "4.3.5"
   },
   "devDependencies": {
     "@types/csv-stringify": "^3.1.0",
-    "@vendure/testing": "^1.9.2",
-    "@vendure/ui-devkit": "^1.9.2",
+    "@vendure/testing": "^1.9.3",
+    "@vendure/ui-devkit": "^1.9.3",
     "commander": "^7.1.0",
     "concurrently": "^5.0.0",
     "csv-stringify": "^5.3.3",

+ 3 - 3
packages/elasticsearch-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/elasticsearch-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -25,8 +25,8 @@
     "fast-deep-equal": "^3.1.3"
   },
   "devDependencies": {
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
   }

+ 3 - 3
packages/email-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/email-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -35,8 +35,8 @@
     "@types/fs-extra": "^9.0.1",
     "@types/handlebars": "^4.1.0",
     "@types/mjml": "^4.0.4",
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
   }

+ 3 - 3
packages/harden-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/harden-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -21,7 +21,7 @@
     "graphql-query-complexity": "^0.12.0"
   },
   "devDependencies": {
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2"
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3"
   }
 }

+ 3 - 3
packages/job-queue-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/job-queue-plugin",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "license": "MIT",
   "main": "package/index.js",
   "types": "package/index.d.ts",
@@ -24,8 +24,8 @@
   "devDependencies": {
     "@google-cloud/pubsub": "^2.8.0",
     "@types/ioredis": "^4.28.10",
-    "@vendure/common": "^1.9.2",
-    "@vendure/core": "^1.9.2",
+    "@vendure/common": "^1.9.3",
+    "@vendure/core": "^1.9.3",
     "bullmq": "^1.86.7",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"

+ 4 - 4
packages/payments-plugin/package.json

@@ -1,6 +1,6 @@
 {
     "name": "@vendure/payments-plugin",
-    "version": "1.9.2",
+    "version": "1.9.3",
     "license": "MIT",
     "main": "package/index.js",
     "types": "package/index.d.ts",
@@ -29,9 +29,9 @@
     "devDependencies": {
         "@mollie/api-client": "^3.6.0",
         "@types/braintree": "^2.22.15",
-        "@vendure/common": "^1.9.2",
-        "@vendure/core": "^1.9.2",
-        "@vendure/testing": "^1.9.2",
+        "@vendure/common": "^1.9.3",
+        "@vendure/core": "^1.9.3",
+        "@vendure/testing": "^1.9.3",
         "braintree": "^3.0.0",
         "nock": "^13.1.4",
         "rimraf": "^3.0.2",

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

@@ -101,7 +101,7 @@ import { BraintreePluginOptions } from './types';
  *       // Braintree account.
  *       paypal: {
  *         flow: 'checkout',
- *         amount: order.totalWithTax,
+ *         amount: order.totalWithTax / 100,
  *         currency: 'GBP',
  *       },
  *     }),

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

@@ -3,6 +3,7 @@ import { Args, Query, Resolver } from '@nestjs/graphql';
 import {
     ActiveOrderService,
     Ctx,
+    Customer,
     ID,
     InternalServerError,
     Logger,
@@ -48,10 +49,30 @@ export class BraintreeResolver {
             const args = await this.getPaymentMethodArgs(ctx);
             const gateway = getGateway(args, this.options);
             try {
-                const result = await gateway.clientToken.generate({
+                let result = await gateway.clientToken.generate({
                     customerId: includeCustomerId === false ? undefined : customerId,
                 });
-                return result.clientToken;
+                if (result.success === true) {
+                    return result.clientToken;
+                } else {
+                    if (result.message === 'Customer specified by customer_id does not exist') {
+                        // For some reason the custom_id is invalid. This could occur e.g. if the ID was created on the Sandbox endpoint and now
+                        // we switched to Production. In this case, we will remove it and allow a new one
+                        // to be generated when the payment is created.
+                        if (this.options.storeCustomersInBraintree) {
+                            order.customer.customFields.braintreeCustomerId = undefined;
+                            await this.connection.getRepository(ctx, Customer).save(order.customer);
+                        }
+                        result = await gateway.clientToken.generate({ customerId: undefined });
+                        if (result.success === true) {
+                            return result.clientToken;
+                        }
+                    }
+                    Logger.error(`Could not generate Braintree clientToken: ${result.message}`, loggerCtx);
+                    throw new InternalServerError(
+                        `Could not generate Braintree clientToken: ${result.message}`,
+                    );
+                }
             } catch (e) {
                 Logger.error(
                     `Could not generate Braintree clientToken. Check the configured credentials.`,

+ 3 - 3
packages/testing/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/testing",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "description": "End-to-end testing tools for Vendure projects",
   "keywords": [
     "vendure",
@@ -34,7 +34,7 @@
   },
   "dependencies": {
     "@types/node-fetch": "^2.5.4",
-    "@vendure/common": "^1.9.2",
+    "@vendure/common": "^1.9.3",
     "faker": "^4.1.0",
     "form-data": "^3.0.0",
     "graphql": "15.5.1",
@@ -45,7 +45,7 @@
   "devDependencies": {
     "@types/mysql": "^2.15.15",
     "@types/pg": "^7.14.5",
-    "@vendure/core": "^1.9.2",
+    "@vendure/core": "^1.9.3",
     "mysql": "^2.18.1",
     "pg": "^8.4.0",
     "rimraf": "^3.0.0",

+ 4 - 4
packages/ui-devkit/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/ui-devkit",
-  "version": "1.9.2",
+  "version": "1.9.3",
   "description": "A library for authoring Vendure Admin UI extensions",
   "keywords": [
     "vendure",
@@ -40,8 +40,8 @@
     "@angular/cli": "12.2.16",
     "@angular/compiler": "12.2.16",
     "@angular/compiler-cli": "12.2.16",
-    "@vendure/admin-ui": "^1.9.2",
-    "@vendure/common": "^1.9.2",
+    "@vendure/admin-ui": "^1.9.3",
+    "@vendure/common": "^1.9.3",
     "chalk": "^4.1.0",
     "chokidar": "^3.5.1",
     "fs-extra": "^10.0.0",
@@ -52,7 +52,7 @@
     "@rollup/plugin-node-resolve": "^11.2.0",
     "@types/fs-extra": "^9.0.8",
     "@types/glob": "^7.1.3",
-    "@vendure/core": "^1.9.2",
+    "@vendure/core": "^1.9.3",
     "rimraf": "^3.0.2",
     "rollup": "^2.40.0",
     "rollup-plugin-terser": "^7.0.2",