この記事は約15分で読めます。
本文は約8971文字です
【2026年】AmazonアフィリエイトをPA-API経由でやるのは無理ゲーになった。

Amazonアフィリエイト(アソシエイト)はそもそも還元率が低くて儲かりません。
ですが商品の取り扱いの多さからアフィリエイトしやすいので商品を紹介している人は多いと思います。
Amazonアフィエイトリンクを作成する際に、商品検索、画像や価格などをPA-API経由で取得することができますが、このAPIの利用制限がめちゃくちゃ厳しくなりました。
CocoonのAmazonアフィリエイトリンクもPA-API経由で作成されますが、PA-APIの利用制限ですぐに表示できなくなります。
PochippなどもPA-APIを使うので、同じ状況です。
PA-APIの利用制限にひっかかると、商品検索ができません。
PA-APIの利用を前提としたAmazonアフィリエイト環境は全く機能しなくなってしまいました。
少なくともPochippは作成済みのAmazonリンクはPA-APIと無関係に表示できるのですが、Cocoon側はPA-APIの利用制限にかかると、一律固定のメッセージリンクに置き換わります。
これだと流石に何やってるのかわからなくなります。
CocoonからSWELLにテーマを載せ変えた際に、CocoonのAmazonショートコードをPA-APIを使用しないタイプに置き換えることにしました。
<?php
/**
* Plugin Name: Cocoon Amazon Shortcode Porting for SWELL
* Description: SWELL環境でCocoon形式の[amazon]ショートコードを動作させる互換プラグイン(直接ID指定&画像フォールバック対応版)
* Version: 1.4.0
*/
if ( ! defined( 'ABSPATH' ) ) exit;
add_shortcode( 'amazon', 'cocoon_amazon_shortcode_porting' );
function cocoon_amazon_shortcode_porting( $atts ) {
// 1. 全角・スマートクオート(” “ ″ ’ ‘)が含まれる場合の自動パース補正
if ( is_array( $atts ) ) {
$cleaned_atts = [];
foreach ( $atts as $key => $value ) {
if ( is_numeric( $key ) ) {
// asin=”4905084253″ などの未解釈属性をパース
$raw = str_replace( ['”', '“', '″', '’', '‘'], '"', $value );
if ( preg_match( '/^([a-zA-Z0-9_-]+)\s*=\s*"?(.*?)"?$/u', $raw, $m ) ) {
$cleaned_atts[$m[1]] = trim( $m[2], '"' );
}
} else {
$cleaned_atts[$key] = str_replace( ['”', '“', '″', '’', '‘'], '', $value );
}
}
$atts = array_merge( $atts, $cleaned_atts );
}
$atts = shortcode_atts( [
'asin' => '',
'kw' => '',
'title' => '',
'count' => '',
], $atts, 'amazon' );
$asin = trim( $atts['asin'] );
$kw = trim( $atts['kw'] );
$title = trim( $atts['title'] );
if ( empty( $asin ) && empty( $kw ) ) {
return '';
}
// ------------------------------------------------------------------
// 各アフィリエイトID設定(空文字の場合はボタン自体が出力されません)
// ------------------------------------------------------------------
$amazon_tracking_id = 'xxxxxxxxx-22';
$rakuten_affiliate_id = ''; // 例: '12345678.abcde' (空なら楽天市場ボタン非表示)
$yahoo_sid = ''; // 例: '1234567' (バリューコマースSID)
$yahoo_pid = ''; // 例: '8765432' (バリューコマースPID)
// 表示タイトルの決定
$display_title = ! empty( $title ) ? $title : ( ! empty( $kw ) ? $kw : 'Amazonで詳細を見る' );
$search_kw = urlencode( ! empty( $kw ) ? $kw : $display_title );
// 2. 画像URLの設定(メイン・サブ・フォールバック)
$img_primary = ! empty( $asin ) ? "https://images-na.ssl-images-amazon.com/images/P/{$asin}.01.LZZZZZZZ.jpg" : '';
$img_secondary = ! empty( $asin ) ? "https://images-na.ssl-images-amazon.com/images/P/{$asin}.01.MAIN.jpg" : '';
$img_fallback = 'https://placehold.jp/150x150.png?text=No+Image';
$img_src = ! empty( $img_primary ) ? $img_primary : $img_fallback;
// 3. onerror (404対策) および onload (1px透過画像対策) のフォールバックJavaScript
$img_js_attr = sprintf(
'onerror="if(this.src!=\'%1$s\'){this.src=\'%1$s\';}else{this.src=\'%2$s\';}" onload="if(this.naturalWidth<=1){this.src=\'%2$s\';}"',
esc_url( $img_secondary ),
esc_url( $img_fallback )
);
// 1. Amazon URL(IDがある場合のみ生成)
$amazon_url = '';
if ( ! empty( $amazon_tracking_id ) ) {
$amazon_url = ! empty( $asin )
? "https://www.amazon.co.jp/dp/{$asin}?tag={$amazon_tracking_id}"
: "https://www.amazon.co.jp/s?k={$search_kw}&tag={$amazon_tracking_id}";
}
// 2. 楽天市場 URL(IDがある場合のみ生成)
$rakuten_url = '';
if ( ! empty( $rakuten_affiliate_id ) ) {
$raw_rakuten_url = "https://search.rakuten.co.jp/search/mall/{$search_kw}/";
$rakuten_url = "https://hb.afl.rakuten.co.jp/hgc/{$rakuten_affiliate_id}/?pc=" . urlencode( $raw_rakuten_url );
}
// 3. Yahoo!ショッピング URL(SID/PID の両方がある場合のみ生成)
$yahoo_url = '';
if ( ! empty( $yahoo_sid ) && ! empty( $yahoo_pid ) ) {
$raw_yahoo_url = "https://shopping.yahoo.co.jp/search?p={$search_kw}";
$yahoo_url = "https://ck.jp.ap.valuecommerce.com/servlet/referral?sid={$yahoo_sid}&pid={$yahoo_pid}&vc_url=" . urlencode( $raw_yahoo_url );
}
ob_start();
?>
<div class="cocoon-amazon-card-port">
<div class="cap-img-box">
<?php if ( ! empty( $amazon_url ) ) : ?>
<a href="<?php echo esc_url( $amazon_url ); ?>" target="_blank" rel="noopener noreferrer nofollow">
<img src="<?php echo esc_url( $img_src ); ?>" alt="<?php echo esc_attr( $display_title ); ?>" loading="lazy" <?php echo $img_js_attr; ?>>
</a>
<?php else : ?>
<img src="<?php echo esc_url( $img_src ); ?>" alt="<?php echo esc_attr( $display_title ); ?>" loading="lazy" <?php echo $img_js_attr; ?>>
<?php endif; ?>
</div>
<div class="cap-content-box">
<div class="cap-title">
<?php if ( ! empty( $amazon_url ) ) : ?>
<a href="<?php echo esc_url( $amazon_url ); ?>" target="_blank" rel="noopener noreferrer nofollow">
<?php echo esc_html( $display_title ); ?>
</a>
<?php else : ?>
<?php echo esc_html( $display_title ); ?>
<?php endif; ?>
</div>
<div class="cap-buttons">
<?php if ( ! empty( $amazon_url ) ) : ?>
<a href="<?php echo esc_url( $amazon_url ); ?>" class="cap-btn cap-btn-amazon" target="_blank" rel="noopener noreferrer nofollow">Amazon</a>
<?php endif; ?>
<?php if ( ! empty( $rakuten_url ) ) : ?>
<a href="<?php echo esc_url( $rakuten_url ); ?>" class="cap-btn cap-btn-rakuten" target="_blank" rel="noopener noreferrer nofollow">楽天市場</a>
<?php endif; ?>
<?php if ( ! empty( $yahoo_url ) ) : ?>
<a href="<?php echo esc_url( $yahoo_url ); ?>" class="cap-btn cap-btn-yahoo" target="_blank" rel="noopener noreferrer nofollow">Yahoo!ショッピング</a>
<?php endif; ?>
</div>
</div>
</div>
<?php
return ob_get_clean();
}
// CSSスタイルの直接出力
add_action( 'wp_head', function() {
if ( is_admin() ) return;
?>
<style id="cocoon-amazon-port-css">
.cocoon-amazon-card-port {
display: flex;
gap: 16px;
border: 1px solid #e5e5e5;
border-radius: 8px;
padding: 16px;
margin: 1.5em 0;
background: #fff;
box-shadow: 0 2px 4px rgba(0,0,0,0.04);
align-items: center;
box-sizing: border-box;
}
/* 画像枠の固定と溢れ防止 */
.cocoon-amazon-card-port .cap-img-box {
flex: 0 0 120px;
width: 120px;
height: 120px;
min-width: 0;
overflow: hidden;
}
/* <a> タグを親要素いっぱいに広げる(これで max-height が効くようになります) */
.cocoon-amazon-card-port .cap-img-box a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
/* 画像サイズを 120px × 120px 以内に強制収容 */
.cocoon-amazon-card-port .cap-img-box img {
max-width: 100% !important;
max-height: 100% !important;
width: auto !important;
height: auto !important;
object-fit: contain;
margin: 0 auto;
}
.cocoon-amazon-card-port .cap-content-box {
flex: 1;
min-width: 0; /* 文字・ボタン溢れ防止 */
}
.cocoon-amazon-card-port .cap-title {
font-weight: bold;
font-size: 0.95em;
margin-bottom: 12px;
line-height: 1.4;
}
.cocoon-amazon-card-port .cap-title a {
color: #333;
text-decoration: none;
}
.cocoon-amazon-card-port .cap-title a:hover {
text-decoration: underline;
}
.cocoon-amazon-card-port .cap-buttons {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.cocoon-amazon-card-port .cap-btn {
display: inline-block;
padding: 6px 14px;
font-size: 0.8em;
font-weight: bold;
color: #fff !important;
border-radius: 4px;
text-decoration: none !important;
transition: opacity 0.2s;
}
.cocoon-amazon-card-port .cap-btn:hover { opacity: 0.85; }
.cocoon-amazon-card-port .cap-btn-amazon { background-color: #ff9900; }
.cocoon-amazon-card-port .cap-btn-rakuten { background-color: #bf0000; }
.cocoon-amazon-card-port .cap-btn-yahoo { background-color: #ff0033; }
@media (max-width: 600px) {
.cocoon-amazon-card-port { flex-direction: column; text-align: center; }
.cocoon-amazon-card-port .cap-img-box { width: 100px; height: 100px; }
.cocoon-amazon-card-port .cap-buttons { justify-content: center; }
}
</style>
<?php
}, 99 );コメントを閉じる

コメント