doushan5245 2015-04-30 01:41
浏览 82

CodeIgniter PaymentWall响应正文与预期的模式不匹配:确定

Pingback wasn't successful. Reason: Response body does not match the expected pattern: OK

Signature base string uid=currency=type=0ref=369e67e903ca0b2261cd342575b8979e

Signature = MD5(Signature base string) 2aa9f1c847d1492b18cd017cdf78290b

this is model.donate.php

<?php

in_file();

class Mdonate{
    protected $registry, $db, $config;
    private $vars = array();
    protected $hash_item = '';
    protected $paypal_ipn_url = 'https://www.paypal.com/cgi-bin/webscr';
    protected $paypal_ipn_url_ssl = 'www.paypal.com';
    protected $req = 'cmd=_notify-validate';
    protected $post = array();
    protected $paypal_response;
    public $order_details = array();
    protected $pw_ip_white_list = array('174.36.92.186', '66.220.10.3', '174.36.92.186', '174.36.96.66', '174.36.92.187', '174.36.92.192', '174.37.14.28');
    protected $pw_reason_list = array(0     => 'Invalid Reason',
                                      1     => 'Chargeback',
                                      2     => 'Credit Card fraud',
                                      3     => 'Order fraud',
                                      4     => 'Bad data entry',
                                      5     => 'Fake / proxy user',
                                      6     => 'Rejected by advertiser',
                                      7     => 'Duplicate conversions',
                                      8     => 'Goodwill credit taken back',
                                      9     => 'Cancelled order',
                                      10    => 'Partially reversed transaction');

    public function __construct(){
        $this->registry = registry::getInstance();
        $this->db = $this->registry->db;
        $this->config = $this->registry->config;
    }

    public function __set($key, $val){
        $this->vars[$key] = $val;
    }

    public function __get($name){
        return $this->vars[$name];
    }

    public function __isset($name){
        return isset($this->vars[$name]);
    }

    public function get_paypal_packages(){
        return $this->db->query('SELECT id, package, reward, price, currency FROM dmncms_donate_paypal_packages WHERE status = 1 ORDER BY orders ASC')->fetch_all();
    }

    public function check_package($id){
        $count = $this->db->snumrows('SELECT COUNT(id) as count FROM dmncms_donate_paypal_packages WHERE id = '.$this->db->escape($id).' AND status = 1');
        return ($count == 1);
    }

    public function insert_paypal_order($reward, $price, $currency){
        $this->hash_item = md5($_SESSION['name'].$price.$currency.uniqid(microtime(),1));
        $stmt = $this->db->prepare('INSERT INTO dmncms_donate_paypal_orders (amount, currency, credits, account, hash) VALUES(:amount, :currency, :credits, :account, :hash)');
        return $stmt->execute(array(':amount'   => $price, ':currency'  => $currency, ':credits'    => $reward, ':account'  => $_SESSION['name'], ':hash'   => $this->hash_item));  
    }

    public function get_paypal_data(){
        return array('email' => $this->config->load_xml_config('donate|pp_email'), 'item' => $this->hash_item, 'user' => $_SESSION['name']);
    }

    public function gen_post_fields($data){
        $data_array = explode('&', $data);
        foreach($data_array as $value){
            $value = explode ('=', $value);
            if(count($value) == 2)
                $this->post[$value[0]] = urldecode($value[1]);
        }
        foreach($this->post as $key => $value) {        
            $this->req .= "&".$key."=".urlencode($value);
        }
    }

    public function post_back_paypal_fsock(){
        $header = "POST /cgi-bin/webscr HTTP/1.0
";  
        $header .= "Content-Type: application/x-www-form-urlencoded
";
        $header .= "Host: ".$this->paypal_ipn_url_ssl."
";
        $header .= "Content-Length: " . strlen($this->req) . "
";
        $header .= "Connection: close

";
        $fp = fsockopen('ssl://'.$this->paypal_ipn_url_ssl, 443, $errno, $errstr, 30);
        if(!$fp){
            $this->writelog('PayPal sent fsockopen error no. '.$errno.': '.$errstr.'','Paypal');
            return false;
        } 
        else{
            fputs($fp, $header.$this->req);
            while(!feof($fp)){
                $this->paypal_response = fgets($fp, 1024);
            }
            fclose($fp);
        }
        return true;
    }

    public function post_back_paypal_curl(){
        $request = curl_init();
        curl_setopt_array($request, array(CURLOPT_URL => $this->paypal_ipn_url,
                                          CURLOPT_POST => TRUE,
                                          CURLOPT_POSTFIELDS => $this->req,
                                          CURLOPT_RETURNTRANSFER => TRUE,
                                          CURLOPT_HTTPHEADER => array('Connection: Close'),
                                          CURLOPT_SSL_VERIFYPEER => TRUE,
                                          CURLOPT_SSL_VERIFYHOST => 2,
                                          CURLOPT_FORBID_REUSE => TRUE,
                                          CURLOPT_CAINFO => APP_PATH.DS.'data'.DS.'cacert.pem'));
        $this->paypal_response = curl_exec($request);
        if(curl_errno($request)){
            $this->writelog(curl_error($request), 'Paypal');
            return false;
        }
        curl_close($request);
        return true;
    }

    public function validate_paypal_payment(){
        if(stripos($this->paypal_response, "VERIFIED") !== false){
            if(!$this->check_email()){
                return false;   
            }
            if(!$this->check_order_number()){
                return false;
            }
            switch($this->vars['payment_status']){
                case 'Completed':
                    if($this->vars['tax'] > 0){
                        $this->vars['mc_gross'] -= $this->vars['tax']; 
                    }                   
                    if($this->vars['mc_gross'] == $this->order_details['amount']){
                        if($this->vars['mc_currency'] == $this->order_details['currency']){
                            if($this->check_completed_transaction()){
                                return false;
                            }   
                            if($this->check_pending_transaction()){
                                if($this->update_transaction_status()){
                                    return true;
                                }
                            }
                            else{
                                if($this->insert_transaction_status()){
                                    return true;
                                }
                            }
                        }
                    }
                break;
                case 'Pending':
                    if($this->vars['tax'] > 0){
                        $this->vars['mc_gross'] -= $this->vars['tax']; 
                    }
                    if(!$this->check_completed_transaction() && !$this->check_pending_transaction()){
                        $this->insert_transaction_status();
                    }
                break;
                case 'Reversed': case 'Refunded':
                    $this->decrease_credits($this->order_details['account'], $this->order_details['credits']);
                    $this->update_transaction_status();
                    if($this->config->load_xml_config('donate|pp_punish_player') == 1){
                        $this->block_user($this->order_details['account']);
                    }
                break;
            }
        }
        if(stripos($this->paypal_response, "INVALID") !== false){
            $this->writelog('PayPal sent [status: INVALID] [transaction id: '.$this->vars['txn_id'], 'Paypal');
        }
    }

    private function check_email(){
        if(strtolower($this->vars['receiver_email']) != strtolower($this->config->load_xml_config('donate|pp_email'))){
            $this->writelog('PayPal sent invalid reciever email: '.$this->vars['receiver_email'].'', 'Paypal');
            return false;
        }
        return true;
    }

    private function check_order_number(){
        $count = $this->db->snumrows('SELECT COUNT(id) AS count FROM dmncms_donate_paypal_orders where hash = '.$this->db->escape($this->vars['item_number']));
        if($count == 1){
            $this->order_details = $this->db->query('SELECT amount, currency, account, credits FROM dmncms_donate_paypal_orders where hash = '.$this->db->escape($this->vars['item_number']))->fetch();
            return true;
        }
        else{
            $this->writelog('PayPal sent invalid order [transaction id: '.$this->vars['txn_id'].']', 'Paypal');
            return false;
        }
    }

    private function check_completed_transaction(){
        $count = $this->db->snumrows('SELECT COUNT(id) AS count FROM dmncms_donate_paypal_transactions where transaction_id = '.$this->db->escape($this->vars['txn_id']).' and status = \'Completed\'');
        if($count > 0){
            return true;
        }
        return false;
    }

    private function check_pending_transaction(){
        $count = $this->db->snumrows('SELECT COUNT(id) AS count FROM dmncms_donate_paypal_transactions where transaction_id = '.$this->db->escape($this->vars['txn_id']).' and status = \'Pending\'');
        if($count > 0){
            return true;
        }
        return false;
    }

    private function update_transaction_status(){
        $stmt = $this->db->prepare('UPDATE dmncms_donate_paypal_transactions SET status = :status WHERE transaction_id = :trans_id');
        return $stmt->execute(array(':status' => $this->vars['payment_status'], ':trans_id' => $this->vars['txn_id']));
    }

    private function insert_transaction_status(){
        $stmt = $this->db1->prepare('INSERT INTO dmncms_donate_paypal_transactions (transaction_id, amount, currency, acc, credits, order_date, status, payer_email) VALUES (:trans_id, :gross, :currency, :account, :credits, :time, :payment_status, :payer_email)');
        return $stmt->execute(array(':trans_id' => $this->vars['txn_id'], ':gross' => $this->vars['mc_gross'], ':currency' => $this->vars['mc_currency'], ':account' => $this->order_details['account'], ':credits' => $this->order_details['credits'], ':time' => time(), ':payment_status' => $this->vars['payment_status'], ':payer_email' => $this->vars['payer_email']));
    }

    public function reward_user($acc, $credits){
        $stmt = $this->db->prepare('UPDATE bg_user SET cash = cash + :credits WHERE bg_user = :account');
        $stmt->execute(array(':account' => $acc, ':credits' => str_replace('-', '', $credits)));
    }

    private function decrease_credits($acc, $credits){
        $stmt = $this->db1->prepare('UPDATE bg_user SET cash = cash - :credits WHERE bg_user = :account');
        $stmt->execute(array(':credits' => str_replace('-', '', $credits), ':account' => $acc));
    }

    private function block_user($acc){
        return;
    }

    public function validate_ip_list(){
        return (in_array($_SERVER['REMOTE_ADDR'], $this->pw_ip_white_list));
    }

    public function validate_pw_signature(){
        return (md5('uid='.$this->vars['uid'].'currency='.$this->vars['currency'].'type='.$this->vars['type'].'ref='.$this->vars['ref'].$this->config->load_xml_config('donate|pw_secretkey')) == $this->vars['sig']);
    }

    public function validate_pw_payment(){
        if(!$this->check_reference()){
            if($this->log_pw_transaction()){
                return true;
            }
        }
        else{
            if($this->vars['type'] == 2){
                $this->change_pw_transaction_status();
                if($this->vars['reason'] == 2 || $this->vars['reason'] == 3){
                    $this->block_user($this->vars['uid']);
                }       
                $this->decrease_credits($this->vars['uid'], $this->vars['currency']);   
            }
        }
    }

    private function check_reference(){
        $count = $this->db->snumrows('SELECT COUNT(uid) AS count FROM dmncms_donate_paymentwall WHERE uid = '.$this->db->escape($this->vars['uid']).' AND ref = '.$this->db->escape($this->vars['ref']).'');
        if($count > 0){ 
            return true;
        }
        return false;
    }

    private function log_pw_transaction(){
        $prepare = $this->db->prepare('INSERT INTO dmncms_donate_paymentwall (uid, currency, type, ref, reason, order_date) VALUES (:uid, :currency, :type, :ref, :reason, :time)');
        return $prepare->execute(array(':uid' => $this->vars['uid'], ':currency' => $this->vars['currency'], ':type' => $this->vars['type'], ':ref' => $this->vars['ref'], ':reason' => 'Complete', ':time' => time()));
    }

    private function change_pw_transaction_status(){
        $stmt = $this->db->prepare('UPDATE dmncms_donate_paymentwall SET currency = :currency, reason = :reason, order_date = :order_date WHERE uid =:uid AND ref = :ref');
        $stmt->execute(array(':currency' => $this->vars['currency'], ':reason' => $this->pw_reason_list[$this->vars['reason']], ':order_date' => time(), ':uid' => $this->vars['uid'], ':ref' => $this->vars['ref']));
    }

    public function writelog($logentry, $lgname) {
        $log = '['.$_SERVER['REMOTE_ADDR'].'] ['.(isset($_SESSION['name']) ? $_SESSION['name'] : 'Unknown').'] '.$logentry.'';
        $log_name = APP_PATH.DS.'logs'.DS.$lgname.'_'.date("m-d-y").'.txt';
        $logfile = @fopen($log_name, "a+");
        if($logfile){
            fwrite($logfile, "[".date ("h:iA")."] $log
");
            fclose($logfile);
        }
    }
}

This is view.paymentwall.php / http://domain.com/donate/paymentwall - im using it for pingback adress

<?php 
    if(load::get('errors') != false){
        foreach(load::get('errors') as $errors){
            echo '<div class="notification-box notification-box-error">'.$errors.'</div>';
        }
    }
    if(load::get('pw') == false || load::get('pw') == 0){
        echo '<div class="notification-box notification-box-error">This donation method is disabled.</div>';
    }
    else{
        echo '<div style="/* border: 1px dotted black; *//* -webkit-border-radius: 5px; */-moz-border-radius: 5px;/* border-radius: 5px; */margin-top: 10px;    padding: 10px;    height: auto;    background: rgba(55, 52, 55, 1);    box-shadow: 0 0 4px rgba(0,0,0,.6), 0 1px 1px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.015), inset 0 1px 0 rgba(255,255,255,.05);    -webkit-border-radius: 5px;    -moz-border-radius: 5px;    border-radius: 5px;    /* margin-left: -38px; */    z-index: 1;">
                <div style="padding: 2px; text-align: center;"><iframe src="http://wallapi.com/api/ps/?key='.load::get('pw_apikey').'&uid='.$_SESSION['name'].'&widget='.load::get('pw_widget').'" width="'.load::get('pw_w_width').'" height="'.load::get('pw_w_height').'" frameborder="0"></iframe></div>
              </div>';
    }
?>
  • 写回答

2条回答 默认 最新

  • dongshi1102 2015-04-30 08:40
    关注

    It is necessary to use appropriate algorithm and parameters for signature calculation based on version you would like to use :

    https://www.paymentwall.com/en/documentation/Signature-Calculation/2313

    If the version is 2 or 3 your parameters should be sorted alphabetically.

    For pingback you have to return only string "OK" from your server in case of successful pingback/negative pingback.

    评论

报告相同问题?

悬赏问题

  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器