资讯专栏INFORMATION COLUMN

Laravel中集成PayPal

xiaoqibTn / 2714人阅读

摘要:最近在写一个面向国外买家的一个商城项目,既然面向国外,那就要用到这个支付平台。因为在对接的过程中遇到了一些问题,花费了一些时间,所以把对接的过程记下来,也希望能帮助到用到的朋友。以下皆以代码的形式展现,没有截图,但我尽量用代码讲解明白。

最近在写一个面向国外买家的一个商城项目,既然面向国外,那就要用到PayPal这个支付平台。因为在对接PayPal的过程中遇到了一些问题,花费了一些时间,所以把对接的过程记下来,也希望能帮助到用到PayPal的朋友。

我集成的是paypal/rest-api-sdk-phpPayPalapiv1v2两个版本,我用的这个是v1版本。

以下皆以代码的形式展现,没有截图,但我尽量用代码讲解明白。
假设你已经有了用laravel写的一个项目:

Step:1安装扩展包
composer require paypal/rest-api-sdk-php
Step:2创建payment.php配置文件

Config目录新建payment.php配置文件,内容如下

return [
    "paypal" => [
        /** set your paypal credential **/
        "client_id" =>"paypal client_id",
        "secret" => "paypal secret ID",
        /**
         * SDK 配置
         */
        "settings" => array(
            /**
             * 沙盒测试"sandbox" 或者 "live"
             */
               "mode" => "sandbox",
            /**
             * 请求超时时间
             */
            "http.ConnectionTimeOut" => 1000,
            /**
             * 是否开启日志:true开启,false不开启
             */
            "log.LogEnabled" => true,
            /**
             * 日志存储的文件
             */
            "log.FileName" => storage_path() . "/logs/paypal.log",
            /**
             * 日志级别 "DEBUG", "INFO", "WARN" or "ERROR"
                *
             */
            "log.LogLevel" => "INFO"
        ),
    ],
    
    "2checkout" => [
        //
    ]
];
Step:3创建路由
    // 第一步:显示表单,这是一个简单的表单页面,我们把金额输入,然后点击提交
    Route::get("paypal-form", "PaymentPayPalController@payPalShow")->name("paypal-form");

    // 第二步:第一步提交后发送请求,请求该方法,该方法用于创建订单,创建支付流程
    Route::post("paypal-pay", "PaymentPayPalController@pay")->name("payment.paypay.pay");

    // 第三步:异步回调
    Route::post("paypal-notify", "PaymentPayPalController@payPalNotify")->name("payment.paypal.notify");

    // 第三步:前端回调
    Route::get("paypal-return", "PaymentPayPalController@payPalReturn")->name("payment.paypal.return");

    // 第三步:取消
    Route::get("paypal-cancel", "PaymentPayPalController@payPalCancel")->name("payment.paypal.cancel");
Step:3创建控制器
_api_context = new ApiContext(new OAuthTokenCredential(
            $payPal_config["client_id"],
            $payPal_config["secret"]
        ));
        $this->_api_context->setConfig($payPal_config["setting"]);
    }

    // 显示表单
    public function payPalShow()
    {
        return view("payment.paypal");
    }
    
    // 第二步,请求这里
    public function pay(Request $request)
    {
        $payer = new Payer();
        $payer->setPaymentMethod("paypal");

        // 产品名称,币种,数量,单个产品金额
        $item1 = new Item();
        $item1->setName("item1")
            ->setCurrency("USD")
            ->setQuantity(1)
            ->setPrice($request->get("amount"));

        // 将所有产品集合到 ItemList中
        $item_list = new ItemList();
        $item_list->setItems([$item1]);

        $amount = new Amount();
        $amount->setCurrency("USD")
            ->setTotal($request->get("amount"));

        // 生成交易
        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($item_list)
            ->setDescription("你的交易")
            ->setNotifyUrl(route("notify_url")) // 注意,这里设置异步回调地址
            ->setInvoiceNumber($order->order_number); // 这里设置订单号

        // 设置前端回调地址和取消支付地址
        $redirect_urls = new RedirectUrls();
        $redirect_urls->setReturnUrl(route("payment.paypal.return"))
        ->setCancelUrl(route("payment.paypal.cancel"));
        
        $payment = new Payment();
        $payment->setIntent("Sale")
            ->setPayer($payer)
            ->setRedirectUrls($redirect_urls)
            ->setTransactions(array($transaction));
        try {
            // 这里生成支付流程
            $payment->create($this->_api_context);
        } catch (PayPalExceptionPayPalConnectionException $ex) {
            if (config("app.debug")) {
                session()->put("error","Connection timeout");
                return redirect()->route("paypal-form");

                /** echo "Exception: " . $ex->getMessage() . PHP_EOL; **/
                /** $err_data = json_decode($ex->getData(), true); **/
                /** exit; **/

            } else {
                session()->put("error","Some error occur, sorry for inconvenient");
                return redirect()->route("paypal-form");
            }
        }

        foreach($payment->getLinks() as $link) {
            if($link->getRel() == "approval_url") {
                $redirect_url = $link->getHref();
                break;
            }
        }

        // $payment->getId()得到的是支付流水号
        session()->put("paypal_payment_id", $payment->getId());

        if(isset($redirect_url)) {
            // 跳转到支付页面
            return redirect()->away($redirect_url);
        }

        session()->put("error","Unknown error occurred");
        return session()->route("paypal-form");
    }
    
    
    public function payPalReturn(Request $request)
    {
        // 支付成功后,在前端页面跳转回来时,url地址中会带有paymentID 和 PayerID
        $payment_id = session()->get("paypal_payment_id");
        session()->forget("paypal_payment_id");

        if (empty(Input::get("PayerID")) || empty(Input::get("token"))) {
            session()->put("error","Payment failed");

            return redirect()->route("paypal-form");
        }
        $payment = Payment::get($payment_id, $this->_api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId(Input::get("PayerID"));
        $result = $payment->execute($execution, $this->_api_context);


        // 当拿到的状态时approved表示支付成功
        if ($result->getState() == "approved") {

            session()->put("success","Payment success");
            return redirect()->route("paypal-form");
        }
        session()->put("error","Payment failed");

        return redirect()->route("paypal-form");
    }
    
    public function payPalNotify()
    {
        Log::info(12312, Input::get());
        // 这里写我们的业务逻辑,订单状态更新,物流信息等等.
    }
}
Step:4创建表单
{{ csrf_field() }}
@if ($errors->has("amount")) {{ $errors->first("amount") }} @endif

以上既是我做商城项目时PayPal的对接流程,因为英语不好的问题,开发起来会出现很多问题,
如果英文好,想知道更多的用法,可以看PayPal的开发者文档,还有demo演示。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31266.html

相关文章

  • 联想懂得流量卡 「api 2.0」php SDK(laravel 扩展)

    摘要:原文地址不知道是不是有和我一样使用到联想懂得物联网卡的兄。戳这里以下是使用说明此扩展是联想的,可以方便的在中集成。由于联想懂得的接口还在开发中,所以这个扩展包将处于开发阶段,等稳定之后会发布版本。 原文地址 不知道是不是有和我一样使用到联想懂得物联网卡的兄dei。我将接口封装成了laravel框架的扩展,也可以在laravel之外的项目中使用。 github戳这里 以下是使用说明: 此...

    Paul_King 评论0 收藏0
  • Laravel 5 中使用 Laravel Excel 实现 Excel/CSV 文件导入导出功

    摘要:本文非原创,基于学院在中使用实现文件导入导出功能这篇文章在实际中测试调整。简介在中集成套件中的,从而方便我们以优雅的富有表现力的代码实现文件的导入和导出。 本文非原创,基于laravel 学院《在 Laravel 5 中使用 Laravel Excel 实现 Excel/CSV 文件导入导出功能》 这篇文章在实际中测试调整。 showImg(https://segmentfault.c...

    XFLY 评论0 收藏0
  • Laravel学习笔记之Errors Tracking神器——Sentry

    摘要:中异常处理类主要包含两个方法和,其中就是主要用来向第三方发送异常报告,这里选择向这个神器发送异常报告,并使用通知开发人员。通过也能发现的执行流程。 说明:Laravel学习笔记之bootstrap源码解析中聊异常处理时提到过Sentry这个神器,并打算以后聊聊这款神器,本文主要就介绍这款Errors Tracking神器Sentry,Sentry官网有一句话个人觉得帅呆了: Stop ...

    xiguadada 评论0 收藏0
  • 为PHP程序员的正确姿势

    摘要:因为这对于一个刚参加工作的工程师来说,这有可能就是一月和一个月的区别了。多编写网站编程说到底其实也就是一门手艺,就对于智商差不多的程序员来说,技艺的高超程度往往就在于练的多少了。 利益相关:以下的所有文字都是仅代表个人观点,不代表全组织的利益。 本人就是一大三狗,自学PHP时间已经快两年了,感觉自己还是一个入门级的选手。说说自己是如何一步步走过来的。 1. 官方文档 对,我还是坚...

    mikyou 评论0 收藏0
  • weex踩坑之旅第二弹 ~ 在weex中集vue-router

    摘要:也就是说在中,我们的代码是要在环境中运行。而在中,是没有等以及的,即所有的框架都是不可以使用的。比如相关组件,相关组件,等都不能在中引用。是可以在中使用的。 接着第一弹讲,我们已经搭建好一个属于自己的weex项目了,然后如何开发呢?由于之前项目中都是采用vue全家桶进行开发,路由使用vue-router插件,状态管理使用vuex,Ajax前后台交互使用axios,图标库使用font-a...

    tyheist 评论0 收藏0

发表评论

0条评论

xiaoqibTn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<