diff --git a/pom.xml b/pom.xml
index 29b479551de824fbe6a7499d9a4bfc550133df29..92784181694e60c0febbc95a991891569ce0f817 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2263,6 +2263,11 @@
 			<artifactId>checkout-sdk</artifactId>
 			<version>1.0.2</version>
 		</dependency>
+		<dependency>
+			<groupId>com.paypal.sdk</groupId>
+			<artifactId>rest-api-sdk</artifactId>
+			<version>1.14.0</version>
+		</dependency>
 		<!-- end Paypal -->
 
 		<!-- Start test dependencies -->
@@ -2347,7 +2352,6 @@
 			<groupId>com.google.code.gson</groupId>
 			<artifactId>gson</artifactId>
 			<version>2.8.6</version>
-			<scope>test</scope>
 		</dependency>
 		<dependency>
 			<groupId>com.google.guava</groupId>
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
index 6b417248dfa609621cc2bddf024e597949a0c88d..e57ecd8c5a0d244002a728b3c5bfffb3c24f2c28 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/PaypalCheckoutModule.java
@@ -19,11 +19,16 @@
  */
 package org.olat.resource.accesscontrol.provider.paypalcheckout;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.core.configuration.AbstractSpringModule;
+import org.olat.core.logging.Tracing;
+import org.olat.core.util.StringHelper;
 import org.olat.core.util.coordinate.CoordinatorManager;
+import org.olat.resource.accesscontrol.provider.paypalcheckout.manager.PaypalRESTWebhookProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -37,10 +42,13 @@ import org.springframework.stereotype.Service;
 @Service
 public class PaypalCheckoutModule extends AbstractSpringModule {
 	
+	private static final Logger log = Tracing.createLoggerFor(PaypalCheckoutModule.class);
+	
 	private static final String PAYPAL_CLIENT_ID = "paypal.checkout.v2.client.id";
 	private static final String PAYPAL_CLIENT_SECRET = "paypal.checkout.v2.client.secret";
 	private static final String PAYPAL_CURRENCY = "paypal.checkout.v2.currency";
 	private static final String PAYPAL_SMART_BUTTONS = "paypal.checkout.v2.smart.buttons";
+	private static final String PAYPAL_WEBHOOK_ID = "paypal.webhhok.id";
 	
 	private static final String[] currencies = new String[] {
 			"AUD",
@@ -77,6 +85,11 @@ public class PaypalCheckoutModule extends AbstractSpringModule {
 	private String paypalCurrency;
 	@Value("${paypal.checkout.v2.smart.buttons:true}")
 	private boolean smartButtons;
+	@Value("${paypal.webhhok.id:#{null}}")
+	private String webhookId;
+	
+	@Autowired
+	private PaypalRESTWebhookProvider webhookProvider;
 	
 	@Autowired
 	public PaypalCheckoutModule(CoordinatorManager coordinatorManager) {
@@ -93,7 +106,32 @@ public class PaypalCheckoutModule extends AbstractSpringModule {
 		clientId = getStringPropertyValue(PAYPAL_CLIENT_ID, clientId);
 		clientSecret = getStringPropertyValue(PAYPAL_CLIENT_SECRET, clientSecret);
 		paypalCurrency = getStringPropertyValue(PAYPAL_CURRENCY, paypalCurrency);
+		webhookId = getStringPropertyValue(PAYPAL_WEBHOOK_ID, webhookId);
 		smartButtons = "true".equals(getStringPropertyValue(PAYPAL_SMART_BUTTONS, Boolean.toString(smartButtons)));
+		
+		if(!StringHelper.containsNonWhitespace(webhookId) && StringHelper.containsNonWhitespace(clientId) && StringHelper.containsNonWhitespace(clientSecret)) {
+			updateWebhook(clientId, clientSecret);
+		}
+	}
+	
+	public void updateWebhook() {
+		updateWebhook(clientId, clientSecret);
+	}
+	
+	private void updateWebhook(String id, String secret) {
+		webhookId = webhookProvider.hasWebhook(id, secret, sandbox);
+		if(webhookId == null) {
+			List<String> eventNames = new ArrayList<>();
+			eventNames.add("PAYMENT.CAPTURE.COMPLETED");
+			eventNames.add("PAYMENT.CAPTURE.DENIED");
+			eventNames.add("PAYMENT.CAPTURE.PENDING");
+			webhookId = webhookProvider.createWebhook(id, secret, eventNames, sandbox);
+			if(StringHelper.containsNonWhitespace(webhookId)) {
+				setStringProperty(PAYPAL_WEBHOOK_ID, webhookId, true);
+			}
+		} else {
+			log.info("PayPal webhook successfully retrieved: {}", webhookId);
+		}
 	}
 
 	public String getClientId() {
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalRESTWebhookProvider.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalRESTWebhookProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..08bedbf78a2e378194ddd54015f6620faf038ed3
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/manager/PaypalRESTWebhookProvider.java
@@ -0,0 +1,105 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.resource.accesscontrol.provider.paypalcheckout.manager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+import org.olat.core.helpers.Settings;
+import org.olat.core.logging.Tracing;
+import org.springframework.stereotype.Service;
+
+import com.paypal.api.payments.EventType;
+import com.paypal.api.payments.Webhook;
+import com.paypal.api.payments.WebhookList;
+import com.paypal.base.Constants;
+import com.paypal.base.rest.APIContext;
+import com.paypal.base.rest.PayPalRESTException;
+
+/**
+ * Helper methods to manage PayPal Webhooks (deprecated but useful).
+ * 
+ * Initial date: 12 nov. 2020<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+@Service
+public class PaypalRESTWebhookProvider {
+	
+	private static final Logger log = Tracing.createLoggerFor(PaypalRESTWebhookProvider.class);
+	
+	public String hasWebhook(String clientId, String clientSecret, boolean sandbox) {
+		try {
+			String mode = sandbox ? Constants.SANDBOX : Constants.LIVE;
+			APIContext apiContext = new APIContext(clientId, clientSecret, mode);
+			
+			WebhookList webhookList = new WebhookList();
+			webhookList = webhookList.getAll(apiContext);
+			List<Webhook> webhooks = webhookList.getWebhooks();
+			
+			String webhookEndpoint = webhookEndpoint();
+			
+			for(Webhook webhook:webhooks) {
+				String url = webhook.getUrl();
+				if(url.equals(webhookEndpoint)) {
+					return webhook.getId();
+				}
+			}
+		} catch (PayPalRESTException e) {
+			log.error("", e);
+		}
+		return null;
+	}
+	
+	public String webhookEndpoint() {
+		String serverContext = Settings.getServerContextPathURI();
+		if(!serverContext.endsWith("/")) {
+			serverContext += "/";
+		}
+		return serverContext + "checkoutv2";
+	}
+	
+	public String createWebhook(String clientId, String clientSecret, List<String> eventNames, boolean sandbox) {
+		List<EventType> eventTypes = new ArrayList<>();
+		for(String eventName:eventNames) {
+			EventType eventType = new EventType();
+			eventType.setName(eventName);
+			eventTypes.add(eventType);
+		}
+		
+		String webhookEndpoint = webhookEndpoint();
+		Webhook webhook = new Webhook();
+		webhook.setUrl(webhookEndpoint);
+		webhook.setEventTypes(eventTypes);
+		
+		try{
+			String mode = sandbox ? Constants.SANDBOX : Constants.LIVE;
+			APIContext apiContext = new APIContext(clientId, clientSecret, mode);
+			Webhook createdWebhook = webhook.create(apiContext, webhook);
+			String webhookId = createdWebhook.getId();
+			log.info(Tracing.M_AUDIT, "PayPal webhook created: {}", webhookId);
+			return webhookId;
+		} catch (PayPalRESTException e) {
+			log.error("", e);
+			return null;
+		}
+	}
+}
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
index 2cf4ce25806e4eba86b724c5c04c4fd1d3b87523..d4b5a9795981ae3f50ee2db09adbd49356fd93bc 100644
--- a/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypalcheckout/ui/PaypalCheckoutAccountConfigurationController.java
@@ -169,10 +169,19 @@ public class PaypalCheckoutAccountConfigurationController extends FormBasicContr
 				paypalModule.setPaypalCurrency(currencyEl.getSelectedKey());
 			}
 			paypalModule.setSmartButtons(smartButtonsEl.isOneSelected() && smartButtonsEl.isSelected(0));
+			doUpdateWebhook();
 		} else {
 			paypalModule.setClientId(null);
 			paypalModule.setClientSecret(null);
 		}
 		showInfo("saved");
 	}
+	
+	private void doUpdateWebhook() {
+		try {
+			paypalModule.updateWebhook();
+		} catch (Exception e) {
+			logError("", e);
+		}
+	}
 }
\ No newline at end of file