php 对接paypal的SDK实现支付详解(源代码)

编程入门 行业动态 更新时间:2024-10-08 05:30:55

php 对接paypal的SDK实现支付详解(<a href=https://www.elefans.com/category/jswz/34/1769335.html style=源代码)"/>

php 对接paypal的SDK实现支付详解(源代码)

paypal支付接口准备工作

  • 首先去申请一个paypal账号,/。
  • 申请完毕并登录,进入/。即可看到你申请账号自动配属的两个测试账号,账号类别分别是:BUSINESS和PERSONAL,PERSONAL的账号里面有$9999,测试费用,表激动。

  • 下面去给两个账号设置密码,点击账号展开,然后点击Profile,会弹出账号信息框,里面可以设置密码等一堆属性。如果点击账号始终无法展开,请吐槽下paypal,然后F5再点。
  • 下面进入,点击REST API apps栏目下面的Create App按钮,写进一个APP名称,然后选择一个测试账户作为此APP绑定的账号,如果你在上一步没有申请新的测试账号,那么这里默认就是选择了BUSINESS账号。

  • 然后打开创建的APP,可以看到APP的clientId和clientSecret。

  • paypal的测试环境域名为sandbox.paypal,正式域名为www.paypal。一下测试均为测试环境。

至此准备工作差不多了,开始动代码。

PayPal-PHP-SDK下载

  • 通过composer(composer安装教程)下载PayPal-PHP-SDK,具体的composer.json如下:
{"require" : {"paypal/rest-api-sdk-php" : "1.7.4"},"repositories": {"packagist": {"type": "composer","url": ""}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 切换至项目目录并执行composer install,PayPal-PHP-SDK安装完毕。
  • 因为PayPal-PHP-SDK里面的composer.json里面的require有psr/log,所以在在目录vendor下有三个文件夹:composer,paypal和psr。
  • 此时项目的目录结构如下,其中的app文件夹是下面实例化创建的文件夹。 

PayPal-PHP-SDK支付接口测试

然后就简单了,PayPal-PHP-SDK里面有一个sample项目,里面有各种实例。 
打开浏览器,输入http://~/rest-api-sdk-php/sample/index.php,“~”符号改为你自己的路径。 
可以看到sample了,如下图: 
 
图中的PayPal Payments - similar to Express Checkout in Classic APIs即为支付接口,对应的代码路径为~/rest-api-sdk-php/sample/payments/CreatePaymentUsingPayPal.php。

PayPal Payments的逻辑大致如下:

  • 创建一个支付,发送到paypal服务端
  • paypal服务端返回一个用户授权地址
  • 转链到用户授权地址,用户授权
  • 用户授权完毕,paypal返回到客户端设置的execute地址,付款实现。

实现如下: 
~/rest-api-sdk-php/sample/payments/CreatePaymentUsingPayPal.php有如下代码

// ### Get redirect url
// The API response provides the url that you must redirect
// the buyer to. Retrieve the url from the $payment->getApprovalLink()
// method
// 获取到重定向地址
$approvalUrl = $payment->getApprovalLink();// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
// 将重定向地址打印出来
ResultPrinter::printResult("Created Payment Using PayPal. Please visit the URL to Approve.".$approvalUrl, "Payment", "<a href='$approvalUrl' >$approvalUrl</a>", $request, $payment);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

点击 
 
页面执行完毕,既看到paypal服务端返回的授权地址 
 
转链到授权地址 
 
用户登录授权之后 
 
点击继续,返回用户设置的execute地址 
 
至此,PayPal-PHP-SDK支付接口sample支付过程完毕。

支付接口实例化

在项目根目录创建app文件夹,创建几个必须的文件如下: 
 
其中: 
- payment.php,创建支付 
- exec.php,执行支付,用户授权返回地址 
- cancel.php,用户取消支付 
- common.php,公共文件

payment.php文件



<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | paypal支付DEMO
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail>
// +----------------------------------------------------------------------
// | Datetime: 2016-07-28 10:56:40
// +----------------------------------------------------------------------
// | Copyright: Perfect Is Shit
// +----------------------------------------------------------------------
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\Transaction;
use PayPal\Api\ShippingAddress;// ### Payer
// A resource representing a Payer that funds a payment
// For paypal account payments, set payment method
// to 'paypal'.
$payer = new Payer();
$payer->setPaymentMethod("paypal");// ### Itemized information
// (Optional) Lets you specify item wise
// information//参数
$shipping = 15;//运费
$tax = 10;//税费
$quantity = 4;//数量
$price = 30;//单价
$subtotal = $quantity * $price;//商品总价=数量*单价
$total = $subtotal + $shipping + $tax;//总费用$item1 = new Item();
$item1->setName('test pro 1')//购物详情->setCurrency('USD')->setQuantity($quantity)->setSku("testpro1_01") // Similar to `item_number` in Classic API  物品号->setPrice($price);// $item2 = new Item();
// $item2->setName('test pro 2')
//     ->setCurrency('USD')
//     ->setQuantity(5) //数量
//     ->setSku("testpro2_01") // Similar to `item_number` in Classic API 物品号
//     ->setPrice(20);$itemList = new ItemList();
$itemList->setItems(array($item1));//如果多个可array($item1,$item2,...)// 自定义用户收货地址,避免用户在paypal上账单的收货地址和销售方收货地址有出入
// 这里定义了收货地址,用户在支付过程中就不能更改收货地址,否则,用户可以自己更改收货地址
$address = new ShippingAddress();
$address->setRecipientName('什么名字') //买家名->setLine1('什么街什么路什么小区')//地址->setLine2('什么单元什么号')//详情地址->setCity('城市名')//城市名->setState('浙江省')//省份->setPhone('12345678911')//手机号码->setPostalCode('12345')//邮政编码->setCountryCode('CN');//国家编号$itemList->setShippingAddress($address);// ### Additional payment details
// Use this optional field to set additional
// payment information such as tax, shipping
// charges etc.
// 传价格参数
$details = new Details();
$details->setShipping($shipping)//运费->setTax($tax)//税费->setSubtotal($subtotal);//金额 和上面的物品价格总和对应// ### Amount
// Lets you specify a payment amount.
// You can also specify additional details
// such as shipping, tax.
// 总价要和上面的三项费用一致
$amount = new Amount();
$amount->setCurrency("USD")->setTotal($total)->setDetails($details);// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it.
$transaction = new Transaction();
$transaction->setAmount($amount)->setItemList($itemList)->setDescription("Payment description")->setInvoiceNumber(uniqid());// ### Redirect urls
// Set the urls that the buyer must be redirected to after
// payment approval/ cancellation.
$baseUrl = getBaseUrl();
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("$baseUrl/exec.php?success=true&subtotal=$subtotal&total=$total&shipping=$shipping&tax=$tax")->setCancelUrl("$baseUrl/cancel.php?success=false");// ### Payment
// A Payment Resource; create one using
// the above types and intent set to 'sale'
$payment = new Payment();
$payment->setIntent("sale")->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions(array($transaction));$payment->create($apiContext);$approvalUrl = $payment->getApprovalLink();
// 打印出用户授权地址,这里仅仅实现支付过程,流程没有进一步完善。
dump($approvalUrl);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116

exec.php文件

<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | 执行支付DEMO
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail>
// +----------------------------------------------------------------------
// | Datetime: 2016-07-28 11:53:10
// +----------------------------------------------------------------------
// | Copyright: Perfect Is Shit
// +----------------------------------------------------------------------
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;// ### Approval Status
// Determine if the user approved the payment or not
if (isset($_GET['success']) && $_GET['success'] == 'true' && isset($_GET['shipping']) && isset($_GET['tax']) && isset($_GET['subtotal']) && isset($_GET['total'])) {//接收参数$shipping = $_GET['shipping'];//运费$tax = $_GET['tax'];//税费$subtotal = $_GET['subtotal'];//商品总价$total = $_GET['total'];//总费用// Get the payment Object by passing paymentId// payment id was previously stored in session in// CreatePaymentUsingPayPal.php$paymentId = $_GET['paymentId'];$payment = Payment::get($paymentId, $apiContext);// ### Payment Execute// PaymentExecution object includes information necessary// to execute a PayPal account payment.// The payer_id is added to the request query parameters// when the user is redirected from paypal back to your site$execution = new PaymentExecution();$execution->setPayerId($_GET['PayerID']);// ### Optional Changes to Amount// If you wish to update the amount that you wish to charge the customer,// based on the shipping address or any other reason, you could// do that by passing the transaction object with just `amount` field in it.// Here is the example on how we changed the shipping to $1 more than before.$transaction = new Transaction();$amount = new Amount();$details = new Details();$details->setShipping($shipping)//运费->setTax($tax)//税费->setSubtotal($subtotal);//金额$amount->setCurrency('USD');$amount->setTotal($total);$amount->setDetails($details);$transaction->setAmount($amount);// Add the above transaction object inside our Execution object.$execution->addTransaction($transaction);header("Content-type: text/html; charset=utf-8");try {// Execute the payment$result = $payment->execute($execution, $apiContext);echo "支付成功";// 账单唯一交易号,paypal账户交易记录里面的标示  $data['tradeId'] = '账单唯一交易号:'.$result->transactions[0]->related_resources[0]->sale->id;  // 账单号,paypal账户交易记录里面的标示  $data['billId'] = '账单号:'.$result->transactions[0]->invoice_number;  // payid,接口查询使用的账单id  $data['payId'] = 'payid:'.$result->id;  echo "<pre>";var_dump($data);} catch (Exception $ex) {echo "支付失败";exit(1);}return $payment;
} else {echo "PayPal返回回调地址参数错误";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75

cancel.php文件

<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | 取消支付DEMO
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail>
// +----------------------------------------------------------------------
// | Datetime: 2016-07-29 11:31:32
// +----------------------------------------------------------------------
// | Copyright: Perfect Is Shit
// +----------------------------------------------------------------------
echo "用户取消支付";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

common.php文件

<?php
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------
// | 公共文件
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail>
// +----------------------------------------------------------------------
// | Datetime: 2016-07-28 11:55:30
// +----------------------------------------------------------------------
// | Copyright: ShowMore
// +----------------------------------------------------------------------
require_once('../vendor/autoload.php');use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;// 下面为申请app获得的clientId和clientSecret,必填项,否则无法生成token。
$clientId = '';
$clientSecret = '';
$apiContext = new ApiContext(new OAuthTokenCredential($clientId,$clientSecret)
);
$apiContext->setConfig(array('mode' => 'sandbox','log.LogEnabled' => true,'log.FileName' => '../PayPal.log','log.LogLevel' => 'DEBUG', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS'cache.enabled' => true,// 'http.CURLOPT_CONNECTTIMEOUT' => 30// 'http.headers.PayPal-Partner-Attribution-Id' => '123123123'//'log.AdapterFactory' => '\PayPal\Log\DefaultLogFactory' // Factory class implementing \PayPal\Log\PayPalLogFactory)
);// 浏览器友好的变量输出
function dump($var, $echo=true, $label=null, $strict=true) {$label = ($label === null) ? '' : rtrim($label) . ' ';if (!$strict) {if (ini_get('html_errors')) {$output = print_r($var, true);$output = "<pre>" . $label . htmlspecialchars($output, ENT_QUOTES) . "</pre>";} else {$output = $label . print_r($var, true);}} else {ob_start();var_dump($var);$output = ob_get_clean();if (!extension_loaded('xdebug')) {$output = preg_replace("/\]\=\>\n(\s+)/m", "] => ", $output);$output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';}}if ($echo) {echo($output);return null;}elsereturn $output;
}/*** ### getBaseUrl function* // utility function that returns base url for* // determining return/cancel urls** @return string*/
function getBaseUrl()
{if (PHP_SAPI == 'cli') {$trace=debug_backtrace();$relativePath = substr(dirname($trace[0]['file']), strlen(dirname(dirname(__FILE__))));echo "Warning: This sample may require a server to handle return URL. Cannot execute in command line. Defaulting URL to http://localhost$relativePath \n";return "http://localhost" . $relativePath;}$protocol = 'http';if ($_SERVER['SERVER_PORT'] == 443 || (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {$protocol .= 's';}$host = $_SERVER['HTTP_HOST'];$request = $_SERVER['PHP_SELF'];return dirname($protocol . '://' . $host . $request);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

支付接口实例测试

执行payment.php文件,得到授权地址,如下: 
 
转链到用户授权地址 
 
用户登录授权,可以看到在我们设置过收货地址之后,支付收货地址是默认无法更改的。 
 
用户点击继续,会转链到我们的支付成功回调地址exec.php。 
 
用户点击取消并返回,会转链到我们的支付失败回调地址cancel.php 
 
支付过后可进入sandbox账号中心查看是否有交易。 


 

更多推荐

php 对接paypal的SDK实现支付详解(源代码)

本文发布于:2024-02-14 01:11:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761278.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:源代码   详解   php   paypal   SDK

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!