dongxixian7803 2015-08-02 21:21
浏览 31

从localhost重定向到Paypal沙箱,在OS X上通过MAMP Pro运行?

I'm running a website locally via MAMP Pro and am having issues with connecting to PayPal sandbox. I don't think you can do this locally, right?

Here's my code:

Order.php

<?php
class Order extends Application {
    private $_table = 'orders';
    private $_table_2 = 'orders_items';
    private $_table_3 = 'statuses';

    private $_basket = array();

    private $_items = array();

    private $_fields = array();
    private $_values = array();

    private $_id = null;

    public function getItems() {
        $this->_basket = Session::getSession('basket');
        if (!empty($this->_basket)) {
            $objCatalogue = new Catalogue();
            foreach($this->_basket as $key => $value) {
                $this->_items[$key] = $objCatalogue->getProduct($key);
            }
        }
    }

    public function createOrder() {
        $this->getItems();

        if (!empty($this->_items)) {
            $objUser = new User();
            $user = $objUser->getUser(Session::getSession(Login::$_login_front));

            if (!empty($user)) {
                $objBasket = new Basket();

                $this->_fields[] = 'client';
                $this->_values[] = $this->db->escape($user['id']);

                $this->_fields[] = 'vat_rate';
                $this->_values[] = $this->db->escape($objBasket->_vat_rate);

                $this->_fields[] = 'vat';
                $this->_values[] = $this->db->escape($objBasket->_vat);

                $this->_fields[] = 'subtotal';
                $this->_values[] = $this->db->escape($objBasket->_sub_total);

                $this->_fields[] = 'total';
                $this->_values[] = $this->db->escape($objBasket->_total);

                $this->_fields[] = 'date';
                $this->_values[] = Helper::setDate();

                $sql  = "INSERT INTO `{$this->_table}` (`";
                $sql .= implode("`, `", $this->_fields);
                $sql .= "`) VALUES ('";
                $sql .= implode("', '", $this->_values);
                $sql .= "')";

                $this->db->query($sql);
                $this->_id = $this->db->lastId();

                if (!empty($this->_id)) {
                    $this->_fields = array();
                    $this->_values = array();
                    return $this->addItems($this->_id);
                }
            }
            return false;
        }
        return false;
    }

    private function addItems($order_id = null) {
        if (!empty($order_id)) {
            $error = array();
            foreach($this->_items as $item) {
                $sql = "INSERT INTO `{$this->_table_2}`
                        (`order`, `product`, `price`, `qty`)
                        VALUES ('{$order_id}', '".$item['id']."', '".$item['price']."', '".$this->_basket[$item['id']]['qty']."')";
                if (!$this->db->query($sql)) {
                    $error[] = $sql;
                }
            }
            return empty($error) ? true : false;
        }
        return false;
    }

    public function getOrder($id = null) {
        $id = !empty($id) ? $id : $this->_id;
        $sql = "SELECT * FROM `{$this->_table}`
                WHERE `id` = '".$this->db->escape($id)."'";
        return $this->db->fetchOne($sql);
    }

    public function getOrderItems($id = null) {
        $id = !empty($id) ? $id : $this->_id;
        $sql = "SELECT * FROM `{$this->_table_2}`
                WHERE `order` = '".$this->db->escape($id)."'";
        return $this->db->fetchAll($sql);
    }
}

Paypal.php

<?php
class PayPal {

// environment
private $_environment = 'sandbox';

// urls
private $_url_production = 'https://www.paypal.com/cgi-bin/webscr';
private $_url_sandbox = 'https://www.sandbox.paypal.com/cgi-bin/webscr';

// url to be used
private $_url;

// transaction type : 
// _xclick = buy now buttons
// _cart = basket
private $_cmd;

// all products array
private $_products = array();

// all input fields array
private $_fields = array();

// your paypal id
private $_business = '';

// page style
private $_page_style = null;

// return url
private $_return;

// cancel url
private $_cancel_payment;

// notify url (IPN)
private $_notify_url;

// currency code
private $_currency_code = 'GBP';

// tax / vat amount for _cart
public $_tax_cart = 0;

// tax / vat amount for _xclick
public $_tax = 0;

// pre-populating checkout pages
// address1 *, address2, city *, state *, zip *
// country *, email *, first_name *, last_name *
// you have to have all required fields filled in - otherwise it won't work
public $_populate = array();

// data received from paypal
private $_ipn_data = array();

// path to the log file for ipn response
private $_log_file = null;

// result of sending data back to paypal after ipn
private $_ipn_result;










public function __construct($cmd = '_cart') {

    $this->_url = $this->_environment == 'sandbox' ?
                    $this->_url_sandbox :
                    $this->_url_production;

    $this->_cmd = $cmd;

    $this->_return = SITE_URL."/?page=return";
    $this->_cancel_payment = SITE_URL."/?page=cancel";
    $this->_notify_url = SITE_URL."/?page=ipn";
    $this->_log_file = ROOT_PATH.DS."log".DS."ipn.log";

}







public function addProduct($number, $name, $price = 0, $qty = 1) {

    switch($this->_cmd) {

        case '_cart':
        $id = count($this->_products) + 1;
        $this->_products[$id]['item_number_'.$id] = $number;
        $this->_products[$id]['item_name_'.$id] = $name;
        $this->_products[$id]['amount_'.$id] = $price;
        $this->_products[$id]['quantity_'.$id] = $qty;
        break;
        case '_xclick':
        if (empty($this->_products)) {
            $this->_products[0]['item_number'] = $number;
            $this->_products[0]['item_name'] = $name;
            $this->_products[0]['amount'] = $price;
            $this->_products[0]['quantity'] = $qty;
        }
        break;

    }

}







private function addField($name = null, $value = null) {
    if (!empty($name) && !empty($value)) {
        $field  = '<input type="hidden" name="'.$name.'" ';
        $field .= 'value="'.$value.'" />';
        $this->_fields[] = $field;
    }
}










private function standardFields() {
    $this->addField('cmd', $this->_cmd);
    $this->addField('business', $this->_business);
    if ($this->_page_style != null) {
        $this->addField('page_style', $this->_page_style);
    }
    $this->addField('return', $this->_return);
    $this->addField('notify_url', $this->_notify_url);
    $this->addField('cancel_payment', $this->_cancel_payment);
    $this->addField('currency_code', $this->_currency_code);
    $this->addField('rm', 2);

    switch($this->_cmd) {
        case '_cart':
        if ($this->_tax_cart != 0) {
            $this->addField('tax_cart', $this->_tax_cart);
        }
        $this->addField('upload', 1);
        break;
        case '_xclick':
        if ($this->_tax != 0) {
            $this->addField('tax', $this->_tax);
        }
        break;
    }

}









private function prePopulate() {
    if (!empty($this->_populate)) {
        foreach($this->_populate as $key => $value) {
            $this->addField($key, $value);
        }
    }
}











private function processFields() {
    $this->standardFields();
    if (!empty($this->_products)) {
        foreach($this->_products as $product) {
            foreach($product as $key => $value) {
                $this->addField($key, $value);
            }
        }
    }
    $this->prePopulate();
}











private function getFields() {
    $this->processFields();
    if (!empty($this->_fields)) {
        return implode("", $this->_fields);
    }
}













private function render() {
    $out  = '<form action="'.$this->_url.'" method="post" id="frm_paypal">';
    $out .= $this->getFields();
    $out .= '<input type="submit" value="Submit" />';
    $out .= '</form>';
    return $out;
}












public function run($transaction_id = null) {
    if (!empty($transaction_id)) {
        $this->addField('custom', $transaction_id);
    }
    return $this->render();
}

















}

paypal.php

This is in a folder called mod and is on my include path set in an autoloader.php file, which has method for quick access to for example the SITE_URL and ROOT_PATH

<?php
require_once('../inc/autoload.php');

// tokens
$token2 = Session::getSession('token2');
$objForm = new Form();
$token1 = $objForm->getPost('token');

if ($token2 == Login::string2hash($token1)) {

// create order
$objOrder = new Order();
if ($objOrder->createOrder()) {

    // populate order details
    $order = $objOrder->getOrder();
    $items = $objOrder->getOrderItems();


    if (!empty($order) && !empty($items)) {

        $objBasket = new Basket();
        $objCatalogue = new Catalogue();
        $objPayPal = new PayPal();


        foreach($items as $item) {
            $product = $objCatalogue->getProduct($item['product']);
            $objPayPal->addProduct(
                $item['product'], 
                $product['name'], 
                $item['price'], 
                $item['qty']
            );
        }


        $objPayPal->_tax_cart = $objBasket->_vat;


        // populate client's details
        $objUser = new User();
        $user = $objUser->getUser($order['client']);

        if (!empty($user)) {

            // get user country record
            $objCountry = new Country();
            $country = $objCountry->getCountry($user['country']);


            // pass client's details to the PayPal instance
            $objPayPal->_populate = array(
                'address1'      => $user['address_1'],
                'address2'      => $user['address_2'],
                'city'          => $user['town'],
                'state'         => $user['county'],
                'zip'           => $user['post_code'],
                'country'       => $country['code'],
                'email'         => $user['email'],
                'first_name'    => $user['first_name'],
                'last_name'     => $user['last_name']                   
            );


            // redirect client to PayPal
            echo $objPayPal->run($order['id']);



        }

    }

}   

}

And lastly...

summary.php

<?php
Login::restrictFront();

$token1 = mt_rand();
$token2 = Login::string2hash($token1);
Session::setSession('token2', $token2);

$objBasket = new Basket();

$out = array();

$session = Session::getSession('basket');

if (!empty($session)) {
$objCatalogue = new Catalogue();
foreach($session as $key => $value) {
    $out[$key] = $objCatalogue->getProduct($key);
}
}

require_once('_header.php');

?>


<?php

echo "<div id=\"cat_prod\"><h1>- ORDER SUMMARY -</h1></div>";

?>

<?php if (!empty($out)) { ?>

<div id="big_basket">

    <form action="" method="post" id="frm_basket">

        <table cellpadding="0" cellspacing="0" border="0" class="tbl_repeat">
            <tbody id="basket_table">

                <tr style="background-color: #f2f3ee;"> 

                    <th class="ta_left">Item</th>
                    <th class="ta_r">Qty</th>
                    <th class="ta_r col_15">Price</th>

                </tr>

                <?php foreach ($out as $item) { ?>

                <tr>
                    <td class="ta_left_name"><?php echo Helper::encodeHTML($item['name']); ?></td>
                    <td class="ta_left_qty" style="float:right; padding: 10px 0px 10px"><input type="text" name="qty-<?php echo $item['id']; ?>"
                    id="qty-<?php echo $item['id']; ?>" class="fld_qty"
                    value="<?php echo $session[$item['id']]['qty']; ?>" /></td>
                    <td class="ta_r">&pound;<?php echo number_format($objBasket->itemTotal($item['price'], $session[$item['id']]['qty']), 2); ?></td>

                </tr>

                <?php } ?>

                <?php if ($objBasket->_vat_rate != 0) { ?>

                <tr style="border-bottom: dashed 1px #aaa">

                    <td class="ta_left" colspan="2">Sub-total :</td>
                    <td class="ta_r bt_td">&pound;<?php echo number_format($objBasket->_sub_total, 2); ?></td>
                    <td class="ta_r bt_td">&#160;</td>

                </tr>

                <tr style="border-bottom: dashed 1px #aaa">

                    <td class="ta_left" colspan="2">VAT (<?php $objBasket->_vat_rate; ?>%) :</td>
                    <td class="ta_r bt_td">&pound;<?php echo number_format($objBasket->_vat, 2); ?></td>
                    <td class="ta_r bt_td">&#160;</td>

                </tr>

                <?php } ?>

                <tr>

                    <td class="ta_right" colspan="2"><strong>Total :</strong></td>
                    <td class="ta_r bt_td">&pound;<?php echo number_format($objBasket->_total, 2); ?></td>
                    <td class="ta_r bt_td">&#160;</td>

                </tr>


            </tbody>    
        </table>

        <div class="dev br_td">&#160;</div>

        <div class="sbm sbm_blue fl_r paypal" id="<?php echo $token1; ?>">

            <span class="btn">Proceed to Paypal</span>

        </div>

        <div class="sbm sbm_blue fl_l">

        <a href="/?page=basket" class="btn">Amend Order</a>

        </div>

    </form>

</div>

<div class="dn">
    <img src="images/loadinfo.net.gif" alt="Proceeding to Paypal" />
</div>

<?php } else { ?>

<br /><br />
<p><em>Your basket is currently empty.</em></p>

<?php } ?>

<?php
require_once('_footer.php');

?>

Basically, when I click the Proceed to Paypal button in the summary.php page it is supposed to redirect to sandbox (at the moment for local testing) and populate all their details address, name, email etc as required. What happens though is nothing bar the page updating to show an egg timer and message saying "please wait whilst we direct you to PayPal"... which is what I've coded it to change to dynamically.

I have tried echoing on many lines in paypal.php and from the network area in Firefox it is posting 200 OK when I click the button, then token id is shown in Params, but I'm getting nothing under the Response tab and am not redirected to sandbox.

Readout from Firefox on clicking button

From reading the IPNSimulator docs I don't think you can test this locally.

And, from viewing a few Stack Overflow posts like Paypal Sandbox Test Tool IPN Simulator in Localhost I think you can use ngrok to force a domain name for site URL, but am not sure how to do this.

There is also localtunnel, but I'm not sure how to use that nor even where to download it as the site is practically blank with info here...


I'm unable to check this by uploading to my server as all my paths are directed locally for files/pages... it's messed up and I can't figure out what I need to change to get all the pages working on a direct domain name/path.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
    • ¥15 Vue3地图和异步函数使用
    • ¥15 C++ yoloV5改写遇到的问题
    • ¥20 win11修改中文用户名路径
    • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
    • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
    • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
    • ¥15 帮我写一个c++工程
    • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
    • ¥15 关于smbclient 库的使用