45. pepsi-stage-auto-pay

Payer automatiquement les demandes de remise GNU Taler (le côté émetteur du péage à l’envoi).

45.1. Rôle

pepsi-stage-auto-pay a deux rôles auto-détectés. Sur le chemin entrant, c’est le pendant émetteur de pepsi-stage-anti-spam : lorsqu’un courrier que ce déploiement a relayé est retenu à l’extrémité distante derrière une barrière de péage à l’envoi, cette barrière envoie par e-mail une demande de paiement à l’expéditeur original, et cette étape détecte de telles demandes et les règle automatiquement, de sorte que le message retenu est libéré et remis. Sur le chemin de soumission, c’est un point de terminaison libre-service pour le wallet (activé par RESPONSE_STAGE ; voir ci-dessous). Référence : pepsi-stage-auto-pay(1).

Une demande est reconnue au champ d’en-tête Taler:, l’une des deux extensions d’en-tête privées documentées dans Extensions du protocole SMTP ; plusieurs URI dans un même champ, comme plusieurs champs, sont acceptés. La détection n’est pas une autorisation : l’étape ne paie que pour du courrier dont ce déploiement peut prouver qu’il est à l’origine, ce qu’elle établit à partir de l’en-tête Pepsi-Origin: récupéré dans le message revenu — un HMAC RFC 2104 sur l’hôte émetteur, l’expéditeur et un nonce qui doit encore être suivi dans pepsi.origin_nonce.

Aucun des deux en-têtes n’est enregistré au titre de la RFC 3864, et aucun ne porte de préfixe X-, conformément à la RFC 6648. L’URI taler:// qu’ils transportent relève du schéma propre à GNU Taler plutôt que d’un schéma enregistré à l’IANA (la RFC 7595 fixe cette procédure) ; les instructions de virement bancaire que renvoie la commande libre-service withdraw utilisent le schéma d’URI payto: du RFC 8905. (L’étape ne détient aucun identifiant marchand : elle paie au moyen d’un wallet, et seul le côté qui facture, pepsi-stage-anti-spam, s’authentifie auprès d’un backend marchand.)

45.2. Libre-service de wallet (chemin de soumission)

Lorsque RESPONSE_STAGE est défini, un message d’origine locale (authentifié) vers <CONTROL_LOCAL_PART>@<served-domain> (partie locale par défaut pepsi-wallet) permet à l’expéditeur d’opérer son propre wallet par e-mail — parallèlement à pepsi-stage-edit-settings, mais indexé sur l’expéditeur d’enveloppe. La commande est le Subject: du message : balance, withdraw CUR:VAL EXCHANGE-URL (un rechargement manuel depuis l’exchange GNU Taler nommé — choisi par demande, puisqu’un wallet est multi-monnaie et multi-exchange — la réponse donne les instructions de virement bancaire), pull CUR:VAL [subject] (un pull pair-à-pair — la réponse donne un URI taler://pay-pull/… à transférer) ou push <taler://pay-push/…> (accepter un push pair ; l’URI peut être dans le corps). La réponse localisée (modèle wallet.<lang>.body, expéditeur nul) est injectée à RESPONSE_STAGE et l’original consommé ; une demande malformée reçoit les instructions d’utilisation. Si le wallet rencontre une exigence KYC, la réponse porte le lien KYC à la place (libre-service uniquement — jamais pendant le paiement de demandes entrantes). Tout autre message passe vers NEXT_STAGE.

45.3. Décision

Pilotée par les en-têtes du message (pas son state) :

  • pas d’en-tête Taler: → pas une demande ; transférer vers NEXT_STAGE sans modification (de sorte que l’étape peut être placée sans risque tôt sur le chemin entrant).

  • un en-tête Taler:, mais l’origine de la demande n’est pas prouvée — pas de preuve Pepsi-Origin: valide (falsifiée/expirée, ou toute demande lorsque [pepsi-origin] n’est pas configuré) → ne jamais payer ; transférer vers NEXT_STAGE.

  • origine prouvée → pour chaque URI taler://pay/…, en pilotant le helper de wallet privilégié pepsi-helper-auto-pay(1) : coter son prix (le preview du helper), le réserver sur le budget par message original (MAX_TOTAL) et sur le budget quotidien du wallet payeur (MAX_TOTAL_PER_DAY) et, s’il tient dans les deux, le régler (le pay du helper).

    • chaque demande réglée → rejeter le rebond désormais redondant (supprimer la ligne) ;

    • une demande qui ne peut pas être tarifée, dépasse l’un ou l’autre budget ou diffère de monnaie → transférer vers NEXT_STAGE afin que le message continue comme un rebond ordinaire et que l’expéditeur soit informé ;

    • une demande réservée sous le budget dont le paiement échoue ensuite → la réservation est remboursée aux deux registres (le paiement non dépensé ne doit consommer aucun des deux budgets) et le message est transféré. Auto-pay essaie de payer ; s’il ne peut pas, il ne fait rien (journalise l’erreur) et laisse passer le rebond.

45.4. Budget cumulatif

Le budget est indexé sur le nonce Pepsi-Origin, qui identifie le message sortant original. Un message éclaté vers une liste de diffusion suscite plusieurs demandes — une par membre dont le site facture — qui portent toutes le même nonce renvoyé en écho depuis l’original, de sorte qu’elles partagent un seul budget. Le registre par message réside dans pepsi.origin_nonce.amount ; chaque règlement l’avance atomiquement (la fonction auto_pay_try_spend verrouille la ligne), et une demande qui pousserait le total courant au-delà de MAX_TOTAL est refusée. Le plafond porte sur une monnaie unique. Un compte peut redéfinir son propre MAX_TOTAL par e-mail via pepsi-stage-edit-settings (la redéfinition est indexée sur le compte qui reçoit la demande — l’expéditeur original).

MAX_TOTAL à lui seul borne un message, pas un correspondant : quiconque a reçu l’un de nos messages détient une preuve valide, de sorte que quelqu’un qui en a reçu k peut réclamer MAX_TOTAL k fois. MAX_TOTAL_PER_DAY est l’agrégat : ce qu’un wallet peut dépenser sur toute période de 24 heures — celui de l’utilisateur sous WALLET_MODE = local-user, celui de l’expéditeur sous shared/per-sender, celui du déploiement sous shared/unified. Il n’est jamais par correspondant, que les listes de diffusion et les alias rendent impossible à connaître. Le même appel auto_pay_try_spend vérifie les deux budgets et enregistre la réservation dans pepsi.auto_pay_spend — sérialisé par wallet, de sorte que des demandes concurrentes pour des messages différents ne peuvent pas le dépasser — et auto_pay_refund supprime à nouveau la réservation lorsque le paiement ne peut être réglé. La fenêtre est glissante sur 24 heures ; la limite est mono-devise, dans la devise de MAX_TOTAL ; non réglée, il n’y en a aucune.

La vérification réutilise la machinerie de preuve d’origine : voir Extensions du protocole SMTP et pepsi-stage-relay-to-internet (qui estampille Pepsi-Origin sur le courrier sortant et enregistre le nonce).

45.5. Compte de wallet et helper

Toute interaction avec le wallet est effectuée par le helper pepsi-helper-auto-pay(1) setuid-root, qui abandonne ses privilèges au profit du bon utilisateur avant d’exécuter taler-wallet-cli. WALLET_MODE choisit le compte : local-user paie depuis le wallet local propre au destinataire du rebond (l’expéditeur original ; le destinataire doit se résoudre en un compte local autorisé), tandis que shared (la valeur par défaut) paie depuis un unique compte WALLET_USER dédié (par défaut pepsi-wallets) dont le home contient la ou les bases de données de wallet — une par expéditeur (WALLET_SCOPE = per-sender) ou un unique wallet unifié partagé par tous (WALLET_SCOPE = unified, par exemple une entreprise). Comme l’étape lance le helper par exec, son binaire est installé en autonome et SGID pepsi-wallets (le helper est setuid-root, root:pepsi-wallets, mode 4750).

Note

Tout ce qui dépend de la version de taler-wallet-cli est confiné dans pepsi-helper-auto-pay : l’orthographe de la sous-commande et des drapeaux qu’emploie chaque opération (build_wallet_args), et les petits analyseurs qui extraient de sa sortie un montant, une URI payto:, une URI taler:// et un lien KYC. L’étape elle-même ne parle qu’au helper, de sorte qu’un futur changement de la CLI y reste confiné.

45.6. Configuration

[stage-<name>] : PROGRAM = pepsi-stage-auto-pay, MAX_TOTAL (un montant Taler CURRENCY:VALUE bornant la dépense totale par message original, obligatoire), MAX_TOTAL_PER_DAY (facultatif, même devise, bornant la dépense d’un wallet sur toute période de 24 heures), NEXT_STAGE (obligatoire — où est transféré un message impayé ou qui n’est pas une demande), et les réglages de wallet WALLET_MODE, WALLET_USER, WALLET_SCOPE, WALLET_CLI, WALLET_PAY_OPTIONS et HELPER ; le rôle libre-service ajoute RESPONSE_STAGE (qui l’active), CONTROL_LOCAL_PART, RESPONSE_FROM et RESPONSE_SUBJECT (un withdraw nomme son exchange dans la demande, aucun n’est donc configuré). Le secret de preuve d’origine est la section partagée [pepsi-origin]. Voir pepsi-stage-auto-pay(1).

45.7. État

  • Entrées : les en-têtes Taler: et Pepsi-Origin: du message (le corps est aussi parcouru à la recherche d’un Pepsi-Origin intégré). Les registres des dépenses sont pepsi.origin_nonce.amount (par message) et pepsi.auto_pay_spend (par wallet, dernières 24 heures), pas le state du message.

  • Sorties : aucune sur le message ; il est avancé vers NEXT_STAGE ou supprimé.

45.8. Voir aussi

pepsi-stage-anti-spam, pepsi-stage-relay-to-internet, pepsi-stage-edit-settings, Extensions du protocole SMTP, pepsi-stage-auto-pay(1).