close

事前準備

1. paypal帳號

2. paypal沙箱帳號

3. codeigniter 3主程式

 

第一步:先申請paypal帳號與paypal沙箱測試帳號

需要先申請一個商用帳號,並啟用api,網址在下方

https://developer.paypal.com/

第二步:新增paypalmodel

application/model建立一個Palpal_class.php的檔案 並貼上以下程式碼

<?php

class Paypal_class extends CI_Model{
    public function __construct(){
        parent::__construct();
    }
    public function PPHttpPost($method, $querystring){
        if($this->check_mode()){
            $paypal_user = "xxx";
            $paypal_password = "xxx";
            $paypal_signature = "xxx";
            $api_url = "https://api-3t.sandbox.paypal.com/nvp";
        }else{
            $paypal_user = "xxx";
            $paypal_password = "xxx";
            $paypal_signature = "xxx";
            $api_url = "https://api-3t.paypal.com/nvp";
        }
        
        //Set the curl parameters.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $api_url);

        // Turn off the server and peer verification (TrustManager Concept).
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        $nvpreq = "&METHOD=".$method."&VERSION=109.0&PWD=".urlencode($paypal_password)."&USER=".urlencode($paypal_user)."&SIGNATURE=".urlencode($paypal_signature).$querystring;
        // Set the request as a POST FIELD for curl.
        curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
        // Get response from the server.
        $httpResponse = curl_exec($ch);
        
        if(!$httpResponse){
            exit($method." failed: ".curl_error($ch).'('.curl_errno($ch).')');
        }
        // Extract the response details.
        $httpResponseAr = explode("&", $httpResponse);
        $httpParsedResponseAr = array();
        foreach ($httpResponseAr as $i => $value){
            $tmpAr = explode("=", $value);
            if(sizeof($tmpAr) > 1){
                $httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
            }
        }
        if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)){
            exit("Invalid HTTP Response for POST request(".$nvpreq.") to ".$api_url);
        }
        return $httpParsedResponseAr;
    }
}

第三步:在controller使用paypal model

application/controller建立cart.php檔案 並貼上以下程式碼

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Cart extends CI_Controller{
    public function __construct(){
        parent:: __construct();
    }
    //購買清單
    public function index(){
        $this->load->view("cart");
    }
    //paypal付款
    public function payment(){
        //載入paypal model
        $this->load->model("Paypal_Class");


        //接受表單資料
        $LOGOIMG = "logo url";
        $currencyCodeType = $this->input->post("currencyCodeType");
        $L_PAYMENTREQUEST_0_NAME0 = $this->input->post("L_PAYMENTREQUEST_0_NAME0");;
        $L_PAYMENTREQUEST_0_NUMBER0 = $this->input->post("L_PAYMENTREQUEST_0_NUMBER0");
        $L_PAYMENTREQUEST_0_AMT0 = $this->input->post("L_PAYMENTREQUEST_0_AMT0");
        $L_PAYMENTREQUEST_0_QTY0 = $this->input->post("L_PAYMENTREQUEST_0_QTY0");
        $PAYMENTREQUEST_0_ITEMAMT = $this->input->post("PAYMENTREQUEST_0_ITEMAMT");
        $PAYMENTREQUEST_0_AMT = $this->input->post("PAYMENTREQUEST_0_AMT");
        $PAYMENTREQUEST_0_SHIPTOSTREET = $this->input->post("PAYMENTREQUEST_0_SHIPTOSTREET");
        $PAYMENTREQUEST_0_SHIPTOSTREET2 = $this->input->post("PAYMENTREQUEST_0_SHIPTOSTREET2");
        $PAYMENTREQUEST_0_SHIPTOCITY = $this->input->post("PAYMENTREQUEST_0_SHIPTOCITY");
        $PAYMENTREQUEST_0_SHIPTOSTATE = $this->input->post("PAYMENTREQUEST_0_SHIPTOSTATE");
        $PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE = $this->input->post("PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE");
        $PAYMENTREQUEST_0_SHIPTOZIP = $this->input->post("PAYMENTREQUEST_0_SHIPTOZIP");
        $PAYMENTREQUEST_0_SHIPTOPHONENUM = $this->input->post("PAYMENTREQUEST_0_SHIPTOPHONENUM");
        
        if($this->input->post("action")=="checkout"){
            $return_url = base_url()."cart/payment"; //驗證後返回付款頁
            $cancel_url = base_url()."cart/cancel"; //取消交易頁
            
            $querystring = "&LOGOIMG=".$LOGOIMG;
            $querystring .= "&PAYMENTREQUEST_0_PAYMENTACTION=".urlencode("SALE")."&REQCONFIRMSHIPPING=1&NOSHIPPING=1&ALLOWNOTE=0";
            $querystring .= "&L_PAYMENTREQUEST_0_NAME0=".urlencode($L_PAYMENTREQUEST_0_NAME0);
            $querystring .= "&L_PAYMENTREQUEST_0_NUMBER0=".urlencode($L_PAYMENTREQUEST_0_NUMBER0);
            $querystring .= "&L_PAYMENTREQUEST_0_AMT0=".urlencode($L_PAYMENTREQUEST_0_AMT0);
            $querystring .= "&L_PAYMENTREQUEST_0_QTY0=".urlencode($L_PAYMENTREQUEST_0_QTY0);
            $querystring .= "&PAYMENTREQUEST_0_ITEMAMT=".urlencode($PAYMENTREQUEST_0_ITEMAMT);
            $querystring .= "&PAYMENTREQUEST_0_AMT=".urlencode($PAYMENTREQUEST_0_AMT);
            $querystring .= "&PAYMENTINFO_0_CURRENCYCODE=".urlencode($currencyCodeType);
            $querystring .= "&RETURNURL=".urlencode($return_url);
            $querystring .= "&CANCELURL=".urlencode($cancel_url);
            
            $httpParsedResponseAr = $this->Paypal_Class->PPHttpPost("SetExpressCheckout", $querystring);
            
            if("SUCCESS" == strtoupper($httpParsedResponseAr['ACK']) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr['ACK'])){
                //是否為paypal測試api
                if($this->Paypal_Class->check_mode()){
                    $paypal_url ="https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=".$httpParsedResponseAr['TOKEN'];
                }else{
                    $paypal_url ="https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&useraction=commit&token=".$httpParsedResponseAr['TOKEN'];
                }

                header("Location: ".$paypal_url);
            }else{
                echo '<div style="color:red"><b>SetExpressCheckout Error : </b>'.urldecode($httpParsedResponseAr['L_LONGMESSAGE0']).'</div>';
                echo '<pre>';
                print_r($httpParsedResponseAr);
                echo '</pre>';
            }
        }elseif($this->input->get("token")!="" && $this->input->get("PayerID")!=""){
            $querystring = "&PAYMENTREQUEST_0_PAYMENTACTION=".urlencode("SALE");
            $querystring .= "&L_PAYMENTREQUEST_0_NAME0=".urlencode($L_PAYMENTREQUEST_0_NAME0);
            $querystring .= "&L_PAYMENTREQUEST_0_NUMBER0=".urlencode($L_PAYMENTREQUEST_0_NUMBER0);
            $querystring .= "&L_PAYMENTREQUEST_0_AMT0=".urlencode($L_PAYMENTREQUEST_0_AMT0);
            $querystring .= "&L_PAYMENTREQUEST_0_QTY0=".urlencode($L_PAYMENTREQUEST_0_QTY0);
            $querystring .= "&PAYMENTREQUEST_0_ITEMAMT=".urlencode($PAYMENTREQUEST_0_ITEMAMT);
            $querystring .= "&PAYMENTREQUEST_0_AMT=".urlencode($PAYMENTREQUEST_0_AMT);
            $querystring .= "&PAYMENTINFO_0_CURRENCYCODE=".urlencode($currencyCodeType);
            $querystring .= "&TOKEN=".$this->input->get("token")."&PAYERID=".$this->input->get("PayerID");
            
            $httpParsedResponseAr = $this->Paypal_Class->PPHttpPost("DoExpressCheckoutPayment", $querystring);
            
            if("SUCCESS" == strtoupper($httpParsedResponseAr['ACK']) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr['ACK'])){
                //交易紀錄
                $TRANSACTIONID = $httpParsedResponseAr['PAYMENTINFO_0_TRANSACTIONID'];
                //$L_LONGMESSAGE0 = urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]);
                //print_r($httpParsedResponseAr);

                $paypal_error_json = json_encode(array(
                                        "ErrorLongMsg" => $httpParsedResponseAr['L_LONGMESSAGE0'],
                                        "ErrorShortMsg" => $httpParsedResponseAr['L_SHORTMESSAGE0'],
                                        "ErrorCode" => $httpParsedResponseAr['L_ERRORCODE0'],
                                        "ErrorSeverityCode" => $httpParsedResponseAr['L_SEVERITYCODE0'],
                                        "PAYMENTSTATUS" => $httpParsedResponseAr['PAYMENTINFO_0_PAYMENTSTATUS']
                                    ));
                
                if('Completed' == $httpParsedResponseAr['PAYMENTINFO_0_PAYMENTSTATUS']){
                    $PAYPAL_result = '
                        <p style="font-size:13px;">Your order has been confirmed. Your order confirmation will be sent to your email ( '.$user_email.' ).</p>
                        <p style="font-size:13px;">If you have any questions, please <a href="/contact" style="color:red;text-decoration:underline;">contact</a> our customer service team.</p>';
                    $paypal_error = "";
                }elseif(json_decode($paypal_error_json)->ErrorCode==10486){
                    $PAYPAL_result = '
                        <div class="hero-unit">
                            Display the Transaction Details
                            <h4> There is a Funding Failure in your account. You can modify your funding sources to fix it and make purchase later. </h4>
                            Payment Status: '.$paypal_error_json->PAYMENTSTATUS.'
                            <h3> Click <a href="https://www.sandbox.paypal.com/">here </a> to go to PayPal site.</h3>
                        </div>';
                    $paypal_error = $paypal_error_json->PAYMENTSTATUS;
                }else{
                    $PAYPAL_result = "DoExpressCheckout API call failed. <br>";
                    $PAYPAL_result .= "Detailed Error Message: " . $ErrorLongMsg . " <br>";
                    $PAYPAL_result .= "Short Error Message: " . $ErrorShortMsg . " <br>";
                    $PAYPAL_result .= "Error Code: " . $ErrorCode . " <br>";
                    $PAYPAL_result .= "Error Severity Code: " . $ErrorSeverityCode;
                    $paypal_error = $paypal_error_json->PAYMENTSTATUS;
                }
                    //導向完成頁
                    header("Location: ".base_url()."cart/finished?orders_num=".$order_num);
                }//end $orders_insert if
            }elseif("FAILURE" == strtoupper($httpParsedResponseAr["ACK"]) || "FAILUREWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){
                //取得會員基本資料
                $this->db->where("sn", $this->session->userdata("member_sn"));
                $member_info_query = $this->db->get("member");
                if($member_query->num_rows()){
                    $member_row = $member_query->row();
                    $email = $member_row->email;
                }else{
                    $email = "";
                }
                
                $L_LONGMESSAGE0 = urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]);
                $ErrorCode = urldecode($httpParsedResponseAr["L_ERRORCODE0"]);
                $ErrorShortMsg = urldecode($httpParsedResponseAr["L_SHORTMESSAGE0"]);
                $ErrorLongMsg = urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]);
                $ErrorSeverityCode = urldecode($httpParsedResponseAr["L_SEVERITYCODE0"]);
                
                //交易錯誤代碼
                $paypal_error_json = json_encode(array(
                                    "ErrorLongMsg" => $ErrorLongMsg,
                                    "ErrorShortMsg" => $ErrorShortMsg,
                                    "ErrorCode" => $ErrorCode,
                                    "ErrorSeverityCode" => $ErrorSeverityCode,
                                    "PAYMENTSTATUS" => $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]
                                ));
                
                if('Completed' == $httpParsedResponseAr["PAYMENTINFO_0_PAYMENTSTATUS"]){
                    $PAYPAL_result = '
                        <p style="font-size:13px;">Your order has been confirmed. Your order confirmation will be sent to your email ( '.$email.' ).</p>
                        <p style="font-size:13px;">If you have any questions, please <a href="/contact" style="color:red;text-decoration:underline;">contact</a> our customer service team.</p>';
                    $paypal_error = "";
                }elseif(json_decode($paypal_error_json)->ErrorCode==10486){
                    $PAYPAL_result = '
                        <div class="hero-unit">
                            Display the Transaction Details
                            <h4> There is a Funding Failure in your account. You can modify your funding sources to fix it and make purchase later. </h4>
                            Payment Status: '.$paypal_error_json->PAYMENTSTATUS.'
                            <h3> Click <a href="https://www.sandbox.paypal.com/">here </a> to go to PayPal site.</h3>
                        </div>';
                    $paypal_error = $paypal_error_json->PAYMENTSTATUS;
                }else{
                    $PAYPAL_result = "DoExpressCheckout API call failed. <br>";
                    $PAYPAL_result .= "Detailed Error Message: " . $ErrorLongMsg . " <br>";
                    $PAYPAL_result .= "Short Error Message: " . $ErrorShortMsg . " <br>";
                    $PAYPAL_result .= "Error Code: " . $ErrorCode . " <br>";
                    $PAYPAL_result .= "Error Severity Code: " . $ErrorSeverityCode;
                    $paypal_error = $paypal_error_json->PAYMENTSTATUS;
                }
                echo $PAYPAL_result."<br/><br/>";
                echo $paypal_error;
                //header("Location: ".base_url()."cart/cancel");
            }else{
                echo '<div style="color:red"><b>DoExpressCheckout Error : </b>'.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'</div>';
                echo '<pre>';
                print_r($httpParsedResponseAr);
                echo '</pre>';
            }//end "SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"]) if
        }else{
            echo '<script>alert("data send error!");history.back();</script>';
        }//end $this->input->post("checkout")=="yes" if
    }
    //購物完成頁
    public function finished(){
        $this->load->view("finished");
    }
    //取消交易頁
    public function cancel(){
        //清除購物車資料
        $this->cart->destroy();
        $this->load->view("cancel");
    }

}

第四步:在view底下新增購物車相關頁面

(1) view底下建立cart.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
    <div class="row">
        <div class="col-xs-12">
            <ol class="breadcrumb">
                <li class="home"><a href="<?php echo base_url();?>">Home</a></li>
                <li>My Cart</li>
                <li class="active">Shopping Cart</li>
            </ol>
            <div class="row">
                <div class="col-md-12 col-sm-6">
                    <!-- pc view -->
                    <table class="table hidden-xs">
                        <tr>
                            <th>Cat. No.</th>
                            <th>Product name</th>
                            <th>Package</th>
                            <th>Qty</th>
                            <th>Unit price</th>
                            <th>Price</th>
                            <th> </th>
                        </tr>
                        <?php
                        foreach($this->cart->contents() as $items){
                        ?>
                        <tr>
                            <td><?php echo $items['cat_no'];?></td>
                            <td><?php echo $product_name;?></td>
                            <td><?php echo $items['package'];?> <?php echo $items['unit'];?></td>
                            <td>
                                <input type="hidden" name="rowid_<?php echo $items['id'];?>" value="<?php echo $items['rowid'];?>">
                                <select name="qty_<?php echo $items['id'];?>" onchange="update('<?php echo $items['id'];?>')">
                                <option></option>
                                <?php for($q=1;$q<=10;$q++){?>
                                <option value="<?php echo $q;?>" <?php if($q==$items['qty']){?>Selected<?php }?>><?php echo $q;?></option>
                                <?php }//end $q for?>
                                </select>
                            </td>
                            <td class="text-right">$ <?php echo $this->cart->format_number($items['price'])." ".$items['dollars'];?></td>
                            <td class="text-right">$ <?php echo $this->cart->format_number($items['subtotal'])." ".$items['dollars'];?></td>
                            <td><button type="button" class="btn btn-danger btn-xs" onclick="del('<?php echo $items['rowid'];?>')">Remove</button></td>
                        </tr>
                        <?php }//end $data_item foreach?>
                        <tr>
                            <td colspan="5"> </td>
                            <td><h4>Subtotal</h4></td>
                            <td class="text-right"><h4 class="total_span"><strong>$ <?php if($this->cart->total()!=0){echo $this->cart->format_number($this->cart->total())." ".$items['dollars'];}else{echo "0";}?></strong></h4></td>
                        </tr>
                    </table>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

(2)view底下新增finished.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
    <div class="row">
        <div id="content" class="col-xs-12 col-md-12">
            <ol class="breadcrumb">
                <li class="home"><a href="<?php echo base_url();?>">Home</a></li>
                <li>My Cart</li>
                <li class="active">Finish</li>
            </ol>
            <div id="cart_info">
                <div class="panel">
                    <div class="panel-body">
                        <div class="box">
                            <h3>Thank you for shopping with arigo. A confirmation letter will be sent to your email shortly.</h3>
                            <h4>Your order number is: 12345</h4>
                            <h4>
                                <a href="javascript:void(0)" title="order history">Click here</a> to review your order history or 
                                <a href="javascript:void(0)">contact us</a> if you need more assistance.
                            </h4>
                        </div>
                    </div>
                </div>
            </div>
            <span id="top-link-block" class="hidden">
                <a href="#top" class="well well-sm" onclick="$('html,body').animate({scrollTop:0},'slow');return false;">
                    <i class="glyphicon glyphicon-chevron-up"></i> Back to Top
                </a>
            </span>
        </div>
    </div>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

(3)view底下建立cancel.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
    <div class="row">
        <div id="content" class="col-xs-12 col-md-12">
            <ol class="breadcrumb">
                <li class="home"><a href="<?php echo base_url();?>">Home</a></li>
                <li>My Cart</li>
                <li class="active">Cancel</li>
            </ol>
            <div id="cart_info">
                <div class="panel">
                    <div class="panel-heading">Cancel order</div>
                    <div class="panel-body">
                        <div class="box">
                            <h3>You cancelled the order.</h3>
                        </div>
                    </div>
                </div>
            </div>
            <span id="top-link-block" class="hidden">
                <a href="#top" class="well well-sm" onclick="$('html,body').animate({scrollTop:0},'slow');return false;">
                    <i class="glyphicon glyphicon-chevron-up"></i> Back to Top
                </a>
            </span>
        </div>
    </div>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

(4)view底下建立checkout.php檔案

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
                    <form id="orderForm" class="form-horizontal" role="form" action="<?php echo base_url();?>cart/payment" method="post">
                    <input type="hidden" name="action" value="checkout">
                    <input type="hidden" name="currencyCodeType" value="<?php echo $items['dollars'];?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTONAME" value="<?php echo $this->session->userdata("shipping_first_name")." ".$this->session->userdata("shipping_last_name");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTOSTREET" value="<?php echo $this->session->userdata("shipping_address1");?>">
                    <input type="hidden" name="PAYMENTREQUEST_n_SHIPTOCITY" value="<?php echo $this->session->userdata("shipping_city");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTOSTATE" value="<?php echo $this->session->userdata("shipping_state");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE" value="<?php echo $this->session->userdata("shipping_country");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTOZIP" value="<?php echo $this->session->userdata("shipping_zip");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_SHIPTOPHONENUM" value="<?php echo $this->session->userdata("shipping_phone");?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_NAME0">
                    <input type="hidden" name="PAYMENTREQUEST_0_NUMBER0">
                    <input type="hidden" name="PAYMENTREQUEST_0_AMT0" value="<?php echo round($payment_total, 2);?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_QTY0" value="1">
                    <input type="hidden" name="PAYMENTREQUEST_0_ITEMAMT" value="<?php echo round($payment_total, 2);?>">
                    <input type="hidden" name="PAYMENTREQUEST_0_AMT" value="<?php echo round($payment_total, 2);?>">
                    <div class="text-right" id="orders_action">
                    </form><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

有問題請方下方留言讓我知道並改進唷

arrow
arrow

    ying5320 發表在 痞客邦 留言(0) 人氣()