php PayPal支付收款接口开发实例

国际收款,paypal是最莫过于方便的支收付平台了,而且支持信用卡,最近做个项目用到,所以去测试了一番,期间虽然遇到一些蛋疼的事,但最终还是顺利通过了。

好了,废话不多说,我们一步一步来说一下。

首先登陆paypal开发者平台
https://developer.paypal.com/developer/accounts/

点击左侧仪表导航上的 My Apps & 创建一个应用,名字随便取, 创建后点击应用,会出现用到的两个密钥. Client ID 和点击show后显示的Secret,把这两个密钥复制保存一下,回头用到.

然后点击 SANDBOX -> Accounts

这里paypal比较人性化,自动给你设置了两个沙盒账户,一个是收款的账户,一个是用来测试付款的账户. 测试的账户里有9999$供你测试使用.

把这两个账户的密码需要改一下才能使用,点击账号旁边的小箭头,再点击下面的Profile, 在弹出框里点击Change password,修改密码,另外这个账户也是这样.

以上账号都是paypal的沙盒测试环境.

接下来部署paypal的SDK,测试代码和介绍这里都有http://paypal.github.io/PayPal-PHP-SDK/

下载sdk包,我的环境是CentOS, git下载地址:https://github.com/paypal/PayPal-PHP-SDK.git

接下来如果你的服务器还没有安装php composer包管理器的话,需要先安装一下,具体请到这下载和了解https://docs.phpcomposer.com/
下载安装命令是

curl -sS https://getcomposer.org/installer | php

安装完成后,在网站根目录下,会出现一个vendor目录,这个就是我们要用到的paypal包了。

接下来我们创建一个公共文件app.php,让他自动运行包文件,代码如下:

<?php
require "vendor/autoload.php"; //载入sdk的自动加载文件
//创建支付对象实例
$paypal = new \PayPal\Rest\ApiContext(
    new \PayPal\Auth\OAuthTokenCredential(
        '你的Client ID密钥',
        '你的Secret密钥'
    )
);

接下来创建一个form提交付款表单html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>购买</title>
    </head>
    <body>
        <div>
            <form action="checkout.php" method="post" autocomplete="off">
                <label for="item">
                    商品
                    <input type="text" name="product">
                </label>
                <br>
                <label for="amount">
                    价格
                    <input type="text" name="price">
                </label>
                <br>
                <input type="submit" value="提交">
            </form>
        </div>
    </body>
</html>

再创建表单处理和对接paypal文件 checkout.php

<?php
use \PayPal\Api\Payer;
use \PayPal\Api\Item;
use \PayPal\Api\ItemList;
use \PayPal\Api\Details;
use \PayPal\Api\Amount;
use \PayPal\Api\Transaction;
use \PayPal\Api\RedirectUrls;
use \PayPal\Api\Payment;
use \PayPal\Exception\PayPalConnectionException;

require "app.php";
if (!isset($_POST['product'], $_POST['price'])) {
    die("lose some params");
}
$product = $_POST['product'];
$price = $_POST['price'];
$shipping = 2.00; //运费

$total = $price + $shipping;

$payer = new Payer();
$payer->setPaymentMethod('paypal');

$item = new Item();
$item->setName($product)
    ->setCurrency('USD')
    ->setQuantity(1)
    ->setPrice($price);

$itemList = new ItemList();
$itemList->setItems([$item]);

$details = new Details();
$details->setShipping($shipping)
    ->setSubtotal($price);

$amount = new Amount();
$amount->setCurrency('USD')
    ->setTotal($total)
    ->setDetails($details);

$transaction = new Transaction();
$transaction->setAmount($amount)
    ->setItemList($itemList)
    ->setDescription("支付描述内容")
    ->setInvoiceNumber(uniqid());

$redirectUrls = new RedirectUrls();
//支付后回调地址
$redirectUrls->setReturnUrl('https://xx.com/pay.php?success=true')
    ->setCancelUrl('https://xx.com/pay.php?success=false');

$payment = new Payment();
$payment->setIntent('sale')
    ->setPayer($payer)
    ->setRedirectUrls($redirectUrls)
    ->setTransactions([$transaction]);

try {
    $payment->create($paypal);
} catch (PayPalConnectionException $e) {
    echo $e->getData();
    die();
}

$approvalUrl = $payment->getApprovalLink();
header("Location: {$approvalUrl}");

跳转paypal支付页面后,用沙盒账户里的购买账户登录付款,如果登录不成功,需要再次修改密码才能登录,成功支付后,你可以查看账户里已经成功扣款了,登录商家收款账号,也可以看见成功收到一笔资金了。

最后我们再来处理下回调,判断支付是否成功或者失败,命名为pay.php

<?php

require 'app.php';

use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;

//参数错误
if(!isset($_GET['success'], $_GET['paymentId'], $_GET['PayerID'])){
    die();
}

//交易失败
if((bool)$_GET['success']=== 'false'){

    echo '交易错误已取消!';
    die();
}

$paymentID = $_GET['paymentId'];
$payerId = $_GET['PayerID'];

$payment = Payment::get($paymentID, $paypal);

$execute = new PaymentExecution();
$execute->setPayerId($payerId);

try{
    $result = $payment->execute($execute, $paypal);
}catch(Exception $e){
    die($e);
}
echo '支付成功!';

到此这个支付收款流程已经走完了,更多源代码请到官方查看API说明http://paypal.github.io/PayPal-PHP-SDK/sample/

最后这里有个小问题要告诉大家,如果你切换到live模式后,也就是正式账户,而不是沙盒账号,提交表单后提示:Client Authentication failed,身份验证失败,这个时候你需要在app.php里面加一段代码,切换到live模式才行

$paypal->setConfig(
            array(
                'mode' => 'live'
            )
);

写到最后,换成正式账号后,付款的时候提醒: 很抱歉我们无法完成您的购物。

这里是paypal的一种限制,如果你的收款账号注册国家是中国,那付款的那个人账号不能是中国的,只能是国外的,比如香港,美国等.