Contributing to OwnPay โ
First off - thank you for considering a contribution to OwnPay! ๐ Whether it's a bug report, a new payment gateway, a translation, a documentation fix, or a feature, every contribution helps make self-hosted, open-source payment infrastructure better for everyone.
This guide explains how to get involved effectively.
๐ Code of Conduct โ
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold it. Please report unacceptable behavior to [email protected].
๐งญ Ways to Contribute โ
- ๐ Report bugs - open a clear, reproducible issue.
- ๐ก Suggest features - start a discussion or feature request.
- ๐ Build a gateway/plugin - add a payment gateway or add-on (see below).
- ๐ Translate - add or improve a language catalog (see TRANSLATIONS.md).
- ๐ Improve docs - fix typos, clarify guides, expand examples.
- ๐งน Improve code - fix bugs, add tests, refactor with care.
Not sure where to start? Look for issues labelled
good first issueorhelp wanted.
๐ Getting Set Up โ
- Fork the repository and clone your fork.
- Follow Local Setup to get a local instance running (~2 minutes).
- Create a feature branch from
dev(the integration branch PRs target):bashgit checkout dev git checkout -b feat/short-description
Requirements: PHP 8.3+ (bcmath, json, mbstring, openssl, pdo_mysql, curl), Composer 2, MySQL 8 / MariaDB 10.4+.
๐ Development Workflow โ
- Make your changes in a focused branch (one logical change per PR).
- Add or update tests for any behavior you change.
- Run the full local check suite (this is what CI runs):bash
composer test # PHPUnit - all tests must pass composer analyse # PHPStan - must stay clean at level 9 composer lint # Twig + JS + CSS linting - Commit with a clear message and a DCO sign-off (see below).
- Push to your fork and open a Pull Request against
dev.
โ PRs must pass
composer test,composer analyse, andcomposer lintbefore review. Green checks get reviewed faster.
๐ฏ Coding Standards โ
OwnPay maintains a high quality bar. Please match the existing code and these rules:
- Strict types everywhere. Every PHP file starts with
declare(strict_types=1);as its first statement (no BOM). - PHPStan level 9 must stay green. Don't suppress errors with baselines,
@phpstan-ignore, or needless casts - fix the root cause. - Money is always bcmath strings, never floats. Financial correctness is non-negotiable.
- Tenant scoping is mandatory. Never run a scoped query without
forTenant()/*Scoped(); useforAllTenants()only for deliberate owner-level views. - Build URLs via
DomainUrlService(buildCheckoutUrl(),buildCallbackUrl()) - never hardcode a host (white-label domains depend on this). - CSRF tokens via
SecurityHelpers::csrfToken()- never read$_SESSIONdirectly. - Prepared statements only. No string-interpolated SQL, ever.
- Escape output. Twig autoescaping stays on; never
|rawuntrusted data. - Keep it lean. No new heavyweight dependencies without discussion; prefer the existing first-party utilities.
- Comments explain why, not what. Document non-obvious decisions.
For the full feature inventory, see the Feature Reference. For the bigger picture, read the Architecture Guide.
๐ Contributing a Payment Gateway or Plugin โ
Gateways and add-ons are plugins under modules/:
- Create
modules/gateways/<slug>/with amanifest.json(metadata, capabilities, CSP origins, icon). - Add an adapter class implementing
OwnPay\Gateway\GatewayAdapterInterface(use theGatewayDefaultstrait for no-op defaults). - Declare
supportedCurrencies()accurately (return[]for "any currency"). - Keep the plugin within the sandbox rules - no
exec,shell_exec,eval, raw PDO, etc. - Test the full flow (initiate โ callback โ verify โ refund) locally.
See the gateway developer guide on Gateway Developer Guide for the full contract and examples.
๐ Contributing Translations โ
OwnPay has full i18n for both the admin panel and customer checkout. To add or update a language, follow TRANSLATIONS.md - create a dot-notation JSON catalog (keep :placeholders intact) and place core languages in config/languages/.
โ๏ธ Commit Messages & DCO Sign-Off โ
We use the Developer Certificate of Origin (DCO). By signing off, you certify you have the right to submit the contribution under the project's license.
Add a sign-off line to every commit by using the -s flag:
git commit -s -m "feat(gateway): add Acme Pay adapter"This appends:
Signed-off-by: Your Name <[email protected]>Please write clear messages. We encourage Conventional Commits style (feat:, fix:, docs:, refactor:, test:, chore:), though it isn't strictly enforced.
๐ฅ Pull Request Guidelines โ
- Keep PRs focused - one logical change each. Split large work into reviewable pieces.
- Fill out the PR description: what changed, why, and how to test it.
- Link the related issue (e.g.
Closes #123). - Update documentation and tests alongside code.
- Be responsive to review feedback - we review with care because this is payment software.
- Ensure all CI checks are green.
โ๏ธ Licensing of Contributions โ
OwnPay is licensed under the GNU AGPL-3.0. By submitting a contribution, you agree that your work is licensed under the same AGPL-3.0 license as the project (inbound = outbound), and you certify its origin via your DCO sign-off. No separate CLA is required.
๐ Thank You โ
Every issue, PR, translation, and idea moves OwnPay forward. We're building this in the open, for the community - and we're glad you're here.
Questions about contributing? Reach out at [email protected] or open a discussion.
โค๏ธ Built by the Community, for the Community.