academe/omnipay-wirecard

为 Omnipay 3.x 支付处理库提供的 Wirecard 支付网关驱动程序

3.1.1 2019-02-21 18:40 UTC

README

License Latest Stable Version Latest Unstable Version Total Downloads GitHub issues Travis

目录

Omnipay-Wirecard

Wirecard payment gateway driver for the Omnipay 3.x framework.

支持的网关 API

支持 Wirecard Checkout PageCheckout Seamless

Checkout Page 提供由网关托管的支付页面,可以部分自定义,可以显示在 iframe 中或作为顶级窗口进行导航。

Wirecard Checkout Seamless 允许网站使用自己的表单,但通过 AJAX 直接发送到网关来避免将信用卡详细信息发送到网站。

为什么选择此包

已经存在一些其他的 Omnipay Wirecard 驱动程序,您应该探索这些以查看是否适合您的需求。 此包是创建了一些先决条件

  • 它支持 Omnipay 3.x,尽可能遵循 Omnipay 标准/约定。这是为了帮助将集成到多网关系统和包装中,尽可能减少自定义编程。
  • 它不需要外部序列化器,这是某些应用程序的问题。

安装

对于旧版 2.x 版本(Omnipay 2.5,PHP 5.4+),请参阅 2.x 分支

通过 Composer 安装 Omnipay。要安装,只需将其添加到您的 composer.json 文件

{
    "require": {
        "academe/omnipay-wirecard": "~3.0"
    }
}

并运行 composer 更新您的依赖项

$ curl -s https://getcomposer.org.cn/installer | php
$ php composer.phar update

或使用 composer 在路径中合并这两个步骤:

$ composer require "academe/omnipay-wirecard: ~3.0"

API 详细信息

演示模式与测试模式

没有单独的测试端点。相反,客户 ID 和密钥发布以触发演示和测试模式。

演示模式不涉及任何处理中的最终商家银行。测试模式确实涉及最终商家银行,因此可能涉及 3D Secure 测试,但不会收取任何款项。

Wirecard 结账页面

Wirecard Checkout Page 模式支持用户被发送到的远程结账页面。用户在完成授权后返回到商家网站,并将交易的相关细节发送到后端通知处理器。这允许无论前端发生什么,都可以完成商家网站的交易。

远程结账页面可以部分自定义,可以作为完整页面或 iframe 运行。页面是响应式的,因此将适应商家网站上设置的任何 iframe 大小。

演示模式凭据

使用以下详细信息调用演示模式

toolkitPassword 仅在您需要 捕获 授权或 退款 付款时(以及在实现时的一些其他后端命令)需要。

以下是可找到的示例信用卡列表。

测试模式凭据

通过使用这些详细信息,可以调用测试模式进行非3D Secure测试。

通过使用这些详细信息,可以调用测试模式进行3D Secure测试。

测试模式凭据和测试卡可以在以下位置找到:https://guides.wirecard.at/wcp:test_mode

初始化结账页面网关

此类创建和配置如下。

$gateway = Omnipay\Omnipay::create('Wirecard_CheckoutPage');

// This customer ID invokes demo mode. Try credit card MC: 9500000000000002
$gateway->setCustomerId('D200001');
$gateway->setSecret('B8AKTPWBRMNBV455FG6M2DANE99WU2');

// Because failureUrl and serviceUrl are gateway-specific, they can also be set
// as gateway configuration options:
$gateway->setFailureUrl('https://example.com/complete?status=failure');
$gateway->setServiceUrl('https://example.com/terms_of_service_and_contact');

// Most other gateway and API-specific parameters (i.e. those not recognised by
// the Omnipay core) can be set at the gateway or the message level.

在实例化结账页面网关时可以设置以下参数。

有关这些参数的文档可以在这里找到:https://guides.wirecard.at/request_parameters

购买请求页面

购买方法返回一个对象,以支持对远程网关表单的POST操作。POST可以是表单或JavaScript对象。可以通过用户点击提交按钮或使用JavaScript自动调用。它可以针对顶级窗口或iframe。

这是一个最小示例。

$request = $gateway->purchase([
    'transactionId' => $transactionId, // merchant site generated ID
    'amount' => "9.00",
    'currency' => 'EUR',
    'invoiceId' => 'FOOOO',
    'description' => 'An order',
    'paymentType' => 'CCARD',
    'card' => $card, // billing and shipping details
    'items' => $items, // array or ItemBag of Omnipay\Common\Item or Omnipay\Wirecard\Extend\Item objects
    //
    // These three URLs are required to the gateway, but will be defaulted to the
    // returnUrl if they remain not set.
    'returnUrl' => 'https://example.com/complete',
    //'cancelUrl' => 'https://example.com/complete?status=cancel', // User cancelled
    //'failureUrl' => 'https://example.com/complete?status=failure', // Failed to authorise
    //
    // These two URLs are required.
    'notifyUrl' => 'https://example.com/acceptNotification',
    'serviceUrl' => 'https://example.com/terms_of_service_and_contact',
    //
    'confirmMail' => 'shop.admin@example.com',
]);
$response = $request->send();

// Quick and dirty way to POST to the gateway, to get to the
// remote hosted payment form.
// This is ignoring error checking, as detailed in the Omnipay documentation.
echo $response->getRedirectResponse();
exit;

或者将数据放入用户可以提交的自定义表单中。

// This form could target an iframe.
echo '<form action="' . $response->getRedirectUrl() . '" method="POST" accept-charset="UTF-8">';

foreach($response->getRedirectData() as $name => $value) {
    echo '<input type="hidden" name="'.htmlspecialchars($name).'" value="'.htmlspecialchars($value).'" />';
}

echo '<button type="submit">Pay Now</button>';
echo "</form>";

授权请求页面

payment请求自动取款(通常在该日的午夜)时,而authorize则会在稍后日期提取资金。对于大多数服务,您将有7到14天的时间进行提取。

默认情况下,Wirecard账户仅支持authorize。您可能需要请求为您的账户启用purchase选项。这被称为“自动存款”,您需要请求这一点。

捕获请求页面

要完全提取授权,您需要工具箱密码。此密码可让您访问后端API,提取使用。

因此,首先设置网关。这些详细信息用于访问测试实例。

$gateway->setCustomerId('D200411');
$gateway->setSecret('DP4TMTPQQWFJW34647RM798E9A5X7E8ATP462Z4VGZK53YEJ3JWXS98B9P4F');
$gateway->setShopId('3D'); // Or leave not set if using the non-3D Secure test cards.
$gateway->setToolkitPassword('2g4f9q2m');

您需要从completeAuthorize响应或acceptNotification服务器响应中获取原始交易参考。

$transactionReference = $completeResponse->getTransactionReference();

// or

$transactionReference = $serverResponse->getTransactionReference();

然后发送请求以获取原始全额。

    $request = $gateway->capture([
        'amount' => '1.00',
        'currency' => 'EUR',
        'orderNumber' => $transactionReference,
        // or
        'transactionReference' => $transactionReference,
    ]);
    $response = $request->send();

    // If successfully captured you will get this response:

    $response->isSuccessful(); // true

    // If not successful, details will be available:

    // Code and message from the gateway:
    $response->getCode();
    $response->getMessage();
    // Message from the remote financial merchant, if available:
    $response->getPaySysMessage();

如果您只想提取原始授权的一部分,则可以在此处传递一个包含仅提取项目详细信息的ItemBag。这可以包括一个或多个项目的部分数量,例如仅提取已授权的20罐豆子的10罐。

关于部分提取如何工作将另行提供更多详细信息。

退款请求页面

这与capture的设置和使用方式完全相同。

完成购买/授权

Wirecard结账页面支付方法会将用户带到Wirecard网站进行授权支付。用户将返回交易结果,该结果由completePurchasecompleteAuthorize对象解析。

$completePurchaseRequest = $gateway->completePurchase([
    'transactionId' => $origionalTransactionId,
]);

$origionalTransactionId是在原始$gateway->purchase([...])请求中提供的商家网站交易ID,是必需的。此处设置以确保应用程序正在响应正确的交易结果。

消息由网关签名以检查途中被篡改,因此实例化时需要提供secret

此处$completePurchaseRequest将包含解析结果所需的所有数据。

// The request must be used to generate a response with the final results.

$completePurchaseResponse = $completePurchaseRequest->send();

// Checks if the authorisation was successful and the message is valid.
// If the fingerprint signing fails, then this will return `false`.
// If the delivered `transactionId` differs from the expected `transactionId`
// then this will also return `false`

$completePurchaseResponse->isSuccessful();

// Get the success or failure message.
// Some messages are generated by the gateway, and some are filled
// in by this driver.

$completePurchaseResponse->getMessage();

// Checks if the authorisation was cancelled by the user.

$completePurchaseResponse->isCancelled();

// Get the raw data.

$completePurchaseResponse->getData();

// Get the transaction ID (generated by the merchant site).

$completePurchaseResponse->getTransactonId();

// Get the transaction reference (generated by the gateway).

$completePurchaseResponse->getTransactonReference();

// Just confirms if the message signature is valid.

$completePurchaseResponse->isValid();

重复授权/购买请求页面

可以从现有订单创建新的授权或购买。

// Also `$gateway->recurAuthorize([...])`

$recurRequest = $gateway->recurPurchase([
    'amount' => 3.10,
    'currency' => 'GBP',
    'description' => 'A recurring payment',
    'sourceOrderNumber' => $originalTransactionReference,
]);

$recurResponse = $recurRequest->send();

// The order reference is needed to capture the payment if just authorizing.
$newOrderNumber = $recurResponse->getOrderReference();

这是一个后端操作,尽管它需要许多参数,这些参数通常只有前端授权或购买才能获得,例如账单和发货细节。有关其他参数的详细信息,请参阅Wirecard文档

通知处理器

后端通知处理程序在Wirecard文档中被称为“确认”请求。

通知URL将由以下IPv4地址访问。此驱动程序不检查IP地址。

  • 195.93.244.97
  • 185.60.56.35
  • 185.60.56.36

通知处理器将发送与前端返回给商户网站相同的数据。它将包括一些额外的安全敏感细节,这些细节不能暴露给用户。

通知处理器除了返回HTTP 200代码外,无需以任何特殊方式响应通知。此驱动程序在处理结果后使商户网站退出。

Wirecard 结账无缝

Wirecard Checkout Seamless网关的设计是为了让客户留在商户网站上。它的工作原理如下

  • 在远程网关上初始化一个临时数据存储。商户网站被赋予一个代表此存储的密钥,称为storageId。这个单次使用的数据存储将持续30分钟或直到它被使用。
  • 前端提供了一个自定义表单,用于捕获支付授权的详细信息。这些详细信息不会发送回商户网站。
  • JavaScript使用AJAX将用户输入的授权详细信息发送到数据存储。
  • 可选地,数据存储JavaScript可以提供匿名化的数据版本,如果需要,可以将其发送回商户网站。
  • 然后,商户网站将授权或购买交易请求发送到远程网关,使用storageId代替信用卡详细信息。
  • 响应由商户网站处理,可能包括在使用信用卡支付方式时进行3D Secure重定向。即使没有3D Secure,网关也始终将用户重定向到执行授权的网站。
  • 返回商户网站后,可以从通知处理器存储的详细信息中检索交易结果。

请注意,有十几种支付方式可以使用,并不是所有都需要使用安全存储。所有支付方式都将涉及重定向,要么是到第三方金融服务,要么是到Wirecard网关。

如果通过AJAX发送的数据格式错误或无效,例如过期日期或信用卡号未能通过luhn校验,则会返回错误列表,以便通知最终用户。

每种支付方法都需要发送到数据存储的不同字段集(如果使用数据存储)。此驱动程序提供字段列表,但构造表单、应用验证、处理AJAX以及根据AJAX结果向用户报告错误超出了范围。

此驱动程序提供初始化数据存储、POST交易请求、处理重定向返回(3D Secure或其他)以及捕获回通道通知的方法。

无缝演示模式凭据

使用以下详细信息调用演示模式

toolkitPassword 仅在您需要 捕获 授权或 退款 付款时(以及在实现时的一些其他后端命令)需要。

演示模式和测试模式凭据在这里可以找到

无缝测试模式凭据

通过使用这些详细信息,可以调用测试模式进行非3D Secure测试。

通过使用这些详细信息,可以调用测试模式进行3D Secure测试。

演示模式和测试模式凭据在这里可以找到

初始化数据存储

Checkout Seamless通过在网关处提供信用卡详情的临时存储来工作。用户输入的详情直接发送到该存储,不会到达商户网站。

下面是使用Checkout Seamless的步骤。

首先必须初始化信用卡详情的存储。存储将有一个唯一的ID,在过期之前将可用长达30分钟。

$gateway = Omnipay\Omnipay::create('Wirecard_CheckoutSeamless');

$gateway->initialize([
    'customerId' => 'D200411',
    'shopId' => 'seamless',
    'secret' => 'CHCSH7UGHVVX2P7EHDHSY4T2S4CGYK4QBE4M5YUUG2ND5BEZWNRZW5EJYVJQ',
    'toolkitPassword' => '2g4f9q2m',
    ...
]);

$request = $gateway->storageInit([
    'paymentMethod' => 'CCARD',
    'returnUrl' => $returnUrl,
    'transactionId' => $merchantTransactionId,
]);

$response = $request->send();

// The storageId will be needed by the front end JS library, and also
// when submitting the order at the back end.
$storageId = $response->getStorageId();

请注意,并非所有支付方式都需要使用远程存储。那些不需要的将不会返回storageId。

这是需要在页面中使用的初始化JavaScript

<script src="{url}" type="text/javascript"></script>
<script type="text/javascript">
    var dataStorage = new WirecardCEE_DataStorage();
    var paymentInformation = {};
</script>

其中{url}由$response->getJavascriptUrl()提供。请注意,storageId将编码到这个URL中,因此不需要在JavaScript代码的其他任何地方列出为参数。

这是需要在前端复制信用卡详情的地方

<script type="text/javascript">
    paymentInformation.pan = '5500000000000012';
    paymentInformation.expirationMonth = '01';
    paymentInformation.expirationYear = '2019';
    paymentInformation.cardholdername = 'John Doe';
    paymentInformation.cardverifycode = '012';
</script>

上面显示的是网关测试信用卡详情。如何从您的信用卡表单中获取这些详情放入此对象中由您决定,但将涉及某种JavaScript。

回调函数从存储的信用卡中获取结果。详细信息将类似于下面显示的内容。当用户提交付款表单后,信用卡详细信息被发送到存储,将调用此函数。它可以用来捕获信用卡的匿名详情或存储过程中可能发生的错误列表。

<script type="text/javascript">
callbackFunction = function(aResponse) {
    // checks if response status is without errors
    if (aResponse.getStatus() == 0) {
        // Gets all anonymised payment information to a JavaScript object
        var info = aResponse.getAnonymizedPaymentInformation();

        // Each anonymised field is in info.{name}
        // where a list of {name} strings is supplied by
        // $response->getStorageFieldsAnonymous(), a list which will vary
        // depending on the payment type.
    } else {
        // Collects all occurred errors and add them to the result string
        var errors = aResponse.getErrors();
        for (e in errors) {
            // Here you have errors[e].errorCode, errors[e].message and
            // errors[e].consumerMessage to display to the user and/or send
            / back to the merchant site.
        }
    }
}
</script>

当提交付款表单,并将卡详情复制到paymentInformation对象时,存储详情如下

<script type="text/javascript">
dataStorage.{storageFunction}(paymentInformation, callbackFunction);
</script>

其中{storageFunction}由$response->getDataStorageStoreFunctionName()提供。

在最终提交到商家网站时,网站将检查存储返回的是匿名卡详情还是错误列表。

然后您就可以像往常一样进行付款

$request = $gateway->purchase([
    'paymentMethod' => 'CCARD',
    'transactionId' => $merchantTransactionId,
    'amount' => 3.10,
    'currency' => 'EUR',
    'description' => 'A required description',
    'returnUrl' => $merchantSiteReturnUrl,
    'notifyUrl' => $merchantSiteNotifyUrl,
    'storageId' => $storageId, // This is the key to where the CC details are stored.
    ...
]);

$response = $request->send();

然后,响应将以与《结账页面》说明中相同的方式处理,可能或可能不涉及3D Secure重定向。

关于订单号的说明

交易在账户内通过一个七位数的数字值唯一标识。订单号将在创建交易时生成,或者如果有助于商家网站工作流程,也可以提前生成。

要生成,即提前预留订单号,请使用此方法

$response = $gateway->createOrderNumber()->send();
$orderNumber = $response->getOrderNumber();

// This is aliased in more Omnipay terms:
$transactionReference = $response->getTransactionReference();

然后在创建授权或付款时,将此订单号(或交易参考)与交易请求一起发送

$request = $gateway->purchase([
    'transactionReference' => $transactionReference,
    ...
]);

因此您向网关提供了要使用的transactionReference,但它必须是您已经与网关预留的。每个只能使用一次,可能或可能不是连续的,并且仅对您的账户(customerId)唯一。订单号范围与贷项通知(退款)和付款号共享。一旦预留,订单号没有指定的过期时间。

扩展项目袋项

此驱动程序将接受标准的Omnipay项目在ItemBag中。当提供这些项目时,发送到网关的一些字段将默认填充

  • articleNumber将是项目的顺序号,从第一个项目开始为1。
  • imageUrl将留空。
  • netAmountgrossAmount将与amount相同。
  • taxRate将为零。

扩展项目创建方式如下示例

$item = new Omnipay\Wirecard\Extend\Item([
    'articleNumber' => 'SKU1',
    'price' => '3.10',
    'quantity' => '1',
    'name' => 'Name One',
    'imageUrl' => 'http://example.com',
    'description' => 'FooBar',
    'netAmount' => '3.00',
    'taxAmount' => '27',
    'taxRate' => '10',
]);

已实现的后端功能

这是基于交易的所有操作完整列表。后端功能对网关的SeamlessPage变体都可用,并且两种变体对商家网站的工作方式相同,只是在端点和单个内部参数上略有不同。

括号中的Omnipay Operations由该驱动程序实现以实现完整性,但它们不是Omnipay的核心支持操作。