diff --git a/addons/account_edi/models/account_edi_document.py b/addons/account_edi/models/account_edi_document.py
index c96d48c21955f9da16e6693c16405f3f3a865914..4c3c483ca03f661b1912efcdf40f21dd6f4c8d9c 100644
--- a/addons/account_edi/models/account_edi_document.py
+++ b/addons/account_edi/models/account_edi_document.py
@@ -145,7 +145,7 @@ class AccountEdiDocument(models.Model):
             attachments_to_unlink.unlink()
 
         def _postprocess_cancel_edi_results(documents, edi_result):
-            invoice_ids_to_cancel = set()  # Avoid duplicates
+            moves_to_cancel = self.env['account.move'] # Avoid duplicates
             attachments_to_unlink = self.env['ir.attachment']
             for document in documents:
                 move = document.move_id
@@ -159,10 +159,10 @@ class AccountEdiDocument(models.Model):
                         'blocking_level': False,
                     })
 
-                    if move.is_invoice(include_receipts=True) and move.state == 'posted':
+                    if move.state == 'posted':
                         # The user requested a cancellation of the EDI and it has been approved. Then, the invoice
                         # can be safely cancelled.
-                        invoice_ids_to_cancel.add(move.id)
+                        moves_to_cancel |= move
 
                     if not old_attachment.res_model or not old_attachment.res_id:
                         attachments_to_unlink |= old_attachment
@@ -173,10 +173,9 @@ class AccountEdiDocument(models.Model):
                         'blocking_level': move_result.get('blocking_level', DEFAULT_BLOCKING_LEVEL) if move_result.get('error') else False,
                     })
 
-            if invoice_ids_to_cancel:
-                invoices = self.env['account.move'].browse(list(invoice_ids_to_cancel))
-                invoices.button_draft()
-                invoices.button_cancel()
+            if moves_to_cancel:
+                moves_to_cancel.button_draft()
+                moves_to_cancel.button_cancel()
 
             # Attachments that are not explicitly linked to a business model could be removed because they are not
             # supposed to have any traceability from the user.
diff --git a/addons/account_edi/models/account_payment.py b/addons/account_edi/models/account_payment.py
index ce746c9170551f5f08b02449f648f1b0bebf2025..e1c2a22e67e925fb8b85662775a1fdb665e63981 100644
--- a/addons/account_edi/models/account_payment.py
+++ b/addons/account_edi/models/account_payment.py
@@ -7,9 +7,63 @@ from odoo import models, fields, api, _
 class AccountPayment(models.Model):
     _inherit = 'account.payment'
 
+    edi_show_cancel_button = fields.Boolean(
+        compute='_compute_edi_show_cancel_button')
+    edi_show_abandon_cancel_button = fields.Boolean(
+        compute='_compute_edi_show_abandon_cancel_button')
+
+    @api.depends('state', 'edi_document_ids.state')
+    def _compute_edi_show_cancel_button(self):
+        for payment in self:
+            if payment.state != 'posted':
+                payment.edi_show_cancel_button = False
+                continue
+
+            payment.edi_show_cancel_button = any([doc.edi_format_id._needs_web_services()
+                                                  and doc.state == 'sent'
+                                                  for doc in payment.edi_document_ids])
+
+    @api.depends('state', 'edi_document_ids.state')
+    def _compute_edi_show_abandon_cancel_button(self):
+        for payment in self:
+            payment.edi_show_abandon_cancel_button = any(doc.edi_format_id._needs_web_services()
+                                                         and doc.state == 'to_cancel'
+                                                         for doc in payment.edi_document_ids)
+
     def action_process_edi_web_services(self):
         return self.move_id.action_process_edi_web_services()
 
     def action_retry_edi_documents_error(self):
         self.ensure_one()
         return self.move_id.action_retry_edi_documents_error()
+
+    def button_cancel_posted_payments(self):
+        """
+        Mark the edi.document related to this payment to be canceled.
+        """
+        to_cancel_documents = self.env['account.edi.document']
+        for payment in self:
+            payment.move_id._check_fiscalyear_lock_date()
+            is_payment_marked = False
+            for doc in payment.edi_document_ids:
+                if doc.edi_format_id._needs_web_services() and doc.attachment_id and doc.state == 'sent':
+                    to_cancel_documents |= doc
+                    is_payment_marked = True
+            if is_payment_marked:
+                payment.message_post(body=_("A cancellation of the EDI has been requested."))
+        to_cancel_documents.write({'state': 'to_cancel', 'error': False, 'blocking_level': False})
+
+    def button_abandon_cancel_posted_payments(self):
+        '''Cancel the request for cancellation of the EDI.
+        '''
+        documents = self.env['account.edi.document']
+        for payment in self:
+            is_payment_marked = False
+            for doc in payment.edi_document_ids:
+                if doc.state == 'to_cancel':
+                    documents |= doc
+                    is_payment_marked = True
+            if is_payment_marked:
+                payment.message_post(body=_("A request for cancellation of the EDI has been called off."))
+
+        documents.write({'state': 'sent'})
diff --git a/addons/account_edi/views/account_payment_views.xml b/addons/account_edi/views/account_payment_views.xml
index 594a1d5cd6d9ad5d846a3675a4277d1d3d849394..fb7d811031121db28b6b7d419865438d7ab9a0b9 100644
--- a/addons/account_edi/views/account_payment_views.xml
+++ b/addons/account_edi/views/account_payment_views.xml
@@ -14,6 +14,20 @@
             <field name="model">account.payment</field>
             <field name="inherit_id" ref="account.view_account_payment_form" />
             <field name="arch" type="xml">
+                <xpath expr="//button[@name='action_cancel']" position="after">
+                    <field name="edi_show_cancel_button" invisible="1"/>
+                    <field name="edi_show_abandon_cancel_button" invisible="1"/>
+                    <button name="button_cancel_posted_payments"
+                            string="Request EDI Cancellation"
+                            type="object"
+                            groups="account.group_account_invoice"
+                            attrs="{'invisible' : [('edi_show_cancel_button', '=', False)]}"/>
+                    <button name="button_abandon_cancel_posted_payments"
+                            string="Call off EDI Cancellation"
+                            type="object"
+                            groups="account.group_account_invoice"
+                            attrs="{'invisible' : [('edi_show_abandon_cancel_button', '=', False)]}"/>
+                </xpath>
                 <xpath expr="//header" position="after">
                     <field name="edi_blocking_level" invisible="1" />
                     <field name="edi_error_count" invisible="1" />