Table 1060 Payment Service Setup, source in 29

Source29

src/Layers/W1/BaseApp/Bank/Setup/PaymentServiceSetup.Table.al662 lines, Copyright (c) Microsoft Corporation. MIT

// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Bank.Setup;

using Microsoft.Bank.BankAccount;
using Microsoft.Sales.Document;
using Microsoft.Sales.History;
using System.IO;
using System.Reflection;

/// <summary>
/// Configures external payment service providers for online payment processing.
/// Manages integration settings for services like PayPal, Microsoft Wallet, and WorldPay.
/// </summary>
/// <remarks>
/// Supports multiple payment providers with individual configuration and enable/disable control.
/// Integrates with sales documents to offer payment options to customers.
/// Extensible through OnCanChangePaymentService and related integration events.
/// </remarks>
table 1060 "Payment Service Setup"
{
    Caption = 'Payment Service Setup';
    Permissions = TableData "Sales Invoice Header" = rimd,
                  TableData "Payment Reporting Argument" = rimd;
    DataClassification = CustomerContent;

    fields
    {
        /// <summary>
        /// Unique identifier for the payment service configuration.
        /// </summary>
        field(1; "No."; Text[250])
        {
            Caption = 'No.';
        }
        /// <summary>
        /// Display name of the payment service provider.
        /// Shown to users in payment selection interfaces.
        /// </summary>
        field(2; Name; Text[250])
        {
            Caption = 'Name';
            ToolTip = 'Specifies the name of the payment service.';
            NotBlank = true;
        }
        /// <summary>
        /// Detailed description of the payment service and its capabilities.
        /// Provides additional information about the payment provider to users.
        /// </summary>
        field(3; Description; Text[250])
        {
            Caption = 'Description';
            ToolTip = 'Specifies the description of the payment service.';
            NotBlank = true;
        }
        /// <summary>
        /// Controls whether this payment service is active and available for use.
        /// When disabled, the service will not appear in payment options.
        /// </summary>
        field(4; Enabled; Boolean)
        {
            Caption = 'Enabled';
            ToolTip = 'Specifies that the payment service is enabled.';
        }
        /// <summary>
        /// Determines if this payment service should be included on all sales documents by default.
        /// When enabled, automatically adds this service to new and existing invoices.
        /// </summary>
        field(5; "Always Include on Documents"; Boolean)
        {
            Caption = 'Always Include on Documents';
            ToolTip = 'Specifies that the payment service is always available in the Payment Service field on outgoing sales documents.';

            trigger OnValidate()
            var
                SalesHeader: Record "Sales Header";
            begin
                if Confirm(UpdateExistingInvoicesQst) then begin
                    SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Invoice);
                    if SalesHeader.FindSet(true) then
                        repeat
                            SalesHeader.SetDefaultPaymentServices();
                            SalesHeader.Modify();
                        until SalesHeader.Next() = 0;
                end;
            end;
        }
        /// <summary>
        /// Record ID pointing to the specific setup record for this payment service.
        /// Links to provider-specific configuration tables.
        /// </summary>
        field(6; "Setup Record ID"; RecordID)
        {
            Caption = 'Setup Record ID';
            DataClassification = CustomerContent;
        }
        /// <summary>
        /// Page ID for the payment service setup configuration page.
        /// Allows users to access provider-specific setup options.
        /// </summary>
        field(7; "Setup Page ID"; Integer)
        {
            Caption = 'Setup Page ID';
        }
        /// <summary>
        /// URL link to the payment service provider's terms of service.
        /// Provides legal and usage information for the payment service.
        /// </summary>
        field(8; "Terms of Service"; Text[250])
        {
            Caption = 'Terms of Service';
            ToolTip = 'Specifies a link to the Terms of Service page for the payment service.';
            Editable = false;
            ExtendedDatatype = URL;
        }
        /// <summary>
        /// Indicates whether the payment service is currently available for use.
        /// May be controlled by system conditions or external service status.
        /// </summary>
        field(100; Available; Boolean)
        {
            Caption = 'Available';
            ToolTip = 'Specifies that the icon and link to the payment service will be inserted on the outgoing sales document.';
        }
        /// <summary>
        /// Codeunit ID that handles the business logic for this payment service.
        /// Contains provider-specific implementation for payment processing.
        /// </summary>
        field(101; "Management Codeunit ID"; Integer)
        {
            Caption = 'Management Codeunit ID';
        }
    }

    keys
    {
        key(Key1; "No.")
        {
            Clustered = true;
        }
    }

    fieldgroups
    {
    }

    trigger OnDelete()
    begin
        DeletePaymentServiceSetup(true);
    end;

    var
        NoPaymentMethodsSelectedTxt: Label 'No payment service is made available.';
        SetupPaymentServicesQst: Label 'No payment services have been set up.\\Do you want to set up a payment service?';
        SetupExistingServicesOrCreateNewQst: Label 'One or more payment services are set up, but none are enabled.\\Do you want to:';
        CreateOrUpdateOptionQst: Label 'Set Up a Payment Service,Create a New Payment Service';
        UpdateExistingInvoicesQst: Label 'Do you want to update the ongoing Sales Invoices with this Payment Service information?';
        ReminderToSendAgainMsg: Label 'The payment service was successfully changed.\\The invoice recipient will see the change when you send, or resend, the invoice.';

    /// <summary>
    /// Opens the setup card page for this payment service configuration.
    /// Allows users to modify provider-specific settings and parameters.
    /// </summary>
    procedure OpenSetupCard()
    var
        DataTypeManagement: Codeunit "Data Type Management";
        SetupRecordRef: RecordRef;
        SetupRecordVariant: Variant;
    begin
        if not DataTypeManagement.GetRecordRef("Setup Record ID", SetupRecordRef) then
            exit;

        SetupRecordVariant := SetupRecordRef;
        PAGE.RunModal("Setup Page ID", SetupRecordVariant);
    end;

    /// <summary>
    /// Creates payment reporting arguments for a specific document and its associated payment services.
    /// Generates the data needed for payment provider integration and customer communication.
    /// </summary>
    /// <param name="PaymentReportingArgument">Temporary table to populate with payment service arguments</param>
    /// <param name="DocumentRecordVariant">Source document record (typically Sales Header or Invoice)</param>
    procedure CreateReportingArgs(var PaymentReportingArgument: Record "Payment Reporting Argument"; DocumentRecordVariant: Variant)
    var
        DummySalesHeader: Record "Sales Header";
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
        DataTypeMgt: Codeunit "Data Type Management";
        DocumentRecordRef: RecordRef;
        PaymentServiceFieldRef: FieldRef;
        SetID: Integer;
        LastKey: Integer;
    begin
        PaymentReportingArgument.Reset();
        PaymentReportingArgument.DeleteAll();

        DataTypeMgt.GetRecordRef(DocumentRecordVariant, DocumentRecordRef);
        DataTypeMgt.FindFieldByName(DocumentRecordRef, PaymentServiceFieldRef, DummySalesHeader.FieldName("Payment Service Set ID"));

        SetID := PaymentServiceFieldRef.Value();

        GetEnabledPaymentServices(TempPaymentServiceSetup);
        LoadSet(TempPaymentServiceSetup, SetID);
        TempPaymentServiceSetup.SetRange(Available, true);

        if not TempPaymentServiceSetup.FindFirst() then
            exit;

        repeat
            LastKey := PaymentReportingArgument.Key;
            Clear(PaymentReportingArgument);
            PaymentReportingArgument.Key := LastKey + 1;
            PaymentReportingArgument.Validate("Document Record ID", DocumentRecordRef.RecordId);
            PaymentReportingArgument.Validate("Setup Record ID", TempPaymentServiceSetup."Setup Record ID");
            PaymentReportingArgument.Insert(true);
            CODEUNIT.Run(TempPaymentServiceSetup."Management Codeunit ID", PaymentReportingArgument);
        until TempPaymentServiceSetup.Next() = 0;
    end;

    /// <summary>
    /// Retrieves payment services configured to be always included on documents.
    /// Returns a set ID for enabled payment services that are set to be included by default.
    /// </summary>
    /// <param name="SetID">Output parameter containing the set ID for default payment services</param>
    /// <returns>True if default payment services were found, false otherwise</returns>
    procedure GetDefaultPaymentServices(var SetID: Integer): Boolean
    var
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
        TempRecordSetBuffer: Record "Record Set Buffer" temporary;
        RecordSetManagement: Codeunit "Record Set Management";
    begin
        OnRegisterPaymentServices(TempPaymentServiceSetup);
        TempPaymentServiceSetup.SetRange("Always Include on Documents", true);
        TempPaymentServiceSetup.SetRange(Enabled, true);

        if not TempPaymentServiceSetup.FindFirst() then
            exit(false);

        TransferToRecordSetBuffer(TempPaymentServiceSetup, TempRecordSetBuffer);
        RecordSetManagement.GetSet(TempRecordSetBuffer, SetID);
        if SetID = 0 then
            SetID := RecordSetManagement.SaveSet(TempRecordSetBuffer);

        exit(true);
    end;

    /// <summary>
    /// Presents payment service selection dialog to user and returns the selected set ID.
    /// Handles the complete workflow for selecting payment services including setup prompts.
    /// </summary>
    /// <param name="SetID">Input/output parameter for the payment service set ID</param>
    /// <returns>True if user selected payment services, false if cancelled</returns>
    procedure SelectPaymentService(var SetID: Integer): Boolean
    var
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
    begin
        if not GetEnabledPaymentServices(TempPaymentServiceSetup) then begin
            if not AskUserToSetupNewPaymentService(TempPaymentServiceSetup) then
                exit(false);

            // If user has setup the service then just select that one
            if TempPaymentServiceSetup.Count = 1 then begin
                TempPaymentServiceSetup.FindFirst();
                SetID := SaveSet(TempPaymentServiceSetup);
                exit(true);
            end;
        end;

        if SetID <> 0 then
            LoadSet(TempPaymentServiceSetup, SetID);

        TempPaymentServiceSetup.Reset();
        TempPaymentServiceSetup.SetRange(Enabled, true);

        if not (PAGE.RunModal(PAGE::"Select Payment Service", TempPaymentServiceSetup) = ACTION::LookupOK) then
            exit(false);

        TempPaymentServiceSetup.SetRange(Available, true);
        if TempPaymentServiceSetup.FindFirst() then
            SetID := SaveSet(TempPaymentServiceSetup)
        else
            Clear(SetID);

        exit(true);
    end;

    local procedure GetEnabledPaymentServices(var TempPaymentServiceSetup: Record "Payment Service Setup" temporary): Boolean
    begin
        TempPaymentServiceSetup.Reset();
        TempPaymentServiceSetup.DeleteAll();
        OnRegisterPaymentServices(TempPaymentServiceSetup);
        TempPaymentServiceSetup.SetRange(Enabled, true);
        exit(TempPaymentServiceSetup.FindSet());
    end;

    local procedure TransferToRecordSetBuffer(var TempPaymentServiceSetup: Record "Payment Service Setup" temporary; var TempRecordSetBuffer: Record "Record Set Buffer" temporary)
    var
        CurrentKey: Integer;
    begin
        TempPaymentServiceSetup.FindFirst();

        repeat
            CurrentKey := TempRecordSetBuffer.No;
            Clear(TempRecordSetBuffer);
            TempRecordSetBuffer.No := CurrentKey + 1;
            TempRecordSetBuffer."Value RecordID" := TempPaymentServiceSetup."Setup Record ID";
            TempRecordSetBuffer.Insert();
        until TempPaymentServiceSetup.Next() = 0;
    end;

    /// <summary>
    /// Saves a temporary payment service setup collection as a persistent set.
    /// Converts temporary payment service records into a record set that can be referenced by ID.
    /// </summary>
    /// <param name="TempPaymentServiceSetup">Temporary payment service setup records to save as a set</param>
    /// <returns>Set ID for the saved payment service collection</returns>
    procedure SaveSet(var TempPaymentServiceSetup: Record "Payment Service Setup" temporary): Integer
    var
        TempRecordSetBuffer: Record "Record Set Buffer" temporary;
        RecordSetManagement: Codeunit "Record Set Management";
    begin
        TransferToRecordSetBuffer(TempPaymentServiceSetup, TempRecordSetBuffer);
        exit(RecordSetManagement.SaveSet(TempRecordSetBuffer));
    end;

    /// <summary>
    /// Loads a payment service set into temporary records based on the provided set ID.
    /// Marks payment services as available based on their inclusion in the specified set.
    /// </summary>
    /// <param name="TempPaymentServiceSetup">Temporary payment service setup records to load into</param>
    /// <param name="SetID">Set ID identifying which payment services to load</param>
    procedure LoadSet(var TempPaymentServiceSetup: Record "Payment Service Setup" temporary; SetID: Integer)
    var
        TempRecordSetBuffer: Record "Record Set Buffer" temporary;
        RecordSetManagement: Codeunit "Record Set Management";
    begin
        if not TempPaymentServiceSetup.FindFirst() then
            exit;

        RecordSetManagement.GetSet(TempRecordSetBuffer, SetID);

        if not TempRecordSetBuffer.FindFirst() then begin
            TempPaymentServiceSetup.ModifyAll(Available, false);
            exit;
        end;

        repeat
            TempRecordSetBuffer.SetRange("Value RecordID", TempPaymentServiceSetup."Setup Record ID");
            if TempRecordSetBuffer.FindFirst() then begin
                TempPaymentServiceSetup.Available := true;
                TempPaymentServiceSetup.Modify();
            end;
        until TempPaymentServiceSetup.Next() = 0;
    end;

    /// <summary>
    /// Returns a comma-separated text string of selected payment service names.
    /// Provides user-friendly display of payment services included in a set.
    /// </summary>
    /// <param name="SetID">Set ID identifying which payment services to include in text</param>
    /// <returns>Comma-separated list of payment service names, or 'No payment service is made available' if none selected</returns>
    procedure GetSelectedPaymentsText(SetID: Integer) SelectedPaymentServices: Text
    var
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
    begin
        SelectedPaymentServices := NoPaymentMethodsSelectedTxt;

        if SetID = 0 then
            exit;

        OnRegisterPaymentServices(TempPaymentServiceSetup);
        LoadSet(TempPaymentServiceSetup, SetID);

        TempPaymentServiceSetup.SetRange(Available, true);
        if not TempPaymentServiceSetup.FindSet() then
            exit;

        Clear(SelectedPaymentServices);
        repeat
            SelectedPaymentServices += StrSubstNo(',%1', TempPaymentServiceSetup.Name);
        until TempPaymentServiceSetup.Next() = 0;

        SelectedPaymentServices := CopyStr(SelectedPaymentServices, 2);
    end;

    /// <summary>
    /// Determines if payment service configuration can be changed for a given document.
    /// Validates document status and payment method compatibility for payment service modifications.
    /// </summary>
    /// <param name="DocumentVariant">Document record to check for payment service change eligibility</param>
    /// <returns>True if payment service can be changed, false if document is closed or incompatible</returns>
    procedure CanChangePaymentService(DocumentVariant: Variant) Result: Boolean
    var
        SalesInvoiceHeader: Record "Sales Invoice Header";
        DataTypeManagement: Codeunit "Data Type Management";
        DocumentRecordRef: RecordRef;
        PaymentMethodCodeFieldRef: FieldRef;
        IsHandled: Boolean;
    begin
        DataTypeManagement.GetRecordRef(DocumentVariant, DocumentRecordRef);
        IsHandled := false;
        OnCanChangePaymentServiceOnAfterGetRecordRef(DocumentVariant, DocumentRecordRef, Result, IsHandled);
        if IsHandled then
            exit(Result);
        case DocumentRecordRef.Number of
            Database::"Sales Invoice Header":
                begin
                    SalesInvoiceHeader.Copy(DocumentVariant);
                    SalesInvoiceHeader.CalcFields(Closed, "Remaining Amount");
                    if SalesInvoiceHeader.Closed or (SalesInvoiceHeader."Remaining Amount" = 0) then
                        exit(false);
                end
            else
                if DataTypeManagement.FindFieldByName(
                        DocumentRecordRef, PaymentMethodCodeFieldRef, SalesInvoiceHeader.FieldName("Payment Method Code"))
                then
                    if not CanUsePaymentMethod(Format(PaymentMethodCodeFieldRef.Value)) then
                        exit(false);
        end;

        exit(true);
    end;

    local procedure CanUsePaymentMethod(PaymentMethodCode: Code[10]) Result: Boolean
    var
        PaymentMethod: Record "Payment Method";
        IsHandled: Boolean;
    begin
        IsHandled := false;
        OnBeforeCanUsePaymentMethod(PaymentMethodCode, Result, IsHandled);
        if IsHandled then
            exit;

        if not PaymentMethod.Get(PaymentMethodCode) then
            exit(true);

        exit(PaymentMethod."Bal. Account No." = '');
    end;

    /// <summary>
    /// Enables changing payment service configuration for a posted sales invoice.
    /// Updates the payment service set ID on the posted invoice and provides user feedback.
    /// </summary>
    /// <param name="SalesInvoiceHeader">Posted sales invoice header to update with new payment service</param>
    procedure ChangePaymentServicePostedInvoice(var SalesInvoiceHeader: Record "Sales Invoice Header")
    var
        PaymentServiceSetup: Record "Payment Service Setup";
        SetID: Integer;
    begin
        SetID := SalesInvoiceHeader."Payment Service Set ID";
        if PaymentServiceSetup.SelectPaymentService(SetID) then begin
            SalesInvoiceHeader.Validate("Payment Service Set ID", SetID);
            SalesInvoiceHeader.Modify(true);
            if GuiAllowed and (Format(SalesInvoiceHeader."Payment Service Set ID") <> '') then
                Message(ReminderToSendAgainMsg);
        end;
    end;

    local procedure AskUserToSetupNewPaymentService(var TempPaymentServiceSetup: Record "Payment Service Setup" temporary): Boolean
    var
        TempNotEnabledPaymentServiceSetupProviders: Record "Payment Service Setup" temporary;
        TempPaymentServiceSetupProviders: Record "Payment Service Setup" temporary;
        SetupOrCreatePaymentService: Option ,"Setup Payment Services","Create New";
        SelectedOption: Integer;
        DefinedPaymentServiceExist: Boolean;
    begin
        if not GuiAllowed then
            exit(false);

        OnRegisterPaymentServiceProviders(TempPaymentServiceSetupProviders);
        if not TempPaymentServiceSetupProviders.FindFirst() then
            exit(false);

        // Check if there are payment services that are not enabled
        OnRegisterPaymentServices(TempNotEnabledPaymentServiceSetupProviders);
        DefinedPaymentServiceExist := TempNotEnabledPaymentServiceSetupProviders.FindFirst();

        if DefinedPaymentServiceExist then begin
            SelectedOption := StrMenu(CreateOrUpdateOptionQst, 1, SetupExistingServicesOrCreateNewQst);
            case SelectedOption of
                SetupOrCreatePaymentService::"Setup Payment Services":
                    PAGE.RunModal(PAGE::"Payment Services");
                SetupOrCreatePaymentService::"Create New":
                    NewPaymentService();
                else
                    exit(false);
            end;
            exit(GetEnabledPaymentServices(TempPaymentServiceSetup));
        end;

        // Ask to create a new service
        if Confirm(SetupPaymentServicesQst) then begin
            NewPaymentService();
            exit(GetEnabledPaymentServices(TempPaymentServiceSetup));
        end;

        exit(false);
    end;

    /// <summary>
    /// Checks if payment services are available for display in user interfaces.
    /// Determines visibility of payment service functionality based on registered providers.
    /// </summary>
    /// <returns>True if payment service providers are registered and should be visible, false otherwise</returns>
    procedure IsPaymentServiceVisible(): Boolean
    var
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
    begin
        OnRegisterPaymentServiceProviders(TempPaymentServiceSetup);
        exit(not TempPaymentServiceSetup.IsEmpty);
    end;

    /// <summary>
    /// Initiates creation of a new payment service through the setup workflow.
    /// Handles provider selection and setup dialog presentation to the user.
    /// </summary>
    /// <returns>True if payment service was successfully created, false if cancelled or failed</returns>
    procedure NewPaymentService(): Boolean
    var
        TempPaymentServiceSetup: Record "Payment Service Setup" temporary;
        TempPaymentServiceSetupProviders: Record "Payment Service Setup" temporary;
    begin
        OnRegisterPaymentServiceProviders(TempPaymentServiceSetupProviders);
        case TempPaymentServiceSetupProviders.Count of
            0:
                exit(false);
            1:
                begin
                    TempPaymentServiceSetupProviders.FindFirst();
                    OnCreatePaymentService(TempPaymentServiceSetupProviders);
                    exit(true);
                end;
            else begin
                Commit();
                if PAGE.RunModal(PAGE::"Select Payment Service Type", TempPaymentServiceSetup) = ACTION::LookupOK then begin
                    OnCreatePaymentService(TempPaymentServiceSetup);
                    exit(true);
                end;
                exit(false);
            end;
        end;
    end;

    /// <summary>
    /// Assigns the primary key for a payment service setup record based on its setup record ID.
    /// Ensures unique identification of payment service configurations.
    /// </summary>
    /// <param name="PaymentServiceSetup">Payment service setup record to assign primary key to</param>
    procedure AssignPrimaryKey(var PaymentServiceSetup: Record "Payment Service Setup")
    begin
        PaymentServiceSetup."No." := Format(PaymentServiceSetup."Setup Record ID");
    end;

    /// <summary>
    /// Deletes the underlying payment service setup record referenced by the Setup Record ID.
    /// Performs cleanup of related configuration data when removing payment services.
    /// </summary>
    /// <param name="RunTrigger">Whether to execute delete triggers on the referenced setup record</param>
    procedure DeletePaymentServiceSetup(RunTrigger: Boolean)
    var
        DataTypeManagement: Codeunit "Data Type Management";
        SetupRecordRef: RecordRef;
    begin
        DataTypeManagement.GetRecordRef("Setup Record ID", SetupRecordRef);
        SetupRecordRef.Delete(RunTrigger);
    end;

    /// <summary>
    /// Opens the Terms of Service URL in the default browser or application.
    /// Enables users to review payment service provider terms and conditions.
    /// </summary>
    procedure TermsOfServiceDrillDown()
    begin
        if "Terms of Service" <> '' then
            HyperLink("Terms of Service");
    end;

    /// <summary>
    /// Integration event for registering available payment services in the system.
    /// Enables extensions to add custom payment service configurations.
    /// </summary>
    /// <param name="PaymentServiceSetup">Temporary record for collecting payment service registrations</param>
    /// <remarks>
    /// Raised during payment service discovery to allow extensions to register their services.
    /// </remarks>
    [IntegrationEvent(false, false)]
    procedure OnRegisterPaymentServices(var PaymentServiceSetup: Record "Payment Service Setup")
    begin
    end;

    /// <summary>
    /// Integration event for registering payment service providers and their capabilities.
    /// Allows extensions to define new payment provider types and configurations.
    /// </summary>
    /// <param name="PaymentServiceSetup">Record for provider registration and setup</param>
    /// <remarks>
    /// Raised when building the list of available payment service providers.
    /// </remarks>
    [IntegrationEvent(false, false)]
    procedure OnRegisterPaymentServiceProviders(var PaymentServiceSetup: Record "Payment Service Setup")
    begin
    end;

    /// <summary>
    /// Integration event raised before checking if a payment method can be used.
    /// Enables custom validation logic for payment method availability.
    /// </summary>
    /// <param name="PaymentMethodCode">Payment method code being validated</param>
    /// <param name="Result">Whether the payment method can be used (can be modified by subscribers)</param>
    /// <param name="IsHandled">Set to true to skip standard validation logic</param>
    /// <remarks>
    /// Raised from CanUsePaymentMethod function before standard payment method validation.
    /// </remarks>
    [IntegrationEvent(false, false)]
    local procedure OnBeforeCanUsePaymentMethod(PaymentMethodCode: Code[10]; var Result: Boolean; var IsHandled: Boolean)
    begin
    end;

    /// <summary>
    /// Integration event for custom payment service creation logic.
    /// Allows extensions to perform additional setup when creating payment services.
    /// </summary>
    /// <param name="PaymentServiceSetup">Payment service setup record being created</param>
    /// <remarks>
    /// Raised when a new payment service is being created through the setup process.
    /// </remarks>
    [IntegrationEvent(false, false)]
    procedure OnCreatePaymentService(var PaymentServiceSetup: Record "Payment Service Setup")
    begin
    end;

    /// <summary>
    /// Integration event raised when removing payment services from all documents.
    /// Enables custom cleanup logic when disabling payment service integration.
    /// </summary>
    /// <remarks>
    /// Raised when globally disabling payment service inclusion on documents.
    /// </remarks>
    [IntegrationEvent(false, false)]
    procedure OnDoNotIncludeAnyPaymentServicesOnAllDocuments()
    begin
    end;

    /// <summary>
    /// Integration event raised after determining document context for payment service changes.
    /// Enables custom validation logic for payment service modification permissions.
    /// </summary>
    /// <param name="DocumentVariant">Document record being evaluated</param>
    /// <param name="DocumentRecordRef">Record reference for the document</param>
    /// <param name="Result">Whether payment service can be changed (can be modified by subscribers)</param>
    /// <param name="IsHandled">Set to true to skip standard validation logic</param>
    /// <remarks>
    /// Raised from CanChangePaymentService function after getting document record reference.
    /// </remarks>
    [IntegrationEvent(false, false)]
    local procedure OnCanChangePaymentServiceOnAfterGetRecordRef(DocumentVariant: Variant; DocumentRecordRef: RecordRef; var Result: Boolean; var IsHandled: Boolean)
    begin
    end;
}