印刷する

ストア

外部支払処理(クレジット決済)

はじめに

予め用意されている支払方法(銀行振込、PayPal)の他にクレジットカード決済を利用したい場合に、特定の支払いゲートウェイを使用するための処理スクリプトを実装しています。
ストア機能拡張の設定で「外部支払処理」を有効にして支払い処理スクリプトのURLを指定すると、ユーザーが[注文]ボタンをクリックした時にはスクリプトにリダイレクトされ、また支払いの処理が完了した時にはINTER-STREAMへリダイレクトします。

注文時にユーザーをペイメントプロセッサにリダイレクトするタイミングで、注文に必要な詳細データがGET変数(ペイメントプロセッサのURLに追加されたもの)として送信されます。データには検証署名(ハッシュ)も含まれます。
一方、再度INTER-STREAMへリダイレクトされる際には、処理内容を取得するために、支払い処理プログラムのスクリプトも適切なデータをGET変数として送信されるようにする必要があります。返されたデータは対応する検証署名(ハッシュ)を含まなければなりません。

外部支払処理を使用するためのストア機能拡張の設定

[ストア>設定]から「一般」タブを開き、「売り上げ」セクションの[支払方法:外部支払処理]にチェックを入れ保存します。

「外部支払処理」タブが追加されるので移動します。

必要な情報を入力します。

  • 支払処理URL:支払処理スクリプトのURL。絶対URLである必要があります。
  • Key:検証署名(ハッシュ)を生成するために使用されるキー(文字列)。
    このキーは、対応する署名を生成するために支払い処理プログラムでも使用する必要があります。
  • 定期支払を有効にする:[Yes]にするとサブスクリプションにおける自動請求機能が外部支払処理でも有効になります。

実装:サンプルコード

支払い処理プログラムのサンプルコード(php)をダウンロードします。
定期支払い処理なしのサンプル
定期支払い処理ありのサンプル ※試用期間付きサブスクリプションを考慮

実装:定期支払いなしの場合

INTER-STREAMから送信されたデータを受信する

INTER-STREAMは、支払詳細を支払処理スクリプトのURLにGET変数として追加します。

http://.../payment_processor.php?id_gateway={id_gateway}&id_order={id_order}&amount={amount}¤cy_code={currency_code}&order_number={order_number}&signature={signature}&id_user={user_id}
  • id_gateway:INTER-STREAM支払いゲートウェイのID
  • id_order:注文ID
  • amount:支払額(10進数)
  • currency_code:通貨単位(USD, EUR, etc.)
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。
  • id_user:ユーザー(購入者)のID

データの検証
支払いを処理する前に、ハッシュを使用してデータを検証します。

PHPの例)

$key = "the secret key";
$data = array(
     "id_gateway" => (string)$id_gateway,
     "id_order" => (string)$id_order,
     "amount" => (string)$amount,
     "currency_code" => $currency_code,
     "order_number" => (string)$order_number
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));

ハッシュを生成したらINTER-STREAMから送信されたものと比較して、一致している必要があります。

開発テストの際にハッシュが一致しない(そして受信しているデータが変更されていないことが確実である)場合は、スクリプトとINTER-STREAM側とでハッシュの生成に使用されるキーが同じであることを確認してください。それらが同じであれば、受信したデータがURLデコードされている事と正確に署名を生成している事を確認してください。

支払いが完了した後にINTER-STREAMへ戻る

支払いを処理したら、ユーザーをINTER-STREAMへリダイレクトさせる必要があります。戻りURLには注文の詳細、支払い結果、ならびにハッシュがGET変数として含まれている必要があります。

必要なデータ(GET変数)

  • iq:注文ID("id_order")
  • tp:接頭辞"gid_"と接尾辞"-step_2"を持つゲートウェイID("id_gateway")
    例)ゲートウェイID=3の場合、tpは"gid_3-step_2"となります。
  • status:支払いステータス。"SUCCESS"もしくは"ERROR"
  • status_msg:status="ERROR"の場合はメッセージを入力し、それ以外の場合は空欄にします。
  • transaction:取引ID。通常はペイメントゲートウェイから提供された取引IDです。
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

戻りURLの検証署名(ハッシュ)を生成する
戻りURLでデータが変更されていないかどうかを判断するために、INTER-STREAMが使用するハッシュを生成する必要があります。

PHPの例)

$key = "the secret key";
$data = array(
     "id_gateway" => (string)$id_gateway,
     "id_order" => (string)$id_order,
     "status" => $status, // "SUCCESS"もしくは"ERROR"
     "id_transaction" => (string)$id_transaction // 取引ID
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));

必要なデータとハッシュを入手したら、戻りURLを作成します。

{INTER-STREAMのベースURL}/index.php?go=store&do=payOrder&iq={注文ID}&tp=gid_{ゲートウェイID}-step_2&status={ステータス}&status_msg={メッセージ(urlエンコード)}&transaction={取引ID(urlエンコード)}&signature={ハッシュ(urlエンコード)}

例)
INTER-STREAMのベースURL:https://www.interstreamdomain.com/(SSLが有効になっている場合)
注文ID:99
ゲートウェイID:3
支払いステータス:"SUCCESS"
ステータスメッセージ: ""(URLエンコード)
取引ID:98dfgdf89g7dg97df(URLエンコード)
署名(ハッシュ):MGI5YzY0ZmE2N2Y4NW3ZDFmN2M0Zjc%3D(URLエンコード)
↓↓↓
生成される戻りURL:

https://www.interstreamdomain.com/index.php?go=store&do=payOrder&iq=99&tp=gid_3-step_2&status=SUCCESS&status_msg=&transaction=98dfgdf89g7dg97df&signature=MGI5YzY0ZmE2N2Y4NW3ZDFmN2M0Zjc%3D

INTER-STREAM側でデータ検証できる場合は、注文を処理し、購入したコンテンツへのアクセスを許可して、対応するメッセージをユーザーに表示します。

実装:定期支払いありの場合

定期支払いを処理するための支払い処理スクリプトを作成するときは、以下のケースを考慮する必要があります。
1. 支払い
2. 定期支払いプロファイルのステータスチェック
3. 定期支払いプロフィールのキャンセル

ケース1:支払い処理 [?action=pay]

最初のケースは支払いです。INTER-STREAM側では値が"pay"のGET変数"action"(="?action=pay")を介して、支払いを要求します。

INTER-STREAMから送信されたデータを受信する

INTER-STREAMは、支払詳細(1回払い+定期支払い)をGET変数として支払処理プログラムのスクリプトのURLに追加します。

http://.../payment_processor.php?action=pay&id_gateway={id_gateway}&id_order={id_order}&amount={amount}¤cy_code={currency_code}&order_number={order_number}&signature={signature}&id_user={user_id}&rp_num={number_of_recurring_payments}&rp_1_...

1回払いのデータ

  • id_gateway:INTER-STREAM支払いゲートウェイのID
  • id_order:注文ID
  • amount:支払額(10進数)
  • currency_code:通貨単位(USD, EUR, etc.)
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。
  • id_user:ユーザー(購入者)のID

1回払いのデータの検証
支払いを処理する前に、ハッシュを使用してデータを検証します。

PHPの例)

$key = "the secret key";
$data = array(
     "id_gateway" => (string)$id_gateway,
     "id_order" => (string)$id_order,
     "amount" => (string)$amount,
     "currency_code" => $currency_code,
     "order_number" => (string)$order_number
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));

ハッシュを生成したらINTER-STREAMから送信されたものと比較して、一致している必要があります。

開発テストの際にハッシュが一致しない(そして受信しているデータが変更されていないことが確実である)場合は、スクリプトとINTER-STREAM側とでハッシュの生成に使用されるキーが同じであることを確認してください。それらが同じであれば、受信したデータがURLデコードされている事と正確に署名を生成している事を確認してください。

※ここまでは「定期支払いなし」の場合と同一の内容です。

定期支払いのデータ
INTER-STREAM側で定期支払いの設定を要求している場合は、追加のGET変数が含まれます。

  • rp_num:定期支払い請求番号
    定期支払いの、以下の各データフィールドには"rp_n_{data_field_name}"というプレフィックスが付けられます。"n"は定期支払い請求番号です。
    INTER-STREAMへ再度戻る際にも番号が必要であることに注意してください。
  • rp_n_sku:定期支払い請求"n"のSKU
  • rp_n_amount:定期支払い請求"n"の金額。通貨単位は1回払い時の設定と同じになります。
  • rp_n_period:定期支払い請求"n"の期間。"DAY","WEEK","MONTH","YEAR"のいずれか
  • rp_n_period_frequency:定期支払い請求"n"の期間の頻度(int値)。
    "period"と"period_frequecy"は購入者のクレジットカードに請求する期間を決定します。
  • rp_n_first_payment_date:定期支払い請求"n"の最初の支払日(UTCタイムゾーンを持つUnixタイムスタンプ)。
    定期支払いにおける購入者のクレジットカードへの最初の請求日です。
    例)「period="MONTH",period_frequency=1,first_payment_date="22 Feb 2019"」の場合
    1回目の支払い日 = 2019年2月22日
    2回目の支払い日 = 2019年3月22日
    3回目の支払い日 = 2019年4月22日
  • rp_n_signature:定期支払い請求"n"を検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

定期支払い請求を含む配列の作成とデータの検証
定期支払い請求を含む配列を作成している間に、ハッシュを使用してデータを検証します。
検証には、INTER-STREAM側と同様にハッシュを生成し、受け取ったものと比較する必要があります。ハッシュが一致しない場合は、失敗した要求をインデックス"ERROR"のメッセージとともに配列に追加する必要があります。
それ以外の場合は、後で処理するためにvalid要求を配列に追加します。

PHPの例)

$key = "the secret key"; // 通常はスクリプトの冒頭に定義されます
$recurring_payments = array();
if ( isset($_GET["rp_num"]) && $_GET["rp_num"]>0)
{
  for ( $i=0; $i<$_GET["rp_num"]; $i++)
  {
// 定期支払いデータ"i"を収集
      $rp_sku = (isset($_GET["rp_".$i."_sku"]))? rawurldecode($_GET["rp_".$i."_sku"]) : "";
      $rp_amount = (isset($_GET["rp_".$i."_amount"]))? $_GET["rp_".$i."_amount"] : 0.0;
      $rp_period = (isset($_GET["rp_".$i."_period"]))? $_GET["rp_".$i."_period"] : "";
      $rp_period_frequency = (isset($_GET["rp_".$i."_period_frequency"]))? $_GET["rp_".$i."_period_frequency"] : 0;
      $rp_first_payment_date = (isset($_GET["rp_".$i."_first_payment_date"]))? $_GET["rp_".$i."_first_payment_date"] : 0;
      $rp_signature = (isset($_GET["rp_".$i."_signature"]))? rawurldecode($_GET["rp_".$i."_signature"]) : "";

// "signature"変数のものと比較する為のシグネチャ(ハッシュ)を生成
      $rp_computed_signature = base64_encode(hash_hmac('sha256', md5( $rp_sku . floatval($rp_amount) . $rp_period_frequency . $rp_period ) , $key, true));

      if ( $rp_computed_signature!=$rp_signature)
      {
// 署名が一致しない場合は失敗したアイテムを追加(処理からはスキップされますが結果をINTER-STREAMへ返すために「失敗」として保存)
// 失敗した項目は"ERROR"配列インデックスを持つ必要があります。それ以外の場合、この配列インデックスは戻り値に含めないでください
        $recurring_payments[$i]=array(
                "error" => "無効な定期支払いデータもしくは署名の不一致",
                "sku" => "",
                "amount" => 0,
                "period" => "",
                "period_frequency" => 0,
                "first_payment_date" => 0,
                "profile_id" => "",
                "status" => "Invalid profile"
                );
      }else{
// 後で処理するために有効な項目を追加
        $recurring_payments[$i]=array(
                "sku" => $rp_sku,
                "amount" => $rp_amount,
                "period" => $rp_period,
                "period_frequency" => $rp_period_frequency,
                "first_payment_date" => $rp_first_payment_date,
// この要求を処理した後で以下のデータフィールドに入力する必要があります
                "profile_id" => "MyUniqueInternalProfileID", // 今後プロファイルを識別するためのID
                "status" => "Active" // Active, Pending, Cancelled, Suspended, Expired
                );
      }
  }
}

配列が生成されたら、リクエストを処理する必要があります。上記の例からわかるように、処理された有効な商品ごとにユニークなIDを返す必要があります。これが定期支払いの内部IDとなります。
内部IDは支払処理スクリプトにプロファイルのステータス(有効かどうか、最後の支払いまたは次の支払いの日付など)の確認、或いはプロファイルのキャンセルを要求するために使用されます。

支払い処理後にINTER-STREAMへ戻る

1回払いと定期支払いを処理したら、ユーザーをINTER-STREAMへリダイレクトする必要があります。 戻りURLには注文の詳細、1回払い及び定期支払いの結果、ならびに対応するハッシュがGET変数として含まれている必要があります。

1回払いの戻りデータ

必要なデータ(GET変数)

  • iq:注文ID("id_order")
  • tp:接頭辞"gid_"と接尾辞"-step_2"を持つゲートウェイID("id_gateway")
    例)ゲートウェイID=3の場合、tpは"gid_3-step_2"となります。
  • status:支払いステータス。"SUCCESS"もしくは"ERROR"
  • status_msg:status="ERROR"の場合はメッセージを入力し、それ以外の場合は空欄にします。
  • transaction:取引ID。通常はペイメントゲートウェイから提供された取引IDです。
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

戻りURLの検証署名(ハッシュ)を生成する
戻りURLでデータが変更されていないかどうかを判断するために、INTER-STREAMが使用するハッシュを生成する必要があります。

PHPの例)

$key = "the secret key";
$data = array(
     "id_gateway" => (string)$id_gateway,
     "id_order" => (string)$id_order,
     "status" => $status, // "SUCCESS"もしくは"ERROR"
     "id_transaction" => (string)$id_transaction // 取引ID
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));

必要なデータとハッシュを入手したら、戻りURLを作成します。

{INTER-STREAMのベースURL}/index.php?go=store&do=payOrder&iq={注文ID}&tp=gid_{ゲートウェイID}-step_2&status={ステータス}&status_msg={メッセージ(urlエンコード)}&transaction={取引ID(urlエンコード)}&signature={ハッシュ(urlエンコード)}

例)
INTER-STREAMのベースURL:https://www.interstreamdomain.com/(SSLが有効になっている場合)
注文ID:99
ゲートウェイID:3
支払いステータス:"SUCCESS"
ステータスメッセージ: ""(URLエンコード)
取引ID:98dfgdf89g7dg97df(URLエンコード)
署名(ハッシュ):MGI5YzY0ZmE2N2Y4NW3ZDFmN2M0Zjc%3D(URLエンコード)
↓↓↓
生成される戻りURL:

https://www.interstreamdomain.com/index.php?go=store&do=payOrder&iq=99&tp=gid_3-step_2&status=SUCCESS&status_msg=&transaction=98dfgdf89g7dg97df&signature=MGI5YzY0ZmE2N2Y4NW3ZDFmN2M0Zjc%3D

※ここまでは「定期支払いなし」の場合と同一の内容です。

定期支払いの戻りデータ

定期支払い要求がある場合は、GET変数として各要求のデータと、さらに定期支払いの有無を示すフラグも含める必要があります。
・定期支払いフラグ:前述のGET変数"tp"には、さらに文字列"-rp_1"を割り当てる必要があります。
例)ゲートウェイID=3の場合、tpは"&tp=gid_3-step_2-rp_1"となります。
・定期支払い請求ごとに"rp_n_{data_field_name}"の形式で対応するGET変数が必要です。"n"は定期支払い請求番号です。

  • rp_n_error:(オプション)"ERROR"インデックスが定期支払い配列に存在する場合のみ
  • rp_n_profile_id
  • rp_n_status
  • rp_n_first_payment_date
  • rp_n_signature:データ"n"を検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

PHPの例)

$key = "the secret key";
$return_url = "...."; // これまでに作成した戻りURL

if ( !empty($recurring_payments))
{
// 定期支払い返却フラグを追加
  $return_url = str_replace('-step_2&','-step_2-rp_1&',$return_url);

  foreach ( $recurring_payments as $rp_index => $rp_data)
  {
// ハッシュ生成
    $rp_signature = base64_encode(hash_hmac('sha256', md5( $rp_data["profile_id"] . $rp_data["status"] ) , $key, true));

// 戻りURLにGET変数を追加
    if ( isset($rp_data["error"])) $return_url .= "&rp_".$rp_index."_error=".urlencode($rp_data["error"]);
    $return_url .= "&rp_".$rp_index."_profile_id=".urlencode($rp_data["profile_id"]);
    $return_url .= "&rp_".$rp_index."_status=".urlencode($rp_data["status"]);
    $return_url .= "&rp_".$rp_index."_first_payment_date=".$rp_data["first_payment_date"];
    $return_url .= "&rp_".$rp_index."_signature=".urlencode($rp_signature);
  }
}

リダイレクト
INTER-STREAM側でデータを検証できた場合、注文を処理し、購入したコンテンツへのアクセスを許可し、定期支払いプロファイルをサブスクリプションに割り当て、対応するメッセージをユーザーに表示します。

ケース2:定期支払いプロファイルのステータス確認 [?action=rp_status]

2番目のケースは定期支払いプロファイルのステータスチェックです。INTER-STREAM側では値が"rp_status"のGET変数"action"(="?action=rp_status")を通じて、定期支払いプロファイルのステータスを要求します。

INTER-STREAMから送信されたデータを受信する

INTER-STREAMは、要求データをGET変数として支払処理プログラムのスクリプトURLに追加します。

http://.../payment_processor.php?action=rp_status&profile_id={recurring_payment_profile_id}&signature={signature}

要求データ

  • profile_id:定期支払いプロファイルのID。
    定期支払いプロファイルを設定するときにこのプロセッサがINTER-STREAM側に返したIDです。
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

要求データの検証
処理を続行する前に、ハッシュを使用してデータを検証します。
検証には、INTER-STREAM側と同様にハッシュを生成し、受け取ったものと比較する必要があります。

PHPの例)

$key = "the secret key";
$profile_id = (isset($_GET["profile_id"]))? $_GET["profile_id"] : "";
$data = array(
     "action" => "rp_status",
     "profile_id" => (string)$profile_id
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));
INTER-STREAMへデータを返す

プロファイル情報を取得したら、データをJSON形式の配列として返す必要があります。

必要な配列インデックス

  • error:(オプション)処理エラーが発生した場合のみ
  • status:プロファイルのステータス。可能な値=Active,Pending,Cancelled,Suspended,Expired
  • last_payment_date:最後に支払い処理をおこなった日(UTCタイムゾーンを含むUnixタイムスタンプ)
  • next_payment_date:次回の支払い日(UTCタイムゾーンを含むUnixタイムスタンプ)

PHPの例)処理が成功した場合

echo json_encode( array(
     "status" => "Active",
     "last_payment_date" => 1422344201,
     "next_payment_date" => 1425022599
     ));

PHPの例)エラー

echo json_encode( array(
     "error" => "(詳細なエラーメッセージ)"
     ));

ケース3:定期支払いプロファイルのキャンセル [?action=rp_cancel]

最後のケースは定期支払いプロファイルのキャンセルです。INTER-STREAM側では値が"rp_cancel"のGET変数"action"(="?action=rp_cancel")を使用して、定期支払いプロファイルのキャンセルを要求します。

INTER-STREAMから送信されたデータを受信する

INTER-STREAMは、要求データをGET変数として支払処理プログラムのスクリプトURLに追加します。

http://.../payment_processor.php?action=rp_cancel&profile_id={recurring_payment_profile_id}&signature={signature}

要求データ

  • profile_id:定期支払いプロファイルのID。
    定期支払いプロファイルを設定するときにこのプロセッサがINTER-STREAM側に返したIDです。
  • signature:データを検証するための署名(ハッシュ)。
    シグネチャはHMAC SHA256を使用して、ストアの設定に入力されたkeyで生成されます。

要求データの検証
処理を続行する前に、ハッシュを使用してデータを検証します。
検証には、INTER-STREAM側と同様にハッシュを生成し、受け取ったものと比較する必要があります。

PHPの例)

$key = "the secret key";
$profile_id = (isset($_GET["profile_id"]))? $_GET["profile_id"] : "";
$data = array(
     "action" => "rp_cancel",
     "profile_id" => (string)$profile_id
);
$signature = base64_encode(hash_hmac('sha256', json_encode($data), $key, true));
INTER-STREAMへ結果を返す

プロファイルをキャンセルしたら、結果をJSON形式の配列として返す必要があります。

必要な配列インデックス

  • error:(オプション)処理エラーが発生した場合のみ
  • status:キャンセル後のプロファイルのステータス。"Cancelled"でなくてはなりません。

PHPの例)処理が成功した場合

echo json_encode( array(
     "status" => "Cancelled"
     ));

PHPの例)エラー

echo json_encode( array(
     "error" => "A deatiled error message..."
     ));