ロゴ
HOME > jQuery・Javascript > 外部サイトへポストしてレスポンスを受け取る – curl

外部サイトへポストしてレスポンスを受け取る – curl

2015年06月30日

カード決済を伴うWEBシステムを書く機会が割と多いのですが、日本だとソフトバンクやベリトランスといった大手さんや、海外だとエラボンなど、だいたい共通するのは指定されたURLに対して変数を飛ばして処理するという事です。

ただ、最近はカード番号を自社サーバーに保持すると保守面が大変になるので、決済会社のフォームへ移動して決済し、元サイトに戻ってくるといったような仕組みを取り入れるケースが多くなっています。

こういったケースだと単純にPOSTすれば良いのですが、例えばカードのオーソリだけを取りたいケースや、仮売上の本決済処理をCRONで回しているケースなど、ブラウザ処理外で外部サイトとの通信を行う必要が出てくることも有ります。

色々と方法は有るのですが、PHPのCurlという関数が便利です。

サンプル https://studio-key.com/Sample2/Kickback/

サンプルが行っている処理は、外部サイト(Curlが使えるサーバーが他になく、とりあえずstudio-key.comのサブドメインへ)へフォーム内容とユニークな値をPOSTし、キックバックされたものをsqliteデータベースへ記録する、というものです。これらの処理をページリロード無しで行います。

外部サイトへデータを投げるpost.php

session_start();

$_POST['unq']    = md5(time().$_SERVER["REMOTE_ADDR"]); //ユニークな乱数を作る
$_SESSION['unq'] = $_POST['unq']; //後から使いたいのでとりあえずsessionに記録
$post_param      = http_build_query($_POST); //postの値をURLエンコードされたクエリ文字列にする
$url             = 'http://manual.studio-key.com/Sample/kickback.php?'.$post_param; //通信先

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$kickback = curl_exec($ch) or die(curl_error());
curl_close($ch);

Curlには色々な指定が可能ですが、基本的にはこれだけです。

投げれた外部サイトで変数を処理する kickback.php

/*
 * サンプルなので簡単にだがサニタイズする
 */
  $data = array();
  foreach ($_GET AS $key=>$str){
    $data[$key] = htmlspecialchars($str , ENT_QUOTES , "UTF-8");
  }
  
  $post_param = http_build_query($data); //postの値をURLエンコードされたクエリ文字列にする
  $url        = 'https://studio-key.com/Sample2/Kickback/sql.php?'.$post_param; //通信先

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  $kickback = curl_exec($ch) or die(curl_error());

  curl_close($ch);

こちらは受け取った変数を元サイトのsql.phpへ投げ返します。

受け取った変数をデータベースに記録する sql.php

/*
 * サンプルなので簡単にだがサニタイズする
 */
  $data = array();
  foreach ($_GET AS $key=>$str){
    $data[$key] = htmlspecialchars($str , ENT_QUOTES , "UTF-8");
  }

try { 
  $stmt = $db->prepare('INSERT INTO access ("ip","unq","str") VALUES (:ip,:unq,:str)');
  $stmt->bindParam(':ip'   , $_SERVER["REMOTE_ADDR"], PDO::PARAM_STR);
  $stmt->bindParam(':unq'  , $data['unq'], PDO::PARAM_STR);
  $stmt->bindParam(':str'  , $data['str'], PDO::PARAM_STR);
  
  $stmt->execute();
  
} catch (PDOException $err) { 

}

ここでデータベースに記録します。

つまりこれで、最初に発行したユニークな値とフォームの内容は、自分のホームページ→外部サイト→自分のホームページ、と巡ってデータベースに記録されます。

後は蛇足で、戻ってきているかどうかをjqueryで判定し、表示しています。

jQuery(document).ready(function(){
  $(document).on('click','#send',function(){ 
    var data = $("#form").serialize();
      $.ajax({
            type: "POST",
            url: "post.php",
            data: data,
      });
    $("#form").html('<img src="loader.gif">');
    Timer=setInterval(function(){
      check_data();
    },3000);
  });
  
  function check_data(){
      $.ajax({
            url: "data_get.php",
            dataType :'html',
      }).done(function(html){
        if(html != 'Error'){
          $("#form").html(html);
          clearInterval(Timer);
        }
      });
  }
});

これを使うと何が出来るかと言うと、例えばカード決済だと決済会社のDBとこちらのDBで共通のユニークな値を保持しておき、決済後にカード決済会社と通信してキャンセルにしたり本決済処理を行ったりなどがPOSTせずに出来るようになります。

いえ、ブラウザ的にPOSTしてもいいんですが、数十数百というデータをカード会社からのキックバックによって条件分岐する場合などは、裏で自動化しておいた方が良いですね。

あと、PHPは使えるけどデータベースサーバーは利用不可なケース。市役所のHPなどは割とこういう事もあるようです。

こういう場合はデータベースが扱える外部サイトにデータを保管し、都度通信を行ってデータを得るような手順です。

お試しを。

蛇足になりますが、こういう仕事をしていると、インターネット通販でカード番号を入力するページが、そのサイト上のフォームだと怖くて代引きにしたり振込にしたりなどしています。