天天看点

Paypal支付/回调/退款

一.下载依赖包

二.发起支付

<?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; 
    }
           
原文链接:https://learnku.com/articles/26282
Paypal支付/回调/退款