Affiliate Infrastructure Overhaul: PA-API Independence, 3-Button Cards, and the FANZA Sidebar Experiment
The Day Amazon Kicked Us Out
On April 10, 2026, we attempted to migrate netouyonews affiliate blocks from hand-coded HTML to Cocoon’s native [amazon asin="X"] shortcode. It looked clean — one line per book instead of fifteen.
Then we hit AssociateNotEligible:
Your account does not currently meet the eligibility requirements
to access the Product Advertising API.
Amazon’s PA-API requires 3+ completed sales in 180 days to maintain access. Our 75 clicks hadn’t converted enough. The shortcodes rendered as broken error cards visible only to admins, but public-facing product displays were reduced to bare text links.
Time to fix: 0. We had to build something that doesn’t depend on Amazon’s mood.
The 3-Button Card Architecture
We designed a hand-coded HTML card that works with zero API dependencies:
┌─────────────────────────────────────┐
│ [Book Cover Image] Title │
│ Author │
│ [Amazon] [Rakuten] [DMM] │
└─────────────────────────────────────┘
Image Sources (No API Required)
| Store | Image Source | Auth Needed |
|---|---|---|
| Amazon | m.media-amazon.com/images/P/{ASIN}.jpg | None |
| Rakuten | thumbnail.image.rakuten.co.jp/...?_ex=400x400 | App ID (search only) |
| DMM | pics.dmm.com/mono/hobby/{cid}/{cid}pl.jpg | None |
The Amazon image CDN trick (m.media-amazon.com/images/P/{ASIN}.jpg) returns book covers for any valid ASIN without authentication. This is the foundation of our PA-API-free system.
Affiliate Link Formats
| Store | URL Pattern | Tracking |
|---|---|---|
| Amazon | amazon.co.jp/dp/{ASIN}/?tag=netouyo01-22 | ✅ Associate tag |
| Rakuten | hb.afl.rakuten.co.jp/hgc/{AFF_ID}/?pc={target} | ✅ Affiliate ID |
| DMM | al.dmm.com/?lurl={target}&af_id=netouyo-990 | ✅ Affiliate ID |
Book Curation via Rakuten Books API
Instead of trusting manually-entered ASINs (which turned out to be wrong in 2 of 6 posts — 4101104409 was “不毛地帯” not “石油の世紀”), we now curate books using Rakuten’s BooksTotal Search API:
url = f'https://app.rakuten.co.jp/services/api/BooksTotal/Search/20170404'
f'?format=json&keyword={topic}&applicationId={APP_ID}&hits=3&sort=sales'
This gives us verified (title, author, ISBN, cover image) tuples. No more ASIN guessing.
DMM URL Format Discovery
DMM’s search URL format is non-obvious. We tested 5 patterns:
| Pattern | Status |
|---|---|
book.dmm.com/search/?keyword=X | ❌ Redirects to homepage |
book.dmm.com/list/?search_keyword=X | ❌ Redirects to homepage |
www.dmm.com/search/-/list/?searchstr=X | ❌ 404 |
www.dmm.com/search/=/searchstr=X/ | ✅ 200 OK |
book.dmm.com/search/index/?k=X | ❌ Redirects |
The correct format uses =/ not -/list/?. This is DMM’s proprietary URL schema that’s not documented anywhere obvious.
Batch REST API Operations
All 6 existing netouyonews articles were updated via WordPress REST API in a single batch operation:
- Fetch each post’s raw content (
?context=edit) - Extract old affiliate blocks (regex-based boundary detection)
- Rebuild with new 3-button card HTML
- POST updated content back
The entire batch (6 posts) completed in ~8 seconds with 0.3s inter-request delay.
Brand Normalization (Bonus)
While we had all posts open, we also ran a brand replacement pass:
NT Media→NT編集部(across all published posts)- Applied via REST API
str.replace()in a single pass
FANZA Sidebar Widget (A-lite MVP)
For revenue experimentation, we deployed a sticky sidebar widget with two stacked 300×300 product cards:
- Top: DMM.com hobby/figure (美少女フィギュア,
mono/hobbyAPI) - Bottom: FANZA videoa ranking #1 (
digital/videoaAPI)
DMM API Image Gotcha
DMM’s mono/hobby endpoint returns imageURL with only list and small keys — no large. But the URL pattern {cid}ps.jpg → {cid}pl.jpg works for 600px images. The API docs don’t mention this.
Deployment
Widget HTML was hand-pasted into Cocoon’s “サイドバースクロール追従” widget area (Custom HTML widget). No REST API for widget management — Cocoon’s widget areas aren’t easily addressable via WP REST.
Cocoon Shortcode: Why We Couldn’t Use It
Cocoon’s [amazon asin="X"] shortcode is elegant — one line, auto-fetches product data, renders beautiful cards with Amazon + Rakuten + DMM buttons.
But it requires PA-API access. Without it:
- Cards render as
product-item-errordivs - Admin sees “AssociateNotEligible” error
- Public sees bare “Amazonで詳細を見る” text links
Lesson: Don’t depend on third-party API availability for revenue-critical UI. Hand-coded HTML with CDN images is uglier but indestructible.
Results
| Metric | Before | After |
|---|---|---|
| Working affiliate links | 2/8 posts | 8/8 posts |
| Stores per book | 1 (Amazon only) | 3 (Amazon + Rakuten + DMM) |
| Book cover images | 0 | 3 per article |
| PA-API dependency | Yes | No |
| FANZA sidebar | None | Sticky widget (2 products) |
| Brand consistency | Mixed | NT編集部 unified |
What’s Next
- PA-API recovery: Once Amazon sales hit the 3-sale threshold, PA-API re-enables automatically. At that point, we can optionally switch back to Cocoon shortcodes — but the hand-coded system works fine as a permanent fallback.
- Rakuten Affiliate tracking: Currently using
hb.afl.rakuten.co.jpwrapper. Need to verify click attribution is working in Rakuten’s dashboard. - FANZA sidebar rotation: Currently static (manual product selection). Phase 2 would auto-rotate weekly via cron + DMM API.
--humanizelint mode: Adding AI-ism detection tovalidate_mdx.py(e.g., 冷徹, 浮き彫りにする, 紐解く).