15年软件开发经验 只做源码定制 互联网+定制化解决方案

15年软件开发经验,只做源码定制!

原创设计 定制开发

满足您的个性化需求

当前位置:首页 后端开发 Thinkphp5

Paypal,PayPal支付,Paypal参数设置

教腾豪| 发布于 2021-08-27 20:42:45| 238阅读| 0点赞| 0评论
举报

PC网站用于PayPal支付,一种支付方式,网站下单进行Paypal支付

Paypal支付,是目前网站流行的一种支付方式,Paypal也是需要依赖工具包来进行开发

paypal依赖包 composer require paypal/rest-api-sdk-php

用 composer 命令来下载依赖包


Paypal支付的参数也是要用到Paypal秘钥和ID,查看Paypal API文档,来进行开发,对接,

参考文档 https://learnku.com/articles/26282,这是参考文档,可以去翻阅查看


沙盒环境

沙盒环境就和本地环境差不多,是一种模拟Paypal的流程支付环境也称沙盒环境

沙盒登录 https://www.sandbox.paypal.com/c2/signin

参考这个文档进行调试和开发


下面是Paypal支付调取,同步回调和异步回调,退款的方法,

<?php
namespace app\index\controller;
use think\Controller;

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\Api\Refund;
use PayPal\Api\Sale;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use PayPal\Api\PaymentExecution;

class Paypal extends Controller
{
    const clientId = 'Ac6pDC0T8z9tY6UtMah1F1bThTS5ZBvljoC-HmM2IQozJVau9RzBfryaG4bgsnYCEFC2xezoALZTKWm_';//ID
    const clientSecret = 'EBUOzWInmgG1ZUjqVP41o6QTyzpQgVp3DOiI8CAfJMFoaoCh_W9QrCpDx98D2npSHRZ25WdHh3fGiScP';//秘钥
    const accept_url = 'http://gougoule.com/index/Paypal/Callback'; //同步回调
    const error_log = './error_log/paypal_errors.log'; //错误日志
    const Currency = 'USD';//币种
    protected $PayPal;

//sb-cng47f6173606@business.example.com  a123456789
//sb-ye47ag6160608@personal.example.com  a123456789

    public function __construct()
    {
        $this->PayPal = new ApiContext(
            new OAuthTokenCredential(
                self::clientId,
                self::clientSecret
            )
        );
        //如果是沙盒测试环境不设置,请注释掉
//        $this->PayPal->setConfig(
//            array(
//                'mode' => 'live',
//            )
//        );
    }

    /**
     * paypal支付
     * @param $price float 金额
     * @param $order_sn string 订单号
     * @param $product string 商品名
     * @param $description string 商品描述
     * @param $shipping float 运费
     *
     */
    public function pay($price=10, $order_sn=123456, $product='商品', $description='描述内容', $shipping = 0)
    {
        $paypal = $this->PayPal;
        $total = $price + $shipping;//总价
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');
        $item = new Item();
        $item->setName($product)->setCurrency(self::Currency)->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::accept_url . '?success=true&order_sn='.$order_sn)->setCancelUrl(self::accept_url . '/?success=false');
        $payment = new Payment();
        $payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]);
        try {
            $payment->create($paypal);
            $approvalUrl = $payment->getApprovalLink();
            echo json_encode(['code'=>200, 'msg'=>'成功!','url'=>$approvalUrl]);
            //header("Location: {$approvalUrl}"); //自动跳转页面
            exit();
        } catch (PayPalConnectionException $e) {
            error_log(date('Y-m-d H:i:s')." paypal pay fail: ".$e->getData()."\n", 3, self::error_log);
            echo json_encode(['code'=>202, 'msg'=>$e->getData()]);
            exit();
        }
    }

    /**
     * 同步回调方法
     */
    public function Callback()
    {
        $success = trim($_GET['success']);
        if ($success == 'false' && !isset($_GET['paymentId']) && !isset($_GET['PayerID'])) {
            error_log(date('Y-m-d H:i:s')." paypal Callback fail: 取消付款"."\n", 3, self::error_log);
            echo json_encode(['code'=>202, 'msg'=>'取消付款']);
            exit();
        }
        $paymentId = trim($_GET['paymentId']);
        $PayerID = trim($_GET['PayerID']);
        $order_sn = trim($_GET['order_sn']); //订单号
        if (!isset($success, $paymentId, $PayerID)) {
            error_log(date('Y-m-d H:i:s')." paypal Callback fail: 支付失败"."\n", 3, self::error_log);
            echo json_encode(['code'=>202, 'msg'=>'支付失败']);
            exit();
        }
        if ((bool)$_GET['success'] === 'false') {
            error_log(date('Y-m-d H:i:s')." paypal Callback fail:".'支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】'."\n", 3, self::error_log);
            echo json_encode(['code'=>202,'msg'=>'支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】']);
            exit();
        }
        $payment = Payment::get($paymentId, $this->PayPal);
        $execute = new PaymentExecution();
        $execute->setPayerId($PayerID);

        try {
            $payment->execute($execute, $this->PayPal);
//            error_log(date('Y-m-d H:i:s')."同步回调:".json_encode($_GET)."\n", 3, self::error_log);

            /*
             * 将$paymentId保存到数据表
             * */

            echo json_encode(['code'=>200,'msg'=>'支付成功,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】,订单号【'.$order_sn.'】']);
            exit();
        } catch (Exception $e) {
            error_log(date('Y-m-d H:i:s')." paypal Callback fail:".$e->getMessage(). ",支付失败,支付ID【" . $paymentId . "】,支付人ID【" . $PayerID . "】"."\n", 3, self::error_log);
            echo json_encode(['code'=>202,'msg'=>$e . ',支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】']);
            exit();
        }
    }

    //异步回调(在控制台设置)
    public function notify(){
        //通知结果 https://developer.paypal.com/docs/api-basics/notifications/webhooks/notification-messages/
        $json_data = file_get_contents('php://input');
//        error_log(date('Y-m-d H:i:s')."异步回调:".$json_data."\n", 3, self::error_log);
        $json_data = str_replace("'", '', $json_data);
        $json_data = json_decode($json_data,true);
        if(empty($json_data)){
            error_log(date('Y-m-d H:i:s')."paypal notify fail: 参加为空!"."\n", 3, self::error_log);
            exit();
        }
        try {
            //自己打印$json_data的值看有那些是你业务上用到的
            $id = $json_data['resource']['id'];  //付款id(退款用),存表
            $paymentId = $json_data['resource']['parent_payment']; //用此字段查询出订单表
            if($json_data['resource_type']=='sale'){ //支付完成

                /*
                * 处理相关业务
                * */

            }elseif ($json_data['resource_type']=='refund'){ //退款成功
                $total=$json_data['resource']['amount']['total']; //退款金额

                /*
                * 处理相关业务
                * */

            }
        } catch (\Exception $e) {
            //记录错误日志
            error_log(date('Y-m-d H:i:s')."paypal notify fail:".$e->getMessage()."\n", 3, self::error_log);
            exit();
        }
        return "success";
    }

    //退款
    public function returnMoney($txn_id = "3LV45487XU194815F",$price=1){ //异步回调中拿到的id
        try {
            $amt = new Amount();
            $amt->setCurrency('USD')
                ->setTotal($price);  // 退款的费用
            $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
            echo json_encode(['code' => 202,'msg'=> $e->getMessage()]);
            exit();
        }
        $refundedSale = $refundedSale->toArray();
        // 退款完成
        if($refundedSale['state']=='completed'){
            echo json_encode(['code' => 200,'msg' =>'退款成功!']);
            exit();
        }else{
            echo json_encode(['code' => 202,'msg' =>'退款失败!']);
            exit();
        }
    }


}
0

0条评论

别默默看啦~登录/注册一起参与讨论吧~

热门标签

教腾豪
微信扫一扫立即咨询
账号登录|扫码登录

立即注册 |忘记密码?

欢迎注册

已有账号马上登录

重置密码

扫码绑定微信
微信扫一扫

绑定手机号

分享到-微信

举报

  • 举报类型:

  • 举报描述:

您好,当前积分不足。

在线客服
拨打电话
17330196230 13230981129
顶部