story-research-zapwall/docs/payment-notes-system.md
2026-01-06 14:24:35 +01:00

9.9 KiB

Payment Notes System

Author: Équipe 4NK Date: 2026-01-05 Status: Implemented

Overview

This document describes the implementation of explicit payment notes (kind 1) for all confirmed payments, in addition to zap receipts (kind 9735). These notes use the project's tag system and are automatically published after payment confirmation.

Motivations

  • Transparency: Provide explicit, searchable payment records on Nostr
  • Tag System Compliance: All payment notes use the project's standardized tag system
  • Traceability: Enable easy querying and aggregation of payments
  • User Experience: Users can see their payment history in their Nostr feed

Root Causes

  • Zap receipts (kind 9735) are created by Lightning wallets and may not always include all project-specific tags
  • Need for explicit payment records that follow the project's tag conventions
  • Requirement to document all payment types (purchases, review tips, sponsoring) consistently

Implementation

1. Tag System Extension

New Payment Type

Added 'payment' to the TagType union in lib/nostrTagSystemTypes.ts:

export type TagType = 'author' | 'series' | 'publication' | 'quote' | 'payment'

PaymentTags Interface

New interface for payment notes:

export interface PaymentTags extends BaseTags {
  type: 'payment'
  paymentType: 'purchase' | 'review_tip' | 'sponsoring'
  amount: number
  payerPubkey: string
  recipientPubkey: string
  paymentHash: string
  zapReceiptId?: string
  articleId?: string
  reviewId?: string
  seriesId?: string
  text?: string
}

Tag Builder

Added buildPaymentTags function in lib/nostrTagSystemBuild.ts to construct payment note tags:

  • kind_type: Payment type (purchase, review_tip, sponsoring)
  • amount: Payment amount in sats
  • payer: Payer's pubkey
  • recipient: Recipient's pubkey
  • payment_hash: Payment hash or transaction ID
  • zap_receipt: Zap receipt ID (if applicable)
  • article: Article ID (if applicable)
  • review_id: Review ID (if applicable)
  • series: Series ID (if applicable)
  • text: Optional plain text message
  • transaction_id: Bitcoin transaction ID (for sponsoring)

2. Payment Notes Service

New file lib/paymentNotes.ts contains three main functions:

publishPurchaseNote

Publishes an explicit payment note for article purchases.

Parameters:

  • articleId: Article ID
  • authorPubkey: Author's pubkey
  • payerPubkey: Payer's pubkey
  • amount: Payment amount in sats
  • paymentHash: Payment hash from zap receipt
  • zapReceiptId: Zap receipt event ID (optional)
  • category: Article category
  • seriesId: Series ID (optional)
  • payerPrivateKey: Payer's private key for signing

Process:

  1. Generates hash ID using generatePurchaseHashId
  2. Builds object ID with buildObjectId
  3. Constructs tags using buildTags with PaymentTags
  4. Includes JSON metadata with full payment information
  5. Publishes kind 1 event with payment confirmation message

publishReviewTipNote

Publishes an explicit payment note for review tips.

Parameters:

  • articleId: Article ID
  • reviewId: Review ID
  • authorPubkey: Author's pubkey
  • reviewerPubkey: Reviewer's pubkey
  • payerPubkey: Payer's pubkey
  • amount: Payment amount in sats
  • paymentHash: Payment hash from zap receipt
  • zapReceiptId: Zap receipt event ID (optional)
  • category: Article category
  • seriesId: Series ID (optional)
  • text: Optional plain text message
  • payerPrivateKey: Payer's private key for signing

Process:

  1. Generates hash ID using generateReviewTipHashId
  2. Builds object ID with buildObjectId
  3. Constructs tags using buildTags with PaymentTags
  4. Includes JSON metadata with full tip information
  5. Publishes kind 1 event with tip confirmation message (includes text if provided)

publishSponsoringNote

Publishes an explicit payment note for sponsoring payments.

Parameters:

  • authorPubkey: Author's pubkey
  • payerPubkey: Payer's pubkey
  • amount: Payment amount in sats
  • paymentHash: Payment hash or transaction ID
  • category: Author category (optional)
  • seriesId: Series ID (optional)
  • articleId: Article ID (optional)
  • text: Optional plain text message
  • transactionId: Bitcoin transaction ID (optional)
  • payerPrivateKey: Payer's private key for signing

Process:

  1. Generates hash ID using generateSponsoringHashId
  2. Builds object ID with buildObjectId
  3. Constructs tags using buildTags with PaymentTags
  4. Adds transaction_id tag if provided (for Bitcoin mainnet payments)
  5. Includes JSON metadata with full sponsoring information
  6. Publishes kind 1 event with sponsoring confirmation message (includes text if provided)

3. Integration Points

Purchase Payments

File: lib/paymentPollingMain.ts

After a purchase payment is confirmed (zap receipt verified), the system:

  1. Sends private content to the user
  2. Tracks content delivery
  3. Triggers automatic transfer
  4. Publishes explicit payment note:
    • Retrieves article information to get category and seriesId
    • Gets zap receipt to extract payment hash
    • Calls publishPurchaseNote with all relevant information

Error Handling: If note publication fails, the payment process continues (non-blocking).

Review Tips

File: components/ReviewTipForm.tsx

Review tips are handled via zap requests. The explicit note publication should be triggered after zap receipt confirmation. Currently, the zap request is published, and the actual payment is handled by Alby/WebLN.

Note: Review tip note publication should be integrated when zap receipt confirmation is implemented for review tips.

Sponsoring Payments

File: lib/sponsoringPaymentTracking.ts

After a sponsoring payment transaction is verified on Bitcoin mainnet, the system:

  1. Verifies the transaction
  2. Tracks the sponsoring payment
  3. Publishes explicit payment note (if payer information is available)

Note: Currently, sponsoring note publication requires payer information (pubkey, private key, category, text, etc.) which may not always be available at tracking time. This should be handled when the user submits the transaction ID.

4. Zap Receipt Queries

New file lib/zapReceiptQueries.ts provides:

getZapReceiptById

Retrieves a zap receipt event (kind 9735) by its ID.

Use Case: Extract payment hash and other information from zap receipts for payment note publication.

Tag Structure

Purchase Payment Note Tags

#payment
#sciencefiction or #research
#id_<hash>
#service_zapwall.fr
#version_0
#kind_type_purchase
#amount_<amount>
#payer_<payerPubkey>
#recipient_<authorPubkey>
#payment_hash_<paymentHash>
#zap_receipt_<zapReceiptId> (optional)
#article_<articleId>
#series_<seriesId> (optional)
#json_<JSON metadata>

Review Tip Payment Note Tags

#payment
#sciencefiction or #research
#id_<hash>
#service_zapwall.fr
#version_0
#kind_type_review_tip
#amount_<amount>
#payer_<payerPubkey>
#recipient_<reviewerPubkey>
#payment_hash_<paymentHash>
#zap_receipt_<zapReceiptId> (optional)
#article_<articleId>
#review_id_<reviewId>
#series_<seriesId> (optional)
#text_<text> (optional)
#json_<JSON metadata>

Sponsoring Payment Note Tags

#payment
#sciencefiction or #research
#id_<hash>
#service_zapwall.fr
#version_0
#kind_type_sponsoring
#amount_<amount>
#payer_<payerPubkey>
#recipient_<authorPubkey>
#payment_hash_<paymentHash>
#series_<seriesId> (optional)
#article_<articleId> (optional)
#text_<text> (optional)
#transaction_id_<transactionId> (optional, for Bitcoin mainnet)
#json_<JSON metadata>

JSON Metadata Structure

All payment notes include a json tag with complete payment information:

Purchase

{
  "type": "purchase",
  "id": "<hash>_0_0",
  "hash": "<hash>",
  "version": 0,
  "index": 0,
  "payerPubkey": "<pubkey>",
  "articleId": "<articleId>",
  "authorPubkey": "<pubkey>",
  "amount": 800,
  "paymentHash": "<hash>"
}

Review Tip

{
  "type": "review_tip",
  "id": "<hash>_0_0",
  "hash": "<hash>",
  "version": 0,
  "index": 0,
  "payerPubkey": "<pubkey>",
  "articleId": "<articleId>",
  "reviewId": "<reviewId>",
  "reviewerPubkey": "<pubkey>",
  "authorPubkey": "<pubkey>",
  "amount": 100,
  "paymentHash": "<hash>",
  "text": "<optional text>"
}

Sponsoring

{
  "type": "sponsoring",
  "id": "<hash>_0_0",
  "hash": "<hash>",
  "version": 0,
  "index": 0,
  "payerPubkey": "<pubkey>",
  "authorPubkey": "<pubkey>",
  "amount": 4600000,
  "paymentHash": "<hash>",
  "seriesId": "<seriesId>",
  "articleId": "<articleId>",
  "text": "<optional text>",
  "transactionId": "<transactionId>"
}

Error Handling

  • Payment note publication failures do not block the payment process
  • Errors are logged but do not prevent payment confirmation
  • Users can still access content even if note publication fails

Future Improvements

  1. Review Tip Note Publication: Integrate automatic note publication after review tip zap receipt confirmation
  2. Sponsoring Note Publication: Improve integration to capture payer information at transaction submission time
  3. Payment History: Create UI to display user's payment history from payment notes
  4. Aggregation: Use payment notes for financial aggregations and statistics
  5. Search: Enable searching payment notes by various criteria (article, author, date, etc.)

Files Modified

  • lib/nostrTagSystemTypes.ts: Added PaymentTags interface
  • lib/nostrTagSystemBuild.ts: Added buildPaymentTags function
  • lib/paymentNotes.ts: New file with payment note publication functions
  • lib/paymentPollingMain.ts: Integrated purchase note publication
  • lib/zapReceiptQueries.ts: New file for zap receipt queries
  • lib/sponsoringPaymentTracking.ts: Prepared for sponsoring note publication (currently commented out)
  • docs/object-identification-system.md: Object ID format and structure
  • docs/tag-system.md: Project tag system documentation
  • docs/payment-flows.md: Payment flow documentation