Commit graph

322 commits

Author SHA1 Message Date
457b13eef1 Fix crypto watcher crash by adding missing app property to ShopContextRequestWrapper
The wrapper class wasn't properly exposing the app attribute needed for email
sending during payment finalization. This caused AttributeError crashes when
processing real payments. Added explicit app property to ensure proper access.
2025-09-23 16:02:15 -04:00
72ac3d29ca Fix crypto sync status detection with proper imports
The sync status request methods were failing due to relative import errors
when trying to import crypto clients. Changed to absolute imports to resolve:
- "attempted relative import beyond top-level package" errors
- Monero and Dogecoin sync status now properly detected
- Payment method availability correctly reflects wallet/node sync status

This restores the intended functionality where crypto payment buttons only
appear when the underlying nodes/wallets are fully synchronized.
2025-09-23 15:33:19 -04:00
45dca33b65 Fix Monero sync detection for remote nodes and apply code formatting
- Change Monero is_synced() to simple height > 0 check for remote nodes
- Update get_sync_status() to return appropriate status for remote node setup
- Fixes false "syncing" status when using upstream Monero nodes
- Apply black code formatting for consistency

This preserves the sync status detection functionality while fixing
issues with remote Monero node deployments.
2025-09-23 15:29:12 -04:00
fbc0b55dc3 Add sync status checks for crypto payment methods
Crypto payment buttons now only appear when nodes are fully synced,
preventing failed payments due to incomplete blockchain synchronization.

- Add is_synced() and get_sync_status() methods to MoneroClient and DogecoinClient
- Add request.monero_synced and request.dogecoin_synced request methods
- Update payment visibility logic to require both enabled AND synced status
- Add helpful sync status messages in checkout template when nodes are syncing
- Prevent customer frustration from unsynchronized payment processing

Payment method visibility now requires:
1. App globally enabled
2. Shop has cold wallet configured
3. RPC accessible and responsive
4. Node/wallet fully synchronized
2025-09-23 15:01:49 -04:00
171fc916b7 Fix auto-sweep database persistence bug
Auto-sweep functions were not persisting swept_tx_hash to database because
the modified crypto_payment objects weren't being added to the session.

- Add dbsession parameter to auto_sweep_payment functions
- Add explicit dbsession.add(crypto_payment) calls when sweep succeeds
- Update tests to verify swept_tx_hash is set and payment added to session
- Fix existing tests to work with new function signatures

This resolves the issue where swept payments had NULL swept_tx_hash despite
successful fund transfers, which caused infinite processing loops.
2025-09-23 13:46:45 -04:00
b2a47f6789 Move crypto documentation to docs directory
- Move CRYPTO.rst to docs/CRYPTO.rst
- Move CRYPTO_PROBLEMS.rst to docs/CRYPTO_PROBLEMS.rst

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 13:21:15 -04:00
3d2554373b Remove Monero documentation from README
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 13:17:30 -04:00
6e888f55c3 Add status constants and expired_refunded state
- Add CryptoPayment status constants for cleaner code maintenance
- Add STATUS_EXPIRED_REFUNDED for payments that expired but received funds and were refunded
- Use ACTIVE_STATUSES and TERMINAL_STATUSES for better organization
- Update all status assignments to use constants instead of magic strings
- Fix test expectation for expired_refunded status

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 13:15:55 -04:00
16d581e612 Use efficient database filtering for swept payments
- Filter at database level with swept_tx_hash.is_(None) for minimum result set
- Remove artificial "swept" status - keep "confirmed" as final state
- is_swept property derives from swept_tx_hash column, no separate boolean
- Stuck payments with swept_tx_hash set will be automatically excluded

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 13:05:09 -04:00
4ed53ba062 Fix unit tests: correct product unlock check and overpayment logic
- Replace non-existent is_unlocked_for_user with get_userproduct_for_user check
- Move overpayment refund logic outside elif branch to apply to both new and stuck payments
- All crypto watcher tests now pass

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 12:57:21 -04:00
800b7965b5 Fix crypto watcher stuck payments and improve cart deactivation
- Exclude already-swept payments from watcher queue to prevent endless processing
- Mark swept payments as "swept" status to remove from future cycles
- Fix cart deactivation by ensuring shop/user objects are attached to session
- Add debug logging for cart deactivation to track behavior
- Resolves issue where confirmed payments were processed every 20 seconds indefinitely

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-23 12:35:56 -04:00
4fbe9fedd4 Apply black code formatting
Formatted Python code using black for:
- crypto_clients.py
- crypto_watcher.py
- test_crypto_watcher.py

Maintains consistent code style across the codebase.
2025-09-23 10:49:26 -04:00
0b5b0d2461 Add test for cart deactivation on crypto payment confirmation
Added test_finalize_invoice_deactivates_cart to verify that when a
cryptocurrency payment is confirmed, the user's active cart is replaced
with a new empty cart.

The test verifies:
- User starts with a non-empty cart
- After finalize_invoice(), user gets a new empty cart
- New cart has different ID than the old cart

This ensures the UX improvement works correctly - users see an empty
cart after their crypto payment is confirmed.
2025-09-23 10:47:09 -04:00
067107d3c0 Deactivate cart when crypto payment is confirmed
When a cryptocurrency payment is confirmed in finalize_invoice(),
create a new empty cart for the user, mirroring the behavior of
Stripe payments in save_cart().

This ensures users see an empty cart immediately after their crypto
payment is detected on the blockchain, improving the UX by allowing
them to start shopping again instead of seeing the items they just paid for.

- Added logic to get user's current active cart for the shop
- Create new empty cart only if current cart is not empty
- Added logging for debugging
- Mirrors save_cart() behavior used in Stripe checkout flow
2025-09-23 10:38:43 -04:00
64d7a3b12a Switch DogecoinClient to use requests library
Replace urllib with requests library for DogecoinClient HTTP calls:
- Consistent with MoneroClient implementation
- Cleaner code using requests.post() with Basic auth
- Removed unused _headers method and imports
- Both crypto clients now use the same HTTP library

This provides better reliability and consistency across all RPC clients.
2025-09-23 08:53:26 -04:00
4693fa495f Replace urllib with requests for MoneroClient HTTP calls
Switch from urllib to requests library for all MoneroClient HTTP requests.
The requests library handles Digest authentication correctly while urllib
has compatibility issues with Monero wallet RPC server implementation.

- Simplified code by removing complex urllib Digest auth workarounds
- Uses requests.post() with HTTPDigestAuth for authenticated requests
- Maintains backward compatibility with no-auth configurations
- Adds requests as a runtime dependency for Monero functionality

Fixes Digest authentication issues that caused '401 digest auth failed' errors.
2025-09-23 08:50:17 -04:00
e8c4f5e879 Add base URL to Digest auth password manager
Small fix to help urllib match credentials correctly by adding
both the full RPC URL and base URL to the password manager.

This may resolve Digest authentication issues with Monero wallet RPC.
2025-09-23 08:43:09 -04:00
4d0021ed91 Merge branch 'do-only-good-everyday' into 'master'
Dogecoin payment support

See merge request engineering/make-post-sell/make_post_sell!47
2025-09-23 11:17:05 +00:00
68d4ccfc25 Dogecoin payment support 2025-09-23 11:17:05 +00:00
a6d6860d2a Add comprehensive MONERO.rst documentation
Document the amazing multi-tenant Monero cash register system:
- Multi-tenant architecture with account isolation
- Complete payment flow from checkout to cold storage
- Risk management with confirmation tiers
- Auto-sweep triggered by unlocked funds
- Database schema and payment tracking
- Benefits for all stakeholders

Fixed inaccuracies:
- Removed QR code references (not implemented yet)
- Corrected quote expiration to 60 minutes
- Fixed auto-sweep trigger (unlocked funds, not confirmations)
- Removed automatic quote renewal (quotes expire)
- Streamlined content focus
2025-09-22 09:34:08 -04:00
3f65ed86d3 new file: MONERO.rst 2025-09-22 09:22:15 -04:00
caccee8862 Add UUID string usage note to CLAUDE.md
Document uuid_str property for string operations on model identifiers.
2025-09-22 08:31:49 -04:00
3f23b7eea8 Fix UUID subscriptable error and improve Monero account creation
- Fix crypto_processor.py UUID slicing error by using shop.uuid_str
- Use clean UUID-based label: mps-shop-{uuid}
- Add account tagging with shop name for human identification
- Update development.ini to use environment variables for payment toggles
- Run black formatter on all Python files

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-22 08:27:09 -04:00
2a89b94a29 Fix duplicate column in migration 0f59018f6537
Remove crypto_quote_expiry_seconds operations that were duplicating
what migration 193438acaa95 already added. Only keep payment_risk_threshold columns.
2025-09-21 23:09:31 -04:00
d1c5416c0d Merge branch 'MakePostSellXMR-fixed' into 'master'
Add Monero (XMR) payment support

See merge request engineering/make-post-sell/make_post_sell!46
2025-09-22 01:45:54 +00:00
f3cd1e7116 Add Monero (XMR) payment support 2025-09-22 01:45:54 +00:00
0c8e1b4f89 Allow style attribute on img tags to override CSS width
- Added style attribute to bleach allowlist for img tags
- Fixes issue where CSS img { width: 100%; } overrides width attribute
- Inline style='width:360px;' has higher specificity than stylesheet
- Now supports both width='360' and style='width:360px;' formats
2025-07-28 10:53:38 -04:00
cfe63b2f92 modified: setup.py 2025-07-27 21:33:44 -04:00
1a66bd210e modified: make_post_sell/tests/test_functional.py 2025-07-27 21:32:45 -04:00
7e7ccd7581 Bump version to 1.0.7
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 21:08:54 -04:00
e29afe56fe Complete invoice coupon display testing for groupr regression
- Expand groupr regression test to validate full end-to-end invoice display
- Add proper Stripe key configuration through settings form workflow
- Handle complex transaction management and session state after commits
- Test now produces valid invoice showing coupon discounts for groupr scenario
- Validates both AttributeError fix and invoice template enhancements
- Gracefully handles session/ownership edge cases in checkout completion

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 21:02:21 -04:00
698b44e9e6 Expand groupr regression test to verify invoice coupon display
Extended the free coupon checkout test to also verify that:
- Checkout completion creates an invoice with coupon redemptions
- Invoice page displays discount breakdown with coupon information
- Coupon codes and descriptions appear on invoice
- Discount amounts are calculated correctly

This ensures the invoice discount display enhancement works end-to-end.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 20:33:00 -04:00
76c171df18 Add discount/coupon breakdown to invoice template
Add comprehensive pricing breakdown to invoice display showing:
- Subtotal before discounts
- Applied coupon codes and descriptions
- Total discount amount
- Handling costs
- Final total

Critical for ecommerce transparency - both customers and shop owners
can now see what discounts were applied to each invoice.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 20:28:11 -04:00
267db2e278 Remove transaction management workarounds from tests
Remove manual transaction.manager.commit/begin calls that were masking
the real transaction management issues in cart_complete_checkout.

Keep only minimal session re-querying needed for test object attachment.
Now that root cause is fixed, tests can run without transaction workarounds.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 19:56:32 -04:00
b9669c1f6a Bump version to 1.0.6
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 19:51:31 -04:00
0c6516d3f9 Fix NoTransaction error in cart checkout completion
Remove manual transaction management (tm.begin/commit) that was conflicting
with pyramid_tm's automatic transaction handling. Keep tm.abort() calls
for proper rollback on payment failures.

Fixes production issue affecting users like groupr and bluediamon during
free cart checkout completion.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 19:50:53 -04:00
0697eacb89 Fix database transaction management in download permissions test
Properly handle database state by committing current transaction and
re-querying objects before web interface testing. This fixes database
locking issues while preserving full HTML verification of download button
absence when product has no file.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 18:57:09 -04:00
8182a53465 Remove is_ready mock from basic download permissions test
The test_product_download_permissions_basic should test real unmocked
behavior to verify download button doesn't appear when no file exists.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 18:53:21 -04:00
7ef0a05fd3 Extend groupr regression test to include download functionality and bump to v1.0.5
- Add download permissions testing to free coupon checkout regression test
- Create separate basic download permissions test with HTML assertions
- Fix database state management by removing manual user deletion in tearDown
- Update version from 1.0.4 to 1.0.5 for new release
- Validate all three download scenarios:
  1. Download permissions work correctly (both tests)
  2. Download button appears when file exists (mocked is_ready)
  3. Download button absent when no file (unmocked behavior)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 18:51:07 -04:00
34bca832bb Add RST table of contents directive to journal 2025-07-27 17:23:00 -04:00
ba58135981 Bump version to 1.0.4 2025-07-27 17:16:09 -04:00
de868682a8 Fix cart discount memoization bug and template null safety
Resolves critical AttributeError in free cart checkout when coupons are applied.

- Fix cart discount calculation cache invalidation in coupon.py
- Add template null safety for active_card in cart_checkout.j2
- Add comprehensive regression test for free cart coupon flow
- Document full defect hunt process in journal.rst

All 87 tests pass. Fixes production crashes during free cart checkout.
2025-07-27 17:09:59 -04:00
3f692aabbd Add regression test for stripe_user_shop None AttributeError
- Add test_cart_checkout_logic_with_none_stripe_user_shop to prevent regression
- Tests the exact scenario that caused production AttributeError
- Validates both old buggy code would crash and new fixed code works
- Covers edge case where stripe_user_shop is None in cart checkout

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 16:01:45 -04:00
95f2957106 Fix NoneType error in cart checkout
- Add null check for stripe_user_shop before accessing active_card property
- Prevents AttributeError: 'NoneType' object has no attribute 'active_card'
- Handle case where stripe_user_shop is None in cart checkout flow

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 15:50:38 -04:00
b67521936e Fix Python 2/3 compatibility issue in base64 decoding
- Replace deprecated .decode("base64") with base64.b64decode() in short_id_to_bytes function
- Add import base64 to meta.py
- Add comprehensive unit tests for short_id_to_bytes and id_to_uuid functions
- Prevents AttributeError: 'str' object has no attribute 'decode' errors
- Resolves bad gateway authentication issues when accessing URLs with short IDs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-27 15:40:04 -04:00
8672802e78 Fix GitLab CI pypi-twine stage for Python 3.12+ externally-managed-environment
- Create virtual environment for twine operations instead of system-wide installs
- Use python3 -m build instead of deprecated setup.py commands
- Resolves PEP 668 externally-managed-environment restrictions in CI
2025-07-27 13:58:57 -04:00
c1fda9a356 Update setup.py version 1.0.3 has 100% test coverage in the cart model. 2025-07-27 17:55:03 +00:00
9f2033d7c4 Merge branch 'cart-code-coverage-100-percent' into 'master'
Achieve 100% test coverage for Cart model

See merge request engineering/make-post-sell/make_post_sell!44
2025-07-27 17:53:05 +00:00
89f8737a58 Achieve 100% test coverage for Cart model 2025-07-27 17:53:05 +00:00
66455dc45a Merge branch 'remarkbox' into 'master'
Add comment & review system for products & content

See merge request engineering/make-post-sell/make_post_sell!43
2025-06-24 13:44:08 +00:00