PagSeguro (支払いゲートウェイ - ブラジル版の PayPal) を自分のサイトに取り込もうとしています。顧客は PagSeguro の使用を終了した後、私が指定した関数に (POST 経由で) データを送信します。ただし、POST を受信していません。考えられるすべてのトラブルシューティングを行った後、PagSeguro に連絡しました。彼らのログは、POST は通常どおり送信されているが、HTTP 302 応答を受信していることを示していると述べています。
なぜこれが起こっているのかを理解するために、非表示の値を持つフォームを作成して、関数への POST の送信をシミュレートしました。何か関係がある場合に備えて、このフォームを別のドメインに置きました。シミュレーション フォームから POST を送信するたびに、HTTP 200 応答を受け取り、POST が受信されたことをログに示します。
PagSeguro が私のシミュレーションとは異なる応答を受け取る可能性があるのはなぜですか? サーバーと関係がありますか、それとも私のスクリプトと関係がありますか?
POST を受信する関数 (CodeIgniter を使用) は次のとおりです。
function pagseguro_retorno(){
if (count($_POST) == 0) {
return FALSE;
}
$msg = 'POST RECEIVED';
$simulate = $this->input->post('Simulate');
if ( ! empty($simulate)){
$result = 'VERIFICADO';
$msg .= ' FROM SIMULATOR';
} else {
$this->load->library(PagSeguroNpi);
$result = $this->PagSeguroNpi->notificationPost();
}
$this->log($msg);
if ($result == "VERIFICADO") {
$id = $this->input->post('Referencia');//cart id
$this->load->model('transacao_model');
$trans_row = $this->transacao_model->get_transaction($id);
if ( ! is_object($trans_row)){
//LOAD NEW TRANSACTION
if ( ! $this->new_transaction($id)){
$notice = "Unable to load new transaction</p><p>";
$this->log($notice);
$notice .= '<pre>'.print_r($_POST, TRUE).'</pre>';
$this->email_notice($notice);
}
}
$this->load->model('carrinho_model');
if($_POST['StatusTransacao'] == 'Aprovado'){
$status = 'apr';
}elseif($_POST['StatusTransacao'] == 'Em Análise'){
$status = 'anl';
}elseif($_POST['StatusTransacao'] == 'Aguardando Pagto'){
$status = 'wtg';
}elseif($_POST['StatusTransacao'] == 'Completo'){
$status = 'cmp';
//nothing more happens here - client must click on 'mark as shipped' before cart is removed and history data is loaded
}elseif($_POST['StatusTransacao'] == 'Cancelado'){
//reshelf - don't set $status, because the cart's about to be destroyed
$this->carrinho_model->reshelf(array($id));
}
if (isset($status)){
$this->carrinho_model->update_carrinho($id, array('status' => $status));
}
} else if ($result == "FALSO") {
$notice = "PagSeguro return was invalid.";
$this->log($notice);
$notice .= '<pre>'.print_r($_POST, TRUE).'</pre>';
$this->email_notice($notice);
} else {
$notice = "Error in PagSeguro request";
$this->log($notice);
$notice .= '<pre>'.print_r($_POST, TRUE).'</pre>';
$this->email_notice($notice);
}
}
セキュリティ更新:
投稿した後、すぐに自分がハッキングの試みに心を開いていることに気付きました。関数は必ずパブリックにする必要があるため、関数の名前を知っている人は誰でも関数にアクセスして「シミュレート」を投稿して、すぐに検証を取得できます。その後、必要なデータを渡すことができました。
関数の名前を推測できない名前に変更し、本番モードでないときはシミュレート オプションを無効にしました。