spatie / payment
Laravel 5 包,用于验证和接受支付网关的支付
Requires
- php: ^5.6|^7.0
- illuminate/support: ~5.1.0|~5.2.0
- illuminate/validation: ~5.1.0|~5.2.0
README
本包不再维护
接受支付网关的支付
此 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 是一家位于比利时的安特卫普网络设计公司。您可以在我们的网站上找到我们所有开源项目的概述 这里。