mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
* feat(bitstamp): EN-1015 add orders + conversions and refactor for production-readiness Adds first-class orders and conversions primitives to the Bitstamp connector and refactors the package along Formance conventions. The HTTP client is split into client/types.go + client/error.go with OpenTelemetry instrumentation and a typed DerivativesUnsupportedError that drives a process-lifetime try-and-skip cache for permission-gated endpoints (my_markets, fees, crypto-transactions). State is moved to opaque cursors with backward-compatible decoders so existing installs keep their watermarks. Payments are now a three-source union (user_transactions + crypto-transactions + withdrawal-requests) with fail-whole-cycle semantics on top-level source errors and log+continue on per-row map errors. Orders reconcile open_orders snapshots with order_status; conversions detect two-asset user_transactions.type=36 (instant buy/sell). Accounts surface the currency ticker as Name; sub-account transfers (types 14/33/35) are modelled as linked PAYOUT/PAYIN pairs correlated via metadata, reflecting Bitstamp's one-API-key-per-account scope. The Temporal task tree nests balances under accounts (Qonto FromPayload pattern) with payments, orders and conversions as independent roots. Install-time enrichment loads markets, my_markets, trading fees and withdrawal fees in parallel via a generic refreshCache[T] helper with TTL. Full transformation logic lives in a dedicated mappers/ subpackage with extensive unit coverage. MAPPINGS.md documents every decision, the error-policy matrix, and the known historical-orders gap. * fix(bitstamp): address PR #724 CodeRabbit review — evict on order_status error, deterministic enrichment, log levels Evict retention-expired tracked orders in fetchNextOrders when GetOrderStatus errors out: a stale ID past the 30-day window will keep failing the call indefinitely, growing state unbounded and spamming Error logs every cycle. Log the eviction at Info because the failure is expected for retention-expired entries. Make representative market/trading-fee selection in buildEnrichmentForCurrency deterministic by picking the lexicographically-smallest match on a composite key (CounterCurrency|MarketType for markets, CurrencyPair for fees) to prevent account-metadata flapping if the PSP returns rows reordered between cycles. Downgrade the derivatives-row skip log in fetchNextConversions from Errorf to Infof — it is an expected branch on a spot-only connector, not a fault. Drop a redundant AbsAmount wrap inside an IsZeroAmount call (Sign() already handles negatives natively). Add language tag to a MAPPINGS.md fenced block to satisfy markdownlint. New unit tests cover the eviction-on-error path and lock the deterministic-representative contract via permutation testing. Co-authored-by: Cursor <[email protected]> * Remove any cache initializations from Install step, remove useless skip behaviour for crypto-transactions and withdrawals * Use GET request for my_markets endpoint, and only handle derivative not supported error where likely to occur * Drastically reduce amount of caching - instead fetch enrichment data only when new accounts are found * Delay fetch currencies calls until after we know if work needs to be done to reduce unneeded requests in inactive accounts * Revert changes to balance fetching that made it only fetch balance once * Import transactions with trailing zeros that exceed the currency's reported precision * One exclusive decimal amount parser function among different functions * Allow two orders with the same ID to be present in a slice by combining them into one record with multiple adjustments * Use CreatedAt to determine order or order adjustments * Make Orders workflow a child of accounts, and search markets related to the currency of the account * Enhance metadata returned in orders * Only save real account IDs related to orders * Import each order event only once via the source currency * Regenerate capabilities * Add paging mechanism and fix expectations about market event IDs * Export even if account is destination account * Address coderabbit comments * Fix comments on workflow header * Address coderabbit comments regarding models order * Only use user transactions endpoint to fetch both conversions and payments * Truncate trailing digits when they exceed the precision bitstamp provided - raw values still preserved in raw payload --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Crimson Thompson <[email protected]>
1 line
4.3 KiB
JSON
1 line
4.3 KiB
JSON
{"adyen":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"atlar":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_OTHERS"],"bankingbridge":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS"],"bankingcircle":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_CREATE_BANK_ACCOUNT","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"bitstamp":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_ORDERS","CAPABILITY_FETCH_CONVERSIONS"],"coinbaseprime":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_ORDERS","CAPABILITY_FETCH_CONVERSIONS"],"column":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_BANK_ACCOUNT","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"currencycloud":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"dummypay":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_ALLOW_FORMANCE_ACCOUNT_CREATION","CAPABILITY_ALLOW_FORMANCE_PAYMENT_CREATION","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"fireblocks":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS"],"generic":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_ALLOW_FORMANCE_ACCOUNT_CREATION","CAPABILITY_ALLOW_FORMANCE_PAYMENT_CREATION"],"increase":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_CREATE_BANK_ACCOUNT","CAPABILITY_TRANSLATE_WEBHOOKS","CAPABILITY_CREATE_WEBHOOKS"],"mangopay":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_OTHERS","CAPABILITY_CREATE_BANK_ACCOUNT","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"modulr":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"moneycorp":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"plaid":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"powens":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"qonto":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS"],"routable":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT"],"stripe":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"tink":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"],"wise":["CAPABILITY_FETCH_ACCOUNTS","CAPABILITY_FETCH_BALANCES","CAPABILITY_FETCH_EXTERNAL_ACCOUNTS","CAPABILITY_FETCH_PAYMENTS","CAPABILITY_FETCH_OTHERS","CAPABILITY_CREATE_TRANSFER","CAPABILITY_CREATE_PAYOUT","CAPABILITY_CREATE_WEBHOOKS","CAPABILITY_TRANSLATE_WEBHOOKS"]} |