本文共 15331 字,大约阅读时间需要 51 分钟。
目前市场上有几种付款方式可供选择。PayPal结账选项就是其中之一。在我之前的文章中,我已经讨论了几个支付选项 - 使用PHP的Braintree PayPal,支付系统和使用PHP和MySQL的PayPal Express Checkout。这些是迄今为止观看次数最多的热门文章。今天,让我们看看PayPal Express Checkout如何与React JS配合使用。
用于测试用户名的实时演示沙箱PayPal凭据:demos@9lessons.info密码: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 = {
“” +
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提取提供程序
导入Title和ProductList组件。函数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组件并设置属性值,如产品值,pid和userData。从“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 = {
“” +
这个。国家。产品。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 CheckoutPayPal Express Checkout PHP RESTful +社交登录API在Github上下载此项目
index.php
包含在POST方法调用之后。请使用ReactJS查看使用Facebook和Google登录<?PHP
/ ### Srinivas Tamada ### /
/ ### ### /
需要 '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
$ cd react-login-paypal$ yarn start转载于:https://blog.51cto.com/13959020/2287490