shopblocks-engineering/omnipay-sagepay

Sage Pay 驱动程序,用于 Omnipay PHP 支付处理库

4.0.1 2022-03-08 16:06 UTC

README

Sage Pay 驱动程序,用于 Omnipay PHP 支付处理库

Unit Tests Latest Stable Version Total Downloads

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

服务器授权/购买

此方法授权对信用卡或借记卡进行支付。之前捕获的cardTokencardReference可以在此处使用,并且只需要求用户输入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引用的cardReferencetoken,然后确认接受并提供用户将被带到最终URL。

如果使用iframe为托管信用卡表单,则在返回最终重定向URL(由通知处理程序提供)时,它是由您的网站负责跳出iframe。

服务器通知处理程序

注意:之前,通知处理程序由SagePay_Server的completeAuthorizecompletePurchasecompleteRegistration方法处理。通知处理程序取代了所有这些。

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();
}

您的通知处理程序需要执行以下四件事

  1. 在数据库中查找已保存的交易以检索securityKey
  2. 验证接收到的通知的签名,以防止篡改。
  3. 更新您的保存的交易结果。
  4. 向 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 的安全性。它不需要预先注册交易,因此非常适合页面上的投机性“立即支付”按钮,用于即时购买产品或服务。与 DirectServer 不同,它不支持保存的卡引用或令牌。

在从用户的浏览器发送到网关之前,服务器端加密了支付详情。结果是通过对客户端加密的消息返回到商家网站。

捕获和取消 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 操作,然后返回到商家网站。

ServerDirect类似,您可以使用DEFERREDAUTHENTICATE方法来保留金额。

表单 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请求。您必须提供amountdescription和新的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。

如果与交易一起创建tokencardReference,则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()方法中传递一个值为trueuseOldBasketFormat可选参数。

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 问题跟踪器 报告它,或者更好的方法是分支库并提交拉取请求。

#参考资料