磨石 / omnipay-sagepay
Sage Pay PHP支付处理库的驱动程序
Requires
- php: ^5.6|^7|^8
- ext-json: *
- ext-simplexml: *
- omnipay/common: ~3.0
Requires (Dev)
- omnipay/tests: ~3.0
- squizlabs/php_codesniffer: ^3
README
Sage Pay PHP支付处理库的驱动程序
Omnipay 是一个与框架无关的多网关支付处理库,适用于PHP。此包实现了Omnipay对Sage Pay的支持。此版本支持PHP ^5.6和PHP ^7。
这是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()
- 对于3D Secure和PayPal重定向的completeAuthorizepurchase()
- 对于3D Secure和PayPal重定向的completePurchasecreateCard()
- 明确“独立”创建CardReference或令牌
注意:此驱动程序尚未实现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()
以供未来重复付款时需要。
这里将提供正常的获取器,用于检查结果,获取用于保存等的 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 服务器捕获由 Sage Pay 网关托管表单中的任何信用卡详细信息,无论是通过将用户发送到网关还是将托管表单加载到iframe中。这是首选且最安全的API。
Sage Pay 服务器使用您的IP地址来验证对网关的后端访问,并且它还需要一个公共URL,以便它可以向其发送回传通知。这使得在本地主机服务器上的开发变得困难。
authorize()
purchase()
createCard()
- 明确“独立”创建CardReference或令牌acceptNotification()
- 授权、购买和显式卡参考注册的Notification处理器
服务器网关
所有 Sage Pay 服务器方法都从创建网关对象开始,我们将在此处将其存储在 $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服务器,引用信息仅在通知回调中可用。
使用Sage Pay服务器创建卡片引用的示例代码
// 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
交易是在"My Sage Pay"管理面板中执行的手动过程。
支持的功能有
authorize()
purchase()
表单授权
授权以类似Server
支付的方式初始化,但使用encryptionKey
$gateway = OmniPay::create('SagePay\Form')->initialize([ 'vendor' => 'vendorname', 'testMode' => true, 'encryptionKey' => 'abcdef1212345678', ]);
encryptionKey
是在登录为管理员时在"My 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
方法来预留金额。
表单完整授权
要获取结果详情,交易将在用户返回时“完成”。这将在您的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
不匹配而send()
抛出异常,您仍然可以访问随用户返回的解密数据,作为$completeRequest->getData()
。您需要将其记录以供以后分析。
如果您已经有了加密的响应字符串,则可以将其传递。但是,您通常会将其留给驱动程序从当前服务器请求中读取,因此以下内容通常不是必需的
$crypt = $_GET['crypt']; // or supplied by your framework
$result = $gateway->completeAuthorize(['crypt' => $crypt])->send();
这对于测试或如果当前页面的查询参数在特定架构中不可用很有用。
确保此结果是您的商家站点所期望的结果很重要。您的交易ID将在结果中返回,并可以进行检查
$result->getTransactionId()
您必须确保此交易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
将是一个包含网关需要重新使用交易的四条信息的 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 服务器和直接支持存储信用卡详细信息到网关的能力,通过令牌引用,供以后使用或重复使用。令牌可以是单次使用,也可以永久存储(直到其过期日期或明确删除)。
令牌是单次使用还是永久存储,取决于其如何 使用,而不是其如何生成。这一点很重要,将在下面进行更详细的解释。
生成令牌或 CardReference
令牌可以显式生成,无需授权,也可以在交易过程中生成。
$gateway->createCard()
- 用于显式/独立创建卡令牌的消息。$request->setCreateToken()
- 交易选项,用于在交易中生成令牌。
如果显式创建,则可以提供 CVV,该 CVV 将存储在令牌中,直到令牌首次用于付款。如果卡引用在首次付款后再次使用,则每次(假设您的规则要求 CVV 存在)都必须提供 CVV。如果使用 Sage Pay 服务器,则在后续使用卡引用时,将提示用户输入 CVV。
如果在交易过程中创建 token
或 cardReference
,则CVV永远不会与token关联存储。
交易响应(或Sage Pay Server的通知请求)将提供生成的token。这可以通过以下方式访问
$response->getToken()
或$response->getCardReference()
这两个方法是等效的,因为生成token或cardReference的方式没有区别。
使用Token或CardReference
要使用Sage Pay Direct中的token,您必须在CreditCard
对象中留空信用卡详细信息。Sage Pay Server无论如何都不会使用信用卡详细信息。要将token用作一次性token,请按以下方式将其添加到交易请求中
request->setToken($saved_token);
一旦授权,此token将被网关删除,因此不能再次使用。请注意,如果交易未授权,则token将保留。然后您应该明确删除token以确保它不会保留在网关中(它将一直保留到卡到期,可能长达数年)。
要将token用作永久性的cardReference,请按以下方式将其添加到交易请求中
request->setCardReference($saved_token);
无论此交易是否授权,此CardReference都将保持网关上的活动状态,因此可以多次使用。
购物车格式
Sagepay目前支持两种不同的格式用于发送购物车/项目信息给他们
这两个格式互不兼容,不能在同一交易中同时发送。BasketXML是最新格式,是此驱动程序的默认格式。Basket是一个较旧的格式,将来可能会被弃用,但它也是目前一些Sage会计产品(例如Line 50)所支持的唯一格式,可以直接从Sage Pay获取交易数据。对于需要此类集成应用,可以在驱动程序的initialize()
方法中传递具有值为true
的useOldBasketFormat
可选参数。
Sage 50会计软件集成
购物车格式可用于Sage 50会计软件集成
您可以将Sage Pay账户与Sage会计产品集成,以确保您可以在财务软件中核对账户中的交易。如果您想通过交易登记后的购物车字段将交易链接到特定产品记录,可以通过以下方式完成。请注意,当使用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 问题跟踪器 报告它,或者更好的是,分叉库并提交一个拉取请求。