参考:https://github.com/paypal/PayPal-PHP-SDK/wiki

     https://blog.csdn.net/markely/article/details/79044145

  最近公司做一个国际版商城,国内的支付宝和微信支付不太适用,故而选择PayPal。PayPal在国内开发还是比较少的,不如支付宝和微信,所以没有中文文档,辛辛苦苦啃了好几天终于跑通了,在这里做一下总结,方便以后再用。

  PayPal在国外的市场占有率还是很高的,只是手续费之高让人有点儿肾疼,不过这不是我关心的东西,只是实现功能。

  废话不多说,直接展示开发过程。

一、准备工作:

  首先需要测试账号,PayPal开发感觉好的一点是提供测试账号(也叫沙箱账号)

  1、浏览器访问 https://www.paypal.com/c2/home 进入PayPal官网

  2、点击注册,根据 要求填写信息进行注册(easy)

  

  3、注册完成以后,访问https://developer.paypal.com/

  4、点击右上角的 Log Into Dashboard 按钮,登录你刚才注册的账号,进入仪表盘

  5、登录之后点击左侧的accounts,左侧页面会显示你的买家和买家测试账号

  

  6、点击profile,会进入买家的账户管理,在里面可以设置密码和金额等信息

  7、点击左上角的My apps & credentials ,出现如下页面

  8、点击create app,创建自己的应用,这一步主要clientID和secret,在调用API接口是生成token需要这两个值,很重要

  

  二、准备工作做完了,要上代码了

  1、根据wiki上提供的有两种方式下载安装

  

  我选择的是composer,没有安装composer的童鞋自行安装,这里不再赘述。当然也可以使用第二种方式

  2、新建文件夹

  

  3、进去后打开cmd,输入composer require "paypal/rest-api-sdk-php:*" ,回车

  

  4、当看到这个的时候说明下载完成

  

  目录结构如下:vendor目录下是PayPal-PHP-SDK的API接口

  

  新建目录:目录结构如下

  

  payment.php

  

<?php
 require_once("./common.php");
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\RedirectUrls;
use PayPal\Api\ShippingAddress;
use PayPal\Api\Transaction; $payer = new Payer();
$payer->setPaymentMethod("paypal"); //设置商品详情
/**
* 详情信息:单价、收货地址等请结合自己的业务去数据库或者其他存储数据的地方查询
* 这里只是演示支付流程,不结合实际业务
*/
$item1 = new Item();
$item1->setName('test pro 1')
->setCurrency('USD')
->setQuantity()
->setSku("testpro1_01")
->setPrice(2.3);
$item2 = new Item();
$item2->setName('test pro 2')
->setCurrency('USD')
->setQuantity()
->setSku("testpro2_01")
->setPrice(1.1);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
// 自定义用户收货地址,如果这里不定义,在支付页面能够修改,可能会误操作,与用户想等地质不一致
$address = new ShippingAddress(); $address->setRecipientName("张三")
->setLine1("小区名")
->setLine2("楼号")
->setCity("城市")
->setState("省份")
->setPhone() //收货电话
->setPostalCode() //邮编
->setCountryCode('CN'); $itemList->setShippingAddress($address); //设置总价,运费等金额。注意:setSubtotal的金额必须与详情里计算出的总金额相等,否则会失败
$details = new Details();
$details->setShipping()
->setTax()
->setSubtotal(7.8); // 同上,金额要相等
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(10.8)
->setDetails($details); $transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber(uniqid()); /**
* 回调
* 当支付成功或者取消支付的时候调用的地址
* success=true 支付成功
* success=false 取消支付
*/
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("http://localhost/paypal/payment/exec.php?success=true")
->setCancelUrl("http://localhost/paypal/payment/cancel.php?success=false"); $payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
//创建支付
$payment->create($apiContext);
//生成地址
$approvalUrl = $payment->getApprovalLink(); // var_dump($approvalUrl);
//跳转
header("location:" . $approvalUrl);

exec.php

<?php

set_time_limit(3600);
require_once('./common.php'); use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction; if (isset($_GET['success']) && $_GET['success'] == 'true') { $paymentId = $_GET['paymentId'];
$payment = Payment::get($paymentId, $apiContext); $execution = new PaymentExecution();
$execution->setPayerId($_GET['PayerID']); $transaction = new Transaction();
$amount = new Amount();
$details = new Details(); $details->setShipping(1)
->setTax(2)
->setSubtotal(7.8); $amount->setCurrency('USD');
$amount->setTotal(10.8);
$amount->setDetails($details);
$transaction->setAmount($amount); $execution->addTransaction($transaction); try {
$result = $payment->execute($execution, $apiContext);
echo "支付成功"; } catch (Exception $ex) {
echo "支付失败";
die;
} return $payment;
} else {
echo "PayPal返回回调地址参数错误";
}

common.php

<?php

require_once('../vendor/autoload.php');

use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential; // 下面为申请app获得的clientId和clientSecret,必填项,否则无法生成token。
$clientId = 'ATnuSLiYPPpNovryQJ4ZsiD1FfR2Jelv5GBkSGNjd59Ef8SW8XEH48fFwOf7L9wcyZARGx3LanesBuvb';
$clientSecret = 'EAadzJ40KVcpBanjhdAR13N2mxPBi2O7uQYMs8h-wMga5scKmwHEyCIOLLgQk2FLEcEOc2xS5ORwyQSo';
$apiContext = new ApiContext(
new OAuthTokenCredential(
$clientId,
$clientSecret
)
);
$apiContext->setConfig(
array(
'mode' => 'sandbox',
'log.LogEnabled' => true,
'log.FileName' => '../PayPal.log',
'log.LogLevel' => 'DEBUG',
'cache.enabled' => true
)
);

cancel.php

<?php

echo "用户取消支付";

浏览器访问:http://localhost/paypal/payment/payment.php

成功后跳转到

登录买家的账号,在前面提到过。登录成功后跳转到支付页面

点击继续进行付款,成功后回调代码中提供的url

然后登陆自己的沙箱账号:https://sandbox.paypal.com/us/signin,(注:是自己的卖家账号)就能看到刚才支付的详情了

这样一个完整的支付流程就跑通了,如果需要根据自己的业务去设置商品价格详情。

注:这个流程只对两位小数有效,我们的业务是四位小数,当传入四位小数时一直提示传入参数错误,目前还没有找到解决办法,等解决后再来补充,如果有能解决的大佬,欢迎留言,不胜感激。

使用paypal-php-sdk开发php国际支付的更多相关文章

  1. PayPal 开发详解(六):下载paypal立即付款SDK 并编译打包

    1.下载PayPal REST SDKs,地址:https://developer.paypal.com/docs/api/rest-sdks/ paypal api比较混乱,有的已经不推荐使用,比如 ...

  2. IOS开发之—— iOS 支付 [支付宝、银联、微信]

    支付宝iOSsdk官方下载sdk地址:https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId ...

  3. php 微信开发之 微信支付 V3 开发 -CURLOP_TIMEOUT问题

    如果不懂怎么配置的话请看文章 php 微信开发之 微信支付配置 基本配置后在继续本文章的开发 . 本文章就先继续基本的实现!也并不困难.我大概的思路的返回购买者的唯一id 和 订单号的唯一 id 就2 ...

  4. PHP微信支付开发之扫描支付(模式二)后如何回调

    其实在写这篇文章的时候感觉自己已经落伍了,不过笔者在百度上搜索"微信支付开发之扫描支付(模式二)后如何回调"寻找答案时,发现依旧有很多朋友没有解决这个问题,所以就把自己的解决思路分 ...

  5. Android SDK开发与使用的那些事儿

    前言 最近由于工作需要,将应用里的部分功能独立了出来,封装成 SDK 提供给合作伙伴使用.由于经验不足,网上也没多少写这方面内容的文章,遇到了不少的坑,决定记录下来. SDK 其实,刚说到要写SDK也 ...

  6. android开发之微信支付功能的实现

    移动开发中,支付类的App越来越多,对于开发者来说也是不可少的,不可不会的:下面就来说一说支付开发的流程 1.申请你的AppID 请到 开发者应用登记页面 进行登记,登记并选择移动应用进行设置后,将该 ...

  7. Kinect for Windows SDK开发学习相关资源

    Kinect for Windows SDK(K4W)将Kinect的体感操作带到了平常的应用学习中,提供了一种不同于传统的鼠标,键盘及触摸的无接触的交互方式,在某种程度上实现了自然交互界面的理想,即 ...

  8. 微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引

    Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享. ...

  9. 高拍仪拍照SDK开发(良田影像S300L|S500L)

    高拍仪拍照SDK开发下载地址:点击下载 本SDK适用于:良田影像S300L|S500L 高拍仪如图: SDN开发包安装之后找到安装目录,如图: 大家找到各自需要的版本即可,需要注意的是如果需要上传图片 ...

随机推荐

  1. Navicat Premium 12安装与激活(亲测已成功激活)

    说明:博主所提供的激活文件理论支持Navicat Premium 12.0.16 - 12.0.24简体中文64位,但已测试的版本为Navicat Premium 12.0.22.12.0.23和12 ...

  2. 了解有关 in_memory 工作空间的详细信息

    ArcGIS 提供了一个可写入输出要素类和表的内存工作空间.作为将地理处理输出写入磁盘上的某个位置或网络位置的备选方案,可将输出写入内存工作空间中.通常,将数据写入内存工作空间要明显快于写入其他格式( ...

  3. 有依赖的背包---P1064 金明的预算方案

    P1064 金明的预算方案 solution 1 暴搜 70pt dfs (当前搜到了第几个物品,产生的总价值,剩下多少钱) 剪枝 1:如果剩下的钱数<0,直接return就好,没必要继续了 剪 ...

  4. GIS 空间分析案例分析-错误排除经验总结

    GIS 空间分析案例分析-错误排除经验总结 商务科技合作:向日葵,135—4855__4328,xiexiaokui#qq.com 目录:问题发现,问题分析,解决方法,结果 1. problem di ...

  5. 如何向Makefile传递参数?

    答: 直接在make命令的后面加上参数,如: make HOST_CFLAGS=-I. 注意事项: HOST_CFLAGS变量将会替换相应Makefile中的HOST_CFLAGS,也就是Makefi ...

  6. vue 实现返回上一页不请求数据keep-alive

    常规操作: 我们通常会将通过接口请求数据的方法放在==created== 或者 ==mounted==这两个生命周期中的一个里面调用. 但是我们知道,不管是我们刚进入这个页面还是从其他页面返回这个页面 ...

  7. 基于Android的ADT目录

    src: 源代码(重要) gen : 工具自动生成的代码 > BUildconfig 调试的开关,默认开启 > R.java 很多的静态的内部类 > 开发用的jar包 Android ...

  8. OSError: image file is truncated (28 bytes not processed)

    解决办法: 在代码中添加两行 from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES = True

  9. MySQL批量导入Excel数据

    MySQL批量导入Excel数据 1.确定需要导入数据的表名称以及字段,然后在新建的Excel表中,按照表字段正确排序:(注:(Excel文件的名称最好和数据库的名称一致,sheet表的名字最好和表名 ...

  10. MySql 里的IFNULL用法

    IFNULL(expr1,expr2)的用法: 假如expr1 不为 NULL,则 IFNULL() 的返回值为 expr1; 否则其返回值为expr2.IFNULL()的返回值是数字或是字符串,具体 ...