Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@hiteshshimpi-55
Copy link
Contributor

@hiteshshimpi-55 hiteshshimpi-55 commented Dec 7, 2025

Important

Enhance invoice and wallet services by updating unpaid invoice handling and wallet balance calculations.

  • Behavior:
    • GetUnpaidInvoicesToBePaid in invoice.go now returns GetUnpaidInvoicesToBePaidResponse, including unpaid usage and fixed charges.
    • GetWalletBalance in wallet.go updated to use TotalUnpaidUsageCharges from GetUnpaidInvoicesToBePaidResponse.
  • DTOs:
    • Added GetUnpaidInvoicesToBePaidRequest and GetUnpaidInvoicesToBePaidResponse in dto/invoice.go.
  • Tests:
    • Updated TestGetWalletBalance and TestGetWalletBalanceWithEntitlements in wallet_test.go to reflect changes in balance calculation logic.

This description was created by Ellipsis for 77b7b1c. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added auto-complete option for purchased credit transactions, enabling instant credit availability when the setting is enabled.
    • Enhanced wallet balance calculations with improved pending charge tracking.
  • Improvements

    • Refined financial data accuracy in wallet balance endpoints.

✏️ Tip: You can customize this high-level summary in your review settings.

omkar273 and others added 8 commits December 6, 2025 11:54
…e structure, update service method to use new request type
 feat(invoice): account for unpaid usage charges calculating total pending charges
  refactor(wallet): update wallet balance calculations in tests to reflect usage charges only
@coderabbitai
Copy link

coderabbitai bot commented Dec 7, 2025

Warning

Rate limit exceeded

@hiteshshimpi-55 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 16 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between bfc2396 and c903aba.

📒 Files selected for processing (2)
  • internal/service/invoice.go (6 hunks)
  • internal/service/wallet.go (7 hunks)

Walkthrough

This PR refactors the unpaid invoice retrieval API from a slice/decimal return pattern to a structured request/response DTO pattern, introduces auto-complete support for purchased-credit wallet transactions with invoice metadata flags, and updates wallet balance calculations to use usage charges exclusively.

Changes

Cohort / File(s) Summary
New unpaid invoice DTOs
internal/api/dto/invoice.go
Added GetUnpaidInvoicesToBePaidRequest with CustomerID and Currency fields and Validate() method; added GetUnpaidInvoicesToBePaidResponse containing Invoices, TotalUnpaidAmount, TotalUnpaidUsageCharges, and TotalUnpaidFixedCharges.
Invoice service refactoring
internal/service/invoice.go
Refactored GetUnpaidInvoicesToBePaid method signature from (ctx, customerID, currency) → ([]*InvoiceResponse, decimal, error) to (ctx, req) → (*GetUnpaidInvoicesToBePaidResponse, error); now validates request, filters by currency, and aggregates unpaid invoices with usage/fixed charge splits. Changed invoice config retrieval to GetSettingWithDefaults. Added logic to complete purchased-credit wallet transactions when invoice transitions to Succeeded.
Wallet service auto-complete and balance updates
internal/service/wallet.go
Added auto-complete conditional flow in TopUpWallet: when enabled, wallet transactions are created as Completed (not Pending), balance updates immediately, and webhooks publish synchronously; invoice includes auto_completed metadata and PaymentStatus (Pending vs Succeeded). Refactored GetWalletBalance and GetWalletBalanceV2 to use GetUnpaidInvoicesToBePaid response's TotalUnpaidUsageCharges instead of raw unpaid invoice slices. Enhanced logging for auto-complete vs pending paths.
Wallet tests
internal/service/wallet_test.go
Updated test expectations in TestGetWalletBalance and related test cases to reflect wallet balance calculations using usage charges only, removing unpaid-invoice totals from expected results.
Settings validation
internal/types/settings.go
Added partial-update acceptance for invoice_config to allow updates with only optional fields (due_date_days, auto_complete_purchased_credit_transaction). Added validation and boolean-type check for new auto_complete_purchased_credit_transaction field. Extended GetDefaultSettings() to include new field defaulting to false.

Sequence Diagram

sequenceDiagram
    actor Client
    participant WalletSvc as Wallet Service
    participant SettingsSvc as Settings Service
    participant InvoiceSvc as Invoice Service
    participant DB as Database
    participant Webhook as Webhook Publisher

    Client->>WalletSvc: TopUpWallet(amount, currency)
    WalletSvc->>SettingsSvc: GetSettingWithDefaults(invoice_config)
    SettingsSvc->>DB: Fetch invoice config
    DB-->>SettingsSvc: Config with auto_complete flag
    SettingsSvc-->>WalletSvc: Config response

    alt auto_complete_purchased_credit_transaction enabled
        WalletSvc->>InvoiceSvc: CreateInvoice(auto_completed=true, PaymentStatus=Succeeded)
        InvoiceSvc->>DB: Create invoice
        DB-->>InvoiceSvc: Invoice created
        InvoiceSvc-->>WalletSvc: Invoice response
        
        WalletSvc->>DB: Create wallet transaction as Completed
        WalletSvc->>DB: Update wallet balance immediately
        DB-->>WalletSvc: Balance updated
        
        WalletSvc->>Webhook: Publish wallet.transaction.created
        Webhook-->>WalletSvc: Published
        WalletSvc-->>Client: TopUpWallet succeeds (credits available)
    else auto_complete disabled
        WalletSvc->>InvoiceSvc: CreateInvoice(auto_completed=false, PaymentStatus=Pending)
        InvoiceSvc->>DB: Create invoice
        DB-->>InvoiceSvc: Invoice created
        InvoiceSvc-->>WalletSvc: Invoice response
        
        WalletSvc->>DB: Create wallet transaction as Pending
        DB-->>WalletSvc: Transaction created
        WalletSvc-->>Client: TopUpWallet succeeds (credits pending)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–75 minutes

  • Wallet service auto-complete logic: Conditional transactional paths with multiple branches (enabled vs disabled) affecting wallet balance updates, transaction status, and webhook publishing require careful verification of state consistency.
  • Invoice payment success to wallet completion: New cross-service integration where invoice payment success triggers wallet transaction completion; ensure idempotence and proper error handling.
  • GetUnpaidInvoicesToBePaid signature refactoring: Method signature change from slice/decimal returns to request/response DTO; verify all callers updated correctly and response structure matches consumption patterns.
  • Wallet balance calculation changes: Shift from total unpaid amount to usage-only charges; validate test expectations and ensure backward compatibility implications are understood.
  • Settings validation partial-update logic: New conditional validation for optional invoice_config fields; ensure partial updates do not bypass required field checks.

Possibly related PRs

Suggested reviewers

  • nkmishra1997
  • omkar273

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'v1.0.41' does not follow the required naming convention of {{type_of_change}}({{module}}: {{message}}), lacks a type indicator (feat/fix/chore), and does not clearly describe the changes made. Rename the PR title to follow the convention, e.g., 'feat(invoices): separate unpaid usage and fixed charges in response' or 'feat(invoices,wallets): refactor unpaid invoices response structure'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

feat(wallet): add support for tenant-level auto-complete settings and invoice-status–triggered top-ups for purchased credit invoices
Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 77b7b1c in 1 minute and 1 seconds. Click for details.
  • Reviewed 219 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 7 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. internal/service/wallet_test.go:1213
  • Draft comment:
    Repeated use of the same idempotency key ("test_topup_1") in TestDebitWithMultipleCredits may suppress duplicate operations unintentionally. Consider generating unique idempotency keys for each top‐up request.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
2. internal/service/wallet_test.go:1633
  • Draft comment:
    TestDebitIdempotency is currently skipped with a note on non‑idempotency. Consider adding a reference or issue ID for the known bug so tracking is easier.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
3. internal/service/wallet_test.go:1450
  • Draft comment:
    Validation tests in GetCustomerWallets rely on string matching for error messages. Consider checking error codes/constants to make tests more robust against message changes.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
4. internal/service/wallet_test.go:1190
  • Draft comment:
    In TestDebitWithExpiredCredits, the expected error is checked via string content. It’s preferable to verify using an error code so that future changes in wording do not break tests.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
5. internal/service/wallet_test.go:1631
  • Draft comment:
    In TestDebitWithPrioritizedCredits, adding inline comments that explain the expected credit consumption and sorting order (by priority, then nil) would improve clarity and maintainability.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
6. internal/service/wallet_test.go:851
  • Draft comment:
    Consider splitting lengthy test functions into smaller helper functions to improve readability and maintenance.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
7. internal/service/invoice.go:47
  • Draft comment:
    Typographical note: Consider renaming GetInvoicePDFUrl to GetInvoicePDFURL to maintain consistent acronyms (e.g., using 'URL' instead of 'Url').
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.

Workflow ID: wflow_nd23I7GvFT9LXfpM

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/service/wallet.go (1)

1852-1959: V2 balance calculation omits unpaid invoice charges, creating an inconsistency with V1.

GetWalletBalanceV2 calculates totalPendingCharges from subscriptions only (line 1881–1918), whereas GetWalletBalance (V1, line 829–952) also includes unpaid invoice usage charges via GetUnpaidInvoicesToBePaid and adds them to the total (line 921, 102). This means V2 underreports pending charges and does not set UnpaidInvoicesAmount in the response. If V2 is intended to provide accurate real-time balance calculations like V1, it should include unpaid invoice charges.

internal/service/invoice.go (1)

1490-1543: Fix the semantic mismatch in GetUnpaidInvoicesToBePaid: line-item charge splits must reflect actual unpaid portions

The function sums original LineItem.Amount values for invoices with AmountRemaining > 0, but for partially paid invoices this over-counts usage and fixed charges. The response field names ("TotalUnpaidUsageCharges", "TotalUnpaidFixedCharges") imply unpaid amounts, but the implementation sums full original line items. This causes wallet balance calculations to include charges that have already been partially paid.

For correct semantics, pro-rate line-item charges by the ratio AmountRemaining / AmountDue when summing usage and fixed splits. Alternatively, clarify field names to "TotalUsageCharges" and "TotalFixedCharges" if full original amounts are intended, and adjust wallet balance logic accordingly.

🧹 Nitpick comments (1)
internal/api/dto/invoice.go (1)

1218-1231: Consider adding currency validation for consistency.

The Currency field is marked as required but the Validate() method only delegates to validator.ValidateRequest. Other DTOs in this file (e.g., CreateInvoiceRequest.ToInvoice) validate currency using types.ValidateCurrencyCode. Consider adding similar validation to ensure the currency is a valid ISO code.

 func (r *GetUnpaidInvoicesToBePaidRequest) Validate() error {
 	if err := validator.ValidateRequest(r); err != nil {
 		return err
 	}
+	if err := types.ValidateCurrencyCode(r.Currency); err != nil {
+		return err
+	}
 	return nil
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b600371 and bfc2396.

📒 Files selected for processing (5)
  • internal/api/dto/invoice.go (1 hunks)
  • internal/service/invoice.go (5 hunks)
  • internal/service/wallet.go (7 hunks)
  • internal/service/wallet_test.go (5 hunks)
  • internal/types/settings.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
internal/api/dto/invoice.go (1)
internal/validator/validator.go (1)
  • ValidateRequest (35-52)
internal/types/settings.go (2)
internal/errors/builder.go (1)
  • NewErrorf (21-23)
internal/errors/errors.go (1)
  • ErrValidation (16-16)
internal/service/wallet.go (8)
internal/service/settings.go (1)
  • NewSettingsService (29-33)
internal/types/settings.go (1)
  • SettingKeyInvoiceConfig (14-14)
ent/wallet/where.go (7)
  • CreditBalance (129-131)
  • Description (119-121)
  • ID (14-16)
  • EnvironmentID (99-101)
  • Balance (124-126)
  • CustomerID (109-111)
  • Currency (114-116)
internal/domain/wallet/transaction.go (1)
  • Transaction (12-32)
internal/types/wallet.go (1)
  • WalletTxReferenceTypeExternal (99-99)
internal/types/payment.go (2)
  • PaymentStatusPending (13-13)
  • PaymentStatusSucceeded (15-15)
internal/types/webhook.go (1)
  • WebhookEventWalletTransactionCreated (62-62)
internal/api/dto/invoice.go (1)
  • GetUnpaidInvoicesToBePaidRequest (1218-1224)
internal/service/invoice.go (6)
internal/api/dto/invoice.go (3)
  • GetUnpaidInvoicesToBePaidRequest (1218-1224)
  • GetUnpaidInvoicesToBePaidResponse (1233-1245)
  • InvoiceResponse (755-877)
internal/types/settings.go (1)
  • SettingKeyInvoiceConfig (14-14)
internal/types/payment.go (1)
  • PaymentStatusSucceeded (15-15)
internal/service/wallet.go (1)
  • NewWalletService (97-102)
internal/types/currency.go (1)
  • IsMatchingCurrency (82-84)
internal/types/price.go (1)
  • PRICE_TYPE_USAGE (96-96)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: deploy
🔇 Additional comments (14)
internal/api/dto/invoice.go (1)

1233-1245: LGTM!

The response DTO is well-structured with clear field documentation. The separation of TotalUnpaidUsageCharges and TotalUnpaidFixedCharges enables the wallet service to use only usage charges for balance calculations as intended by this PR.

internal/service/wallet_test.go (2)

795-798: LGTM - Test expectations correctly reflect the new usage-only balance calculation.

The updated comments and expected values align with the PR's behavioral change where wallet balance now excludes unpaid invoices and only considers usage charges. The calculation 1000 - 123 = 877 is correct.


1812-1816: LGTM - Entitlement test expectations are consistent with the new balance logic.

All four test scenarios correctly reflect that wallet balance now only includes usage charges (not unpaid invoices). The calculations are consistent:

  • With entitlements affecting usage: 1000 - 78 = 922
  • With disabled entitlements (baseline): 1000 - 123 = 877

Also applies to: 1837-1840, 1861-1864, 1894-1897

internal/types/settings.go (3)

117-117: LGTM - Safe default for new setting.

The default value of false for auto_complete_purchased_credit_transaction is a safe choice. This ensures existing behavior is preserved and requires explicit opt-in for the auto-complete flow.


186-233: Partial update logic is well-implemented.

The approach of checking for the presence of required fields to determine whether full validation should proceed is sensible. This allows updating just due_date_days or auto_complete_purchased_credit_transaction without requiring all other fields.


212-219: LGTM - Boolean validation is consistent with existing patterns.

The validation correctly checks the type and provides a clear error message if the value is not a boolean. This is consistent with the validation pattern used for auto_cancellation_enabled elsewhere in the file.

internal/service/wallet.go (6)

428-441: LGTM - Safe extraction of auto_complete setting with sensible default.

The type assertion with ignored ok value safely defaults to false if the setting is missing or has an unexpected type. This preserves existing behavior and requires explicit configuration to enable auto-complete. Good debug logging is included.


446-506: LGTM - Clean conditional logic for auto-complete vs pending transactions.

The implementation correctly differentiates between auto-complete and pending flows:

  • Auto-complete: Transaction marked COMPLETED, balance updated immediately, credits available
  • Non-auto-complete: Transaction marked PENDING, balance unchanged, zero credits available

This ensures wallet balance only reflects completed transactions.


522-557: LGTM - Invoice creation correctly reflects auto-complete state.

The invoice metadata includes the auto_completed flag for traceability, and the PaymentStatus is correctly set to SUCCEEDED for auto-complete or PENDING otherwise. This maintains consistency between the wallet transaction and invoice states.


658-669: LGTM - Improved idempotency handling for auto-completed transactions.

The method now correctly handles the case where a transaction was auto-completed by returning success (nil) instead of an error. Downgrading to Debug log level is appropriate since this is expected behavior, not an anomaly. This prevents issues if payment webhooks fire for already-completed transactions.


920-951: Verify: Balance calculation now uses usage charges only from unpaid invoices.

The balance calculation now uses resp.TotalUnpaidUsageCharges instead of the total unpaid amount. This means fixed charges from unpaid invoices are excluded from the wallet's pending charges calculation.

Please confirm this is the intended behavior - that the wallet balance should only reflect usage-based charges, not fixed subscription fees from unpaid invoices.


588-596: LGTM - Webhook publication timing is correct.

The webhook is published immediately only for auto-completed transactions. For pending transactions, the webhook will be published when completePurchasedCreditTransaction is called after payment succeeds (line 739). This prevents duplicate events and ensures webhooks fire at the appropriate time.

internal/service/invoice.go (2)

174-197: Using GetSettingWithDefaults for invoice_config is appropriate

Replacing direct config fetch with settingsService.GetSettingWithDefaults(ctx, types.SettingKeyInvoiceConfig) before dto.ConvertToInvoiceConfig is a good move: it centralizes defaults and keeps the conversion logic in one place. Behavior looks correct as long as the default invoice_config shape matches what ConvertToInvoiceConfig expects, which seems to be the intent of the settings refactor.


34-55: InvoiceService interface: GetUnpaidInvoicesToBePaid signature change is properly propagated

The signature change to GetUnpaidInvoicesToBePaid(ctx context.Context, req dto.GetUnpaidInvoicesToBePaidRequest) (*dto.GetUnpaidInvoicesToBePaidResponse, error) is correctly implemented across all locations. The call site in wallet.go (line 921) and all implementations in invoice.go are consistent with the new signature, and the corresponding DTOs are properly defined with validation methods. No orphaned references to an old signature were found.

Comment on lines +1142 to +1163
// If invoice is for a purchased credit (has wallet_transaction_id in metadata) and the payment status transitioned to succeeded,
// complete the wallet transaction to credit the wallet
if status == types.PaymentStatusSucceeded {
// Check if this invoice is for a purchased credit (has wallet_transaction_id in metadata)
if inv.Metadata != nil {
if walletTransactionID, ok := inv.Metadata["wallet_transaction_id"]; ok && walletTransactionID != "" {
walletService := NewWalletService(s.ServiceParams)
if err := walletService.CompletePurchasedCreditTransactionWithRetry(ctx, walletTransactionID); err != nil {
s.Logger.Errorw("failed to complete purchased credit transaction",
"error", err,
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
} else {
s.Logger.Debugw("successfully completed purchased credit transaction",
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
}
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Wallet completion in UpdatePaymentStatus: consider Overpaid + deduplication

Adding wallet completion for purchased-credit invoices to UpdatePaymentStatus makes manual status transitions consistent with reconciliation and avoids stranded wallet transactions. A couple of details to consider:

  • You only complete the purchased-credit wallet transaction when status == types.PaymentStatusSucceeded. In ReconcilePaymentStatus you treat both SUCCEEDED and OVERPAID as “fully paid” for wallet completion. If someone manually moves a purchased-credit invoice to OVERPAID, the wallet would not be credited here. If you want parity with reconciliation, consider:
- if status == types.PaymentStatusSucceeded {
+ if status == types.PaymentStatusSucceeded || status == types.PaymentStatusOverpaid {
  • This block duplicates the logic already present in ReconcilePaymentStatus (down to logging keys). Extracting a small helper, e.g. completePurchasedCreditIfApplicable(ctx, inv, status), would reduce drift risk between the two paths.

Functionally this is otherwise sound: the guard against existing payment records above prevents this manual path from overlapping with the reconciliation path.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If invoice is for a purchased credit (has wallet_transaction_id in metadata) and the payment status transitioned to succeeded,
// complete the wallet transaction to credit the wallet
if status == types.PaymentStatusSucceeded {
// Check if this invoice is for a purchased credit (has wallet_transaction_id in metadata)
if inv.Metadata != nil {
if walletTransactionID, ok := inv.Metadata["wallet_transaction_id"]; ok && walletTransactionID != "" {
walletService := NewWalletService(s.ServiceParams)
if err := walletService.CompletePurchasedCreditTransactionWithRetry(ctx, walletTransactionID); err != nil {
s.Logger.Errorw("failed to complete purchased credit transaction",
"error", err,
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
} else {
s.Logger.Debugw("successfully completed purchased credit transaction",
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
}
}
}
}
// If invoice is for a purchased credit (has wallet_transaction_id in metadata) and the payment status transitioned to succeeded,
// complete the wallet transaction to credit the wallet
if status == types.PaymentStatusSucceeded || status == types.PaymentStatusOverpaid {
// Check if this invoice is for a purchased credit (has wallet_transaction_id in metadata)
if inv.Metadata != nil {
if walletTransactionID, ok := inv.Metadata["wallet_transaction_id"]; ok && walletTransactionID != "" {
walletService := NewWalletService(s.ServiceParams)
if err := walletService.CompletePurchasedCreditTransactionWithRetry(ctx, walletTransactionID); err != nil {
s.Logger.Errorw("failed to complete purchased credit transaction",
"error", err,
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
} else {
s.Logger.Debugw("successfully completed purchased credit transaction",
"invoice_id", inv.ID,
"wallet_transaction_id", walletTransactionID,
)
}
}
}
}
🤖 Prompt for AI Agents
In internal/service/invoice.go around lines 1142 to 1163, the wallet completion
code in UpdatePaymentStatus only runs for PaymentStatusSucceeded and duplicates
logic from ReconcilePaymentStatus; change it to treat OVERPAID the same as
SUCCEEDED (i.e. run when status == types.PaymentStatusSucceeded || status ==
types.PaymentStatusOverpaid) and refactor the duplicated logic into a small
helper function (e.g., completePurchasedCreditIfApplicable(ctx, inv, status) or
completePurchasedCreditIfApplicable(ctx, inv)) that checks inv.Metadata for
"wallet_transaction_id", calls the wallet service
CompletePurchasedCreditTransactionWithRetry, and performs the same logging so
both UpdatePaymentStatus and ReconcilePaymentStatus call that helper to avoid
drift.

subratsahilgupta and others added 2 commits December 7, 2025 17:25
feat(wallet): resolve auto-completed purchased credit invoice line items' value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants