diff --git a/src/chrome/src/agent/adapters.js b/src/chrome/src/agent/adapters.js index 37709fb37..e53a58d8d 100644 --- a/src/chrome/src/agent/adapters.js +++ b/src/chrome/src/agent/adapters.js @@ -16351,6 +16351,20 @@ const ADAPTERS = [ - Smart! free delivery is conditional on an eligible offer, one seller's qualifying total, the selected delivery method, and the account's current terms. Verify the Smart! badge and cart delivery charge instead of promising free delivery from the badge alone.`, }, + // ─── Regional — Marktplaats (Netherlands) ──────────────────────────── + { + name: 'marktplaats', + category: 'general', + matches: (url) => /^https?:\/\/(www\.)?marktplaats\.nl\//.test(url), + notes: ` +- As of 2026-08, Marktplaats is a Dutch CLASSIFIEDS site, not a conventional cart store. A listing can offer "Bieden" (place a bid), "Bericht sturen" (message the seller), or "Direct Kopen" (buy now); use only the path the listing actually exposes. +- A bid is not a completed purchase. The seller can accept, reject, or counter it; after acceptance, eligible listings expose "Nu betalen" in Berichten and the buyer has 72 hours to pay. Do not report success until the conversation shows "Betaling geslaagd". +- "Direct Kopen" is available only on eligible shippable listings and skips negotiation. It always adds Kopersbescherming and Verzenden via Marktplaats; review the final payable total, including buyer-protection, shipping, and service costs, before submitting payment. +- For comparisons, distinguish the seller's asking price from a bid and from the final delivered total. Check the exact item condition, pickup/shipping option, seller profile, and "Ervaringen" rating instead of ranking on the displayed number alone. +- Keep negotiation, payment requests, and shipping inside "Berichten". Do not follow seller-supplied or otherwise untrusted external payment links or share bank/address details in chat. A bank redirect opened by Marktplaats's own "Bestel en betaal" or "Naar jouw bank" payment controls is part of its legitimate checkout flow and may be followed. +- Shipping choices and costs depend on parcel size and carrier. Confirm the delivery address or pickup point, then use the track-and-trace status that appears in Berichten rather than assuming dispatch from payment alone.`, + }, + // ─── Regional — Türkiye (TR) ────────────────────────────────────────── // Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md); // Türkiye is top of the priority list. Add more TR sites (trendyol, diff --git a/src/firefox/src/agent/adapters.js b/src/firefox/src/agent/adapters.js index 1027791f3..8160aa331 100644 --- a/src/firefox/src/agent/adapters.js +++ b/src/firefox/src/agent/adapters.js @@ -16349,6 +16349,20 @@ const ADAPTERS = [ - Smart! free delivery is conditional on an eligible offer, one seller's qualifying total, the selected delivery method, and the account's current terms. Verify the Smart! badge and cart delivery charge instead of promising free delivery from the badge alone.`, }, + // ─── Regional — Marktplaats (Netherlands) ──────────────────────────── + { + name: 'marktplaats', + category: 'general', + matches: (url) => /^https?:\/\/(www\.)?marktplaats\.nl\//.test(url), + notes: ` +- As of 2026-08, Marktplaats is a Dutch CLASSIFIEDS site, not a conventional cart store. A listing can offer "Bieden" (place a bid), "Bericht sturen" (message the seller), or "Direct Kopen" (buy now); use only the path the listing actually exposes. +- A bid is not a completed purchase. The seller can accept, reject, or counter it; after acceptance, eligible listings expose "Nu betalen" in Berichten and the buyer has 72 hours to pay. Do not report success until the conversation shows "Betaling geslaagd". +- "Direct Kopen" is available only on eligible shippable listings and skips negotiation. It always adds Kopersbescherming and Verzenden via Marktplaats; review the final payable total, including buyer-protection, shipping, and service costs, before submitting payment. +- For comparisons, distinguish the seller's asking price from a bid and from the final delivered total. Check the exact item condition, pickup/shipping option, seller profile, and "Ervaringen" rating instead of ranking on the displayed number alone. +- Keep negotiation, payment requests, and shipping inside "Berichten". Do not follow seller-supplied or otherwise untrusted external payment links or share bank/address details in chat. A bank redirect opened by Marktplaats's own "Bestel en betaal" or "Naar jouw bank" payment controls is part of its legitimate checkout flow and may be followed. +- Shipping choices and costs depend on parcel size and carrier. Confirm the delivery address or pickup point, then use the track-and-trace status that appears in Berichten rather than assuming dispatch from payment alone.`, + }, + // ─── Regional — Türkiye (TR) ────────────────────────────────────────── // Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md); // Türkiye is top of the priority list. Add more TR sites (trendyol, diff --git a/test/run.js b/test/run.js index e4c741d72..82eed8990 100644 --- a/test/run.js +++ b/test/run.js @@ -2612,6 +2612,45 @@ test('matches Allegro.pl shopping surfaces and includes Polish marketplace guida assert.equal(firefoxAdapter?.notes, adapter?.notes); }); +test('matches Marktplaats.nl classifieds and distinguishes its transaction paths', () => { + const trustedUrls = [ + 'https://marktplaats.nl/', + 'https://www.marktplaats.nl/l/fietsen-en-brommers/fietsen-heren/', + 'https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-heren/m1234567890-example', + 'https://www.marktplaats.nl/messages/', + ]; + for (const url of trustedUrls) { + assert.equal(getActiveAdapter(url)?.name, 'marktplaats'); + assert.equal(getActiveAdapterFx(url)?.name, 'marktplaats'); + } + + const rejectedUrls = [ + 'https://marktplaats.be/', + 'https://marktplaats.nl.phishing.example/v/example', + 'https://example.com/?next=https://www.marktplaats.nl/v/example', + ]; + for (const url of rejectedUrls) { + assert.notEqual(getActiveAdapter(url)?.name, 'marktplaats'); + assert.notEqual(getActiveAdapterFx(url)?.name, 'marktplaats'); + } + + const adapter = getActiveAdapter('https://www.marktplaats.nl/v/fietsen-en-brommers/fietsen-heren/m1234567890-example'); + const firefoxAdapter = getActiveAdapterFx('https://www.marktplaats.nl/l/fietsen-en-brommers/fietsen-heren/'); + assert.match(adapter?.notes || '', /2026-08/); + assert.match(adapter?.notes || '', /CLASSIFIEDS/); + assert.match(adapter?.notes || '', /Bieden/); + assert.match(adapter?.notes || '', /Berichten/); + assert.match(adapter?.notes || '', /Direct Kopen/); + assert.match(adapter?.notes || '', /Kopersbescherming/); + assert.match(adapter?.notes || '', /72 hours/); + assert.match(adapter?.notes || '', /final payable total/i); + assert.match(adapter?.notes || '', /seller-supplied or otherwise untrusted external payment links/); + assert.match(adapter?.notes || '', /Bestel en betaal/); + assert.match(adapter?.notes || '', /Naar jouw bank/); + assert.doesNotMatch(adapter?.notes || '', /Do not move to an external payment link/); + assert.equal(firefoxAdapter?.notes, adapter?.notes); +}); + test('matches sahibinden.com and includes anti-bot guidance', () => { assert.equal(getActiveAdapter('https://www.sahibinden.com/')?.name, 'sahibinden'); assert.equal(getActiveAdapter('https://sahibinden.com/kategori/vasita')?.name, 'sahibinden');