mmockelyn/payment

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

1.0.1 2022-12-16 03:36 UTC

This package is not auto-updated.

Last update: 2024-09-21 10:00:44 UTC


README

本包不再维护

接受支付网关支付

Latest Version Software License Total Downloads

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

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

Postcardware

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

我们的地址是: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 是一家位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到所有开源项目的概述 在这里