CIHWEB Anywhere Cart
CIHWEBカート
記事のどこにでも、購入ボタンを。
CIHWEBで開発している「CIHWEBカート」(CIHWEB Anywhere Cart)は、いまお使いのWordPressの記事や固定ページに、購入ボタン・お申し込みボタン・JPYCの投げ銭を”コードひとつ”で置ける軽量プラグインです。現在はv0.13.2、プレオープン。ここまで何につまずき、どう直し、どう使いやすくしてきたかを、開発の記録として残します。
まず「カートを作らない」と決めた
一番大きな判断が、これでした。CIHWEBはすでにWelcart・WooCommerce・EC-CUBE・OpenCart向けのJPYC決済を提供しています。そこへ新しいショッピングカート(かご)を足すと自社サービスと競合し、料金の筋も通らなくなる。だから「売り場をもう一つ作る」のではなく、今ある記事を、そのまま売れる場所に変える道具にしました。作るものを絞ったことで、あとの設計が全部シンプルになりました。
一番の失敗 ──「商品リンクに全く見えない」
初期版は、ひとつのショートコードに「購入ボックス」「販売ページ」「バナー」の3役を詰め込んでいました。結果、カードの直下にいきなり住所入力欄が並び、「これが商品リンクだと分からない」「押しても申し込みが出ない」と指摘を受けました。原因は役割の詰め込みすぎ。そこで置き場所を3つに分離しました。
- 購入ボックス(記事の中)── まず大きな購入ボタンだけを出し、押すまでフォームを出さない。押したその場で開いてスクロール。失敗して戻っても開いたまま・入力も保持。
- 販売ページ(商品ごとの単独URL)── バナー・QR・SNSの着地先。購入ボックスと同じ部品に統一。
- LPモード ── 売るためだけの固定ページ。
このLPモードで気づいたのが、ショートコードは「足す」ことはできても「消す」ことはできないという壁でした。投稿日・著者・前後リンク・コメント欄は記事に残ってしまう。ここが「LPには別の方法が要る」の正体で、固定ページのテンプレート方式に切り替えて解決しました。相手のテーマに依存させないよう、プラグイン側で描き切る設計にしています。
「考えさせない・入力させない」を細部で
設計の最優先は「初めての人が説明書なしで、商品登録→販売開始→注文対応まで進めること」。機能を増やすより、ユーザーが考える・入力することを減らす。たとえば「配送あり/なし」を選ぶと、住所入力・送料・発送管理が自動で出たり消えたりします。特商法ページも固定ページを作らせず、プラグインがURLごと用意します。
郵便番号で、いくつもつまずいた
住所入力を軽くするため、郵便番号から都道府県・市区町村・町名まで自動入力できるようにしました。ここが地味に苦労した部分です。
- 最初は「店主がデータを取り込む」設計にしていましたが、「ダウンロードした人がやらなきゃダメですか」の一言で誤りに気づき、同梱前提に作り直しました(120,717件・2.0MB)。
- 「町名まで入れると重い」と思い込んでいたのも間違いで、実測すると644KB→2.0MB、速度は0.02→0.04ミリ秒、メモリは不変。入れない理由がありませんでした。全件をメモリに載せず、見つかった1件だけ読む作りにしています。
- バグも複数。全角で「0410805」と打つと1文字も残らず住所が入らない(半角化を追加)。取り込み直後に古い市区町村が出る(どのファイルから読んだかを見ていなかった)。wp_date()に時差が二重にかかり、ホームの「今日/今月」が1日ずれる。スマホでバナーの商品名が潰れる(flexを折り返しに修正)。
- 外部サービスは一切使いません。お客様の郵便番号がどこかへ送られることはなく、WordPress.orgの規約(外部読み込み禁止)にも沿っています。QRコードも同じ理由で自前生成に切り替えました。
「入力欄があると、壊す事故しか起きない」
決済の接続値(決済開始URL・店舗ID・店舗シークレット・受取アドレス)は、一度貼れば打ち直す場面がありません。そこに編集欄があると、触って壊す事故しか生まないと気づき、見るだけの表に変えました(シークレットは伏せ字、どうしても直すときは「開発者向け」の折りたたみの中)。JPYCの受取アドレスは1文字違うと接続エラー(E110)になるので、CIHWEBの値は[コピー]ボタンで渡す形にしています。
決済は”信じない”作りにした
決済まわりは、性善説で組むと二重入金や取りこぼしが起きます。そこで一貫して「疑ってかかる」設計にしました。
- 「画面が戻った=支払い完了」にしない。戻りは「確認待ち」にするだけで、入金反映とお礼メールはサーバーで支払いを確認してからだけ実行。
- 注文IDと決済試行IDを分離。再試行しても注文IDは不変。webhookは試行の枝番を剥がして注文に解決。
- 冪等。二重クリックや通知の再送があっても、入金処理もメールも1回だけ。
- 価格はスナップショット。あとで値上げしても過去の注文は変わりません。
- 購入直前に最終確認画面(内訳・支払時期・引渡時期・返品)を必ず表示(特商法)。
- 内部では決済6状態×配送3状態を細かく持ちつつ、店主の画面には「振込を確認してください」「発送してください」とやること1行に翻訳して出します。
まとめ買いは「3個で2500円」のような合計指定ではなく段階単価にしました。合計指定だと単価に端数が出て税・送料の表示がずれるためです。
JPYC投げ銭は成立確認、Stripeは仮想確認
- 銀行振込:完成。注文→案内→入金確認→お礼→発送通知(追跡番号)まで通し。
- JPYC(CIHPAY/Polygon):URL組立・HMAC署名・戻り処理・webhook受け口を実装し、テスト環境で決済の成立を確認。金額が注文と違えば409で拒否します。配送なし・金額固定にすれば、そのまま投げ銭・寄付・会費の入口になります。
- Stripe(クレジットカード):テストモードで、申込→決済→戻り→入金反映→メールまでの通しを確認済み(仮想確認済み)。「審査通過後に実装」ではなく「先に作る→テストで通す→審査」に順番を変えました。
迷ったら、その場でAIに聞ける
店主の「操作が分からない」を開発側を経由せず解決できるよう、管理画面に〈使い方をAIに聞く〉を用意しました。[全部コピー]してChatGPTやClaudeに貼ると、このプラグイン専用の案内係になります。説明文は1本に集約し、冒頭に「書いていないことは推測で答えるな」と指示。動作版と説明書の版が違うと画面に注意書きが出ます。
いまここ、そして学び
v0.13.2・プレオープン。管理画面(ダッシュボード・商品カテゴリ・サムネ列)と購入フォームの軽量化は稼働中。残るは配送設定、メール文面の編集、商品カードの固定サイズ化、構造化データ、そして最大の山であるWordPress.org掲載の門(画面文字の英語化+翻訳)です。プラグイン自体は動くので、一般の方も先行して使えます。学びは一つ。「機能を足す」より「線を引く」ほうが難しく、そしてよく効いた、ということでした。