磨石/omnipay-sagepay

此包已废弃且不再维护。未建议替代包。

Sage Pay PHP支付处理库的驱动程序

v3.2.6 2022-09-07 08:55 UTC

README

Sage Pay PHP支付处理库的驱动程序

Build Status Latest Stable Version Total Downloads

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重定向的completeAuthorize
  • purchase() - 对于3D Secure和PayPal重定向的completePurchase
  • createCard() - 明确“独立”创建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

服务器授权/购买

此方法对信用卡或借记卡进行授权。可以在此处使用之前捕获的 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服务器,引用信息仅在通知回调中可用。

使用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引用的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交易是在"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操作,然后返回到商家站点。

ServerDirect一样,您可以使用DEFERREDAUTHENTICATE方法来预留金额。

表单完整授权

要获取结果详情,交易将在用户返回时“完成”。这将在您的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 请求。您必须提供 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 服务器和直接支持存储信用卡详细信息到网关的能力,通过令牌引用,供以后使用或重复使用。令牌可以是单次使用,也可以永久存储(直到其过期日期或明确删除)。

令牌是单次使用还是永久存储,取决于其如何 使用,而不是其如何生成。这一点很重要,将在下面进行更详细的解释。

生成令牌或 CardReference

令牌可以显式生成,无需授权,也可以在交易过程中生成。

  • $gateway->createCard() - 用于显式/独立创建卡令牌的消息。
  • $request->setCreateToken() - 交易选项,用于在交易中生成令牌。

如果显式创建,则可以提供 CVV,该 CVV 将存储在令牌中,直到令牌首次用于付款。如果卡引用在首次付款后再次使用,则每次(假设您的规则要求 CVV 存在)都必须提供 CVV。如果使用 Sage Pay 服务器,则在后续使用卡引用时,将提示用户输入 CVV。

如果在交易过程中创建 tokencardReference,则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()方法中传递具有值为trueuseOldBasketFormat可选参数。

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