2026年版 iPay API 決済連携ガイド

Ashley Innocent

Ashley Innocent

25 3月 2026

2026年版 iPay API 決済連携ガイド

要約

iPay APIは、開発者が決済処理、請求書発行、金融取引をプログラムで統合することを可能にします。OAuth 2.0とAPIキー認証を使用し、支払い、返金、取引、照合のためのRESTfulエンドポイントを提供します。PCI DSSコンプライアンス要件と業界標準のレート制限に従います。このガイドでは、認証設定、決済処理、Webhook統合、セキュリティコンプライアンス、本番環境へのデプロイ戦略について説明します。

はじめに

世界のデジタル決済処理は年間8兆ドルを超えます。Eコマースプラットフォーム、SaaSアプリケーション、またはマーケットプレイスソリューションを構築する開発者にとって、決済APIの統合は選択肢ではなく、顧客からの支払いを安全かつコンプライアンスに準拠して受け入れるために不可欠です。

現実として、企業は支払い失敗、手動による照合、支払い詐欺により収益の5~10%を失っています。堅牢な決済API統合は、決済処理を自動化し、スマートな再試行ロジックで失敗を減らし、自動照合を可能にし、不正検出を実装します。

このガイドでは、決済APIの統合プロセス全体を順を追って説明します。認証設定、決済処理、返金管理、Webhook処理、PCI DSS準拠、セキュリティのベストプラクティス、および本番環境へのデプロイ戦略について学びます。読み終える頃には、本番環境に対応した決済統合を完成させることができるでしょう。

💡
Apidogは決済APIのテストを簡素化します。サンドボックスモードでの決済エンドポイントのテスト、Webhook署名の検証、取引応答の検査、統合問題のデバッグを1つのワークスペースで行えます。API仕様のインポート、モックレスポンスの作成、テストシナリオのチームとの共有が可能です。

ボタン

注意: このガイドは、iPayおよび類似の決済プロセッサーに適用される一般的な決済API統合パターンを扱っています。特定のエンドポイントURLや認証の詳細は異なる場合がありますので、実装の詳細については常に公式のiPayドキュメントを参照してください。

iPay APIとは?

iPayのような決済APIは、金融取引を処理するためのRESTfulなインターフェースを提供します。APIが扱う内容は以下の通りです。

主な機能

機能 説明
RESTful API JSONベースのエンドポイント
OAuth 2.0 + APIキー 安全な認証
Webhook リアルタイムの支払い通知
トークン化 安全なカード保存
3Dセキュア SCA準拠
PCI DSS レベル1準拠が必須
多通貨対応 100以上の通貨をサポート
不正対策ツール リスクスコアリング、ベロシティチェック

支払いフローの概要

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Customer  │───▶│   Merchant  │───▶│  Payment    │
│   (Browser) │    │   (Server)  │    │  Gateway    │
└─────────────┘    └─────────────┘    └─────────────┘
     │                    │                    │
     │  1. Enter Card     │                    │
     │───────────────────▶│                    │
     │                    │                    │
     │  2. Tokenize       │                    │
     │───────────────────▶│  3. Create Intent  │
     │                    │───────────────────▶│
     │                    │                    │
     │                    │  4. Confirm Payment│
     │                    │───────────────────▶│
     │                    │                    │
     │                    │  5. Result         │
     │                    │◀───────────────────│
     │                    │                    │
     │  6. Receipt        │                    │
     │◀───────────────────│                    │

API環境

環境 URL 用途
サンドボックス https://sandbox.ipay.com/api 開発、テスト
本番環境 https://api.ipay.com/api ライブ取引

開始する: 認証設定

ステップ1: iPayアカウントの作成

APIにアクセスする前に:

  1. iPay販売者登録ページにアクセス
  2. 事業確認 (KYB) を完了
  3. 必要書類を提出:
  1. 承認を待つ(1~3営業日)

ステップ2: API資格情報の取得

API資格情報を生成:

  1. iPayマーチャントダッシュボードにログイン
  2. 設定 > APIキー に移動
  3. 新しいAPIキーを作成
  4. 資格情報を安全にコピー
# .env file (NEVER commit to git)
IPAY_API_KEY="live_xxxxxxxxxxxxxxxxxxxx"
IPAY_API_SECRET="secret_xxxxxxxxxxxxxxxxxxxx"
IPAY_WEBHOOK_SECRET="whsec_xxxxxxxxxxxxxxxxxxxx"

セキュリティに関する注意: サンドボックスと本番環境で異なるキーを使用してください。

ステップ3: 認証方法を理解する

iPayは複数の認証方法をサポートしています:

方法 最適な用途 セキュリティレベル
Basic認証 サーバー間通信
OAuth 2.0 マルチテナントアプリ より高
JWT マイクロサービス

ステップ4: 認証済みAPIコールの実行

再利用可能なAPIクライアントを作成:

const IPAY_BASE_URL = process.env.IPAY_SANDBOX
  ? 'https://sandbox.ipay.com/api'
  : 'https://api.ipay.com/api';

const ipayRequest = async (endpoint, options = {}) => {
  const apiKey = process.env.IPAY_API_KEY;
  const apiSecret = process.env.IPAY_API_SECRET;

  // Basic authentication (Base64 encoded)
  const authHeader = Buffer.from(`${apiKey}:${apiSecret}`).toString('base64');

  const response = await fetch(`${IPAY_BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Basic ${authHeader}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': options.idempotencyKey || generateIdempotencyKey(),
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`iPay API Error: ${error.message}`);
  }

  return response.json();
};

function generateIdempotencyKey() {
  return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}

// 使用例
const account = await ipayRequest('/account');
console.log(`Merchant: ${account.business_name}`);

決済処理

支払いインテントの作成

支払いを初期化:

const createPayment = async (paymentData) => {
  const payment = {
    amount: paymentData.amount, // In smallest currency unit (cents)
    currency: paymentData.currency || 'USD',
    customer: paymentData.customerId,
    payment_method: paymentData.paymentMethodId,
    confirm: true,
    description: paymentData.description,
    metadata: {
      orderId: paymentData.orderId,
      customerId: paymentData.customerId
    },
    capture_method: paymentData.captureMethod || 'automatic', // 'automatic' or 'manual'
    statement_descriptor: paymentData.statementDescriptor || 'MYCOMPANY'
  };

  const response = await ipayRequest('/payments', {
    method: 'POST',
    body: JSON.stringify(payment),
    idempotencyKey: paymentData.idempotencyKey
  });

  return response;
};

// 使用例
const payment = await createPayment({
  amount: 2999, // $29.99
  currency: 'USD',
  customerId: 'cus_12345',
  paymentMethodId: 'pm_67890',
  description: 'Order #ORD-001',
  orderId: 'ORD-001',
  statementDescriptor: 'MYCOMPANY INC'
});

console.log(`支払いステータス: ${payment.status}`);
console.log(`支払いID: ${payment.id}`);

支払いステータスフロー

requires_payment_method → requires_confirmation → requires_action
                         → processing → requires_capture → succeeded
                                                        → failed
                                                        → canceled

支払い方法

方法 種類 用途
card クレジット/デビット 標準的な支払い
bank_transfer ACH、SEPA 低手数料送金
digital_wallet Apple Pay、Google Pay モバイル決済
buy_now_pay_later Klarna、Afterpay 分割払い

カード情報のトークン化

将来の利用のためにカードを安全に保存:

const tokenizeCard = async (cardData) => {
  // 生のカードデータをサーバーに送信しないでください
  // 代わりにクライアントサイドのトークン化を使用してください

  // クライアントサイド(ブラウザ/モバイル)
  const response = await fetch(`${IPAY_BASE_URL}/tokens`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${CLIENT_PUBLISHABLE_KEY}`
    },
    body: JSON.stringify({
      card: {
        number: cardData.number,
        exp_month: cardData.expMonth,
        exp_year: cardData.expYear,
        cvc: cardData.cvc
      }
    })
  });

  const token = await response.json();
  return token; // Send token.id to your server
};

// サーバーサイド: トークンを使用して支払い方法を作成
const createPaymentMethod = async (tokenId, customerId) => {
  const response = await ipayRequest('/payment_methods', {
    method: 'POST',
    body: JSON.stringify({
      type: 'card',
      token: tokenId,
      customer: customerId
    })
  });

  return response;
};

3Dセキュア認証

SCA準拠を実装:

const createPaymentWith3DS = async (paymentData) => {
  const payment = await createPayment({
    ...paymentData,
    confirmation_token: true // Return client secret for 3DS
  });

  if (payment.status === 'requires_action') {
    // クライアントは3Dセキュア認証を完了する必要があります
    return {
      requiresAction: true,
      clientSecret: payment.client_secret,
      nextAction: payment.next_action
    };
  }

  return { success: true, payment };
};

// クライアントサイド: 3Dセキュア認証を処理
// iPay.jsまたはモバイルSDKを使用して認証チャレンジを提示します

返金管理

全額返金の処理

支払い全体を返金:

const refundPayment = async (paymentId, reason = null) => {
  const refund = {
    payment: paymentId,
    reason: reason || 'requested_by_customer'
  };

  const response = await ipayRequest('/refunds', {
    method: 'POST',
    body: JSON.stringify(refund),
    idempotencyKey: `refund_${paymentId}_${Date.now()}`
  });

  return response;
};

// 使用例
const refund = await refundPayment('pay_12345', 'duplicate');
console.log(`返金ステータス: ${refund.status}`);
console.log(`返金ID: ${refund.id}`);

一部返金の処理

支払いの一部を返金:

const partialRefund = async (paymentId, amount, reason = null) => {
  const refund = {
    payment: paymentId,
    amount: amount, // In smallest currency unit
    reason: reason || 'requested_by_customer'
  };

  const response = await ipayRequest('/refunds', {
    method: 'POST',
    body: JSON.stringify(refund),
    idempotencyKey: `refund_${paymentId}_${amount}_${Date.now()}`
  });

  return response;
};

// 使用例 - $29.99の支払いから$15.00を返金
const refund = await partialRefund('pay_12345', 1500, 'partial_ship');
console.log(`返金済み: $${refund.amount / 100}`);

返金理由

理由コード 説明
duplicate 重複請求
fraudulent 不正な取引
requested_by_customer 顧客からの要求
order_canceled 注文キャンセル
product_not_received 商品未配達
product_not_as_described 説明と異なる商品

顧客管理

顧客の作成

定期支払いのために顧客情報を保存:

const createCustomer = async (customerData) => {
  const customer = {
    email: customerData.email,
    name: customerData.name,
    phone: customerData.phone,
    metadata: {
      internalId: customerData.internalId,
      tier: customerData.tier
    }
  };

  const response = await ipayRequest('/customers', {
    method: 'POST',
    body: JSON.stringify(customer)
  });

  return response;
};

// 使用例
const customer = await createCustomer({
  email: 'customer@example.com',
  name: 'John Doe',
  phone: '+1-555-0123',
  internalId: 'USR-12345',
  tier: 'premium'
});

console.log(`顧客が作成されました: ${customer.id}`);

顧客に支払い方法を紐付け

将来の利用のためにカードを保存:

const attachPaymentMethod = async (paymentMethodId, customerId) => {
  const response = await ipayRequest(`/payment_methods/${paymentMethodId}/attach`, {
    method: 'POST',
    body: JSON.stringify({
      customer: customerId
    })
  });

  return response;
};

// 使用例
await attachPaymentMethod('pm_67890', 'cus_12345');

顧客の支払い方法の一覧表示

保存されたカードを取得:

const getCustomerPaymentMethods = async (customerId) => {
  const response = await ipayRequest(`/customers/${customerId}/payment_methods`);
  return response;
};

// 使用例
const methods = await getCustomerPaymentMethods('cus_12345');
methods.data.forEach(method => {
  console.log(`${method.card.brand} (下4桁: ${method.card.last4})`);
  console.log(`有効期限: ${method.card.exp_month}/${method.card.exp_year}`);
});

Webhook

Webhookの設定

Webhookエンドポイントを設定:

  1. iPayダッシュボードにログイン
  2. 開発者 > Webhook に移動
  3. エンドポイントを追加 をクリック
  4. HTTPS URLを入力
  5. 購読するイベントを選択

Webhookイベント

イベント トリガー
payment.succeeded 支払いが完了した時
payment.failed 支払いが拒否された時
payment.refunded 返金が処理された時
payment.disputed チャージバックが申請された時
customer.created 新規顧客が作成された時
customer.subscription.updated サブスクリプションが変更された時

Webhookの処理

const express = require('express');
const crypto = require('crypto');
const app = express();

app.post('/webhooks/ipay', express.raw({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['ipay-signature'];
  const payload = req.body;

  // Webhook署名を検証
  const isValid = verifyWebhookSignature(payload, signature, process.env.IPAY_WEBHOOK_SECRET);

  if (!isValid) {
    console.error('無効なWebhook署名');
    return res.status(401).send('Unauthorized');
  }

  const event = JSON.parse(payload.toString());

  // 適切なハンドラーにルーティング
  switch (event.type) {
    case 'payment.succeeded':
      await handlePaymentSucceeded(event.data);
      break;
    case 'payment.failed':
      await handlePaymentFailed(event.data);
      break;
    case 'payment.refunded':
      await handlePaymentRefunded(event.data);
      break;
    case 'payment.disputed':
      await handlePaymentDisputed(event.data);
      break;
    default:
      console.log('未処理のイベントタイプ:', event.type);
  }

  // 受信を確認
  res.status(200).send('OK');
});

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expectedSignature, 'hex')
  );
}

async function handlePaymentSucceeded(data) {
  console.log(`支払いが成功しました: ${data.id}`);

  // 注文ステータスを更新
  await db.orders.update(data.metadata.orderId, {
    status: 'paid',
    paymentId: data.id,
    paidAt: new Date()
  });

  // 確認メールを送信
  await sendOrderConfirmation(data.metadata.orderId);
}

async function handlePaymentFailed(data) {
  console.log(`支払いが失敗しました: ${data.id} - ${data.failure_code}`);

  // 顧客に通知
  await sendPaymentFailedEmail(data.customer, data.failure_message);

  // 再試行ロジックまたは注文を失敗としてマーク
  await db.orders.update(data.metadata.orderId, {
    status: 'payment_failed',
    failureReason: data.failure_message
  });
}

セキュリティとコンプライアンス

PCI DSS要件

決済統合はPCI DSSに準拠する必要があります:

要件 実装
安全なネットワーク HTTPSの使用、ファイアウォール、安全な設定
カード会員データ保護 CVVを保存しない、PANを暗号化
脆弱性管理 定期的なセキュリティ更新、アンチウイルス
アクセス制御 最小特権、MFA、固有ID
監視 ロギング、侵入検知
セキュリティポリシー 文書化されたポリシー、定期的なトレーニング

セキュリティのベストプラクティス

// 1. トークン化を使用 - 生のカードデータを扱わないでください
const token = await tokenizeCard(cardData); // クライアントサイド

// 2. すべての支払い操作にべき等性を実装
const idempotencyKey = `pay_${orderId}_${Date.now()}`;

// 3. サーバーサイドで金額を検証
if (req.body.amount !== calculatedAmount) {
  throw new Error('Amount mismatch - possible tampering');
}

// 4. すべての支払い操作をログに記録(機密データなし)
logger.info('Payment attempted', {
  orderId,
  amount,
  currency,
  customerId,
  timestamp: new Date().toISOString()
  // ログに記録しないでください: カード番号、CVV、支払い方法の詳細すべて
});

// 5. 機密情報には環境変数を使用
const apiKey = process.env.IPAY_API_KEY; // ハードコードしない

// 6. 支払いエンドポイントにレート制限を実装
const paymentLimiter = rateLimit({
  windowMs: 60000,
  max: 10 // 1分あたり10回の支払い試行
});

本番環境デプロイチェックリスト

ライブ決済を処理する前に:

実世界のユースケース

Eコマースのチェックアウト

オンライン小売業者が支払いを統合:

SaaSのサブスクリプション請求

ソフトウェア会社が請求を自動化:

マーケットプレイスのエスクロー

複数当事者の支払いを扱うプラットフォーム:

まとめ

決済APIの統合には、セキュリティ、コンプライアンス、エラー処理への細心の注意が必要です。主なポイントは以下の通りです。

ボタン

よくある質問

iPay APIで認証するにはどうすればよいですか?

APIキーとシークレットを使用したBasic認証、またはマルチテナントアプリケーションの場合はOAuth 2.0を使用します。

顧客のカード情報を保存できますか?

はい、ただしPCI DSSに準拠している必要があります。トークン化を使用して、iPayのボルトにカードを安全に保存してください。

支払い失敗はどのように処理すればよいですか?

指数関数的バックオフによる再試行ロジックを実装し、顧客に通知し、代替の支払い方法を提供してください。

べき等性とは何ですか、なぜ重要ですか?

べき等性とは、同じキーを持つ重複リクエストが同じ結果を生成することを保証し、重複請求を防ぐものです。

カードに請求せずに支払いをテストするにはどうすればよいですか?

iPayドキュメントに記載されているテストカード番号を使用して、サンドボックスモードを使用してください。

Webhook署名とは何ですか?

WebhookがiPayから送信されたものであり、悪意のあるアクターからではないことを検証する暗号化署名です。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる