REDA One Centre d’aide
FR
Langue
English EN Español ES Português PT Italiano bientôt disponible Français FR Deutsch bientôt disponible العربية bientôt disponible
reda.one ↗
Accueil / REDA Financials AI / API et intégration / Extensibilité / Packages d’extension

Packages d’extension

Certaines intégrations sont des produits à part entière — des flux bancaires avec les identifiants du prestataire, la facturation électronique auprès des API gouvernementales. REDA Financials les structure en packages d’extension : le package principal définit un contrat abstrait global, l’extension l’implémente, et un enregistrement de configuration relie les deux. Deux contrats de base sont livrés aujourd’hui, ainsi que trois interfaces de capacité facultatives qu’un prestataire n’implémente que s’il en a besoin.

Fonctionnement du modèle

Les deux contrats suivent la même architecture, et les en-têtes des deux classes la décrivent dans les mêmes termes : « The core package resolves the provider at runtime via: Type.forName(setup.Provider_Class__c).newInstance() ». Aucun des deux contrats n’impose un prestataire en dur. Il y a quatre composants, chacun avec un responsable clairement identifié :

ComposantResponsableRôle
Contrat abstrait — refin.BankFeedProvider / refin.EInvoiceProviderPackage principalClasses abstraites globales (toutes deux marquées @since 2026-05-28) qui définissent les signatures des méthodes et la forme des résultats. Global = partie de la surface stable du package géré.
ImplémentationPackage d’extension (ou votre organisation)Une classe concrète qui étend le contrat ; elle contient toute la logique d’API propre au prestataire. Selon la documentation des deux classes : « Authentication and API credentials are managed entirely by the extension package. »
Enregistrement de configuration — refin__Bank_Feed_Setup__c / refin__E_Invoice_Setup__cVotre administrateurEnregistre le nom pleinement qualifié de la classe d’implémentation dans Provider_Class__c, ainsi que les paramètres d’environnement, d’activation et de périmètre.
Objet de résultat — BankFeedResult / EInvoiceResultPackage principalLa classe interne globale que renvoie chaque méthode, afin que les résultats soient enregistrés de manière uniforme, quel que soit le prestataire.
Contrats ou orchestration. Cet article documente les contrats d’extension — les deux classes globales et leurs objets de configuration, qui constituent la surface stable et publiée. La manière dont le package principal les pilote à l’exécution (tâches de synchronisation planifiées, création automatique des historiques lors de la comptabilisation des documents) dépend de la version et continue d’évoluer. Concevez et codez en vous appuyant sur les contrats ; confirmez auprès de REDA le comportement d’orchestration de la version du package principal que vous avez installée avant d’y adosser une conception opérationnelle.

refin.BankFeedProvider — relevés bancaires automatisés

  • Le contrat : trois méthodes que fournit une implémentation — connect (le processus de liaison du prestataire), sync (récupérer les transactions depuis le curseur et livrer les lignes de relevé), disconnect (révoquer l’accès). Les résultats sont renvoyés sous une forme standard (réussite, transactions importées, curseur mis à jour, solde, erreur).
  • Le câblage : un enregistrement Configuration de flux bancaire par compte connecté — nom du prestataire, environnement (Sandbox/Production), nom de la classe d’implémentation, curseur et statut de synchronisation (Actif / En pause / Erreur / Déconnecté), dernière synchronisation. Les configurations se trouvent sur la page d’enregistrement du compte bancaire.
  • Les identifiants restent dans l’extension — le package principal ne voit jamais les jetons du prestataire ; l’extension gère son authentification de bout en bout.
  • Le bénéfice : les relevés arrivent sous forme de relevés bancaires ordinaires (avec la source d’import renseignée en conséquence) et suivent le même rapprochement des lignes et le même rapprochement bancaire qu’un fichier CSV — l’automatisation en amont, un processus familier en aval.

Le contrat de flux bancaire, méthode par méthode

Chaque méthode reçoit l’enregistrement de configuration comme contexte. La documentation de la classe décrit le modèle : « Each method receives the Bank_Feed_Setup__c record as the primary context — the provider reads the linked bank account and its own credentials to execute sync logic. »

global abstract BankFeedResult sync(refin__Bank_Feed_Setup__c setup);

global abstract BankFeedResult connect(
    refin__Bank_Feed_Setup__c setup,
    Map<String, String> params
);

global abstract void disconnect(refin__Bank_Feed_Setup__c setup);
MéthodeCe que le contrat en attend (d’après la documentation de la classe)
sync« The provider fetches new transactions from the bank API (using the sync cursor from the setup record), converts them to Bank Statement Lines via the core package's internal import path, and returns the updated cursor for persistence. » La documentation précise qu’elle est « Called by the core scheduled batch job » — voir la mise en garde sur l’orchestration ci-dessus ; la partie planification dépend de la version du package principal.
connectLance le processus de liaison d’un nouveau compte bancaire. « Provider-specific: may involve OAuth redirect, token exchange, or API key validation. The params map carries provider-specific connection parameters (e.g. public_token for Plaid, link_id for Belvo). »
disconnect« Revokes access tokens, removes webhooks, and cleans up provider-side resources. The core package updates the setup record's Sync_Status to Disconnected after this method completes. »

BankFeedResult est une classe interne globale — chaque membre est @AuraEnabled global, et le constructeur initialise success à false et transactionsImported à 0 ; une implémentation doit donc mériter sa réussite :

MembreTypeSignification
successBooleanIndique si l’opération s’est terminée. Valeur par défaut : false.
transactionsImportedIntegerNombre de transactions livrées par la synchronisation. Valeur par défaut : 0.
updatedCursorStringLa nouvelle position incrémentale, renvoyée « for persistence » afin que la prochaine synchronisation reprenne là où celle-ci s’est arrêtée.
currentBalanceDecimalLe solde du compte communiqué par le prestataire au moment de la synchronisation.
errorMessageStringLe détail honnête de l’échec lorsque success vaut false.

refin__Bank_Feed_Setup__c — référence des champs

ChampContenu
Bank_Account__cLe compte bancaire REDA desservi par ce flux — une configuration par compte connecté.
Provider_Class__c (libellé « Classe du fournisseur »)Le cœur du câblage. Description textuelle : « Fully qualified Apex class name that extends refin.BankFeedProvider… Extension packages register their implementation here (e.g. plaid.PlaidBankFeedProvider). »
Provider__cSimple nom d’affichage — selon sa propre description, « The actual integration logic is determined by Provider_Class__c, not this field. »
Environment__cL’environnement du prestataire ciblé par la connexion (Sandbox / Production).
Is_Active__cIndique si le flux participe à la synchronisation.
Sync_Cursor__cLa position incrémentale du prestataire — sync la lit et renvoie la valeur mise à jour dans BankFeedResult.updatedCursor.
Sync_Status__cListe de sélection : Actif / En pause / Erreur / Déconnecté. L’aide de la valeur Erreur est explicite : « Error: last sync failed — check Audit Log for details. »
Last_Sync__cLa date de la dernière synchronisation du flux.
Provider_Account_Id__cL’identifiant, côté prestataire, du compte lié.
Comment les lignes de relevé arrivent réellement. La documentation de la classe indique que le prestataire écrit les transactions dans Bank_Statement__c / Bank_Statement_Line__c via le service d’import interne du package principal — mais ce service ne fait pas partie de la surface globale ; le mécanisme exact de livraison des relevés dont dispose une extension dépend donc de la version de votre package principal. Considérez le contrat (récupérer, livrer, renvoyer le curseur) comme fixe et confirmez le chemin de livraison avec REDA lorsque vous développez une implémentation de prestataire.

Un squelette d’implémentation

Voici la forme d’un prestataire — l’équipe de Meridian en esquisse un pour l’API directe de sa banque américaine. Seuls les éléments du contrat sont réels ; les commentaires indiquent où placer la logique de votre prestataire :

global class MeridianBankFeedProvider extends refin.BankFeedProvider {

    global override refin.BankFeedProvider.BankFeedResult connect(
            refin__Bank_Feed_Setup__c setup, Map<String, String> params) {
        refin.BankFeedProvider.BankFeedResult result =
            new refin.BankFeedProvider.BankFeedResult();
        // Échangez les paramètres de connexion (p. ex. public_token) avec le
        // prestataire. Stockez les identifiants dans VOTRE package — jamais dans les objets du package principal.
        result.success = true;
        return result;
    }

    global override refin.BankFeedProvider.BankFeedResult sync(
            refin__Bank_Feed_Setup__c setup) {
        refin.BankFeedProvider.BankFeedResult result =
            new refin.BankFeedProvider.BankFeedResult();
        // 1. Récupérez les transactions depuis setup.refin__Sync_Cursor__c
        // 2. Livrez-les sous forme de lignes de relevé bancaire
        // 3. Renvoyez le nouveau curseur pour qu’il puisse être enregistré
        result.transactionsImported = 42;
        result.updatedCursor = 'cursor-after-this-batch';
        result.success = true;
        return result;
    }

    global override void disconnect(refin__Bank_Feed_Setup__c setup) {
        // Révoquez les jetons et les webhooks côté prestataire ; le package
        // principal passe Sync_Status à Disconnected une fois cette méthode terminée.
    }
}

refin.EInvoiceProvider — facturation électronique réglementaire

  • Le contrat : submit (construire la charge utile propre à la juridiction à partir du document et appeler l’administration fiscale), checkStatus (interroger les administrations asynchrones), cancel (des règles propres à chaque juridiction s’appliquent — la note du contrat cite elle-même le délai de 24 heures au Brésil et l’acceptation par le destinataire au Mexique).
  • Le câblage : une Configuration de facturation électronique par entité/pays — prestataire, environnement, classe d’implémentation, types de documents concernés, et une option Soumission auto à la comptabilisation ; chaque tentative de soumission est enregistrée sous forme d’Historique de facturation électronique sur le document (statut, UUID et numéro fiscaux, charges utiles, réponse, nombre de tentatives) — la piste d’audit de conformité qu’attendent les autorités de contrôle.
  • Note de disponibilité : les historiques et les listes associées sont visibles dans toute l’application (vous avez déjà vu Suivis de facture électronique sur les pages des factures) ; la soumission réelle nécessite l’extension du prestataire pour votre juridiction — vérifiez auprès de REDA ce qui est disponible pour votre pays.

Le contrat de facturation électronique, méthode par méthode

MéthodeSignatureContrat
submitglobal abstract EInvoiceResult submit(refin__E_Invoice_Trail__c trail, SObject sourceDocument)Le document source est un refin__Sales_Invoice__c ou un refin__Purchase_Invoice__c ; le prestataire construit le XML/JSON propre à la juridiction et appelle l’API gouvernementale ; le package principal met à jour l’historique à partir du résultat
checkStatusglobal abstract EInvoiceResult checkStatus(refin__E_Invoice_Trail__c trail)Interrogation des administrations asynchrones qui répondent plus tard
cancelglobal abstract EInvoiceResult cancel(refin__E_Invoice_Trail__c trail)« Jurisdiction-specific rules apply (e.g. Brazil NF-e cancellation within 24h, Mexico CFDI cancellation with receiver acceptance). »

Les trois renvoient un EInvoiceResult — membres : success, status, fiscalUUID, fiscalNumber, responseCode, responseMessage, xmlPayload, responsePayload, errorMessage.

Les objets de facturation électronique — référence des champs

Champ de refin__E_Invoice_Setup__cRôle
Entity__c · Country_Code__c · Environment__c · Is_Active__cQuelle société, quelle juridiction, test ou production, activé ou non
Provider__cSimple nom d’affichage
Provider_Class__cLa classe Apex, désignée par son nom pleinement qualifié, qui étend refin.EInvoiceProvider (l’exemple du champ lui-même : sovos.SovosEInvoiceProvider)
Document_Types__cSélection multiple : Facture de vente / Avoir / Facture d’achat / Avoir fournisseur — d’après sa description : « core package checks this field when determining whether to create an E-Invoice Trail record »
Auto_Submit_On_Post__cTexte exact : « When checked, posting a Sales Invoice or Purchase Invoice automatically creates an E-Invoice Trail record in Draft status, triggering the asynchronous submission process. When unchecked, e-invoice submission must be initiated manually via a quick action or API call. »

L’enregistrement refin__E_Invoice_Trail__c est la ligne d’audit propre à chaque soumission : des champs de relation vers la configuration et la facture source, Document_Type__c, Status__c, Fiscal_UUID__c, Fiscal_Number__c, XML_Payload__c, les champs de réponse (Response_Code__c/Message__c/Payload__c/Date__c), Submitted_Date__c, Retry_Count__c et Provider_Document_Id__c — la chaîne de preuves qu’attendent les autorités de contrôle, une ligne par tentative. Status__c compte huit valeurs : Brouillon, Prêt à envoyer, En file d’attente, Soumis, Accepté, Rejeté, Annulé, Erreur.

Pourquoi des contrats plutôt que des fonctionnalités intégrées ? Les API bancaires et les administrations fiscales diffèrent d’un pays à l’autre et évoluent selon leur propre calendrier. Un contrat global stable permet aux packages spécialisés d’évoluer à leur rythme — et permet à votre organisation de changer de prestataire en modifiant un enregistrement de configuration, sans réimplémenter la gestion bancaire.

Interfaces de capacité facultatives — comment un contrat figé continue de s’enrichir

refin.EInvoiceProvider a été livré en tant que classe abstraite globale dans une version Managed-Released, ce qui signifie qu’aucune méthode ne pourra jamais y être ajoutée. Plutôt que de figer le framework avec elle, REDA ajoute les nouveaux comportements sous forme d’interfaces globales distinctes, ce que Salesforce autorise. Un prestataire étend EInvoiceProvider et implémente les interfaces de capacité qu’il prend en charge ; le package principal détecte cette prise en charge avec instanceof et ignore simplement la capacité pour les prestataires qui ne l’implémentent pas.

InterfaceMéthodesÀ implémenter lorsque
refin.EInvoiceQueueProviderdrain(setup, maxRecords) renvoyant List<EInvoiceEvent> ; acknowledge(setup, events)Votre administration fiscale répond via une file de notifications plutôt que par une réponse synchrone. Un seul drain couvre les deux sens — les mises à jour de statut sortantes et les documents fournisseurs entrants — distingués par EInvoiceEvent.processType. Il n’existe délibérément aucune méthode distincte de « récupération des entrants ».
refin.EInvoiceDocumentProviderfetchDocuments(trail) renvoyant List<EInvoiceDocument>Vous récupérez les pièces légales (XML signé, réponse de l’administration, représentation imprimable comme le DANFE au Brésil) à la demande plutôt que de les livrer directement dans l’événement. Ignorez-la si vos événements contiennent déjà documents.
refin.EInvoiceProvisionerprovisionOrganization(setup, args) ; provisionCompany(setup, args) — toutes deux renvoyant EInvoiceProvisionResultVous prenez en charge le provisionnement en libre-service des structures de compte côté administration depuis l’application. Il s’agit d’une capacité prévue pour une phase ultérieure — aujourd’hui, ces structures sont créées manuellement par le prestataire de conformité. Elle est déclarée dès maintenant précisément parce qu’une API globale publiée ne peut pas être étendue par la suite.
N’accusez réception qu’après avoir enregistré. Le package principal n’appelle acknowledge qu’une fois chaque événement stocké de façon durable — accuser réception d’abord ferait perdre définitivement la notification. Un prestataire ne doit activer aucun mode d’accusé de réception automatique qui devancerait cet appel, et drain ne doit renvoyer que les notifications non acquittées, afin que des appels répétés à drain fassent progresser le traitement.

Les trois types de données qu’elles échangent

  • refin.EInvoiceEvent — une étape de la vie d’un document auprès de l’administration. Le package principal la rattache à un historique grâce à erpDocumentId, une valeur que votre prestataire inscrit dans l’enveloppe sortante et que l’administration renvoie en écho. status est normalisé en Accepted, Rejected, Cancelled ou InProgress — le package principal fonde sa logique de nouvelle tentative et d’état final sur cette valeur, jamais sur le responseCode brut. L’événement contient aussi notificationId, processType (Outbound / Inbound), responseMessage, fiscalUUID, fiscalNumber, une liste documents facultative, payload et eventDate.
  • refin.EInvoiceDocument — une pièce : title, fileExtension ('xml' ou 'pdf'), base64Body et documentKind ('Legal', 'LegalResponse' ou 'Representation'). Le package principal la décode et la joint à l’historique et à la facture source sous forme de fichiers Salesforce, afin que les utilisateurs voient les pièces conformes sur l’enregistrement qu’ils utilisent déjà.
  • refin.EInvoiceProvisionResult — success (par défaut false), externalId (l’identifiant côté prestataire) et message.

documentKind, processType et status sont tous de type String plutôt que des énumérations — délibérément, afin que l’ensemble des valeurs autorisées puisse s’étendre sans casser une signature globale figée. N’écrivez pas de switch exhaustif sur ces valeurs ; traitez celles que vous connaissez et laissez passer les autres.

Erreurs courantes à éviter

ErreurPourquoi c’est problématiqueÀ faire plutôt
Fautes de frappe dans Provider_Class__cLa résolution à l’exécution se fait par le nom — une chaîne erronée signifie que le prestataire ne s’exécute tout simplement jamaisCopiez le nom pleinement qualifié (namespace.ClassName) depuis la documentation de l’extension ; testez la connexion immédiatement
Compter sur Provider__c pour changer de prestataireC’est un libellé d’affichage ; « The actual integration logic is determined by Provider_Class__c, not this field. »Modifiez Provider_Class__c ; mettez à jour le libellé pour les lecteurs humains
Stocker les identifiants de l’administration ou de la banque dans les enregistrements de configurationLe contrat est explicite : « Authentication and API credentials are managed entirely by the extension package »Les identifiants résident dans les informations d’identification nommées propres à l’extension, régies par la sécurité de votre organisation
Faire reposer le code de votre organisation sur les mécanismes internes d’un package de prestataireLes packages de prestataires évoluent selon leur propre calendrier — seuls les contrats globaux refin. constituent le point de jonction stableIntégrez via les enregistrements de configuration et les historiques ; traitez le prestataire comme une boîte noire
Présumer des détails d’orchestration sans tester votre versionLe comportement de planification et d’envoi automatique dépend de la versionVérifiez la planification des synchronisations et le comportement de soumission automatique dans une sandbox, sur vos versions installées, avant de les promettre aux métiers

Pour les équipes qui développent une extension

  • Implémentez la classe abstraite dans l’espace de noms de votre package ; enregistrez le nom pleinement qualifié de la classe dans l’enregistrement de configuration.
  • Maîtrisez vos identifiants (informations d’identification nommées dans votre package), votre mappage d’API, votre sémantique d’erreur — renvoyez des résultats honnêtes ; le package principal les affiche dans le Statut de synchronisation et les historiques.
  • Développez uniquement en vous appuyant sur le contrat — la surface globale documentée est la seule qui soit stable (les règles).

Pour aller plus loin

  1. Importer des relevés bancaires — le processus dans lequel arrivent les flux.
  2. Intégrations AppExchange — la vue d’ensemble de l’écosystème.
  3. Développement Apex sur REDA — les règles de la surface globale.

Questions fréquentes

Le contrat est conçu pour l’écosystème des agrégateurs (Plaid, Belvo et leurs homologues sont les archétypes qu’il cite). Demandez à REDA quelles extensions de prestataires sont disponibles pour votre région — l’offre évolue plus vite que la documentation.

Le contrat résout la classe d’implémentation par son nom ; une implémentation locale à l’organisation est donc techniquement adressable — une option judicieuse pour une API bancaire sur mesure. Packagez-la correctement si elle est appelée à servir au-delà d’une seule organisation.

Cela dépend du pays (le Brésil, le Mexique, l’Italie et l’Arabie saoudite ouvrent la voie ; beaucoup d’autres suivent). C’est à votre conseiller fiscal de répondre à la question « devons-nous le faire ? » ; la configuration et l’extension du prestataire répondent au « comment ».

BankFeedResult indique success, transactionsImported, updatedCursor (le point où reprendra la prochaine synchronisation), currentBalance et errorMessage — les valeurs par défaut sont honnêtes (success=false, aucune transaction importée), si bien qu’un prestataire négligent ne peut pas annoncer une réussite par accident. EInvoiceResult transporte la réponse de l’administration fiscale : identifiants fiscaux, charges utiles de réponse et texte de l’erreur en cas de refus.

C’est l’état de santé de la connexion en un coup d’œil — Actif / En pause / Erreur / Déconnecté. La consigne du champ lui-même pour l’état problématique : « Error: last sync failed — check Audit Log for details. » La valeur Déconnecté est définie par le package principal une fois la méthode disconnect de votre prestataire terminée.

Cet article vous a-t-il été utile ?