事前準備
1. paypal帳號
2. paypal沙箱帳號
3. codeigniter 3主程式
第一步:先申請paypal帳號與paypal沙箱測試帳號
需要先申請一個商用帳號,並啟用api,網址在下方
https://developer.paypal.com/
第二步:新增paypal用model
在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>
有問題請方下方留言讓我知道並改進唷
留言列表