mmockelyn / payment
一个用于验证和接受支付网关支付的 Laravel 5 包
Requires
- php: ^8.0
- illuminate/support: ^9.0
- illuminate/validation: ^9.0
This package is not auto-updated.
Last update: 2024-09-21 10:00:44 UTC
README
本包不再维护
接受支付网关支付
此 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 是一家位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到所有开源项目的概述 在这里。