diff --git a/api/v3/Contribution.php b/api/v3/Contribution.php
index 459b6849822f4592dbc67cd99fb4012a04d31264..3a72fd9f650cfb3469955f25e1d6762ece961cd6 100644
--- a/api/v3/Contribution.php
+++ b/api/v3/Contribution.php
@@ -15,6 +15,8 @@
  * @package CiviCRM_APIv3
  */
 
+use Civi\Api4\Contribution;
+
 /**
  * Add or update a Contribution.
  *
@@ -40,18 +42,14 @@ function civicrm_api3_contribution_create($params) {
   }
   $params['skipCleanMoney'] = TRUE;
 
-  if (!empty($params['check_permissions']) && CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
-    if (empty($params['id'])) {
-      $op = CRM_Core_Action::ADD;
-    }
-    else {
-      if (empty($params['financial_type_id'])) {
-        $params['financial_type_id'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $params['id'], 'financial_type_id');
-      }
-      $op = CRM_Core_Action::UPDATE;
-    }
-    CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($types, $op);
-    if (!array_key_exists($params['financial_type_id'], $types)) {
+  if (!empty($params['check_permissions'])) {
+    // Check acls on this entity. Note that we pass in financial type id, if we have it
+    // since we know this is checked by acls. In v4 we do something more generic.
+    if (!Contribution::checkAccess()
+      ->setAction(empty($params['id']) ? 'create' : 'update')
+      ->addValue('id', $params['id'] ?? NULL)
+      ->addValue('financial_type_id', $params['financial_type_id'] ?? NULL)
+      ->execute()->first()['access']) {
       throw new API_Exception('You do not have permission to create this contribution');
     }
   }
diff --git a/ext/financialacls/financialacls.php b/ext/financialacls/financialacls.php
index abad6279ec09b540b0b0806be045e6a9cb481c7d..a0d94540682fc6cc8be4eb0cfaefe70f3ca332d7 100644
--- a/ext/financialacls/financialacls.php
+++ b/ext/financialacls/financialacls.php
@@ -305,19 +305,41 @@ function _financialacls_civi_api4_authorizeContribution(\Civi\Api4\Event\Authori
   if (!financialacls_is_acl_limiting_enabled()) {
     return;
   }
-  if ($e->getActionName() === 'delete' && $e->getEntityName() === 'Contribution') {
-    $contributionID = $e->getRecord()['id'];
-    // First check contribution financial type
-    $financialType = CRM_Core_PseudoConstant::getName('CRM_Contribute_DAO_Contribution', 'financial_type_id', CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionID, 'financial_type_id'));
-    // Now check permissioned line items & permissioned contribution
-    if (!CRM_Core_Permission::check('delete contributions of type ' . $financialType, $e->getUserID()) ||
-      !CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($contributionID, 'delete', FALSE, $e->getUserID())
-    ) {
+  if ($e->getEntityName() === 'Contribution') {
+    $contributionID = $e->getRecord()['id'] ?? NULL;
+    $financialTypeID = $e->getRecord()['financial_type_id'] ?? CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionID, 'financial_type_id');
+    if (!CRM_Core_Permission::check(_financialacls_getRequiredPermission($financialTypeID, $e->getActionName()), $e->getUserID())) {
       $e->setAuthorized(FALSE);
     }
+    if ($e->getActionName() === 'delete') {
+      // First check contribution financial type
+      // Now check permissioned line items & permissioned contribution
+      if (!CRM_Financial_BAO_FinancialType::checkPermissionedLineItems($contributionID, 'delete', FALSE, $e->getUserID())
+      ) {
+        $e->setAuthorized(FALSE);
+      }
+    }
   }
 }
 
+/**
+ * Get the permission required to perform this action on this financial type.
+ *
+ * @param int $financialTypeID
+ * @param string $action
+ *
+ * @return string
+ */
+function _financialacls_getRequiredPermission(int $financialTypeID, string $action): string {
+  $financialType = CRM_Core_PseudoConstant::getName('CRM_Contribute_DAO_Contribution', 'financial_type_id', $financialTypeID);
+  $actionMap = [
+    'create' => 'add',
+    'update' => 'edit',
+    'delete' => 'delete',
+  ];
+  return $actionMap[$action] . ' contributions of type ' . $financialType;
+}
+
 /**
  * Remove unpermitted financial types from field Options in search context.
  *