mollie / commercetools Goto Github PK
View Code? Open in Web Editor NEWOfficial Mollie integration for CommerceTools
License: MIT License
Official Mollie integration for CommerceTools
License: MIT License
Deployment
My deployment is on:
Expected behaviour
I expected the document configuration for env variable to work:
{
"CT_MOLLIE_CONFIG": {
"mollie": {
"apiKey": "mollieApiKey"
},
"commercetools": {
"projectKey": "example_project_key",
"clientId": "example_client_id",
"clientSecret": "example_client_secret",
"authUrl": "example_auth_url",
"host": "example_host",
"scopes": "example_scopes",
"authentication": {
"isBasicAuth": true,
"username": "username",
"password": "password"
},
"enableRetry": true,
},
"service": {
"port": 3050,
"logLevel": "info",
"logTransports": "terminal"
}
}
}
Actual behaviour
Instead I had to configure it like this:
{
"mollie": {
"apiKey": "mollieApiKey"
},
"commercetools": {
"projectKey": "example_project_key",
"clientId": "example_client_id",
"clientSecret": "example_client_secret",
"authUrl": "example_auth_url",
"host": "example_host",
"scopes": "example_scopes",
"authentication": {
"isBasicAuth": true,
"username": "username",
"password": "password"
},
"enableRetry": true,
},
"service": {
"port": 3050,
"logLevel": "info",
"logTransports": "terminal"
}
}
Deployment
My deployment is on:
Expected behaviour
Running npm run zip-azure-function
generates a zip.
Actual behaviour
An error occurs
> [email protected] build C:\x\y\z\mollie\commercetools-1.0.0\extension
> node_modules/typescript/bin/tsc
'node_modules' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `node_modules/typescript/bin/tsc`
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
Attempted fixes
I fixed this by running the command from a windows subsystem for linux (WSL) terminal.
I had to install node and zip first.
Please provide more information about how this can be reproduced. Please include jsfiddle links, code snippets or any other necessary information
OS Name: Microsoft Windows 10 Enterprise (10.0.19043 Build 19043)
Node version: 14.18.3
Follow the instructions as explained here:
Advice
It would be nice if the following additional information could be added to the instructions:
Payment Method enum in mollie's node SDK does not contain mybank
or voucher
yet.
These are valid for the method
parameter on create order
This should be updated in either v3.6 or v4 (around January 2022) of the SDK. Until then, we will have a workaround in our code to allow those two extra types as well as the main PaymentMethod
.
Once the SDK is updated, we need to :
Deployment
My deployment is on:
Expected behaviour
The notification function deconstructs the request body correctly and has a payloadId which it then uses for further processing.
Actual behaviour
The request body cannot be deconstructed correctly, because the webhook sends the data in an unexpected format. Looking at the unit test implementation, the notification function expects a JSON request body.
But in reality the webhook sends the data formatted differently. See https://docs.mollie.com/overview/webhooks
Attempted fixes
-
Please provide more information about how this can be reproduced. Please include jsfiddle links, code snippets or any other necessary information
-
Deployment
My deployment is on:
Expected behaviour
I expect that following the documentation here results in something I can deploy as an Azure Function. This however is not the case. I could not manage it anyways.
Actual behaviour
A zip file is created which is missing certain files that are required for an Azure Function to run correctly.
Attempted fixes
Please provide more information about how this can be reproduced. Please include jsfiddle links, code snippets or any other necessary information
I documented all the steps I needed to get this working. See below:
Please glance over the following documentation before getting started.
https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-typescript
Create a function project by running the following command:
func init <ProjectName> --typescript
Enter the folder created by the previous command.
Add a HTTP triggered function to the project by running the following command:
func new --name <FunctionName> --template "HTTP trigger" --authlevel "function"
A new folder containing the function has been created and it contains the function.json
file. Edit this file and remove "get"
from the list of methods.
Run the function to check if everything is setup correctly at this point.
npm install && npm start
If the function works as expected we can move on to incorporate the Mollie Extension code base into the project.
Open package.json
and add the following devDependencies
:
"devDependencies": {
"npm-run-all": "^4.1.5",
"typescript": "4.5.4",
"@types/express": "4.17.13",
"@types/lodash": "4.14.178",
"@types/morgan": "1.9.3",
"@types/node": "14.18.5",
"@types/uuid": "8.3.4",
"axios": "0.24.0",
"dotenv": "16.0.0",
"prettier": "2.5.1",
"ts-node": "10.4.0"
}
Also add the following dependencies:
"dependencies": {
"@azure/functions": "3.0.0",
"@commercetools/platform-sdk": "2.1.0",
"@commercetools/sdk-client": "2.1.2",
"@commercetools/sdk-middleware-auth": "6.2.0",
"@commercetools/sdk-middleware-correlation-id": "2.1.4",
"@commercetools/sdk-middleware-http": "6.1.0",
"@commercetools/sdk-middleware-user-agent": "2.1.5",
"@mollie/api-client": "3.6.0",
"express": "4.17.2",
"lodash": "4.17.21",
"morgan": "1.10.0",
"node-fetch-commonjs": "3.1.1",
"uuid": "8.3.2",
"winston": "3.4.0"
}
Make sure name
, version
, author
, license
and description
are also set in package.json
.
Update the tsconfig.json
file. Copy the compiler options from the Mollie project. Set target
to es6
. Set outDir
to dist
.
Replace the contents of index.ts
in the function folder with the contents of azureHandler.ts
.
Copy the typings
folder to function folder.
Do the same for the config
folder.
Create a src
folder in the function folder.
Copy src/types
to the src
folder in the function folder.
Do the same for:
src/requestHandlers
src/logger
src/errorHandlers
src/client
src/authentication
src/makeActions.ts
src/utils.ts
Update <functionFolder>/src/client/initialiseCommercetoolsClient.ts
. Change import { version } from '../../package.json';
to import { version } from '../../../package.json';
Do the same in <functionFolder>/src/client/initialiseMollieClient.ts
.
Add the CT_MOLLIE_CONFIG
parameters to local.settings.json
Run npm install
to install new dependencies.
Run npm run build
and see if everything compiles correctly.
Run the function locally by running npm run start
.
Create a production build:
npm run build:production
Make sure you have an Azure function running on Windows, otherwise the app settings can't be loaded.
If working as expected it can be deployed to the remote function:
func azure functionapp publish <remote-function-app-name>
Configure the application settings for the remote function. The parameters you added to local.settings.json
also need to be added to the remote application settings.
Is this expected that those branches are out of sync?
Currently, extension module takes email address from both cart.billingAddress
and cart.shippingAddress
. I think it would be great to add fallback logic and do:
cart.billingAddress || cart.shippingAddress || cart.customerEmail || cart.customer?.email
About the third one (customerEmail) please make sure the field name is like that.
Deployment
My deployment is on:
Expected behaviour
My function deployed to Azure works.
Actual behaviour
The function does not work.
When I unzip the the extension-module-azure.zip file and look at the contents of index.js I indeed see a couple of require statements pointing to non existing files in the directory structure
Deployment
My deployment is on:
Expected behaviour
I expect the extension and notification modules to pass the configured scopes to the commercetools SDK correctly.
Actual behaviour
The extension and notification modules run into an issue which originates in the commercetools SDK.
Specifically in sdk-middleware-auth.cjs.js
.join
is an array function, so if we configure the scopes as a string in CT_MOLLIE_CONFIG, the option.scopes.join(' ')
call fails with an error which reads options.scopes.join is not a function
.
Attempted fixes
This issue is resolved if the scopes are configured as an array in CT_MOLLIE_CONFIG.
So do this:
...
},
"commercetools": {
"projectKey": "proj-key",
"clientId": "bliep",
"clientSecret": "bloep",
"authUrl": "https://auth.alice.com",
"host": "https://api.bob.com",
"scopes": ["manage_payments:proj-key", "view_customers:proj-key", "view_orders:proj-key"],
"enableRetry": true
},
...
instead of this:
...
},
"commercetools": {
"projectKey": "proj-key",
"clientId": "bliep",
"clientSecret": "bloep",
"authUrl": "https://auth.alice.com",
"host": "https://api.bob.com",
"scopes": "manage_payments:proj-key view_customers:proj-key view_orders:proj-key",
"enableRetry": true
},
...
Clarifying this in the docs should do the trick. :)
We use terraform to manage a part of our commercetools configuration. It would be a nice addition to have a piece of terraform script included in this project which has all the custom type configuration defined in it.
Developers who manage their commercetools configuration through terraform would then be able to just copy the type configuration from this project into their own terraform script.
mollie-custom-types.tf
resource "commercetools_type" "mollie-integration-payment-type" {
key = "ct-mollie-integration-payment-type"
name = {
en = "Mollie Integration payment type"
}
resource_type_ids = ["payment"]
# payment methods request field
field {
type {
name = "String"
}
name = "paymentMethodsRequest"
label = {
en = "Payment methods request"
}
required = false
input_hint = "MultiLine"
}
# payment methods response field
field {
type {
name = "String"
}
name = "paymentMethodsResponse"
label = {
en = "Payment methods response"
}
required = false
input_hint = "MultiLine"
}
# create payment field
field {
type {
name = "String"
}
name = "createPayment"
label = {
en = "Create payment"
}
required = false
input_hint = "MultiLine"
}
}
resource "commercetools_type" "mollie-integration-transaction-type" {
key = "ct-mollie-integration-transaction-type"
name = {
en = "Mollie Integration transaction type"
}
resource_type_ids = ["transaction"]
# line IDs field
field {
type {
name = "String"
}
name = "lineIds"
label = {
en = "Line IDs and Custom Line IDs"
}
required = false
input_hint = "MultiLine"
}
# include shipping field
field {
type {
name = "Boolean"
}
name = "includeShipping"
label = {
en = "Include shipping"
}
required = false
}
# description field
field {
type {
name = "String"
}
name = "description"
label = {
en = "Description"
}
required = false
input_hint = "SingleLine"
}
# metadata field
field {
type {
name = "String"
}
name = "metadata"
label = {
en = "Metadata"
}
required = false
input_hint = "MultiLine"
}
}
resource "commercetools_type" "mollie-integration-interaction-type" {
key = "ct-mollie-integration-interface-interaction-type"
name = {
en = "Mollie Integration payment interface interaction type"
}
resource_type_ids = ["payment-interface-interaction"]
# id field
field {
type {
name = "String"
}
name = "id"
label = {
en = "ID"
}
required = true
input_hint = "SingleLine"
}
# action type field
field {
type {
name = "String"
}
name = "actionType"
label = {
en = "Action type"
}
required = true
input_hint = "SingleLine"
}
# created at field
field {
type {
name = "DateTime"
}
name = "createdAt"
label = {
en = "Created at"
}
required = false
}
# request field
field {
type {
name = "String"
}
name = "request"
label = {
en = "Request"
}
required = false
input_hint = "MultiLine"
}
# response field
field {
type {
name = "String"
}
name = "response"
label = {
en = "Response"
}
required = false
input_hint = "MultiLine"
}
}
TODO:
I want to give the least amount of permissions to the extensions, which are the required permissions?
eg: manage_payments, view_orders
Deployment
My deployment is on:
Expected behaviour
When a customer unsuccessfully completes a checkout process, like a failed or cancelled payment, the cart still exists so that the customer can attempt to complete the checkout successfully again.
Cancel the order if payment was unsuccessful and use the replicate endpoint of Commercetools to create a new cart with the same items in it.
https://docs.commercetools.com/api/projects/carts#replicate-an-existing-cart-or-order-to-a-new-cart
Actual behaviour
An order is created when a user proceeds to the Mollie hosted checkout. This results in the cart's cartState
field being set to ordered
.
When the payment fails or is cancelled, the customer returns to the e-commerce platform, but the cart is "gone" from the customers perspective. They would have to add items again to a new cart to continue.
Deployment
My deployment is on:
Expected behaviour
The mollie extension creates mollie line items, one for each commercetools cart line item based on the corresponding lineItem.taxRate
. Shipping mode multiple allows us to assign multiple shipping methods to different countries to each line item resulting in different tax rates. Thus, we may have to split the single cart line item to one mollie item for each shipping with the quantity assigned via lineItem.shippingDetails.target
.
see function makeMollieLineCustom
in createOrder.ts
Actual behaviour
Right now, the system always uses the customLine.taxRate
(which may not be set)
export function makeMollieLineCustom(customLine: CTCustomLineItem, locale: string): OrderLine {
const lineItem = {
...
vatRate: (customLine.taxRate.amount * 100).toFixed(2),
...
};
...
return lineItem as OrderLine;
}
Attempted fixes
In our case, we have one shipping method per cart item with one shipping address for the whole cart. This means, we only need one mollie line item per cart line item, but the required tax rate is stored in customLine.perMethodTaxRate
and therefore we only had to change the taxRateAmount
calculation accordingly:
export function makeMollieLineCustom(customLine: CTCustomLineItem, locale: string): OrderLine {
const taxRateAmount = customLine.taxRate?.amount
?? customLine.perMethodTaxRate?.find((taxRate) => typeof taxRate !== 'undefined')?.taxRate?.amount
?? (customLine.taxedPrice.totalTax.centAmount ?? 0) / (customLine.taxedPrice.totalNet.centAmount);
const lineItem = {
...
vatRate: (taxRateAmount * 100).toFixed(2),
...
};
...
return lineItem as OrderLine;
}
There is a wrong reference to the cart ID.
Instead of:
const ctActions = await createCtActions(mollieCreatedOrder, ctPayment, cartByPayment.id);
There should be:
const ctActions = await createCtActions(mollieCreatedOrder, ctPayment, cartByPayment.body.results[0].id);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.