执行命令加载composer
composer require "paypal/rest-api-sdk-php"
页面demo
{extend name="layout/user_main" /}
{block name="content"}
<div class="pad_lr12 " style="margin-top: 5rem;">
<a class="btn_full mar_b20 submit" href="javascript:;">check out</a>
</div>
{/block}
{block name="script"}
<script type="text/javascript">
$('.submit').on('click',function () {
PayPal(this);
})
function PayPal(obj) {
data = {};
data.method = 'PayPal';
data.price = $('.method_list').find('.active').eq(0).attr('data-price');
//创建paypal支付,生成支付链接,跳转支付
$.ajax({
url:"{:url('Pay/index')}",
data:data,
type:'post',
success:function (re) {
if(re.code == 1){
location.href = re.data.open_url;
}else{
$.toast(re.msg,'text');
}
}
})
}
</script>
{/block}
使用方式
<?php
namespace app\wap\controller;
use app\wap\service\pay\PayPal;
class Pay extends Base
{
/**
* PayPal支付
* 1.保存支付信息
* 2.判断用户等级是否需要升级
*/
public function index()
{
$param = $this->request->param();
if(!isset($param['method']) || !isset($param['price'])){
$this->error('request was aborted');
}
//生成订单
...
//创建支付
try{
$paypal = new PayPal();
$result = $paypal->createPayPal($data);
if($result['code'] == 0){
$this->error($result['msg']);
}
}catch(\Exception $e){
$this->error($e->getMessage());
}
//跳转到支付确认
$this->success('success','',$result['data']);
}
/**
* 执行付款
* return data array(3) {
["paymentId"] => string(28) "PAY-65076081CX802152WLLZIO4I" //支付ID
["token"] => string(20) "EC-8N633353AD2775827"
["PayerID"] => string(13) "" //付款人ID
}
*/
public function paysuccess()
{
$param = $this->request->param();
try{
//执行paypal支付
$paypal = new PayPal();
$orderInfo = $paypal->payment($param);
$this->paySuccessLogic($orderInfo);
}catch(\Exception $e){
$this->error($e->getMessage());
}
}
//付款成功后的处理逻辑
public function paySuccessLogic($orderInfo)
{
...
$this->success('Recharge success',url('User/index'),'',10);
}
}
paypal支付逻辑处理
<?php
namespace app\wap\service\pay;
require EXTEND_PATH.'lib/PayPalUtil.php';
/**
* PayPal支付
*/
class PayPal
{
protected $config;
public function __construct()
{
parent::__construct();
//获取paypal支付配置
$info = model('Payment')->getPayInfo(['pay_code'=>'PayPal','enabled'=>1]);
if(!$info){
throw new \Exception('Sorry, the way of payment is not supported');
}
$this->config = json_decode($info->toArray()['pay_config'],true);
}
//创建PayPal支付
public function createPayPal($data)
{
//支付成功跳转地址
$successUri = url('Pay/paysuccess','','html',true);
//支付失败跳转地址
$errorUri = url('User/recharge','','html',true);
//调用支付工具类创建支付信息
$payPal = new \ext\lib\PayPalUtil($this->config,$data['money'],$data['order_sn'],$successUri,$errorUri);
$result = $payPal->pay();
return $result;
}
//执行付款
public function payment($param)
{
//调用支付工具类支付
$payPal = new \ext\lib\PayPalUtil($this->config);
$result = $payPal->payment($param['paymentId'],$param['token'],$param['PayerID']);
if($result['code'] == 0){
throw new \Exception('Failure to pay');
}
//判断是否是经批准的
if($result['data']->state != 'approved'){
throw new \Exception('Failure to pay');
}
$orderSn = $result['data']->transactions[0]->invoice_number;
$orderInfo = model('UserRecharge')->where(['order_sn'=>$orderSn])->find();
if(!$orderInfo){
//TODO:数据库订单不存在,支付异常,给用户退款file_put_contents('./recharge.log',json_encode($result).PHP_EOL,FILE_APPEND);
throw new \Exception('Failure to pay');
}
//支付成功,进行后续处理
$orderInfo->pay_id = $result['data']->id;
$orderInfo->cart = $result['data']->cart;
$orderInfo->save();
return $orderInfo;
}
paypal支付工具类
<?php
/**
* PayPal支付工具类.
* User: Victory
* Date: 2018/5/5 0005
* Time: 12:39
*/
namespace ext\lib;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
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;
use PayPal\Api\PaymentExecution;
use think\Controller;
class PayPalUtil extends Controller
{
public $config = [];
public $price = 0;
public $orderSn = 0;
public $redirectUrl = '';
public $cancelUrl = '';
public $apiContext = '';
public function __construct($config,$price = '',$orderSn = '',$redirectUrl = '',$cancelUrl = '')
{
parent::__construct();
$this->config = $config;
$this->price = $price;
$this->orderSn = $orderSn;
$this->redirectUrl = $redirectUrl;
$this->cancelUrl = $cancelUrl;
// dump($this->config);
//实例化paypal支付api环境类
$this->apiContext = new ApiContext(
new OAuthTokenCredential(
$this->config['client_id'], // ClientID
$this->config['client_secret'] // ClientSecret
)
);
$this->apiContext->setConfig(['mode'=>'live']);
}
//使用PayPal创建付款作为付款方式
public function pay()
{
//付款人
$payer = new Payer();
//设置付款方式为paypal
$payer->setPaymentMethod('paypal');
/*$item = new Item(); //项目详情类。
$item->setName('Recharge of a novel member') //项目名称
->setCurrency($this->config['currency']) //设置货币
->setQuantity(1) //设置量
->setPrice($this->price); //设置金额
$itemList = new ItemList(); //支付物品清单。
$itemList->setItems([$item]); //项目清单。*/
/*$details = new Details(); //支付金额的其他细节。
$details->setShipping(0) //运费收取金额
->setSubtotal($this->price); //项目的小计金额。**如果指定了行项目,则需要***/
$amount = new Amount();
$amount->setTotal($this->price); //设置支付金额
$amount->setCurrency($this->config['currency']); //设置支付货币
$transaction = new Transaction(); //交易定义了付款合同 - 付款和完成付款的人是什么。
$transaction->setAmount($amount) //正在收集的数量。
// ->setItemList($itemList) //支付物品清单。
->setDescription("Member recharge VIP") //支付描述内容
->setInvoiceNumber($this->orderSn); //设置发票号码
$redirectUrls = new RedirectUrls(); //设置重定向的URL你只提供贝宝支付。
$redirectUrls->setReturnUrl($this->redirectUrl) //URL,支付者将被重定向到批准支付后。*贝宝账户支付所需的**。
->setCancelUrl($this->cancelUrl); //在支付取消后,付款人将被重定向到的URL。*贝宝账户支付所需的**。
//创建,处理和管理付款类。
$payment = new Payment();
$payment->setIntent('sale') //付款意向。
->setPayer($payer) //该支付的贝宝账户或直接信用卡为代表的资金来源
->setTransactions(array($transaction)) //交易细节,包括数量和项目细节。
->setRedirectUrls($redirectUrls); //设置重定向的URL你只提供贝宝支付。
try {
$payment->create($this->apiContext); //创建和处理支付。在JSON请求主体中,包含带有意图、付款人和事务的“支付”对象。贝宝付款,包括重定向的URL在`支付`对象。
} catch (PayPalConnectionException $ex) {
// This will print the detailed information on the exception.
//REALLY HELPFUL FOR DEBUGGING
// echo $ex->getData();
return ['code'=>0,'msg'=>'code:'.$ex->getCode().',msg:'.$ex->getData(),'data'=>''];
}
$approvalUrl = $payment->getApprovalLink(); //获得批准支付链接
return ['code'=>1,'msg'=>'success','data'=>['open_url'=>$approvalUrl]];
}
//执行付款
public function payment($paymentId,$token,$PayerID){
$payment = Payment::get($paymentId, $this->apiContext); //通过ID显示付款细节
$execution = new PaymentExecution();
$execution->setPayerId($PayerID); //设置付款人ID
try {
$result = $payment->execute($execution, $this->apiContext); //执行付款,执行或完成,贝宝付款,付款人已批准。当您执行支付时,您可以选择性地更新选择性支付信息。
try {
$payment = Payment::get($paymentId, $this->apiContext);//通过ID显示付款细节
} catch (\Exception $ex) {
return ['code'=>0,'msg'=>'Failure to pay1','data'=>''];
}
}catch (\Exception $ex) {
return ['code'=>0,'msg'=>'Failure to pay2','data'=>''];
}
return ['code'=>1,'msg'=>'success','data'=>$payment];
}
}