Velo Payments
Bug bounty Managed triageVelo Payments International Ltd.
Card acquiring, merchant tooling and payout rails. Sandbox credentials, or no report.
- Accepting reports
- $500 – $50,000
- 9 assets in scope
- Launched Oct 2019
- velopay.example
Read the policy · first response 1 business day
Response times
- first response
- 2 hours
- triage
- 1 business day
- reward
- 11 days
- resolution
- 31 days
Program to date
- Resolved
- 1,864
- Total paid
- $3M
- Thanked
- 409
- Average
- $5,186
Rewards by severity
Final amounts depend on demonstrated impact, report quality and asset criticality.
| Severity | CVSS | Reward | Typical findings |
|---|---|---|---|
| Critical | 9.0 – 10.0 | $15,000 – $50,000 | Unauthenticated reach into primary account numbers, forged settlement or payout instructions, extraction of a signing key, any path that moves merchant funds. |
| High | 7.0 – 8.9 | $5,500 – $14,000 | Cross-merchant access to transaction records, authentication bypass on the dashboard, a webhook replay that credits a balance, token vault confusion between merchants. |
| Medium | 4.0 – 6.9 | $1,400 – $5,000 | Object reference flaws exposing merchant metadata, stored scripting behind dashboard authentication, refund logic that can be driven past its configured limit. |
| Low | 0.1 – 3.9 | $500 – $1,200 | Session fixation on a low-value flow, error text naming internal services, an API key that keeps working for a few minutes after rotation. |
In scope
9 assets listed, 8 eligible for a reward. Anything not on this list is out of scope.
| Asset | Type | Max severity | Reward | Notes |
|---|---|---|---|---|
| https://dashboard.velopay.example | URL | Critical | Eligible | Merchant dashboard. Sandbox merchants only. Authenticating with a live merchant account ends your participation, not just the report. |
| https://api.velopay.example/v4 | API | Critical | Eligible | Charges, refunds, disputes and balances. Keys must carry the sk_sbx_ prefix. 40 rps on reads, 5 rps on anything that writes to the ledger. |
| https://checkout.velopay.example | URL | Critical | Eligible | Hosted payment page. Script integrity, frame ancestry, postMessage origins and field overlays are named targets since the March 2025 PCI DSS 4.0 deadline. |
| https://hooks.velopay.example | API | Critical | Eligible | Webhook delivery and signature verification, on the v2 signing scheme since November 2025. Replay and signature stripping pay at the top band. |
| https://payouts.velopay.example/v2 | API | Critical | Eligible | Payout initiation and bank-instrument management, in sandbox since September 2026. Each test merchant now ships with its own payout ledger. |
| Velo iOS SDK | iOS | High | Eligible | Swift Package Manager distribution. Tokenisation, pinning and keychain handling. Release builds only; a debug configuration is not our shipped artefact. |
| Velo Android SDK | Android | High | Eligible | Tokenisation, secure field rendering, and anything that lets the host application read entered card data. |
| https://api.velopay.example/v3 | API | Medium | Eligible | Frozen since August 2024 and caps at Medium regardless of score. Turns off on 31 March 2027; a finding that also reproduces on v4 belongs on v4. |
| vault.velopay.example | Network | Critical | No reward | Token vault inside the cardholder data environment. Reachable only through the API above. Assessed under our PCI programme, so it carries no reward: prove the path, stop, and tell us. |
Out of scope
| Asset | Why |
|---|---|
| Live merchant accounts and any real cardholder data | Prohibited without exception. Touching live cardholder data is handled as an incident, voids safe harbor, and ends participation permanently. |
| Acquiring banks and card-network systems reached through our APIs | Other people's infrastructure. We have no authority to authorise testing there and cannot protect you if you try. |
| Storefronts and plugins that embed our checkout | Merchant-owned code running on merchant hosting. That report goes to the merchant. |
| docs.velopay.example | Documentation and reference content. No authentication, no merchant data, no ledger behind it. |
| status.velopay.example | Hosted by our status provider under their own disclosure terms. |
| Sandbox test keys and reserved test card numbers | Published on purpose. They authorise nothing and route nowhere. |
Findings that will be closed as informative
- Anything obtained with a live merchant account, a real card, or real cardholder data.
- Card enumeration, BIN sweeps or authorisation probing against the live network.
- Scanner findings with no manual validation and no stated financial impact.
- Pinning or tamper-detection findings against a build configuration we do not ship.
- Content spoofing and text injection with no route to a payment decision.
- Rate-limit observations on sandbox endpoints, which are deliberately permissive so you can work.
- Findings that need a rooted or jailbroken device with a debugger already attached.
- Password composition, session timeout and cookie flags on pages that hold no merchant data.
- Third-party library advisories with no reachable path shown in our code.
- Race conditions shown only against the sandbox ledger's overnight batch, which does not exist in production.
Program policy
Program overview
Velo Payments acquires card transactions for roughly 52,000 merchants, runs the dashboard those merchants manage their business in, and settles funds across payout rails we operate ourselves. The asset is money and the record of money. Every severity decision on this page resolves to one question: how close does this finding bring someone to moving, reading or forging value?
The program has run since October 2019. In that time we have resolved 1,864 reports, paid 2,997,508 USD to 409 researchers, and revised this policy eight times: twice because something went wrong, once because a regulator's deadline arrived. Triage is staffed by engineers who work on the payment stack, which is why first response averages two hours rather than two days. We pay the highest ceiling on this directory. In exchange we are the strictest program on it about how you test, and we apply that without discretion.
Testing rules and expectations
Sandbox is not a suggestion
Register a sandbox merchant at dashboard.velopay.example/sandbox. Approval is automatic and takes minutes. Sandbox credentials carry the sk_sbx_ and pk_sbx_ prefixes, and every submission must state the sandbox merchant identifier you used. Reports without one are returned unread. That rule dates from September 2022, a month after a researcher exercised a refund flow against a live merchant account and put a real primary account number in the report.
Use the reserved test instrument numbers from the sandbox documentation. Not your own card, not a colleague's, not a number obtained anywhere else.
Cardholder data
No research question requires live cardholder data to answer it. If you find a path to real primary account numbers, expiry values or authentication data, stop at the moment the path is proven, capture nothing, and tell us within the hour. We will reproduce it against instrumented data ourselves and you will be paid on our reproduction. A report that makes its case by retrieving real cardholder data is processed as a security incident rather than a submission, whatever the intent behind it.
Everything else
- No denial of service, no sustained fuzzing, no load generation against shared sandbox infrastructure.
- Leave people out of it: no phishing, no pretexting, no support calls, no password-reset attempts against employees, merchants, contractors or acquirers.
- No physical attempts against offices or staff devices.
- Do not pivot into a merchant's own systems, however easy our surface makes it look.
- State the UTC window of your session in every submission, next to the merchant identifier.
Proving write access
If you find a way to write, do not prove it by causing damage. Prove it with the smallest change that can be attributed to you and undone in the same minute.
- One or two punctuation characters. Delete a full stop, add a comma. Nothing longer, nothing visible, no payload, no changed number or amount.
- Only on a record you created yourself. Never another user's record, never site content, never anything the public can see.
- Revert within sixty seconds, in the same run, without being asked.
- Capture four states: before, after the change, after the revert, and an independent re-read confirming the revert held.
- If it cannot be reverted, do not change it. Report the write primitive and stop. A row count and a column list already prove database access.
Every request must carry headers that let us separate your traffic from a real attack in our logs:
X-Bug-Bounty: velo-payments
X-Research-Account: <the account you submit the report under>
X-Authorisation-Ref: <engagement or report reference>
X-Request-Id: <unique per request>
User-Agent: sentinel-research/<handle> (+<this page>)
scripts/proof_of_write.py performs exactly this sequence, refuses any host
outside the scope above, refuses a diff longer than two characters, always
attempts the revert, and writes a timestamped evidence file. Run it without
--execute first, then attach the evidence to your report.
Safe harbor
Testing that stays inside the scope table, uses sandbox credentials only and follows the rules above is authorised. We will not bring civil or criminal proceedings over it, and if anyone questions whether the work was allowed, we will answer them in writing on our own letterhead.
That authorisation is deliberately narrow. It does not reach live merchant accounts, real cardholder data, our acquirers, the card networks, or any merchant's own infrastructure. It ends when you retain data beyond what the proof required, disclose before the agreed date, or make payment a condition of telling us what you found.
One thing we will not pretend about: our obligations to the card brands and to our assessors are not ours to waive. Where a finding requires us to notify, we notify, and that has happened once with a researcher who did nothing wrong. Safe harbor protects you from us. It does not stop a regulated process that exists whether or not anybody behaved well.
Reward decisions
A CVSS v3.1 score opens the discussion and financial reachability settles it. Three factors carry real weight: whether funds can move, whether cardholder data is exposed, and whether a merchant boundary is crossed. A dashboard object-reference flaw that exposes another merchant's settlement schedule outranks a technically noisier bug confined to your own account.
Whoever files first with a working reproduction takes the award. A chain is one award at the severity of its outcome, never one award per link. We add 20% where a report identifies the systemic cause instead of a single instance, and more at our discretion where the write-up changes how we design a control. Findings that require merchant collusion or an already-compromised merchant device drop by at least one band.
Disclosure policy
One hundred and twenty days from triage. The window is longer than most because payment changes go through certification before they ship, and we would rather commit to a date we can hold than miss a shorter one. You get a written update every fourteen days without having to ask.
Publication needs our confirmation that the fix is live in every region. Remove merchant identifiers, transaction references, internal service names, and any sandbox value that maps back to a real entity. We review drafts in five business days and we do not touch your technical conclusions.
Report quality
- The sandbox merchant identifier and the key prefix you used.
- The endpoint, the complete request and response, and the SDK version where one is involved.
- Steps a payments engineer can follow without coming back to you with a question.
- One sentence of financial impact: what moves, what leaks, whose money.
- The UTC start and end of the session.
- Anything you left behind in the sandbox ledger, so reconciliation can clear it in the morning.
Hall of fame
Researchers who have reported valid issues to this program.
| # | Researcher | Country | Reports | Points |
|---|---|---|---|---|
| 1 | ledgerfox | United Kingdom | 61 | 9,140 |
| 2 | settle_nine | Netherlands | 52 | 8,265 |
| 3 | tokenzero | Singapore | 67 | 7,688 |
| 4 | iso8583_iv | Poland | 44 | 6,402 |
| 5 | ana.ferro | Portugal | 48 | 5,713 |
| 6 | threeds_kim | South Korea | 33 | 4,990 |
| 7 | hookreplay | Canada | 39 | 4,215 |
| 8 | chargeback_cat | Mexico | 30 | 3,604 |
| 9 | pan_scrub | Israel | 21 | 3,011 |
| 10 | midnight_settle | Australia | 26 | 2,566 |
| 11 | rdx.kh | Kenya | 19 | 2,098 |
| 12 | acq_drift | Brazil | 17 | 1,744 |
| 13 | sepa_sam | Germany | 12 | 1,260 |
| 14 | idem_key | Indonesia | 8 | 883 |
Program updates
-
Payout rails testable in sandbox
Payout initiation and bank-instrument management are open at the Critical band. Every sandbox merchant now gets its own payout ledger so a failed test cannot disturb anyone else's reconciliation.
-
Critical ceiling raised to 50,000 USD
Report VP-2025-118 replayed a webhook against a reused idempotency key and credited a sandbox balance twice. The band it landed in was worth less than the bug, so the ceiling went from 30,000 to 50,000 for reports triaged on or after today.
-
Webhook signing v2 shipped, with credit
The replay finding from October is fixed by a signing scheme that binds the merchant, the event identifier and the delivery attempt. The reporter is named in the release note and reviewed the design before it shipped.
-
Script integrity on the payment page is a named target
PCI DSS 4.0 requirements 6.4.3 and 11.6.1 take effect today. Injection of third-party script into the hosted payment page is explicitly Critical from now on, and the token vault moved to report-only at the same time because it is assessed under the PCI programme rather than here.
-
v3 API frozen and capped at Medium
No further feature work on v3, and no finding against it pays above Medium regardless of score. Migration guidance went out to the 1,300 merchants still on it.
-
Mobile SDKs brought in-house
The iOS and Android SDKs left the contractor who built them and are maintained by our own team. Both are in scope at High, release configuration only.
-
Sandbox merchant identifier is mandatory on every report
Submissions without one are returned unread. This is the direct result of last month's incident and it is not waived for anybody, including researchers we have paid ten times.
-
A live-account test triggered a card-brand notification
A researcher exercised a refund flow against a live merchant account and pasted a real primary account number into the report. Nothing was stolen and nobody acted in bad faith. It still cost four weeks of remediation and a notification we could not avoid making.
-
First response cut to two hours
Triage moved to a follow-the-sun rotation across two offices. Reports that arrive overnight in Europe are read before European business hours start.
-
Disputes and chargebacks added to scope
The dispute lifecycle, evidence upload and representment endpoints are testable in sandbox. Evidence documents are the interesting part: they are the only file upload a merchant can reach.
-
Open to everyone
Eight months of private testing with nineteen researchers ends today. The queue takes submissions from anyone who can register a sandbox merchant.
-
Program launched, sandbox only
One triager, four bands, and a Critical ceiling of 8,000 USD. The sandbox-only rule was written on the first day and has never been relaxed.