1. 程式人生 > >使用React JS和PHP RESTful進行PayPal Express Checkout

使用React JS和PHP RESTful進行PayPal Express Checkout

esc int data url clear imp ner auth config 信息

目前市場上有幾種付款方式可供選擇。PayPal結賬選項就是其中之一。在我之前的文章中,我已經討論了幾個支付選項 - 使用PHP的Braintree PayPal,支付系統和使用PHP和MySQL的PayPal Express Checkout。這些是迄今為止觀看次數最多的熱門文章。今天,讓我們看看PayPal Express Checkout如何與React JS配合使用。

技術分享圖片技術分享圖片?



用於測試用戶名的實時演示沙箱PayPal憑據:[email protected]密碼:9lessons

Live Demo


第一部分:使用ReactJS和RESTful API登錄Facebook和Google

數據庫設計


要構建PayPal結賬訂購系統,您必須創建以下表格。社交登錄用戶表已出現在上一篇文章中。

產品
產品表包含所有產品詳細信息。您可以根據需要擴展此表。

CREATE TABLE 產品(
pid int AUTO_INCREMENT PRIMARY KEY,
產品varchar(300),
product_image varchar(200),
價格浮動,
貨幣varchar(10)
);


訂單
訂單表包含PayPal付款ID的所有用戶訂單詳細信息。

CREATE TABLE 命令(
oid int AUTO_INCREMENT PRIMARY KEY,
pid_fk int,
uid_fk int,
payerID varchar(500),
paymentID varchar(500),
token varchar(500),
created int(11)
);



Home.js
讓我們繼續這篇文章。這裏存在用戶會話存儲數據,用setState存儲數據。使用用戶ID和令牌,您可以訪問其他信息,如產品和訂單詳細信息。

從‘react‘ 導入React ,{ Component } ;

import ‘./Home.css‘ ;

從‘react-router-dom‘ 導入 { Redirect } ;

class Home extends Component {

構造函數(道具){

超級(道具);

這個。state = {

名字:‘‘,

重定向: false,

};

}

componentDidMount(){

讓 data = JSON。解析(的sessionStorage。的getItem(‘用戶數據‘));

安慰。記錄(數據);

這個。的setState({名稱: 數據。用戶數據。名稱})

}

render(){

如果(!的sessionStorage。的getItem(‘用戶數據‘)|| 此。狀態。重定向){

return(< Redirect to = { ‘/‘ } />)

}

回來(

< div >

歡迎{ this。state .name}

</ div >

);

}

}

出口默認首頁;


讓我們開始
您必須為多種用途創建通用組件。在這個項目中,我們通常使用項目標題並註銷。

Title.js
此組件包含項目標題和註銷功能。使用道具可以擾亂數據。您可以在多個頁面中導入此組件。

從“react” 導入React ,{ Component } ;

從“react-router-dom” 導入 { Redirect } ;

import “./ Title.css” ;

class Title extends Component {

構造函數(道具){

超級(道具);

這個。註銷 = 這個。註銷。bind(this);

這個。state = {

重定向: false

};

}

logout(){

sessionStorage。setItem(“userData”,“”);

sessionStorage .clear();

這個。setState({redirect : true });

}

render(){

如果(此。狀態。重定向){

return < Redirect to = { “/” } /> ;

}

回來(

< div className = “row” >

< div className = “medium-12 columns” >

< ul className = “right” >

< li >

< A HREF = “/訂單” >訂單</一>

</ li >

< li >

< a href = “#” onClick = { this。註銷 } >

登出

</ a >

</ li >

</ ul >

< h2 >歡迎{ this。道具 .name} </ h2 >

</ div >

</ div >

);

}

}

出口 默認 標題 ;



ProductsList.js
用於顯示所有產品詳細信息的組件。這裏的產品數據是從React props constuctor 調用的。onClick按鈕this.props.checkOut指向父函數,您將在下一步中找到它。

從“react” 導入React ,{ Component } ;

import “./ ProductsList.css” ;

class ProductsList 擴展 Component {

構造函數(道具){

超級(道具);

}

render(){

讓 productList = 這個。道具。productsData。map(function(productData,index){

回來(

< div className = “row list” key = {index} >

< div className = “medium-3 columns” >

< img

src = {

“https://demos.9lessons.info/PHP-PayPal-ExpressCheckout/img/” +

productData。product_img

}

/>

</ div >

< div className = “medium-3 columns” > { productData .product} </ div >

< div className = “medium-3 columns” > $ { productData。價格 } </ div >

< div className = “medium-3 columns” >

< button className = “button” value = { productData。pid }

onClick = { this。道具。結帳 } >

訂購

</ button >

</ div >

</ div >

);

},此);

return < div > {productList} </ div > ;

}

}

出口 默認的 產品列表 ;


使用RESTful API導入組件和數據綁定

Home.js使用PostData URL提取提供程序
導入TitleProductList組件。函數getProducts()根據登錄用戶ID令牌從產品API獲取數據。

從“react” 導入React ,{ Component } ;

import “./ Home.css” ;

從“react-router-dom” 導入 { Redirect } ;

從“../../services/PostData” 導入 { PostData } ;

從“../Title/Title” 導入標題 ;

從“../ProductsList/ProductsList” 導入ProductsList ;

class Home extends Component {

構造函數(道具){

超級(道具);

這個。state = {

名稱: “”,

重定向: false,

產品: [],

pid : “”

};

這個。getProducts = this。getProducts。bind(this);

這個。checkout = 這個。結帳。bind(this);

}

componentDidMount(){

讓 data = JSON。解析(的sessionStorage。的getItem(“用戶數據”));

這個。的getProducts(數據。用戶數據);

這個。的setState({名稱: 數據。用戶數據。名稱});

}

getProducts(userData){

讓 postData = {uid : userData。uid,token : userData。令牌 };

安慰。log(postData);

PostData(“產品”,postData)。然後(result => {

讓 responseJson =結果;

這個。的setState({產品: responseJson。產品 });

});

}

結帳(e){

讓 pid = e .target。getAttribute(“value”);

sessionStorage。setItem(“pid”,pid);

這個。setState({pid : pid});

}

render(){

如果(!的sessionStorage。的getItem(“用戶數據”)|| 此。狀態。重定向){

return < Redirect to = { “/” } /> ;

}

如果(此。狀態。PID > 0){

return < Redirect to = { “/ checkout” } /> ;

}

回來(

< div className = “row body” >

< Title name = { this。state .name} />

< ProductsList productsData = { this。國家。產品 }

checkout = { this。結帳 } />

</ div >

);

}

}

出口默認首頁;


函數checkOut()根據product value屬性更改this.state.pid值。在render方法中,如果pid值存在,則它將重定向到/ checkout頁面。

使用PayPal和Checkout頁面
您必須安裝PayPal結賬組件才能連接PayPal API。

為React安裝PayPal Express Checkout插件。

$ npm install react-paypal-express-checkout --save


Paypal.js
使用Paypal Express Button插件創建自定義組件。您必須配置您的PayPal沙箱和生產merchent ID以獲得更多信息,並使用PHP和MySQL檢查PayPal Express Checkout。在付款成功時,它將使用createOther方法調用onSuccess。此PHP API將使用payerID,paymentToken等付款數據進行驗證。有效調用將重定向狀態值更改為true,並將其重定向到訂單頁面。

從“react” 導入React ,{ Component } ;

import “./ PayPal.css” ;

從“react-paypal-express-checkout” 導入PaypalExpressBtn ;

從“../../services/PostData” 導入 { PostData } ;

從“react-router-dom” 導入 { Redirect } ;

PayPal 類擴展了 Component {

構造函數(道具){

超級(道具);

這個。state = {

重定向: false

};

這個。createOrder = this。createOrder。bind(this);

}

createOrder(payment){

讓 postData = {

uid : 這個。道具。userData。uid,

令牌: 這個。道具。userData。令牌,

payerID : 付款。payerID,

paymentID : 付款。paymentID,

paymentToken : 付款。paymentToken,

pid : 這個。道具。PID

};

PostData(“createOrder”,postData)。然後(result => {

讓 responseJson =結果;

if(responseJson .status === “true”){

這個。setState({redirect : true });

}

});

}

render(){

如果(此。狀態。重定向){

return < Redirect to = { “/ orders” } /> ;

}

const onSuccess = payment => {

這個。createOrder(付款);

};

const onCancel = data => {

安慰。log(“付款已取消!”,數據);

};

const onError = err => {

安慰。log(“錯誤!”,錯誤);

};

讓 env = “沙盒” ; //改為直播的“制作”

let currency = “USD” ;

讓 total = this。道具 .value;

const client = {

沙箱: “AQwoZAAHsmA5vBLj_mZffS3NWJjNJODewuV2WakPm-BQilgsawTtnbLvWHNC73idcfiaHBOjaeTDkAS8”,

生產: “<插入生產客戶端ID>”

};

回來(

< PaypalExpressBtn

env = {env}

client = {client}

貨幣= {貨幣}

總計= {總計}

onError = {onError}

onSuccess = {onSuccess}

onCancel = {onCancel}

/>

);

}

}

出口 默認 PayPal ;

對於生產,您可以將let evn值更改為“production”。使用我的沙盒令牌進行測試。

CheckOut.js
Checkout頁面,用於顯示有關所選產品的更多詳細信息。導入PayPal組件並設置屬性值,如產品piduserData

從“react” 導入React ,{ Component } ;

import “./ Checkout.css” ;

從“react-router-dom” 導入 { Redirect } ;

從“../../services/PostData” 導入 { PostData } ;

從“../Title/Title” 導入標題 ;

從“../PayPal/PayPal” 導入PayPal ;

class Checkout 擴展 Component {

構造函數(道具){

超級(道具);

這個。state = {

名稱: “”,

重定向: false,

pid : “”,

產品: [],

userData : []

};

}

componentDidMount(){

讓 data = JSON。解析(的sessionStorage。的getItem(“用戶數據”));

這個。getProductData(數據。用戶數據);

這個。的setState({名稱: 數據。用戶數據。名稱});

這個。的setState({的UserData : 數據。的UserData });

}

getProductData(userData){

讓 pid = sessionStorage。getItem(“pid”);

讓 postData = {uid : userData。uid,token : userData。token,pid : pid};

PostData(“getProduct”,postData)。然後(result => {

讓 responseJson =結果;

這個。setState({product : responseJson .product});

});

}

render(){

如果(!的sessionStorage。的getItem(“用戶數據”)|| 此。狀態。重定向){

return < Redirect to = { “/” } /> ;

}

回來(

< div className = “row body” >

< Title name = { this。state .name} />

< h4 >結帳</ h4 >

< div className = “row” >

< div className = “medium-4 columns” > Product </ div >

< div className = “medium-4 columns” >名稱</ div >

< div className = “medium-4 columns” >價格</ div >

</ div >

< div className = “row” >

< div className = “medium-4 columns” >

< img

src = {

“https://demos.9lessons.info/PHP-PayPal-ExpressCheckout/img/” +

這個。國家。產品。product_img

}

/>

</ div >

< div className = “medium-4 columns” > { this。state .product.product} </div >

< div className = “medium-4 columns” >

{ 這。國家。產品。價格 }

< PayPal

value = { this。國家。產品。價格 }

pid = { this。國家。產品。pid }

userData = { this。國家。userData }

/>

</ div >

</ div >

</ div >

);

}

}

出口默認結帳; #


Orders.js
Orders頁面包含您所有成功的訂單。函數getOrders從RESTful apis獲取訂單,組件OrdersList基於state.orders數組呈現。

從“react” 導入React ,{ Component } ;

import “./ Orders.css” ;

從“react-router-dom” 導入 { Redirect } ;

從“../../services/PostData” 導入 { PostData } ;

從“../Title/Title” 導入標題 ;

從“../OrdersList/OrdersList” 導入OrdersList ;

class Orders extends Component {

構造函數(道具){

超級(道具);

這個。state = {

名稱: “”,

重定向: false,

訂單: []

};

這個。getOrders = 這個。getOrders。bind(this);

}

componentDidMount(){

讓 data = JSON。解析(的sessionStorage。的getItem(“用戶數據”));

這個。getOrders(數據。用戶數據);

這個。的setState({名稱: 數據。用戶數據。名稱});

}

getOrders(userData){

讓 postData = {uid : userData。uid,token : userData。令牌 };

PostData(“orders”,postData)。然後(result => {

讓 responseJson =結果;

這個。的setState({訂單: responseJson。訂單 });

});

}

render(){

如果(!的sessionStorage。的getItem(“用戶數據”)|| 此。狀態。重定向){

return < Redirect to = { “/” } /> ;

}

回來(

< div className = “row body” >

< Title name = { this。state .name} />

< OrdersList ordersData = { this。國家。訂單 } />

</ div >

);

}

}

出口 默認 訂單 ;


OrderList.js
顯示用戶付款訂單的組件。

從“react” 導入React ,{ Component } ;

import “./ OrdersList.css” ;

class OrdersList extends Component {

構造函數(道具){

超級(道具);

}

render(){

讓 ordersList = 這個。道具。ordersData。map(function(orderData,index){

回來(

< div clasName = “row orderList” key = {index} >

< div className = “medium-3 columns” > { orderData。oid } </ div >

< div className = “medium-3 columns” > { orderData .product} </ div >

< div className = “medium-3 columns” > $ { orderData。價格 } </ div >

< div className = “medium-3 columns” > { orderData。已創建 } </ div >

</ div >

);

},此);

return < div > {ordersList} </ div > ;

}

}

export default OrdersList ;


使用PHP RESTful
這個項目是使用ReactJS登錄Facebook和谷歌以及使用PHP和MySQL的PayPal Express Checkout

PayPal Express Checkout PHP RESTful +社交登錄API在Github上下載此項目


index.php
包含在POST方法調用之後。請使用ReactJS查看使用Facebook和Google登錄

<?PHP

/ * ### Srinivas Tamada ### * /

/ * ### https://www.9lessons.info ### * /

需要 ‘config.php文件‘ ;

要求 ‘Slim / Slim.php‘ ;

\ Slim \ Slim :: registerAutoloader();

$ app = new \ Slim \ Slim();

$ app - > post(‘/ signup‘,‘signup‘); / *用戶註冊* /

$ app - > post(‘/ products‘,‘products‘); / *用戶產品* /

$ app - > post(‘/ orders‘,‘orders‘); / *用戶訂單* /

$ app - > post(‘/ getProduct‘,‘getProduct‘); / *獲得自豪* /

$ app - > post(‘/ createOrder‘,‘createOrder‘); / *創建訂單* /

$ app - > run();

......

......

......

......

?>


產品
獲取產品表的產品詳細信息。如果你想要你可以擴展添加分頁。

function products (){

$ request = \ Slim \ Slim :: getInstance()- > request();

$ data = json_decode($ request - > getBody());

$ uid = $ data - > uid ;

$ token = $ data - > token ;

$ system_token = apiToken($ uid);

if($ token == $ system_token){

$ db = getDB();

$ sql = “ SELECT * FROM products ” ;

$ stmt = $ db - > prepare($ sql);

$ stmt - > execute();

$ products = $ stmt - > fetchALL(PDO :: FETCH_OBJ);

if($ products){

$ products = json_encode($ products);

echo ‘{“products”:‘ 。$產品 。 ‘}‘ ;

} else {

echo ‘{“error”:{“text”:“無數據可用”}}‘ ;

}

}

其他 {

echo ‘{“error”:{“text”:“No access”}}‘ ;

}

}



訂單
基於帖子輸入uid的用戶訂單詳細信息。

function orders (){

$ request = \ Slim \ Slim :: getInstance()- > request();

$ data = json_decode($ request - > getBody());

$ uid = $ data - > uid ;

$ token = $ data - > token ;

$ system_token = apiToken($ uid);

if($ token == $ system_token){

$ db = getDB();

$的SQL = “ SELECT * FROM 訂單O,產品P. WHERE ? 。pid_fk = P 。PID 和uid_fk = :UID 按訂單? 。OID DESC ; ” ;

$ stmt = $ db - > prepare($ sql);

$ stmt - > bindParam(“uid”,$ uid,PDO :: PARAM_INT);

$ stmt - > execute();

$ orders = $ stmt - > fetchALL(PDO :: FETCH_OBJ);

if($ orders){

$ orders = json_encode($ orders);

echo ‘{“orders”:‘ 。$訂單 。 ‘}‘ ;

} else {

echo ‘{“error”:{“text”:“無數據可用”}}‘ ;

}

}

其他 {

echo ‘{“error”:{“text”:“No access”}}‘ ;

}

}



getProduct
根據產品ID獲取單個產品詳細信息。

function getProduct (){

$ request = \ Slim \ Slim :: getInstance()- > request();

$ data = json_decode($ request - > getBody());

$ uid = $ data - > uid ;

$ token = $ data - > token ;

$ pid = $ data - > pid ;

$ system_token = apiToken($ uid);

if($ token == $ system_token){

$ db = getDB();

$ sql = “ SELECT * FROM products WHERE pid = :pid ” ;

$ stmt = $ db - > prepare($ sql);

$ stmt - > bindParam(“pid”,$ pid,PDO :: PARAM_STR);

$ stmt - > execute();

$ product = $ stmt - > fetch(PDO :: FETCH_OBJ);

if($ product){

$ product = json_encode($ product);

echo ‘{“product”:‘ 。$ product 。 ‘}‘ ;

} else {

echo ‘{“error”:{“text”:“無數據可用”}}‘ ;

}

}

其他 {

echo ‘{“error”:{“text”:“No access”}}‘ ;

}

}



createOrder
創建成功付款的訂單。這將調用內部CURL動作函數paypalCheck

function createOrder (){

$ request = \ Slim \ Slim :: getInstance()- > request();

$ data = json_decode($ request - > getBody());

$ uid = $ data - > uid ;

$ token = $ data - > token ;

$ pid = $ data - > pid ;

$ payerID = $ data - > payerID ;

$ paymentToken = $ data - > paymentToken ;

$ paymentID = $ data - > paymentID ;

$ system_token = apiToken($ uid);

if($ token == $ system_token){

if(paypalCheck($ paymentID,$ pid,$ payerID,$ paymentToken,$ uid)){

echo ‘{“status”:“true”}‘ ;

} else {

echo ‘{“error”:{“text”:“無數據可用”}}‘ ;

}

}

其他 {

echo ‘{“error”:{“text”:“No access”}}‘ ;

}

}


paypalCheck內部函數
使用CURL方法驗證PayPal轉換以便更好地了解使用PHP和MySQL檢查PayPal Express Checkout。

function paypalCheck ($ paymentID ,$ pid ,$ payerID ,$ paymentToken ,$ uid ){

$ ch = curl_init();

$ clientId = PayPal_CLIENT_ID ;

$ secret = PayPal_SECRET ;

curl_setopt($ CH,CURLOPT_URL,PayPal_BASE_URL 。‘的oauth2 /令牌‘);

curl_setopt($ ch,CURLOPT_HEADER,false);

curl_setopt($ ch,CURLOPT_SSL_VERIFYPEER,false);

curl_setopt($ ch,CURLOPT_POST,true);

curl_setopt($ ch,CURLOPT_RETURNTRANSFER,true);

curl_setopt($ ch,CURLOPT_USERPWD,$ clientId 。 “:” 。 $ secret);

curl_setopt($ ch,CURLOPT_POSTFIELDS,“grant_type = client_credentials”);

$ result = curl_exec($ ch);

$ accessToken = null ;

if(empty($ result)){

返回 虛假 ;

}

其他 {

$ json = json_decode($ result);

$ accessToken = $ json - > access_token ;

$卷曲 = curl_init(PayPal_BASE_URL 。‘付款/支付/‘ 。 $ paymentID);

curl_setopt($ curl,CURLOPT_POST,false);

curl_setopt($ curl,CURLOPT_SSL_VERIFYPEER,false);

curl_setopt($ curl,CURLOPT_HEADER,false);

curl_setopt($ curl,CURLOPT_RETURNTRANSFER,true);

curl_setopt($ curl,CURLOPT_HTTPHEADER,array(

‘授權:持票人‘ 。 $ accessToken,

‘接受:application / json‘,

‘Content-Type:application / xml‘

));

$ response = curl_exec($ curl);

$ result = json_decode($ response);

$ state = $ result - > state ;

$ total = $ result - > transactions [ 0 ] - > amount - > total ;

$ currency = $ result - > transactions [ 0 ] - > amount - > currency ;

$ subtotal = $ result - > transactions [ 0 ] - > amount - > details - > subtotal ;

$ recipient_name = $ result - > transactions [ 0 ] - > item_list - > shipping_address - > recipient_name ;

curl_close($ ch);

curl_close($ curl);

$ product = getProductData($ pid);

if($ state == ‘approved‘ && $ currency == $ product - > currency && $ product - > price == $ subtotal){

updateOrder($ pid,$ payerID,$ paymentID,$ paymentToken,$ uid);

返回 true ;

}

其他 {

返回 虛假 ;

}

}

}


updateOrder內部函數
使用付款詳細信息插入訂單詳細信息。

function updateOrder ($ pid ,$ payerID ,$ paymentID ,$ token ,$ uid )

{

if(paymentCheck($ paymentID)< 1 && $ uid > 0){

$ db = getDB();

$ stmt = $ db - > prepare(“ INSERT INTO orders(uid_fk,pid_fk,payerID,paymentID,token,created)VALUES (:uid ,:pid,:payerID,:paymentID,:token,:created)”);

$ stmt - > bindParam(“paymentID”,$ paymentID,PDO :: PARAM_STR);

$ stmt - > bindParam(“payerID”,$ payerID,PDO :: PARAM_STR);

$ stmt - > bindParam(“token”,$ token,PDO :: PARAM_STR);

$ stmt - > bindParam(“pid”,$ pid,PDO :: PARAM_INT);

$ stmt - > bindParam(“uid”,$ uid,PDO :: PARAM_INT);

$ created = time();

$ stmt - > bindParam(“created”,$ created,PDO :: PARAM_INT);

$ stmt - > execute();

$ db = null ;

返回 true ;

}

其他 {

返回 虛假 ;

}

}


paymentCheck內部功能
使用方法交叉檢查預付款不是。

功能paymentCheck ($ paymentID )

{

$ db = getDB();

$ stmt = $ db - > prepare(“ SELECT * FROM orders WHERE paymentID = :paymentID ”);

$ stmt - > bindParam(“paymentID”,$ paymentID,PDO :: PARAM_STR);

$ stmt - > execute();

$ count = $ stmt - > rowcount();

$ db = null ;

返回 $ count ;

}


運行此項目React

$ git clone https://github.com/srinivastamada/react-login-paypal.git
$ cd react-login-paypal
$ yarn start

使用React JS和PHP RESTful進行PayPal Express Checkout