「サイトから直接カードで払えるようにしたい」という相談は、決済代行会社の申込ページを一度見たあとに届くことが多いです。手数料と初期費用の表までは読めたけれど、自分のサイト側に何を作れば動くのかが分からない、という状態です。ここで最初に決めるのは、決済フォームの見た目でも、どの決済代行を選ぶかでもありません。カード番号を自分のサーバーに通すのか、通さないのか。決めるのはまずそこだけです。この一点を後回しにすると、動きはじめてから作り直すことになります。
「決済を自作する」と言ったとき、実際に作っているもの
カード番号を自社のサーバーで保持する、処理する、あるいは通過させる。この3つのどれかに当てはまると、カード業界のセキュリティ基準であるPCI DSSへの準拠が求められます。中小規模の事業者が自力で維持できる水準ではないため、国内のEC加盟店に対しては「非保持化」、つまりカード番号が自社の環境を一度も通らない形にすることが実務上の前提になっています。
非保持化の作り方は大きく3つあります。決済代行会社が用意した決済ページへ遷移させるリンク型。自社ページの中に決済代行のiframeを埋め込む型。そして、決済代行が配布するJavaScriptがブラウザの中でカード番号をトークンへ変換し、自社サーバーにはそのトークンだけが届くトークン型です。トークン型は自社のデザインのまま入力欄を置けるため見た目の自由度が高く、そのぶん実装量が増えます。
| 方式 | カード番号の通り道 | 自作する量 | 向いている場面 |
|---|---|---|---|
| リンク型(決済代行のページへ遷移) | 決済代行のみ | 最少。金額を渡して戻り値を受けるだけ | 単価が固定、点数が少ない、早く出したい |
| iframe埋め込み型 | 決済代行のみ | 少ない。枠の中は触れない | 離脱を減らしたいが実装工数は抑えたい |
| トークン型(JavaScriptで変換) | ブラウザから決済代行へ直接 | 多い。入力検証と非同期処理を自作 | 入力内容で金額が変わる、既存フォームに載せたい |
| 完全自作(カード番号を自社で受ける) | 自社サーバーを通る | — | 現実的な選択肢にならない |
どの方式でも、自作するものは結局3つに落ち着きます。金額を確定させる処理、決済代行へ渡す処理、結果を受け取って注文や申込を確定させる処理です。工数が出るのは1つ目と3つ目で、真ん中は決済代行が配っているライブラリを呼ぶだけのことが多いです。見積りを読むときも、この3つのどこに時間が積まれているかを見ると内訳が読めます。どちらの方式を選ぶかで迷っているなら、Stripe Checkoutと自前の決済フォーム、どちらで作るべきかのほうに判断材料を書いています。
最初の分かれ道は、金額を誰が決めるか
WordPressに決済を載せる案件で、いちばん最初に効いてくる制約がこれです。フォーム系プラグインの決済連携は、1フォーム=1商品=1決済で組まれているものがほとんどで、「入力内容によって請求額が変わる」という要件は標準機能の外側にあります。ここを知らずに見積もると、あとから金額が跳ねます。
実際にあった相談では、選んだサービスの組み合わせで合計金額が変わるフォームを作りたい、という要望でした。要望どおりの自由度で作ると20万〜25万円になることを先に数字で示したうえで、決済機能だけを実装する形で59,000円、管理画面から金額そのものを編集できる形まで含めて95,000円、という段階を出しています。結果として95,000円の形で合意し、実装は6日で終わりました。長引いたのは実装ではなく、その手前の要件を固める期間のほうです。
金額の持ち方でもう一つ、後から必ず刺さるのが直書きです。以前、単一の金額を決済処理の中に直接書いた自作の導線があり、扱う商品が2つになった時点で成立しなくなりました。最初から金額を引数として受け取る形にしておくか、増える見込みがあるなら最初から既製の決済基盤に載せるほうが、合計では安く済みます。
そして、金額はサーバー側で必ず作り直してください。ブラウザから送られてきた金額をそのまま決済代行へ渡す実装は、開発者ツールで数字を書き換えるだけで通ります。フォームからは選択肢の識別子だけを受け取り、単価はサーバー側の定義から引き直して合計を出す。この一手間があるかないかで、性質がまったく変わります。
実装で守っている作法
既存のテーマやプラグインの中に決済処理を書き足さず、独立した1つのプラグインにまとめる。これは決済に限らず守っていますが、決済では特に効きます。150,000円規模で作った受発注まわりの機能でも、本番への反映がプラグインを1つ追加するだけで済み、切り戻しも無効化するだけで完了しました。本体を直接触っていれば、更新のたびに消えるか、消えたことに気づかないかのどちらかになります。
決済ページは、公開されている一般ページと分けて置きます。問い合わせフォームは公開ページ、決済フォームは検索にもナビゲーションにも出さない非公開ページに置き、決済が必要な相手にだけURLを渡す。こうしておくと、事情を知らない訪問者が決済画面にたどり着いて誤って進んでしまう事故が起きません。あわせて、金額の書き換えは管理画面のフォーム編集画面からできる状態で引き渡します。価格改定のたびに発注が必要な作りにしてしまうと、運用のほうが先に止まります。
もう一つ、決済を載せるならプライバシーポリシーの整備をセットにしてください。氏名・連絡先・購入履歴を扱う以上は必要ですし、決済代行の審査でもサイト上の表示が確認されます。
3Dセキュアは「入れる/入れない」の話ではなくなりました
国内のEC加盟店については、クレジットカード・セキュリティガイドラインにおいてEMV 3-Dセキュアの導入が原則として求められる整理になり、2025年3月末が一つの区切りとして示されました。旧来の3Dセキュア(1.0)はカードブランド側のサポートがすでに終了しているため、これから作るなら選択肢はEMV 3-Dセキュアの一択です。
実装側から見たEMV 3-Dセキュアは、認証画面を必ず出す仕組みではありません。加盟店から渡された情報をもとにカード会社側がリスクを判定し、問題がなければ認証画面を出さずに通す仕組みです。つまり、請求先の住所や氏名、メールアドレス、端末やブラウザの情報といったパラメータをきちんと詰めて渡すほど、買う側に追加の操作を求めずに済みます。「3Dセキュアを入れるとかご落ちが増える」という懸念は、渡す情報の設計でかなり変わる部分です。
そしてもう一つ、実装より先に詰まる場所があります。審査です。マーケットプレイス型のサイトを作った案件では、カート側までは用意できていたのに、決済会社の審査が通らずカード決済の接続そのものを実施できませんでした。取扱商材や事業形態によっては、技術的にどれだけ準備しても外部の判断で止まります。決済が使えない状態でも受発注が回る導線を、最初から設計に入れておくのが安全です。
本番切替の日に、事故はここで起きる
決済まわりで実際に起きた事故を1つ書きます。テスト用の決済アカウントから本番用アカウントへの切り替えが漏れたまま公開され、実際の売上10,500円が、本来入るべき口座とは別の口座に着金しました。返金と付け替えで処理はできましたが、原因はコードではなく公開前の確認です。以後、決済の本番切替では次の5点を必ず通してから公開しています。
- 決済アカウントが依頼元名義のものになっているか(開発中に使っていたアカウントのままになりやすい)
- APIキーが本番用に差し替わっているか(
sk_live_で始まるものか) - 管理画面のテストモードが解除されているか
- Webhookの通知先が本番のURLを向いているか
- 少額で実際に決済し、返金まで通して着金先を目視で確認する
5番目を省略しないでください。1〜4を目視で確認しても、口座の紐づけまでは画面上で分からないことがあります。数百円の実決済を1回通すだけで、この種の事故は消えます。なお4番のWebhookは、通知が届かなかったときや二重に届いたときの挙動まで決めておく必要があります。詳しくは決済結果を取りこぼさないための受信処理と、二重計上の防ぎ方で扱っています。
公開したあとに効いてくること
標準の仕組みを独自実装に置き換えると、標準が内部で投げていた通知まで一緒に消えます。受発注機能を独自実装に切り替えた案件では、新規の注文が入ったときの通知が消えていたことに公開後しばらく経ってから気づきました。対処としては、注文確定時にシステム側から自動メッセージを1通投げ、強制的に未読を発生させる形にしています。置き換える前に、標準機能がどこで何を通知しているかを書き出しておくのが確実です。
「注文は入っているのにメールが届かない」という報告は、3点に分解すると原因がすぐ絞れます。完了ページが表示されたか。決済代行の管理画面に決済が立っているか。管理者宛のメールが届いたか。どこまで通っているかが確定すれば、サイト側の処理か、送信側か、受信側かの切り分けが終わります。ここで見落としやすいのが、送信元と宛先が同じドメイン・同じアドレスだと配送されないサーバー設定です。自分宛にだけ届かない、という報告は珍しくないので、公開前のテストは必ず別ドメインの宛先で行ってください。
最後にもう一つ。「画面の表示が更新されない」「注文したのに反映されない」という報告のうち、一定数はブラウザのキャッシュです。実装を疑う前に、一度キャッシュを消して再読み込みしてもらう。実際にそれが原因だったことがあります。WordPressに既製の決済プラグインを入れる場合の手順やつまずきどころは、WordPressにStripe決済を組み込む手順と、つまずく箇所にまとめてあります。
よくある質問
決済代行を通さず、カード会社と直接契約する形にはできますか
技術的には可能ですが、その場合はカード番号を自社の環境で扱うことになり、PCI DSSへの準拠が必要になります。監査とその維持にかかる費用は、決済代行の手数料とは桁が違います。年商が数十億円という規模でない限り、検討の対象になりません。
カートのプラグインを入れれば、自作の部分はゼロになりますか
商品を並べて買ってもらう形なら、ほぼゼロになります。自作が必要になるのは、入力内容で金額が変わる、会員の属性で価格が変わる、決済後に独自の処理を挟むといった要件が入ったときです。逆に言えば、その要件が本当に必要かを先に検討すると、費用は大きく下がります。
フォームに決済を載せるだけなら、いくらから始まりますか
既製のフォームに決済を載せるだけなら数万円台から、管理画面から金額を編集できる状態まで含めて10万円弱、受発注のやり取りや独自のデータ設計が絡むと15万円前後、というのが実際に対応してきた範囲です。金額を動かしているのは決済そのものではなく、その前後にある業務のほうです。
先に決めておくと安く済むことはありますか
3つあります。金額の決まり方(固定か、選択で変わるか、都度入力か)。決済後に何が起きてほしいか(メール、在庫、外部システムへの登録)。そして、返金やキャンセルを誰がどこで操作するか。この3つが決まっていれば、見積りの幅はかなり狭くなります。
決済を自分のサイトに載せるかどうかは、技術の問題より先に、金額の決まり方と決済後の業務の問題です。既存のサイトを見たうえで、既製の仕組みで足りるのか、作る必要があるのかを切り分けてお伝えします。
