graxmonzo / 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 许可),但如果它进入您的生产环境,您需要向我们寄送一张来自您家乡的明信片,说明您正在使用我们哪些包。
我们的地址是: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 是一家位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到所有开源项目的概述 在这里。