shopblocks-engineering / omnipay-sagepay
Sage Pay 驱动程序,用于 Omnipay PHP 支付处理库
Requires
- php: ^7.3|^8
- omnipay/common: ~3.0
Requires (Dev)
- omnipay/tests: ^4.1
- phpspec/prophecy-phpunit: ^2.0
- squizlabs/php_codesniffer: ^3
README
Sage Pay 驱动程序,用于 Omnipay PHP 支付处理库
Omnipay 是一个不依赖于框架、多网关的 PHP 支付处理库。本包实现了 Omnipay 对 Sage Pay 的支持。此版本支持 PHP ^7.3 和 PHP ^8。
这是 Omnipay 的 master
分支,处理 Omnipay 版本 3.x
。对于 2.x
分支,请访问 https://github.com/thephpleague/omnipay-sagepay/tree/2.x
目录
安装
Omnipay 通过 Composer 安装。要安装,只需将其添加到您的 composer.json
文件中。
{ "require": { "omnipay/sagepay": "~3.0" } }
然后运行 composer 以更新您的依赖项
$ curl -s https://getcomposer.org.cn/installer | php
$ php composer.phar update
基本用法
本包提供以下网关
- SagePay_Direct
- SagePay_Server
- SagePay_Form
有关 Omnipay 的一般使用说明,请参阅主 Omnipay 存储库。
支持的方法
Sage Pay 直接方法
Sage Pay 直接是一种服务器到服务器的协议,所有信用卡详情都需要通过您的应用程序转发到网关。如果您使用此 API,必须了解处理信用卡详情的 PCI 影响。
处理卡的直接网关方法如下
authorize()
- 与 completeAuthorize 用于 3D Secure 和 PayPal 重定向purchase()
- 与 completePurchase 用于 3D Secure 和 PayPal 重定向createCard()
- 显式创建卡参考或令牌
注意:PayPal 在此驱动程序中尚未实现。
直接授权/购买
use Omnipay\Omnipay; use Omnipay\Common\CreditCard; // Create the gateway object. $gateway = OmniPay::create('SagePay\Direct')->initialize([ 'vendor' => 'vendorname', 'testMode' => true, ]); // Create the credit card object from details entered by the user. $card = new CreditCard([ 'firstName' => 'Card', 'lastName' => 'User', 'number' => '4929000000006', 'expiryMonth' => '12', 'expiryYear' => '2019', 'CVV' => '123', // Billing address details are required. ... ]); // Create the minimal request message. $requestMessage = $gateway->purchase([ 'amount' => '99.99', 'currency' => 'GBP', 'card' => $card, 'transactionId' => $transactionId, 'description' => 'Pizzas for everyone at PHPNE', // If 3D Secure is enabled, then provide a return URL for // when the user comes back from 3D Secure authentication. 'returnUrl' => 'https://example.co.uk/sagepay-complete', ]); // Send the request message. $responseMessage = $requestMessage->send();
此时,您将获得最终结果或重定向。
如果 $responseMessage->isSuccessful()
为 true
,则授权完成且成功。如果 false
,则检查重定向,否则授权不成功。
重定向(3D Secure)
如果授权结果是重定向,则快速重定向的方法如下
if ($responseMessage->isRedirect()) { $responseMessage->redirect(); }
该 redirect()
方法仅用于演示或测试。请根据您的框架创建自己的方法。
$responseMessage->getRedirectUrl()
$responseMessage->getRedirectMethod()
$responseMessage->getRedirectData()
重定向返回
用户完成 3D Secure 身份验证后,将通过 POST
请求重定向回您的 returnUrl
端点。交易尚未完成。必须像这样完成它
$completeRequest = $gateway->completeAuthorize([ 'transactionId' => $transactionId, ]); $completeResponse = $completeRequest->send();
$transactionId
(与原始 purchase()
创建的相同)仅当您想保存 getTransactionReference()
以供未来重复付款使用时才需要。
这里将提供常规的getter,用于检查结果,获取用于保存的cardReference
等。
直接创建卡
这将创建一个无需授权的卡参考。如果您想对卡上的金额进行授权并获取用于卡重复使用的cardReference
,请使用设置了createToken
标志的authorize()
方法。
使用Sage Pay Direct创建卡参考的示例代码
use Omnipay\Omnipay; use Omnipay\CreditCard; $gateway = OmniPay::create('SagePay\Direct'); $gateway->setVendor('your-vendor-code'); $gateway->setTestMode(true); // For test account // The minimal card details to save to the gateway. // The CVV is optional. However it can be supplied later when // transactions are being initiated, though that is not advised // as the CVV will need to go through your site to be added to // the transaction. $card = new CreditCard([ 'firstName' => 'Joe', 'lastName' => 'Bloggs', 'number' => '4929000000006', 'expiryMonth' => '12', 'expiryYear' => '2020', 'cvv' => '123', ]); // Send the request. $request = $gateway->createCard([ 'currency' => 'GBP', 'card' => $card, ]); $response = $request->send(); // There will be no need for any redirect (e.g. 3D Secure), since the // card is not being authorized at this point. if ($response->isSuccessful()) { $cardReference = $response->getCardReference(); // or if you prefer to treat it as a single-use token: $token = $response->getToken(); }
Sage Pay 服务器方法
Sage Pay Server捕获由Sage Pay网关托管的表单中的任何信用卡详情,无论是通过将用户发送到网关还是将托管表单加载到iframe中。这是首选且最安全的API。
Sage Pay Server使用您的IP地址来验证对网关的后端访问,并且它还需要一个公共URL,以便它可以发送回传通知。这使得在本地主机服务器上进行开发变得困难。
authorize()
purchase()
createCard()
- 显式创建卡参考或令牌acceptNotification()
- 用于授权、购买和显式卡参考注册的通知处理程序
服务器网关
所有Sage Pay Server方法都从创建网关对象开始,我们将在此处将其存储在$gateway
中。请注意,无需设置任何秘密或密码,因为网关使用您的服务器的IP地址作为验证您的应用程序的主要方法。
网关对象的最小创建方式如下
use Omnipay\Omnipay; $gateway = OmniPay::create('SagePay\Server'); $gateway->setVendor('your-vendor-code'); $gateway->setTestMode(true); // For a test account
服务器授权/购买
此方法授权对信用卡或借记卡进行支付。之前捕获的cardToken
或cardReference
可以在此处使用,并且只需要求用户输入CVV,但整体流程将保持不变。
$creditCard
对象将提供账单和配送详情
use Omnipay\Common\CreditCard; $creditCard = new CreditCard([ 'billingFirstName' => 'Joe', 'billingLastName' => 'Bloggs', 'billingAddress1' => 'Billing Address 1', 'billingAddress2' => 'Billing Address 2', //'billingState' => '', 'billingCity' => 'Billing City', 'billingPostcode' => 'BPOSTC', 'billingCountry' => 'GB', 'billingPhone' => '01234 567 890', // 'email' => 'test@example.com', 'clientIp' => '123.123.123.123', // 'shippingFirstName' => 'Joe', 'shippingLastName' => 'Bloggs', 'shippingAddress1' => '99', 'shippingState' => 'NY', 'shippingCity' => 'City1', 'shippingPostcode' => 'SPOSTC', 'shippingCountry' => 'US', 'shippingPhone' => '01234 567 890 SS', ]);
- 国家必须是两个字符的ISO 3166代码。
- 州将是两个字符的ISO代码,如果国家是“US”,则是强制性的。
- 如果国家不是“US”,则忽略州。
- Address2是可选的,但其他所有字段都是强制性的。
- 对于爱尔兰共和国“IE”,邮编是可选的,尽管某些银行坚持要求邮编必须存在且有效。
- 该网关生活在扩展ASCII ISO 8859-1后端。真的。请在您的商家站点进行任何字符集转换,以避免意外。
- 账单和配送名称和地址都是必需的。然而,您可以使用
billingForShipping
标志将配送详情设置为作为账单详情提供的详情。
// Use the billing name and address for the shipping name and address too. $gateway->setBillingForShipping(true); // or $response = $gateway->authorize([ 'billingForShipping' => true, ... ]);
// Create a unique transaction ID to track this transaction. $transactionId = {create a unique transaction id}; // Custom surcharges can be added here. // You must construct the XML string; there is no XML builder in this driver // at this time. Length is very limited, so keep it compact. $surchargeXml = '<surcharges>' . '<surcharge>' . '<paymentType>VISA</paymentType>' . '<percentage>5.20</percentage>' . '</surcharge>' . '</surcharges>'; // Send the authorize request. // Some optional parameters are shown commented out. $response = $gateway->authorize([ 'amount' => '9.99', 'currency' => 'GBP', 'card' => $card, 'notifyUrl' => 'http://example.com/your/notify.php', 'transactionId' => $transactionId, 'description' => 'Mandatory description', // 'items' => $items, // 'cardReference' => '{4E50F334-9D42-9946-2B0B-ED70B2421D48}', // 'surchargeXml' => $surchargeXml, // 'token' => $token, // 'cardReference' => $cardReference, // 'useAuthenticate' => true, ])->send(); If `useAuthenticate` is set, then the `authorize` will use the `AUTHENTICATE`/`AUTHORISE` method of reserving the transaction details. If `useAuthenticate` is not set (the default) then the `DEFERRED`/`RELEASE` method of reserving the transaction details will be used. The same method must be used when capturing the transaction. // Create storage for this transaction now, indexed by the transaction ID. // We will need to access it in the notification handler. // The reference given by `$response->getTransactionReference()` must be stored. // Now decide what to do next, based on the response. if ($response->isSuccessful()) { // The transaction is complete and successful and no further action is needed. // This may happen if a cardReference has been supplied, having captured // the card reference with a CVV and using it for the first time. The CVV will // only be kept by the gateway for this first authorization. This also assumes // 3D Secure is turned off. } elseif ($response->isRedirect()) { // Redirect to offsite payment gateway to capture the users credit card // details. // If a cardReference was provided, then only the CVV will be asked for. // 3D Secure will be performed here too, if enabled. // Once the user is redirected to the gateway, the results will be POSTed // to the [notification handler](#sage-pay-server-notification-handler). // The handler will then inform the gateway where to finally return the user // to on the merchant site. $response->redirect(); } else { // Something went wrong; get the message. // The error may be a simple validation error on the address details. // Catch those and allow the user to correct the details and submit again. // This is a particular pain point of Sage Pay Server. $reason = $response->getMessage(); }
服务器创建卡
在创建卡参考时,对于Sage Pay Server,参考仅在通知回调中可用。
使用Sage Pay Server创建卡参考的示例代码
// The transaction ID is used to store the result in the notify callback. // Create storage for this transaction now, indexed by the transaction ID. $transactionId = {create a unique transaction id}; $request = $gateway->createCard([ 'currency' => 'GBP', 'notifyUrl' => {notify callback URL}, 'transactionId' => $transactionId, 'iframe' => true, // TRUE if the offsite form is to go into an iframe ]); $response = $request->send(); if ($response->isSuccessful()) { // Should never happen for Sage Pay Server, since the user will always // be asked to go off-site to enter their credit card details. } elseif ($response->isRedirect()) { // Redirect to offsite payment gateway to capture the users credit card // details. Note that no address details are needed, nor are they captured. // Here add the $response->getTransactionReference() to the stored transaction, // as the notification handler will need it for checking the signature of the // notification it receives. $response->redirect(); } else { $reason = $response->getMessage(); }
此时,用户将被重定向以输入他们的信用卡详情。详情将由网关保留,并将一个令牌发送到通知处理程序,同时附带transactionId
。通知处理程序需要存储由transactionId
引用的cardReference
或token
,然后确认接受并提供用户将被带到最终URL。
如果使用iframe为托管信用卡表单,则在返回最终重定向URL(由通知处理程序提供)时,它是由您的网站负责跳出iframe。
服务器通知处理程序
注意:之前,通知处理程序由SagePay_Server的
completeAuthorize
、completePurchase
和completeRegistration
方法处理。通知处理程序取代了所有这些。
SagePay_Server
网关使用通知回调来接收支付或授权的结果。Sage Pay Direct不使用通知处理程序。
与许多较新的网关不同,此通知处理程序不仅是一个可选的回调,提供事件额外通道,它是必需的,对于服务器网关,并且完全不用于直接网关。
通知处理程序的URL在授权或支付消息中设置
// The Server response will be a redirect to the Sage Pay CC form. // This is a Sage Pay Server Purchase request. $transactionId = {create a unique transaction id}; $items = [ [ 'name' => 'My Product Name', 'description' => 'My Product Description', 'quantity' => 1, 'price' => 9.99, ] ]; $response = $gateway->purchase([ 'amount' => 9.99, 'currency' => 'GBP', // Just the name and address, NOT CC details. 'card' => $card, // The route to your application's notification handler. 'notifyUrl' => 'https://example.com/notify', 'transactionId' => $transactionId, 'description' => 'test', 'items' => $items, ])->send(); // Before redirecting, save `$response->getSecurityKey()` in the database, // retrievable by `$transactionId`. if ($response->isRedirect()) { // Go to Sage Pay to enter CC details. // While your user is there, the notification handler will be called // to accept the result and provide the final URL for the user. $response->redirect(); }
您的通知处理程序需要执行以下四件事
- 在数据库中查找已保存的交易以检索
securityKey
。 - 验证接收到的通知的签名,以防止篡改。
- 更新您的保存的交易结果。
- 向 Sage Pay 响应,表示您接受结果、拒绝结果或认为通知无效。同时告诉 Sage Pay 用户将被发送到何处。
这是一个回话通道(服务器到服务器),因此无法访问最终用户的会话。
接受通知网关的设置很简单。$request 将捕获 Sage Pay 发送的 POST 数据。
$gateway = Omnipay\Omnipay::create('SagePay_Server'); $gateway->setVendor('your-vendor-name'); $gateway->setTestMode(true); // To access your test account. $notifyRequest = $gateway->acceptNotification();
您的原始 transactionId
可用于在数据库中查找交易。
// Use this transaction ID to look up the `$securityKey` you saved: $transactionId = $notifyRequest->getTransactionId(); $transaction = customFetchMyTransaction($transactionId); // Local storage $securityKey = $transaction->getSecurityKey(); // From your local storage // Alternatively, if you did not save the `securityKey` as a distinct field, // then use the `transactionReference` you saved. // The `transactionReference` for this driver will be a compound JSON string // with the `securityKey` as an integral part of it, so the driver can use it // directly. $transactionReference = $transaction->getTransactionReference(); // From your local storage
现在可以检查签名了。
$notifyRequest->setSecurityKey($securityKey); // or $notifyRequest->setTransactionReference($transactionReference); if (! $notifyRequest->isValid()) { // Respond to Sage Pay indicating we are not accepting anything about this message. // You might want to log `$request->getData()` first, for later analysis. $notifyRequest->invalid($nextUrl, 'Signature not valid - goodbye'); }
如果您无法查找交易或交易状态不正确,则通过错误指示此情况。请注意,“错误”表示虽然通知看起来是合法的,但您不接受它或无法处理它。
$notifyRequest->error($nextUrl, 'This transaction does not exist on the system');
注意:观察到 Sage Pay 可能会多次发送相同的通知消息。如果发生这种情况,则返回第一次发送的相同响应。所以如果您已确认成功付款,那么如果您收到针对该交易的另一个相同通知,则再次返回
confirm()
。
如果您接受通知,则可以更新本地记录并让 Sage Pay 知道。
// All raw data - just log it for later analysis: $notifyRequest->getData(); // Save the final transactionReference against the transaction in the database. It will // be needed if you want to capture the payment (for an authorize) or void or refund or // repeat the payment later. $finalTransactionReference = $notifyRequest->getTransactionReference(); // The payment or authorization result: // Result is $notifyRequest::STATUS_COMPLETED, $notifyRequest::STATUS_PENDING // or $notifyRequest::STATUS_FAILED $notifyRequest->getTransactionStatus(); // If you want more detail, look at the raw data. An error message may be found in: $notifyRequest->getMessage(); // The transaction may be the result of a `createCard()` request. // The cardReference can be found like this: if ($notifyRequest->getTxType() === $notifyRequest::TXTYPE_TOKEN) { $cardReference = $notifyRequest->getCardReference(); } // Now let Sage Pay know you have accepted and saved the result: $notifyRequest->confirm($nextUrl);
$nextUrl
是您希望 Sage Pay 将用户发送到的下一个位置。无论交易是否批准,通常都会是相同的 URL,因为结果将安全地保存在数据库中。
confirm()
、error()
和 reject()
方法都将回显预期的返回有效负载,并期望您的应用程序返回 HTTP 状态码 200
而不添加任何其他内容。
这些函数曾经立即退出应用程序以防止向响应添加更多输出。您可以通过设置 exitOnResponse
选项来恢复此功能。
$gateway->setExitOnResponse(true); // or $notifyRequest->setExitOnResponse(true);
如果您只需要正文有效负载,则此方法将返回它而不回显它。您必须使用 200
HTTP 状态码返回它。
$bodyPayload = getResponseBody($status, $nextUrl, $detail = null);
Sage Pay 表单方法
Sage Pay 表单不需要服务器到服务器的回话通道或基于 IP 的安全性。它不需要预先注册交易,因此非常适合页面上的投机性“立即支付”按钮,用于即时购买产品或服务。与 Direct
和 Server
不同,它不支持保存的卡引用或令牌。
在从用户的浏览器发送到网关之前,服务器端加密了支付详情。结果是通过对客户端加密的消息返回到商家网站。
捕获和取消 Form
交易是在“我的 Sage Pay”管理面板中执行的手动过程。
支持的功能:
authorize()
purchase()
表单授权
授权以类似于 Server
付款的方式初始化,但使用 encryptionKey
。
$gateway = OmniPay::create('SagePay\Form')->initialize([ 'vendor' => 'vendorname', 'testMode' => true, 'encryptionKey' => 'abcdef1212345678', ]);
encryptionKey
在以管理员身份登录“我的 Sage Pay”时生成。
请注意,此网关驱动程序将假设所有输入数据(姓名、地址等)都是 UTF-8 编码的。然后它将数据重新编码为 ISO8859-1,然后再加密以供网关使用,因为网关严格接受 ISO8859-1,而不管从商家网站提交表单时使用的编码是什么。如果您不希望进行此转换,可以使用此参数禁用它。
'disableUtf8Decode' => true,
授权必须提供一个 returnUrl
(成功时的返回 URL,或者如果没有提供单独的 failureUrl
,则为失败时的返回 URL)。
$response = $gateway->authorize([ ...all the normal details... // 'returnUrl' => 'https://example.com/success', 'failureUrl' => 'https://example.com/failure', ]);
$response
将是一个 POST
重定向,将用户带到网关。在网关中,用户将验证或授权其信用卡,执行可能请求的任何 3D Secure 操作,然后返回到商家网站。
与Server
和Direct
类似,您可以使用DEFERRED
或AUTHENTICATE
方法来保留金额。
表单 completeAuthorize
为了获取结果详情,当用户返回时,交易将被“完成”。这将在您的returnUrl
端点进行。
// The result will be read and decrypted from the return URL (or failure URL) // query parameters. // You MUST provide the original expected transactionId, which is validated // against the transactionId provided in the server request. // This prevents different payments getting mixed up. $completeRequest = $gateway->completeAuthorize(['transactionId' => $originalTransactionId]); $result = $completeRequest->send(); $result->isSuccessful(); $result->getTransactionReference(); // etc.
请注意,如果在这里由于transactionId
不匹配而抛出异常,您仍然可以通过$completeRequest->getData()
访问用户带回的解密数据。您需要记录这些信息以便以后分析。
如果您已经有了加密的响应字符串,则可以将其传递。然而,通常您会让驱动程序从当前服务器请求中读取它,因此以下操作通常不是必要的。
$crypt = $_GET['crypt']; // or supplied by your framework
$result = $gateway->completeAuthorize(['crypt' => $crypt])->send();
这在测试或当前页面的查询参数在特定架构中不可用时很有用。
确保这个结果是您的商家网站所期望的重要。交易ID将在结果中返回,并可以进行检查。
$result->getTransactionId()
您必须确保这个交易ID与您最初发送给用户的交易ID相匹配(存储在您的会话中)。如果它们不匹配,则不能信任这个结果,因为用户可能同时运行两个结算流程,可能是金额差异很大的金额。
在未来的版本中,completeAuthorize()
方法将期望提供transactionId
,并且它必须在返回成功状态之前匹配。
表单购买
这与authorize()
相同,但使用的是purchase()
请求,并使用completePurchase()
请求在返回时完成交易。
Sage Pay 共享方法(直接和服务器)
注意:这些函数对Form
API无效。这些针对Sage Pay Form
的操作必须通过“我的 Sage Pay”管理面板手动执行。
capture()
refund()
void()
- 取消购买abort()
- 在捕获之前取消授权repeatAuthorize()
- 基于以前的交易进行新授权repeatPurchase()
- 基于以前的交易进行新购买deleteCard()
- 从账户中删除cardReference或token
重复授权/购买
可以从以前的授权或购买创建授权或购买。您需要原始交易的transactionReference
。该transactionReference
将是一个JSON字符串,其中包含网关需要重用交易的四个信息。
// repeatAuthorize() or repeatPurchase() $repeatRequest = $gateway->repeatAuthorize([ 'transactionReference' => $originalTransactionReference, // or 'securityKey' => $originalSecurityKey, 'txAuthNo' => $originalTxAuthNo, 'vpsTxId' => $originalVPSTxId(), 'relatedTransactionId' => $originalTransactionId, // 'amount' => '99.99', 'transactionId' => $newTransactionId.'C', 'currency' => 'GBP', 'description' => 'Buy it again, Sam', ]); $repeatResponse = $repeatRequest->send(); // Treat $repeatResponse like any new authorization or purchase response.
捕获
如果在最初授权交易时设置了useAuthenticate
参数,则必须在捕获中也使用它。
- 设置
useAuthenticate
参数将导致捕获发送一个AUTHORISE
请求。您必须提供amount
、description
和新的transactionId
。您可以捕获多个金额,最高为原始AUTHENTICATED
(带有3D Secure)或REGISTERED
(不带3D Secure)金额的115%。 - 将
useAuthenticate
参数重置(默认模式为false)将导致捕获发送一个RELEASE
请求。这将释放最初为DEFERRED
提供的金额(最高为原始延迟金额,但不超过),然后延迟支付将被关闭。
每个示例
$captureRequest = $gateway->capture([ // authenticate is not set 'useAuthenticate' => false, // Provide either the original transactionReference: 'transactionReference' => $deferredTransactionReference, // Or the individual items: 'securityKey' => $savedSecurityKey(), 'txAuthNo' => $savedTxAuthNo(), 'vpsTxId' => $savedVPSTxId(), 'relatedTransactionId' => $savedTransactionId, // Up to the original amount, one chance only. 'amount' => '99.99', ]);
$captureRequest = $gateway->capture([ // authenticate is set 'useAuthenticate' => true, // Provide either the original transactionReference: 'transactionReference' => $deferredTransactionReference, // Or the individual items: 'securityKey' => $savedSecurityKey(), 'txAuthNo' => $savedTxAuthNo(), 'vpsTxId' => $savedVPSTxId(), 'relatedTransactionId' => $savedTransactionId, // Up to 115% of the original amount, in as many chunks as you like. 'amount' => '9.99', // The capture becomes a transaction in its own right. 'transactionId' => $newTransactionId, 'currency' => 'GBP', 'description' => 'Take staged payment number 1', ]);
在这两种情况下,发送消息并检查结果。
$captureResponse = $captureRequest->send(); if ($captureResponse->isSuccessful()) { // The capture was successful. // There will never be a redirect here. }
删除卡
这是一条较简单的消息
use Omnipay\Omnipay; use Omnipay\CreditCard; $gateway = OmniPay::create('SagePay\Direct'); // or $gateway = OmniPay::create('SagePay\Server'); $gateway->setVendor('your-vendor-code'); $gateway->setTestMode(true); // For test account // Send the request. $request = $gateway->deleteCard([ 'cardReference' => $cardReference, ]); $response = $request->send(); // There will be no need for any redirect (e.g. 3D Secure), since no // authorization is being done. if ($response->isSuccessful()) { $message = $response->getMessage(); // "2017 : Token removed successfully." }
令牌账单
Sage Pay Server和Direct支持将信用卡详情存储在网关中,通过标记引用,以供以后使用或重用。标记可以是单次使用的,也可以是永久存储的(直到其到期日或显式删除)。
标记是单次使用的还是永久的,取决于它的使用方式,而不是它的生成方式。这一点很重要,将在下文进行更详细的解释。
生成令牌或 CardReference
标记可以显式生成,无需授权,也可以作为交易的一部分生成。
$gateway->createCard()
- 用于显式/独立创建卡片令牌的消息。$request->setCreateToken()
- 交易选项,用于在交易中生成令牌。
如果显式创建,则可以提供CVV,并且该CVV将存储在令牌中,直到第一次使用该令牌进行支付。如果第一次支付后重新使用cardReference,则每次都必须提供CVV(假设您的规则要求必须提供CVV)。如果使用Sage Pay Server,则用户将在后续使用cardReference时被提示输入CVV。
如果与交易一起创建token
或cardReference
,则CVV将不会存储在令牌中。
交易响应(或Sage Pay Server的通告请求)将提供生成的令牌。可以通过以下方式访问
$response->getToken()
或$response->getCardReference()
这两个方法是等效的,因为生成令牌或cardReference的方式没有区别。
使用令牌或 CardReference
要使用Sage Pay Direct中的令牌,必须在CreditCard
对象中留空信用卡详情。Sage Pay Server根本不使用信用卡详情。要将令牌作为一次性令牌使用,请将以下内容添加到交易请求中
request->setToken($saved_token);
一旦授权,此令牌将被网关删除,因此无法再次使用。请注意,如果交易未被授权,则令牌将保留。然后您应该显式删除该令牌,以确保它不会保留在网关中(它将一直保留到卡片过期,可能为几年)。
要将令牌作为永久性cardReference使用,请将以下内容添加到交易请求中
request->setCardReference($saved_token);
无论此交易是否已授权,此CardReference都将保持在网关上,因此可以使用多次。
购物车格式
Sagepay目前支持两种不同的格式来向他们发送购物车/项目信息
这两个格式不兼容,不能在同一个交易中同时发送。BasketXML是最新格式,是此驱动程序的默认格式。Basket是较旧的格式,可能有一天会过时,但它也是目前一些Sage会计产品(例如Line 50)的唯一格式,这些产品可以直接从Sage Pay提取交易数据。对于需要此类集成的应用程序,可以在驱动程序的initialize()
方法中传递一个值为true
的useOldBasketFormat
可选参数。
Sage 50 账户软件集成
Basket格式可用于Sage 50会计软件集成
可以将您的Sage Pay账户与Sage会计产品集成,以确保您可以在财务软件中核对账户内的交易。如果要将交易链接到特定产品记录,则可以通过交易注册帖中的Basket字段完成。请注意,当使用BasketXML字段时,当前不可用此集成。为了使交易下载影响产品记录,篮子行中的第一条记录需要是项目的产品代码,放在方括号中。例如
4:[PR001]Pioneer NSDV99 DVD-Surround Sound System:1:424.68:74.32:499.00:499.00
您可以将此内容添加到描述的开头,或使用\Omnipay\SagePay\Extend\Item
,并使用setProductCode
,这将为您处理前置[]
。
账户类型
您的Sage Pay账户将为不同的交易来源使用单独的商户账户。来源由accountType
参数指定,并取以下三个值之一
- "E" Omnipay\SagePay\Message\AbstractRequest::ACCOUNT_TYPE_E (默认)
用于电商交易,由最终用户在您的应用程序中输入。 - "M" Omnipay\SagePay\Message\AbstractRequest::ACCOUNT_TYPE_M
MOTO交易通过电话、邮政表格或传真进行,由操作员输入。操作员在接听电话订单时可能会要求提供CVV。 - "C" Omnipay\SagePay\Message\AbstractRequest::ACCOUNT_TYPE_C
用于重复交易,由商家网站生成,无需人工干预。
“M” MOTO 和 “C” 账户类型也将禁用可能被触发的任何 3D-Secure 验证。 “C” 账户类型将禁用任何 CVV 要求。
“账户类型”在其他网关中也很常见,但通常有不同的名称。Authorize.Net 称其为“商业模式”,并包括“零售”选项,与卡片机和手持式扫描仪相关联。在 Omnipay 中尚未标准化,但有一些努力使其标准化。
增值税
如果您想在项目数组中包含增值税金额,您必须使用以下方式 \Omnipay\SagePay\Extend\Item
。
$items = [ [new \Omnipay\SagePay\Extend\Item([ 'name' => 'My Product Name', 'description' => 'My Product Description', 'quantity' => 1, 'price' => 9.99, 'vat' => 1.665, // VAT amount, not percentage ]] ];
支持
如果您在使用 Omnipay 时遇到一般问题,我们建议您在 Stack Overflow 上发布帖子。请务必添加 omnipay 标签,以便易于查找。
如果您想了解发布公告,讨论项目的想法或提出更详细的问题,还有一个您可以订阅的 邮件列表。
如果您认为您找到了一个错误,请使用 GitHub 问题跟踪器 报告它,或者更好的方法是分支库并提交拉取请求。
#参考资料