Skip to content

feat: SEP-31 payout retry, SEP-9 fields, SEP-6 DB config, withdrawal logic - #531

Open
levibliz wants to merge 1 commit into
Pidoko257:mainfrom
levibliz:feat/sep31-payout-logic-sep9-fields-sep6-config-withdrawal
Open

feat: SEP-31 payout retry, SEP-9 fields, SEP-6 DB config, withdrawal logic#531
levibliz wants to merge 1 commit into
Pidoko257:mainfrom
levibliz:feat/sep31-payout-logic-sep9-fields-sep6-config-withdrawal

Conversation

@levibliz

Copy link
Copy Markdown
Contributor

Summary

Addresses 4 issues: SEP-31 payout retry with dead letter queue, SEP-9 KYC fields for SEP-6, database-backed SEP-6 configuration, and complete withdrawal logic with fee calculation.

Changes

SEP-31 Payout Logic (#350)

  • New src/services/sep31PayoutService.ts with provider-specific payout routing for 5 mobile money providers (MTN, Airtel, Orange, Vodacom, Tigo)
  • Each provider has configurable min/max amounts, fee percentages, and supported countries
  • Exponential backoff retry: base 10s, max 10min, configurable via environment variables
  • Dead letter queue for unrecoverable failures (unknown provider, max retries exceeded)
  • runPayoutRetryJob() for automated retry processing of queued payouts
  • Full attempt history tracked in payout_attempts table

SEP-9 Fields Support (#349)

  • Added SEP-9 KYC field specifications to src/services/sep6Service.ts
  • Database-backed field definitions with field_name, field_type, description, optional, and enum_values
  • Configuration loaded from sep6_field_specs table with 60s cache TTL
  • Supports text, number, date, enum, and boolean field types

Replace Hard-coded Database in SEP-6 (#348)

  • New src/services/sep6Service.ts replaces in-memory Map with database-backed configuration
  • Uses sep6_asset_configs, sep6_field_specs, and sep6_withdraw_types tables
  • Includes config caching with TTL for performance optimization
  • Full CRUD for SEP-6 transactions: createSep6Transaction(), getSep6Transaction(), updateSep6TransactionStatus(), getSep6TransactionsByAccount()
  • invalidateConfigCache() for admin configuration updates

Withdrawal Logic (#347)

  • Completed TransactionService.withdraw() with full withdrawal flow
  • Balance validation before processing
  • Dynamic fee calculation from fee_configurations table (1% default, $0.50 minimum)
  • Atomic balance deduction via database transaction with rollback on failure
  • Withdrawal ledger logging for audit trail
  • Returns transaction details, fee breakdown, and new balance

Closes #350
Closes #349
Closes #348
Closes #347

…logic

- SEP-31 Payout Logic (Pidoko257#350): New sep31PayoutService with provider-specific
  routing (MTN, Airtel, Orange, Vodacom, Tigo), amount validation per provider,
  exponential backoff retry (base 10s, max 10min, configurable), dead letter
  queue for unrecoverable failures, and runPayoutRetryJob for automated retries.
  Tracks full attempt history in payout_attempts table.

- SEP-9 Fields Support (Pidoko257#349): Added SEP-9 KYC field specifications to
  sep6Service with database-backed field definitions (field_name, field_type,
  description, optional, enum_values). Config loaded from sep6_field_specs
  table with 60s cache TTL.

- Replace Hard-coded Database in SEP-6 (Pidoko257#348): New sep6Service replaces
  in-memory Map with database-backed configuration via sep6_asset_configs,
  sep6_field_specs, and sep6_withdraw_types tables. Includes config caching
  with TTL, full CRUD for SEP-6 transactions (create, get, update, list by
  account), and invalidateConfigCache for admin updates.

- Withdrawal Logic (Pidoko257#347): Completed TransactionService.withdraw() with
  balance validation, fee calculation from fee_configurations table, atomic
  balance deduction via database transaction, withdrawal ledger logging,
  and proper error handling with rollback. Returns transaction, fee breakdown,
  and new balance.

Closes Pidoko257#350
Closes Pidoko257#349
Closes Pidoko257#348
Closes Pidoko257#347
@drips-wave

drips-wave Bot commented Aug 26, 2026

Copy link
Copy Markdown

@levibliz Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants