Paypal支付/回撥/退款
阿新 • • 發佈:2021-01-13
一.下載依賴包
composer require "paypal/rest-api-sdk-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\ Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use PayPal\Api\PaymentExecution;
class Paypal{
const clientId = 'xxxxxxxxx';
const clientSecret = 'xxxxxxxx';
const succee = 'http://xxx.com/Callback?success=true';//發起支付成功同步回撥地址
const fail= 'http://xxx.com/Callback/?success=false';//發起支付成功同步回撥地址
protected $PayPal;
public function __construct(){
$this->PayPal = new ApiContext(
new OAuthTokenCredential(
self::clientId,
self::clientSecret
)
);
//設定支付模式:沙盒模式(sandbox) 和 正式(live)
$this->PayPal->setConfig(
// array(
// 'mode' => 'sandbox',
// 'log.LogEnabled' => true,
// 'log.FileName' => '../PayPal.log',
// 'log.LogLevel' => 'DEBUG',
// 'cache.enabled' => true
// )
array(
'mode' => 'live',
'log.LogEnabled' => true,
'log.FileName' => '../PayPal.log',
'log.LogLevel' => 'FINE',
'cache.enabled' => true
)
);
public function pay() {
$product = '商品';
$price = 1;//價錢
$shipping = 0;//運費
$description = '1123123';
$paypal = $this->PayPal;
$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(self::Currency)->setTotal($total)->setDetails($details);
$transaction = new Transaction();//描述內容
$transaction->setAmount($amount)->setItemList($itemList)->setDescription($description)->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(self::succee)->setCancelUrl(self::fail);
$payment = new Payment();
$payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);
try {
$payment->create($paypal);
} catch (PayPalConnectionException $e) {
echo $e->getData();
}
$approvalUrl = $payment->getApprovalLink();
header("Location: {$approvalUrl}");
}
三.同步回撥
/**
* 回撥
*/
public function Callback(){
$success = trim($_GET['success']);
if ($success == 'false' && !isset($_GET['paymentId']) && !isset($_GET['PayerID'])) {
echo '取消付款';die;
}
$paymentId = trim($_GET['paymentId']);
$PayerID = trim($_GET['PayerID']);
if (!isset($success, $paymentId, $PayerID)) {
echo '支付失敗';die;
}
if ((bool)$_GET['success'] === 'false') {
echo '支付失敗,支付ID【'.$paymentId.'】,支付人ID【'.$PayerID.'】';die;
}
$payment = Payment::get($paymentId, $this->PayPal);
$execute = new PaymentExecution();
$execute->setPayerId($PayerID);
try {
$payment->execute($execute, $this->PayPal);
} catch (Exception $e) {
echo ',支付失敗,支付ID【'.$paymentId.'】,支付人ID【'.$PayerID.'】';
}
echo '支付成功,支付ID【'.$paymentId.'】,支付人ID【'.$PayerID .'】';
}
四.非同步回撥
public function notify(){
//獲取回撥結果
$json_data = $this->get_JsonData();
if(!empty($json_data)){
Log::debug("paypal notify info:\r\n".json_encode($json_data));
}else{
Log::debug("paypal notify fail:參加為空");
}
//自己列印$json_data的值看有那些是你業務上用到的
//比如我用到
$data['invoice'] = $json_data['resource']['invoice_number'];
$data['txn_id'] = $json_data['resource']['id'];
$data['total'] = $json_data['resource']['amount']['total'];
$data['status'] = isset($json_data['status'])?$json_data['status']:'';
$data['state'] = $json_data['resource']['state'];
try {
//處理相關業務
} catch (\Exception $e) {
//記錄錯誤日誌
Log::error("paypal notify fail:".$e->getMessage());
return "fail";
}
return "success";
}
public function get_JsonData(){
$json = file_get_contents('php://input');
if ($json) {
$json = str_replace("'", '', $json);
$json = json_decode($json,true);
}
return $json;
}
五.退款
public function returnMoney(){
try {
$txn_id = "xxxxxxx"; //非同步加調中拿到的id
$amt = new Amount();
$amt->setCurrency('USD')
->setTotal('99'); // 退款的費用
$refund = new Refund();
$refund->setAmount($amt);
$sale = new Sale();
$sale->setId($txn_id);
$refundedSale = $sale->refund($refund, $this->PayPal);
} catch (\Exception $e) {
// PayPal無效退款
return json_decode(json_encode(['message' => $e->getMessage(), 'code' => $e->getCode(), 'state' => $e->getMessage()])); // to object
}
// 退款完成
return $refundedSale;
}