Skip to content

Allow community admins to configure payment methods for order wizard - Issue292#795

Open
Luquitasjeffrey wants to merge 15 commits intomainfrom
issue292
Open

Allow community admins to configure payment methods for order wizard - Issue292#795
Luquitasjeffrey wants to merge 15 commits intomainfrom
issue292

Conversation

@Luquitasjeffrey
Copy link
Copy Markdown
Collaborator

@Luquitasjeffrey Luquitasjeffrey commented May 4, 2026

Fixes #292
Continues #786

Summary
Adds a payment_methods field (array of strings) to the Community model, analogous to community.currencies
Community admins can configure payment methods via a new wizard scene (UPDATE_PAYMENT_METHODS_COMMUNITY_WIZARD_SCENE_ID) accessible from the community admin panel
When a user creates an order (/buy or /sell) in a community that has payment methods configured, the order wizard replaces the free-text payment method input with an inline keyboard allowing selection of one or more methods; the
final value text in the published order is a comma-joined string of all selected methods

Summary by CodeRabbit

  • New Features

    • Community admins can define, edit, reset, and save a list of accepted payment methods via an in-chat wizard; order creation lets users multi-select community payment methods with confirm or choose a custom method (falls back to free-text if none).
  • Localization

    • Added translations for payment-methods flows in 10 languages (EN, DE, ES, FR, IT, PT, RU, UK, KO, FA).
  • Models / Config

    • Communities now store payment methods; sample config adds a max-methods limit.
  • Tests

    • Added tests covering the order/payment-methods selection and flows.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Warning

Rate limit exceeded

@Luquitasjeffrey has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 49 minutes and 4 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ 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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cb578267-25e3-42d7-988f-fd3b684d6c47

📥 Commits

Reviewing files that changed from the base of the PR and between d01c1af and 4315a93.

📒 Files selected for processing (1)
  • .env-sample

Walkthrough

Adds community-level payment methods: model field, admin wizard and callback/button to edit methods, order-flow multi-select integration, middleware registration for the wizard, tests, and i18n strings across multiple locales.

Changes

Community Payment Methods

Layer / File(s) Summary
Data Model & Types
models/community.ts, bot/modules/community/communityContext.ts
ICommunity gains payment_methods: string[]; CommunityWizardState adds selectedMethods: string[].
Wizard Scene
bot/modules/community/scenes.ts
New updatePaymentMethodsCommunityWizard scene: shows current methods, accepts comma-separated input (trims/filters), enforces MAX_COMMUNITY_PAYMENT_METHODS limit, saves to community.payment_methods, and adds /reset to clear and persist an empty array.
Middleware Registration
bot/middleware/stage.ts
Registers CommunityModule.Scenes.updatePaymentMethodsCommunityWizard in the scenes array so generic exit/help commands are applied.
Community UI Wiring
bot/modules/community/messages.ts, bot/modules/community/index.ts, bot/modules/community/commands.ts
Inserts an inline "edit payment methods" button into updateCommunityMessage; registers editPaymentMethodsBtn_<24hex> action to call commands.updateCommunity(..., 'payment_methods'); updateCommunity now routes the 'payment_methods' field into the new wizard.
Order Flow Integration
bot/modules/orders/scenes.ts
Reworks order-creation payment step to support multi-select from community.payment_methods (toggle buttons, confirm requiring ≥1 selection, custom free-text path); uses wizard.state.selectedMethods and derives final paymentMethod as sanitized comma-joined selections or fallback single method text.
Localization
locales/*.yaml (en, de, es, fa, fr, it, ko, pt, ru, uk)
Adds translation keys and messages for managing community payment methods, prompts, selection/confirmation, validation, reset, custom method label, and wizard command help.
Config Sample
.env-sample
Adds MAX_COMMUNITY_PAYMENT_METHODS=15 sample variable.
Tests
tests/bot/modules/orders/scenes.spec.ts
New test suite exercising the order payment-method step: empty-method prompt, rendering/selecting keyboard, multi-select toggling+confirm behavior, confirming with no selection, custom-method fallback, and direct free-text input handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Catrya
  • grunch

Poem

🐰
I hopped through keys and built a scene,
Methods listed, tidy and keen.
Toggle carrots, type and save—
Communities pay, orders behave.
/reset a hop, then onward I cleave. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly identifies the main feature added: allowing community admins to configure payment methods for the order wizard, with issue reference #292.
Linked Issues check ✅ Passed The PR implements all core requirements from issue #292: adds payment_methods field to Community model, creates a wizard scene for admin configuration, replaces free-text with multi-select UI in order wizard, and persists selections as comma-joined strings.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the payment methods feature: model updates, wizard scenes, UI messaging, localization, and tests. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue292

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
Review rate limit: 0/1 reviews remaining, refill in 49 minutes and 4 seconds.

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

Copy link
Copy Markdown
Contributor

@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: 3

🧹 Nitpick comments (1)
locales/uk.yaml (1)

706-715: 💤 Low value

New keys are placed outside the established module section boundaries.

The file groups keys with explicit # START modules/<name> / # END modules/<name> markers. The 10 new keys logically belong to two modules:

  • Community-side (enter_community_payment_methods, current_payment_methods, payment_methods_wizard_commands, payment_methods_saved, payment_methods_reset, community_payment_methods) → # START modules/community# END modules/community
  • Order-side (select_payment_methods, confirm_payment_methods, no_payment_method_selected, custom_payment_method) → # START modules/orders# END modules/orders

Adding them after the last section's closing marker makes the structure inconsistent and harder to maintain as the file grows, especially since all other locale files added in this PR presumably follow the same pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@locales/uk.yaml` around lines 706 - 715, These new translation keys were
added outside module boundaries; move the community-related keys
(community_payment_methods, enter_community_payment_methods,
current_payment_methods, payment_methods_wizard_commands, payment_methods_saved,
payment_methods_reset) into the block between the "# START modules/community"
and "# END modules/community" markers, and move the order-related keys
(select_payment_methods, confirm_payment_methods, no_payment_method_selected,
custom_payment_method) into the "# START modules/orders" … "# END
modules/orders" block so they follow the established module grouping and file
structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@bot/modules/community/scenes.ts`:
- Around line 942-955: The handler currently treats empty or comma-only input as
methods = [] and saves that, clearing community.payment_methods; change it to
detect methods.length === 0 after trimming/splitting and instead send a reply
prompting the user to provide at least one method (e.g., using
ctx.reply(ctx.i18n.t('provide_payment_methods'))), do not set
community.payment_methods or call community.save(), and keep the wizard open
(i.e., return without advancing or exiting the scene) so only an explicit /reset
clears methods.

In `@bot/modules/orders/scenes.ts`:
- Around line 70-73: replaceRegex and paymentMethod are never reassigned so
change their declarations from let to const to satisfy ESLint; update the
declarations for replaceRegex, paymentMethod (which references selectedMethods
and method) to use const so the bindings are immutable while preserving the
existing logic in this block.
- Around line 236-252: When entering the custom payment flow, clear any
previously chosen predefined selections so they don't override the custom text
later; inside the pm_custom branch (the handler assigned to ctx.wizard.state),
reset ctx.wizard.state.selectedMethods = [] (or delete it) before setting
ctx.wizard.state.method = text and calling ctx.wizard.state.updateUI(), and
ensure any serialization logic prefers method when method is set (leave existing
serialization but ensure selectedMethods is emptied here).

---

Nitpick comments:
In `@locales/uk.yaml`:
- Around line 706-715: These new translation keys were added outside module
boundaries; move the community-related keys (community_payment_methods,
enter_community_payment_methods, current_payment_methods,
payment_methods_wizard_commands, payment_methods_saved, payment_methods_reset)
into the block between the "# START modules/community" and "# END
modules/community" markers, and move the order-related keys
(select_payment_methods, confirm_payment_methods, no_payment_method_selected,
custom_payment_method) into the "# START modules/orders" … "# END
modules/orders" block so they follow the established module grouping and file
structure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9650ec14-ccff-4963-a8e8-01c53055cf36

📥 Commits

Reviewing files that changed from the base of the PR and between 41751eb and f80bc90.

📒 Files selected for processing (18)
  • bot/middleware/stage.ts
  • bot/modules/community/commands.ts
  • bot/modules/community/communityContext.ts
  • bot/modules/community/index.ts
  • bot/modules/community/messages.ts
  • bot/modules/community/scenes.ts
  • bot/modules/orders/scenes.ts
  • locales/de.yaml
  • locales/en.yaml
  • locales/es.yaml
  • locales/fa.yaml
  • locales/fr.yaml
  • locales/it.yaml
  • locales/ko.yaml
  • locales/pt.yaml
  • locales/ru.yaml
  • locales/uk.yaml
  • models/community.ts

Comment thread bot/modules/community/scenes.ts
Comment thread bot/modules/orders/scenes.ts Outdated
Comment thread bot/modules/orders/scenes.ts
Copy link
Copy Markdown
Contributor

@mostronatorcoder mostronatorcoder Bot left a comment

Choose a reason for hiding this comment

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

I’m requesting changes because the current data model for community payment methods is ambiguous and can corrupt valid values.

The feature stores community payment methods by splitting admin input on commas, and later stores selected methods as a comma-joined string again. That means a legitimate method containing a comma cannot be represented safely: it will be split when configured and flattened again when persisted to the order.

Concretely, the problem is in:

  • bot/modules/community/scenes.ts (text.split(',') when saving community payment methods)
  • bot/modules/orders/scenes.ts (selected.join(', ') when confirming the selection)

So before merging, the implementation needs one of these two fixes:

  1. Use a representation that is not ambiguous, or
  2. Explicitly reject commas in payment method names and validate that constraint at input time with a clear user-facing error

I also expected test coverage for the new wizard flow and selection logic. This PR adds multiple new branches in order creation UX, but I do not see tests covering them. At minimum, please add tests for:

  • community with configured payment methods
  • multi-select confirmation
  • confirmation with no selection
  • custom free-text fallback
  • community without configured payment methods

Because of the data ambiguity issue, I do not think this is safe to approve yet.

@Luquitasjeffrey
Copy link
Copy Markdown
Collaborator Author

I’m requesting changes because the current data model for community payment methods is ambiguous and can corrupt valid values.

The feature stores community payment methods by splitting admin input on commas, and later stores selected methods as a comma-joined string again. That means a legitimate method containing a comma cannot be represented safely: it will be split when configured and flattened again when persisted to the order.

Concretely, the problem is in:

  • bot/modules/community/scenes.ts (text.split(',') when saving community payment methods)
  • bot/modules/orders/scenes.ts (selected.join(', ') when confirming the selection)

So before merging, the implementation needs one of these two fixes:

  1. Use a representation that is not ambiguous, or
  2. Explicitly reject commas in payment method names and validate that constraint at input time with a clear user-facing error

I also expected test coverage for the new wizard flow and selection logic. This PR adds multiple new branches in order creation UX, but I do not see tests covering them. At minimum, please add tests for:

  • community with configured payment methods
  • multi-select confirmation
  • confirmation with no selection
  • custom free-text fallback
  • community without configured payment methods

Because of the data ambiguity issue, I do not think this is safe to approve yet.

About the splitting of payment methods by a comma, I will dismiss it because:

  • right now, the bot replaces all commas in the payment method with an empty string, which means no published order has a payment method with a comma
  • there was no complains before about not having the ability to include commas in payment methods before
  • by separating payment methods by comma it makes the flow easier for community administrators to provide that kind of customization

Copy link
Copy Markdown
Contributor

@mostronatorcoder mostronatorcoder Bot left a comment

Choose a reason for hiding this comment

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

Thanks for the update. The new test coverage improves this PR substantially, and the intended free-text fallback behavior is now clear.

I initially had concerns about comma ambiguity in payment method names, but after re-reading the admin prompt, the UX explicitly defines commas as the separator for community payment methods:

Enter the payment methods accepted in your community, separated by commas

So within the current product design, commas are effectively reserved as delimiters, which makes the behavior consistent with the prompt.

I still think explicit validation for commas or duplicate entries would make the flow more robust, but at this point I see that as a follow-up improvement rather than a merge blocker.

The added tests cover the main new branches in the order wizard, and the implementation now looks acceptable to me.

Approved.

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (2)
bot/modules/community/scenes.ts (1)

948-951: ⚡ Quick win

Extract MAX_COMMUNITY_PAYMENT_METHODS to a module-level constant, consistent with CURRENCIES.

Line 17 establishes the pattern: const CURRENCIES = parseInt(process.env.COMMUNITY_CURRENCIES || '10'); — parsed once at module load. The new max is re-parsed on every step-2 invocation, diverging from that idiom.

♻️ Proposed refactor
 const CURRENCIES = parseInt(process.env.COMMUNITY_CURRENCIES || '10');
+const MAX_PAYMENT_METHODS = parseInt(
+  process.env.MAX_COMMUNITY_PAYMENT_METHODS || '10',
+);
-      const max = parseInt(process.env.MAX_COMMUNITY_PAYMENT_METHODS || '10');
-      if (methods.length > max) {
-        return await ctx.reply(ctx.i18n.t('max_allowed', { max }));
+      if (methods.length > MAX_PAYMENT_METHODS) {
+        return await ctx.reply(ctx.i18n.t('max_allowed', { max: MAX_PAYMENT_METHODS }));
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bot/modules/community/scenes.ts` around lines 948 - 951, The code parses
MAX_COMMUNITY_PAYMENT_METHODS inside the handler (const max =
parseInt(process.env.MAX_COMMUNITY_PAYMENT_METHODS || '10')) which duplicates
the CURRENCIES pattern; move that parse into a module-level constant (e.g.,
const MAX_COMMUNITY_PAYMENT_METHODS =
parseInt(process.env.MAX_COMMUNITY_PAYMENT_METHODS || '10');) near the existing
CURRENCIES declaration and then replace uses of the local variable max with the
module constant (refer to the handler code that checks methods.length and the
CURRENCIES symbol to align style).
tests/bot/modules/orders/scenes.spec.ts (1)

93-105: ⚡ Quick win

calledWith doesn't verify the inline keyboard markup

ctx.reply.calledWith('select_payment_methods') uses sinon's partial positional matching — it returns true even when reply is called as reply('select_payment_methods', { reply_markup: { inline_keyboard: [...] } }). The assertion therefore doesn't validate that the keyboard buttons were actually constructed and passed, so a regression dropping or malforming the keyboard would not be caught.

Consider asserting on ctx.reply.firstCall.args[1] to verify the reply_markup structure, e.g.:

🔍 Suggested assertion addition
  expect(ctx.reply.calledWith('select_payment_methods')).to.equal(true);
+ const replyMarkup = ctx.reply.firstCall.args[1]?.reply_markup;
+ expect(replyMarkup).to.be.an('object');
+ expect(replyMarkup.inline_keyboard).to.be.an('array').with.length.greaterThan(0);
  expect(ctx.wizard.next.calledOnce).to.equal(true);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/bot/modules/orders/scenes.spec.ts` around lines 93 - 105, The test
currently asserts only that ctx.reply was called with the text
'select_payment_methods' but doesn't validate the inline keyboard; update the
test for runStep0 to inspect ctx.reply.firstCall.args[1] and assert that its
reply_markup.inline_keyboard matches the expected button layout for the
community payment methods (verify button labels and callback_data structure),
while keeping the existing assertions for ctx.wizard.next and
ctx.wizard.state.selectedMethods intact; reference ctx.reply,
ctx.reply.firstCall.args, and runStep0 to locate where to add the assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bot/modules/community/scenes.ts`:
- Around line 948-951: The code parses MAX_COMMUNITY_PAYMENT_METHODS inside the
handler (const max = parseInt(process.env.MAX_COMMUNITY_PAYMENT_METHODS ||
'10')) which duplicates the CURRENCIES pattern; move that parse into a
module-level constant (e.g., const MAX_COMMUNITY_PAYMENT_METHODS =
parseInt(process.env.MAX_COMMUNITY_PAYMENT_METHODS || '10');) near the existing
CURRENCIES declaration and then replace uses of the local variable max with the
module constant (refer to the handler code that checks methods.length and the
CURRENCIES symbol to align style).

In `@tests/bot/modules/orders/scenes.spec.ts`:
- Around line 93-105: The test currently asserts only that ctx.reply was called
with the text 'select_payment_methods' but doesn't validate the inline keyboard;
update the test for runStep0 to inspect ctx.reply.firstCall.args[1] and assert
that its reply_markup.inline_keyboard matches the expected button layout for the
community payment methods (verify button labels and callback_data structure),
while keeping the existing assertions for ctx.wizard.next and
ctx.wizard.state.selectedMethods intact; reference ctx.reply,
ctx.reply.firstCall.args, and runStep0 to locate where to add the assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1389f81a-ac04-4059-a101-ddce6a9c7ffa

📥 Commits

Reviewing files that changed from the base of the PR and between 81bb1ee and d01c1af.

📒 Files selected for processing (3)
  • .env-sample
  • bot/modules/community/scenes.ts
  • tests/bot/modules/orders/scenes.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • .env-sample

Copy link
Copy Markdown
Contributor

@mostronatorcoder mostronatorcoder Bot left a comment

Choose a reason for hiding this comment

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

Thanks for the follow-up. I re-checked the PR after the latest commit, and the previous inconsistency between the in-code fallback and .env-sample is now resolved.

Making the maximum number of community payment methods configurable is a reasonable improvement, and I do not see any new blocking issue introduced by the latest changes.

The remaining thing I would still consider a future improvement is adding a test for the max-limit branch in the payment methods wizard, but I do not see that as a blocker for this PR.

Approved.

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.

Add payments methods on communities

2 participants