spatie/payment

此包已被废弃,不再维护。未建议替代包。

Laravel 5 包,用于验证和接受支付网关的支付

2.0.2 2016-05-03 12:13 UTC

This package is auto-updated.

Last update: 2020-02-16 08:04:36 UTC


README

本包不再维护

接受支付网关的支付

Latest Version Software License Total Downloads

此 Laravel 包允许您接受支付网关的支付。目前唯一的实现是 Europabank

Spatie 是一家位于比利时的安特卫普网络设计公司。您可以在我们的网站上找到我们所有开源项目的概述 这里

Postcardware

您可以使用此包(它是 MIT-licensed),但如果它进入您的生产环境,您需要从您家乡给我们寄一张明信片,说明您正在使用我们的哪个包。

我们的地址是:Spatie, Samberstraat 69D, 2060 安特卫普,比利时。

最好的明信片将被发布在我们的网站上开源页面。

安装

可以通过 Composer 安装此包

composer require spatie/payment

必须安装此服务提供者


//for laravel <=4.2: app/config/app.php

'providers' => [
    ...
    'Spatie\Payment\PaymentServiceProvider'
    ...
];

配置

您可以使用此命令发布配置文件

php artisan config:publish spatie/payment

一个包含一些合理默认值的配置文件将被放置在您的 config/packages 目录中

return
    [
        'form' =>
            [
                /*
                 * The class or classes that you want to put on the submit button
                 * of the payment form
                 */
                'submitButtonClass' => 'test'
            ],

        'europabank' =>
            [
                'clientSecret' => getenv('EUROPABANK_CLIENT_SECRET'),
                'serverSecret' => getenv('EUROPABANK_SERVER_SECRET'),

                /*
                 * MPI Account number
                 */
                'uid' => getenv('EUROPABANK_UID'),

                /*
                 * The url to where the payment will take place
                 */
                'mpiUrl' => '',

                /*
                 * The name of the route where Europabank will redirect to
                 * after the payment has been made
                 *
                 */
                'paymentLandingPageRoute' => 'verifyPayment',

                /*
                 * Optional url of the css which must be applied on the payment form
                 */
                'formCss'=> '',

                /*
                 * Url of the template which will be applied on  Europabank pages
                 */
                'template'=> '',

                /*
                 * Optional title of the payment form
                 */
                'formTitle' => '',

                /*
                 * Optional e-mail address of the merchant
                 */
                'merchantEmail' => '',

                /*
                 * Optional e-mail address to use as sender for the second chance
                 * or payment link e-mail
                 */
                'secondChanceEmailSender' => '',
            ]
    ];

通用支付流程

尽管有多种支付订单的方式,但大多数支付网关都要求您在结账过程中遵循以下流程

1. 客户被重定向到支付提供者

客户完成结账流程并准备支付后,必须将客户重定向到支付提供者的网站。

通过提交包含一些隐藏字段的表单来实现重定向。表单必须提交到支付提供者的网站。隐藏字段至少指定必须支付的金额、订单 ID 和哈希值。

哈希值是使用隐藏表单字段和非公开密钥计算得出的。支付提供者使用的哈希值用于验证请求是否有效。

2. 客户在支付提供者的网站上支付

客户到达支付提供者的网站,可以选择支付方式。支付订单所需的全部步骤都由支付提供者处理。

3. 客户被重定向回

支付订单后,客户将被重定向回。在重定向到商店网站的请求中,会返回一些值。这些值通常是订单ID、支付结果和哈希。

哈希是通过返回的字段和一些秘密的非公开值计算得出的。这个哈希用于验证请求是否有效,并且来自支付提供商。确保彻底检查这个哈希至关重要。

支付结果可能类似于“支付成功”、“客户取消支付”或“支付被拒绝”。

使用方法

此软件包可以帮助您处理一般流程中的第1步和第3步。

1. 将客户重定向到支付提供商

让我们来谈谈技术细节。在您将展示用于将用户重定向到支付提供商的视图的控制器中,您必须以这种方式注入支付网关:

use Spatie\Payment\PaymentGateway;

class CheckoutConfirmOrderController extends BaseController {


    /**
     * @var PaymentGateway
     */
    protected $paymentGateway;

    public function __construct(.. PaymentGateway $paymentGateway ...)
    {
        ...
        $this->paymentGateway = $paymentGateway;
        ...
    }

在同一个控制器中,在您展示视图的方法中,您必须设置$order,您可能在结账过程中构建了这个订单。

public function showOrderDetails()
    {
        $order = $this->orderRepo->getCurrentOrder();
        $paymentGateway = $this->paymentGateway->setOrder($order);

        return View::make('front.checkout.confirmOrder')->with(compact('order', 'paymentGateway'));
    }

您传递给支付网关的$order必须符合PayableOrder接口。


interface PayableOrder {

    /**
     * @return string
     */
    public function getPaymentOrderId();

    /**
     * @return double
     */
    public function getPaymentAmount();

    /**
     * @return string
     */
    public function getPaymentDescription();

    /**
     * @return string
     */
    public function getCustomerEmail();

    /**
     * @return string
     */
    public function getCustomerLanguage();


} 

因此,您的订单模型可能看起来像这样:

....
use Spatie\Payment\PayableOrder;

class Order extends Eloquent implements PayableOrder
{

...

    /**
     * @return string
     */
    public function getPaymentOrderId()
    {
        return $this->id;
    }

    /**
     * Should be in eurocents for most payments providers
     * @return double
     */
    public function getPaymentAmount()
    {
        return $this->getTotal() * 100;
    }

    /**
     * @return string
     */
    public function getPaymentDescription()
    {
        return 'Order ' . $this->id;
    }

    /**
     * @return string
     */
    public function getCustomerEmail()
    {
        return $this->email;
    }

    /**
     * @return string
     */
    public function getCustomerLanguage()
    {
        return App::getLocale();
    }
}

请注意,对于大多数支付提供商,getPaymentAmount()的结果应该指定为欧元分。

处理完上述所有步骤后,您可以生成将客户重定向到支付提供商的表单。

在您的视图中,您可以直接使用getPaymentForm()方法。

{{ $paymentGateway->getPaymentForm() }}

此表单的结果可能如下所示:

<form method="POST" action="https://www.ebonline.be/test/mpi/authenticate" accept-charset="UTF-8">
<input name="Uid" type="hidden" value="9063470101">
<input name="Orderid" type="hidden" value="11">
<input name="Amount" type="hidden" value="5163">
<input name="Description" type="hidden" value="Order 11">
<input name="Hash" type="hidden" value="dee1c95c13aa037ded1a97482be4d10cb9a25e92">
<input name="Beneficiary" type="hidden" value="Shopname">
<input name="Redirecttype" type="hidden" value="DIRECT">
<input name="Redirecturl" type="hidden" value="http://shopname.com/verify-payment">
<input type="submit" value="Pay order">
</form>

点击提交按钮后,客户将被重定向到支付提供商的网站。

您还可以将表单元素的HTML属性作为数组传递。

{{ $paymentGateway->getPaymentForm(['class' => 'form']) }}
<form method="POST" action="https://www.ebonline.be/test/mpi/authenticate" accept-charset="UTF-8" class="form">
<!-- ... -->
</form>

2. 验证支付

因此,现在我们已经将客户重定向到支付提供商。客户在那里执行了一些操作(希望他们支付了订单)然后被重定向回我们的商店网站。

支付提供商将客户重定向到配置文件中指定的paymentLandingPageRoute选项中指定的路由URL。

我们必须验证重定向到我们网站的请求是否有效(我们不希望冒充者错误地放置未支付的订单)。

在处理来自支付提供商的请求的控制器中注入PaymentGateway

use Spatie\Payment\PaymentGateway;

class CheckoutPaymentVerificationController extends BaseController {

    protected $paymentGateway;

    public function __construct(PaymentGateway $paymentGateway)
    {
        $this->paymentGateway = $paymentGateway;
    }
    
    ...

然后,在同一个控制器中,在您处理来自支付提供商的请求的方法中,使用validateGatewayResponse方法。

  public function verifyPayment()
    {
        $this->paymentGateway->validateGatewayResponse(Checkout::getCurrentOrderId());
    }

此方法需要您期望支付的订单ID。通常,您应该在将用户重定向到支付提供商的网站之前将订单ID存储在会话中。

请注意,在之前的示例中使用了Checkout::getCurrentOrderId()。如果您想查看这种优雅的语法,请查看spatie/checkout-package

如果validateGatewayResponse方法得出结论,请求不是有效的,将抛出Spatie\Payment\Exceptions\PaymentVerificationFailedException异常。

3. 获取支付结果

在您验证了从支付提供商到您网站的跳转有效后,您可以确定支付的结果。

要确定结果,您可以使用getPaymentResult()方法。它可以返回这些常量:

  • Spatie\Payment\PaymentGateway::PAYMENT_RESULT_OK:一切正常,订单已支付
  • Spatie\Payment\PaymentGateway::PAYMENT_RESULT_CANCELLED_BY_CARDHOLDER:客户已取消支付
  • Spatie\Payment\PaymentGateway::PAYMENT_RESULT_DECLINED:客户尝试支付,但他的支付被处理支付的金融机构拒绝
  • Spatie\Payment\PaymentGateway::PAYMENT_RESULT_FAILED:发生了意外错误。

以下是一个示例控制器,其中我们验证支付请求并确定结果

use Spatie\Payment\PaymentGateway;

class CheckoutPaymentVerificationController extends BaseController {

    protected $paymentGateway;

    public function __construct(PaymentGateway $paymentGateway)
    {

        $this->paymentGateway = $paymentGateway;
    }

    public function verifyPayment()
    {
        $this->paymentGateway->validateGatewayResponse(Checkout::getCurrentOrderId());

        switch($this->paymentGateway->getPaymentResult())
        {
            case PaymentGateway::PAYMENT_RESULT_OK:
                //take necessary actions to mark order as confirmed
                break;

            case PaymentGateway::PAYMENT_RESULT_CANCELLED_BY_CARDHOLDER:
                //take necessary actions to mark order as failed
                break;

            case PaymentGateway::PAYMENT_RESULT_DECLINED:
                //take necessary actions to mark order as failed
                break;

            case PaymentGateway::PAYMENT_RESULT_FAILED:
                //take necessary actions to mark order as failed
                break;

            case PaymentGateway::PAYMENT_TIMED_OUT:
                //take necessary actions to mark order as failed
                break;

            default:
                throw new Exception('Unknown payment gateway answer');
                break;

        }
    }
}

备注

目前唯一实现的网关提供者是Europabank。他们可以通过多种方式对支付给出反馈,但本包仅支持'DIRECT'重定向类型。

Europabank API提供的选项比本包目前提供的要多得多。

上述所有示例都是根据接口编写的:替换Europabank并使用其他提供者(如Ingenico)应该相当容易。您当然可以发送拉取请求以实现其他提供者。

关于Spatie

Spatie 是一家位于比利时的安特卫普网络设计公司。您可以在我们的网站上找到我们所有开源项目的概述 这里