Laravel中集成PayPal

栏目: PHP · 发布时间: 6年前

内容简介:最近在写一个面向国外买家的一个商城项目,既然面向国外,那就要用到我集成的是以下皆以代码的形式展现,没有截图,但我尽量用代码讲解明白。

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

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

以下皆以代码的形式展现,没有截图,但我尽量用代码讲解明白。

假设你已经有了用 laravel 写的一个项目:

Step:1 安装扩展包

composer require paypal/rest-api-sdk-php

Step:2 创建 paypal.php 配置文件

Config 目录新建 paypal.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', 'Payment\PayPalController@payPalShow')->name('paypal-form');

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

    // 第三步:异步回调
    Route::post('paypal-notify', 'Payment\PayPalController@payPalNotify')->name('payment.paypal.notify');

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

    // 第三步:取消
    Route::get('paypal-cancel', 'Payment\PayPalController@payPalCancel')->name('payment.paypal.cancel');

Step:3 创建控制器

<?php

namespace App\Http\Controllers\Payment;

use App\Http\Controllers\BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use PayPal\Api\Amount;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Rest\ApiContext;

class PayPalController extends BaseController
{
    private $_api_context;

    public function __construct()
    {
        $payPal_config = config('payment.payPal');
        // 初始化 PayPal Api context
        $this->_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.cancel'))
        ->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 (\PayPal\Exception\PayPalConnectionException $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 创建表单

<form class="form-horizontal" method="POST" id="payment-form" role="form" action="{!! URL::route('paypal-pay') !!}" >
    {{ csrf_field() }}
    
    <div class="form-group{{ $errors->has('amount') ? ' has-error' : '' }}">
        <label for="amount" class="col-md-4 control-label">Amount</label>
    
        <div class="col-md-6">
            <input id="amount" type="text" class="form-control" name="amount" value="{{ old('amount') }}" autofocus>
    
            @if ($errors->has('amount'))
                <span class="help-block">
                    <strong>{{ $errors->first('amount') }}</strong>
                </span>
            @endif
        </div>
    </div>
    
    <div class="form-group">
        <div class="col-md-6 col-md-offset-4">
            <button type="submit" class="btn btn-primary">
                Paywith Paypal
            </button>
        </div>
    </div>
</form>

以上既是我做商城项目时 PayPal 的对接流程,因为英语不好的问题,开发起来会出现很多问题,

如果英文好,想知道更多的用法,可以看 PayPal 的开发者文档,还有 demo 演示。


以上所述就是小编给大家介绍的《Laravel中集成PayPal》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Ruby

Programming Ruby

Dave Thomas、Chad Fowler、Andy Hunt / Pragmatic Bookshelf / 2004-10-8 / USD 44.95

Ruby is an increasingly popular, fully object-oriented dynamic programming language, hailed by many practitioners as the finest and most useful language available today. When Ruby first burst onto the......一起来看看 《Programming Ruby》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具