官方文档

https://developer.paypal.com/docs/integration/direct/payments/paypal-payments/#create-paypal-payment

准备工作

先要在官网注册PayPal账号,然后打开沙箱账号管理。

能看到有自动创建的2个沙箱账号,选中PERSONAL账号点击Profile,设置自定义密码(记录该账号和密码)。
然后点击左边菜单栏DASHBOARD-My Apps & Credentials创建沙箱应用.

然后回到沙箱账号管理选中BUSSINESS账号,点击Profile,点击API Credentials,点击REST Apps里的App name。

进入应用页面后,记录下Client ID和Secret。

支付流程

payment相关接口的支付流程为:
1、获取accesstoken
2、商户根据订单填充订单信息(事例index.php中create_payment()相关操作)
3、填充完后将数据POST到'/v1/payments/payment'接口(事例index.php中create_payment()相关操作)
4、根据返回值,跳转到返回值中links里的’rel’=‘approval_url’对应的地址中(事例index.php中create_payment()相关操作)
5、用户(登陆准备工作时记录的PERSONAL账号)在该网页完成付款确认点击继续则跳转到执行payment的链接(create_payment()中设置的’redirect_urls’中的’return_url’)并把payerid和paymentid设置在url的参数中
6、执行payment的链接中,商户需要获取到这2个参数后调用'/v1/payments/payment/{paymentid}/execute'接口,完成支付流程。(事例index.php中excute()相关操作)

事例

下面是简单封装了一下的payment相关操作的接口调用。访问index.php,create_payment函数构造订单信息,授权成功跳转localhost?a=excute&PayerID=xxx&paymentid=xxx,excute函数调用paypal类的ExcutePayment方法完成付款。
Paypal.php类

<?php
class Paypal{protected $appId;protected $appSecret;protected $baseUrl='https://api.sandbox.paypal.com';/*构造函数,把实例化Paypal类时传进来的appId和appSecret保存起来*** */function __construct($appId,$appSecret){$this->appId = $appId;$this->appSecret = $appSecret;}/*curl post*param* $extreUrl string  接口地址* $data     array   提交的数据 为空时为get请求* $header   array   请求头信息* $Oauth    bool    是否使用Oauth验证* return    array   响应信息* */protected function httpRequest($extreUrl,$data,$header,$Oauth=false){$url=$this->baseUrl.$extreUrl;$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);if($Oauth){curl_setopt($curl, CURLOPT_USERPWD,$this->appId.":".$this->appSecret);}//获取请求头信息//curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);curl_setopt($curl, CURLOPT_HTTPHEADER,$header);if($data){curl_setopt($curl, CURLOPT_POSTFIELDS,$data);curl_setopt($curl, CURLOPT_POST,1);}curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);$output = curl_exec($curl);//获取请求头信息//var_dump(curl_getinfo($curl)["request_header"]);curl_close($curl);return json_decode($output,true);}/*请求头部加上Authorization*param* $extreUrl string  接口地址* $data     array   请求的参数* return    array   返回信息* */protected function httpRequestWithAuth($extreUrl,$data=[]){$header[]='Content-Type:application/json';$header[]='Authorization:Bearer '.$this->getAccessToken();return $this->httpRequest($extreUrl,$data,$header);}/*转化数组为键值对形式*param* $array    array   需要转化的数组* return    string  转化后的字符串:参数1=值1&参数2=值2* */protected function array2keyvalue($array){$res=[];foreach($array as $k=>$v){$res[]=$k.'='.$v;}return implode('&',$res);}/*获取accesstoken* 判断存储的accesstoken是否过期,过期则调用接口获取新的accesstoken否则直接返回。* 可以把文件读取改成缓存读取 数据库读取。* return    string  accesstoken值* */protected function getAccessToken(){//从paypal_access_token.json文件中读取accesstoken和过期时间$data = json_decode(file_get_contents("paypal_access_token.json"),true);if ($data['expire_time'] < time()) {$extreUrl='/v1/oauth2/token';$postdata['grant_type']='client_credentials';$postdata=$this->array2keyvalue($postdata);$header[]="Content-type: application/x-www-form-urlencoded";$res=$this->httpRequest($extreUrl,$postdata,$header,true);$access_token = $res['access_token'];if ($access_token) {$data['expire_time'] = time()+$res['expires_in'];$data['access_token'] = $access_token;$fp = fopen("paypal_access_token.json", "w");fwrite($fp, json_encode($data));fclose($fp);}} else {$access_token = $data['access_token'];}return $access_token;}/*创建payment**/public function CreatePayment($array){$extreUrl='/v1/payments/payment';$data['intent']='sale';$data['payer']=['payment_method'=>'paypal'];$transactions['amount']=$array['amount'];$transactions['description']=$array['description'];$transactions['custom']=$array['orderid'];$transactions['invoice_number']=$array['orderid'];$transactions['item_list']['items']=$array['items'];$transactions['payment_options']['allowed_payment_method']='INSTANT_FUNDING_SOURCE';$transactions['item_list']['shipping_address']=$array['shipping_address'];$data['transactions'][]=$transactions;$data['note_to_payer']=$array['note_to_payer'];$data['redirect_urls']=$array['redirect_urls'];return $this->httpRequestWithAuth($extreUrl,json_encode($data));}/* 获取 完成payment *param* paymentId 创建payment后返回的ID* PayerID     用户id 用户完成授权后跳转的excute页面中url带的参数**/public function ExcutePayment($array){$extreUrl='/v1/payments/payment/'.$array['paymentId'].'/execute';$data['payer_id']=$array['PayerID'];return $this->httpRequestWithAuth($extreUrl,json_encode($data));}/* 获取payment详情 *param* paymentId 创建payment后返回的ID**/public function PaymentInfo($array){$extreUrl='/v1/payments/payment/'.$array['paymentId'];return $this->httpRequestWithAuth($extreUrl);}}

index.php代码

<?php
include('Paypal.php');
$appId='你的Client ID';
$appSecret='你的Secret';
$paypal=new Paypal($appId,$appSecret);
$a=!is_null($_GET['a'])?$_GET['a']:'create_payment';
$a($paypal);function create_payment($paypal){$array['description']='订单说明';//orderid调用paypal类CreatePayment时传入‘invoice_number’中 ‘custom’字段可根据需要填充更多信息$array['orderid']=time();//订单商品详情1$product1['name']='hat';$product1['sku']=1;$product1['description']='Brown hat';$product1['price']="3";$product1['currency']='USD';$product1['tax']='0.01';$product1['quantity']=5;//订单商品详情2$product2['name']='handbag';$product2['sku']='xxxx';$product2['description']='Black handbag.';$product2['price']="15";$product2['currency']='USD';$product2['tax']='0.02';$product2['quantity']=1;$array['items'][]=$product1;$array['items'][]=$product2;/*订单费用$array['amount'] 其中total 要和subtotal的计费计算统一不然会报错 subtotal+tax+shipping+handing_fee+shipping_discount+insurance =total*/$array['amount']['total']='30.11';$array['amount']['currency']='USD';//订单收费详情$array['amount']['details']['subtotal']="30.00";$array['amount']['details']['tax']="0.07";$array['amount']['details']['shipping']="0.03";$array['amount']['details']['handling_fee']="1.00";$array['amount']['details']['shipping_discount']="-1.00";$array['amount']['details']['insurance']="0.01";//订单收货地址详情$array['shipping_address']['recipient_name']="Brian Robinson";$array['shipping_address']['line1']="4th Floor";$array['shipping_address']['line2']="Unit #34";$array['shipping_address']['city']="San Jose";$array['shipping_address']['country_code']="US";$array['shipping_address']['postal_code']="95131";$array['shipping_address']['phone']="011862212345678";$array['shipping_address']['state']="CA";//提示信息$array['note_to_payer']="Contact us for any questions on your order.";//执行付款回调地址$array['redirect_urls']['return_url']="http://localhost?a=excute";//取消付款回调地址$array['redirect_urls']['cancel_url']="http://localhost?a=cancel";$res=$paypal->CreatePayment($array);/*这里需要判断是否成功** */if(!$res['debug_id'] && strtolower($res['state'])!='failed'){foreach($res['links'] as $v){if(strtolower($v['rel'])=='approval_url'){header('Location: '.$v['href']);exit;}}}else{echo $res['message'];}
}function excute($paypel){$data['PayerID']=$_GET['PayerID'];$data['paymentId']=$_GET['paymentId'];$res=$paypel->ExcutePayment($data);if(strtolower($res['state'])=='approved'){//完成付款}
}function cancel(){echo '用户取消';
}function check($paypel){$data['paymentId']=$_GET['paymentId'];$res=$paypel->PaymentInfo($data);var_dump($res);
}

create_payment 返回值数据结构

    array(8) {["id"]=>string(30) "PAYID-LR7Y6YA3UM97660A4514331H"["intent"]=>string(4) "sale"["state"]=>string(7) "created"["payer"]=>array(1) {["payment_method"]=>string(6) "paypal"}["transactions"]=>array(1) {[0]=>array(7) {["amount"]=>array(3) {["total"]=>string(5) "30.11"["currency"]=>string(3) "USD"["details"]=>array(6) {["subtotal"]=>string(5) "30.00"["tax"]=>string(4) "0.07"["shipping"]=>string(4) "0.03"["insurance"]=>string(4) "0.01"["handling_fee"]=>string(4) "1.00"["shipping_discount"]=>string(5) "-1.00"}}["description"]=>string(12) "订单说明"["custom"]=>string(10) "1551863640"["invoice_number"]=>string(10) "1551863640"["payment_options"]=>array(3) {["allowed_payment_method"]=>string(22) "INSTANT_FUNDING_SOURCE"["recurring_flag"]=>bool(false)["skip_fmf"]=>bool(false)}["item_list"]=>array(2) {["items"]=>array(2) {[0]=>array(7) {["name"]=>string(3) "hat"["sku"]=>string(1) "1"["description"]=>string(9) "Brown hat"["price"]=>string(4) "3.00"["currency"]=>string(3) "USD"["tax"]=>string(4) "0.01"["quantity"]=>int(5)}[1]=>array(7) {["name"]=>string(7) "handbag"["sku"]=>string(4) "xxxx"["description"]=>string(14) "Black handbag."["price"]=>string(5) "15.00"["currency"]=>string(3) "USD"["tax"]=>string(4) "0.02"["quantity"]=>int(1)}}["shipping_address"]=>array(8) {["recipient_name"]=>string(14) "Brian Robinson"["line1"]=>string(9) "4th Floor"["line2"]=>string(8) "Unit #34"["city"]=>string(8) "San Jose"["state"]=>string(2) "CA"["postal_code"]=>string(5) "95131"["country_code"]=>string(2) "US"["phone"]=>string(15) "011862212345678"}}["related_resources"]=>array(0) {}}}["note_to_payer"]=>string(43) "Contact us for any questions on your order."["create_time"]=>string(20) "2019-03-06T09:14:07Z"["links"]=>array(3) {[0]=>array(3) {["href"]=>string(81) "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LR7Y6YA3UM97660A4514331H"["rel"]=>string(4) "self"["method"]=>string(3) "GET"}[1]=>array(3) {["href"]=>string(94) "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-2VG2711092225420A"["rel"]=>string(12) "approval_url"["method"]=>string(8) "REDIRECT"}[2]=>array(3) {["href"]=>string(89) "https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LR7Y6YA3UM97660A4514331H/execute"["rel"]=>string(7) "execute"["method"]=>string(4) "POST"}}}

报错

所使用的环境是win10+apache2.4+php7.1,如果是使用php7.1以下版本,需要把构造数组$res=[];改成$res=array();
有的人curl_exec执行报错,并且echo curl_no($curl);为35,是因为curl扩展使用的openssl版本过低,不支持TLS 1.2。
解决方式:如果是linux编译php时使用新版的openssl,如果是windows暂时只能用新版的php。

Paypal Payments REST API支付 沙箱测试 php版本相关推荐

  1. Paypal NVP API支付 沙箱测试 php版本

    官方文档 https://developer.paypal.com/docs/classic/api/ 准备工作 参考REST API https://blog.csdn.net/rty426/art ...

  2. Vue node.js实现支付宝支付(沙箱测试)

    一.支付宝开放平台创建应用:打开支付宝开放平台首页(注意:正式环境.沙箱环境都需要此步) 1.选择开发者中心 ---> 网页&移动应用 (此时是实现网站支付功能) 2.选择支付接入 3. ...

  3. 免费沙箱软件模拟支付_小游戏虚拟支付沙箱测试报错

    麻烦问一下各位,沙箱测试时使用的openId和sessionKey必须是在测试地址下,登录验证过的吗? 因为现在测试支付时,一直在报这个问题:{"errcode":90009,&q ...

  4. 支付沙箱测试 NATAPP使用

    一 首先准备沙箱测试支付宝 生成公钥 以及私钥 下载支付宝开放平台开放助手 然后将 公钥设置到此处 二 然后下载 网站 支付demon https://opendocs.alipay.com/open ...

  5. 支付宝接口开发-手机网站支付-沙箱测试

    前面一段时间,因为公司业务需求,需要使用支付宝的手机网站支付接口,因为自己也是第一次使用这个,中间走了不少弯路,现在总结一下,希望对遇到同样问题的朋友有帮助. 第一步:登录蚂蚁金服开放平台蚂蚁金服开放 ...

  6. 支付宝支付 沙箱测试

    支付宝平台文档中心 https://opendocs.alipay.com/open/270/105900 开发者中心 https://developers.alipay.com/platform/d ...

  7. app沙箱宝支付接口怎么测_支付宝沙箱测试DEMO实践

    1.DEMO说明 本次测试只实现支付宝沙箱里面的 扫码支付.商家退款:(本来买家支付也想实现来着:但是没找到相关接口信息所以暂未实现:有知道的朋友请告知) 2.支付宝开放平台沙箱地址: https:/ ...

  8. 魔坊APP项目-18-种植园,基于支付宝提供的沙箱测试环境开发支付接口、服务端, 处理支付结果的同步通知和异步通知、修复页面底部菜单无法被点击的BUG

    种植园 一.基于支付宝提供的沙箱测试环境开发支付接口 沙箱环境: https://openhome.alipay.com/platform/appDaily.htm?tab=info 开发文档: ht ...

  9. java实现支付宝支付完整过程(沙箱测试环境,下篇整合ssm)

    点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 java实 ...

  10. java实现沙箱测试环境支付宝支付(demo)和整合微信支付和支付宝支付到springmvc+spring+mybatis环境全过程(支付宝和微信支付)

    一.支付宝测试环境代码测试 1.下载电脑网站的官方demo: 下载地址:https://docs.open.alipay.com/270/106291/ 2.下载解压导入eclipse readme. ...

最新文章

  1. java开源springboot项目_springBoot 搭建web项目(前后端分离,附项目源代码地址)...
  2. python gevent模块 下载_Python协程阻塞IO非阻塞IO同步IO异步IO
  3. 两道概率题-供大家周末把玩
  4. 谈谈谷歌word2vec的原理
  5. mysql 批量修改数据库存储引擎_mysql批量修改表存储引擎
  6. HTML <!DOCTYPE> 标签
  7. 进入Python世界——Python基础知识
  8. visual2019没有勾选的在如何加入_发票管理系统完成升级,勾选认证平台改头换面,你所有的问题都在这里!...
  9. Python 内置模块之 时间模块 datetime
  10. 【STM32】修改芯片型号后报 Error 的解决方案
  11. mysql面试吗hi提_面试必备的10道MySQL题
  12. 未来感十足:小米发布四曲面屏幕专利
  13. Failed with error: ssh variant simple does not support setting port
  14. 刘强东卸任京东 CEO,“二号位”徐雷接棒:三大电商巨头“二把手”正式集齐
  15. Linux安装maven详细步骤
  16. 泛微OA 任意文件上传漏洞
  17. 人脸检测卷积神经网络_卷积神经网络和计算机视觉的人脸面具检测算法
  18. Mybatis面试合集
  19. Spring MVC -- xxx conflicts with existing xxx
  20. 牛顿迭代法解一元三次方程

热门文章

  1. ps html 优化,photoshop越用越卡的解决方法,ps性能优化教程
  2. Chrome 配置samesite=none方式
  3. 13.0、veu-路由嵌套
  4. 本地Remix与私链节点相连
  5. 地铁工程安全生产预警系统价格
  6. python计算闰年
  7. 【通信工程】大三下课程设计-5G核心网功能设计与部署
  8. vue 实现数字滚动卡片
  9. JS数组ES3-ES6常用方法
  10. ​元宇宙与AI热度不减,Gartner 2023 年十大战略技术趋势完整解析