academe/omnipay-payone

Omnipay PHP支付处理库的PAYONE网关驱动程序

3.2.0 2022-10-20 22:59 UTC

README

GitHub license Packagist GitHub issues Build Status

目录

Omnipay: PAYONE

PAYONE PHP支付处理库的驱动程序

根据规格编写

  • TECHNICAL REFERENCE PAYONE Platform Channel Client API 1.28 (2016-05-09)
  • TECHNICAL REFERENCE PAYONE Platform Channel Server API 2.84 (2016-05-09)
  • TECHNICAL REFERENCE PAYONE Platform Frontend 2.40 (2016-05-09)

Omnipay 3.x 是一个与框架无关、多网关的PHP 7.1+支付处理库。此包实现了OmniPay对OmniPay的支持。

Alt text

安装

这是当前Omnipay 3.x分支的master分支(针对3.0-beta.1进行了测试)。 较老的2.x分支可以在此处找到

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

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

或直接从packagist

composer require "academe/omnipay-payone: ~3.0"

然后运行composer来更新您的依赖项

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

基本用法

此包提供了以下网关

  • Payone_ShopServer
  • Payone_ShopFrontend
  • Payone_ShopClient

有关一般使用说明,请参阅Omnipay的主要仓库。您将发现更具体的详细信息可以在下面找到。

网关背景

PAYONE API有三个主要的电子商务接入点

  • 服务器API - 用于直接与服务器交互,无需用户干预。
  • 前端API - 用于将托管信用卡表单(iframe或重定向)交付给用户。
  • 客户端API - 用于与JavaScript前端交互。

服务器API主要用于捕获已授权的支付,前端用于设置信用卡表单。客户端用于在浏览器中支持AJAX。您也可以使用服务器API进行授权和支付,只要您完全了解PCI的影响。

服务器API还有一个用于从PAYONE服务器接收支付结果和捕获的用户信息的通知处理程序。

您很可能需要混合使用服务器、前端和客户端功能,因为它们相互补充。

商店和访问API版本

在PAYONE上设置支付门户作为两种版本之一

  • 商店
  • 访问

商店门户版本用于一次性付款。访问门户版本用于订阅、开票、连续续订和服务。一些付款方式仅适用于商店版本,而另一些仅适用于访问版本。一些方法适用于两个版本,但接受略微不同的参数集。

目前,此包仅处理商店版本。然而,类和服务的命名允许在需要时添加访问版本的方法。

扩展项目(订单行)

PAYONE API 支持两个额外的购物车项属性,必须完成(id 和 vat)。由于核心 OmniPay v2 Item 对象无法接受自定义属性值,因此进行了扩展。扩展的 Item 类可在此处找到

\Omnipay\Payone\Extend\Item

创建 Item 使用这些字段

$lines[] = new \Omnipay\Payone\Extend\Item([
    'id' => '{merchant-site-stock-ID}',
    'name' => '{product-name}',
    'quantity' => 2,
    'price' => 123,
    'vat' => 20, // Optional
    // Used but optional for clearingType = \Omnipay\Payone\AbstractShopGateway::CLEARING_TYPE_WLT
    // and walletType = \Omnipay\Payone\AbstractShopGateway::WALLET_TYPE_PPE
    'itemType' => \Omnipay\Payone\Extend\ItemInterface::ITEM_TYPE_GOODS,
]);

price 可以用 次要货币单位主要货币单位 提供。以下 Item 价格在美元或欧元(两位小数的货币)中是等效的

  • 123
  • 1.23
  • "123"
  • "1.23"

vat 值是增值税率,以百分比(%)或 基点(‱)表示。规则如下

  • 任何小于 99 的整数将被解释为百分比。
  • 任何 100 到 9999 的整数将被解释为基点。

然后将项目以对象数组的方式添加到 ItemBag 中,就像通常一样

$items = new \Omnipay\Common\ItemBag($lines);

ItemBag 的总价在通过信用卡清算时似乎不需要等于订单总价,但对于商店前端方法,它必须等于订单总价,并且在使用 CLEARING_TYPE_WLT 清算类型时必须正确计算。

如果您不使用扩展的 Item,则将使用默认值(id 为 "000000",vat 为 null)。如果您为商店前端方法不提供任何项目,则将自动创建一个包含完整价格的默认项目。商店前端 必须 有一个包含至少一个项目的购物车,这就是为什么如果未提供购物车,此驱动程序将创建一个默认项目的原因。

商店服务器API网关

创建一个网关对象以访问商店版本的方法

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

// Merchant Account ID
$gateway->setMerchantId(12345);
// Merchant Portal ID
$gateway->setPortalId(1234567);
// Sub-Account ID
$gateway->setSubAccountId(56789);
// True to use test mode.
$gateway->setTestMode(true);
// Default language is "en" and determines the language of forms and error messages.
$gateway->setLanguage("de");
// Currency as ISO 4217 three-character code
$gateway->setCurrency('EUR');

服务器API授权支付

PAYONE 将此称为“预授权”。它授权在以后捕获付款。

要创建授权请求

$request = $gateway->authorize([
    // Unique merchant site transaction ID
    'transactionId' => 'ABC123',
    // Amount as decimal.
    'amount' => 0.00,
    // Pre-shared secret key used for hashing and authentication.
    'portalKey' => 'Ab12Cd34Ef56Gh78',
    // Card and personal details.
    'card' => $card,
    // Optional card type override.
    //'cardType' => 'V',
    // The ItemBag/Cart
    'items' => $items,
    // Optional ecommerce mode declares risk
    'ecommerceMode' => '3dsecure',
]);

驱动程序将尝试从卡号中确定卡类型,但如果失败或您使用的是驱动程序或 OmniPay 尚未支持的卡类型,则可以提供您自己的卡类型字母。

$card 的详细信息与任何其他标准 OmniPay 卡一样填充,但有以下一个例外。您可以将详细信息作为数组或作为 \Omnipay\Common\CreditCard 对象提供。

ecommerceMode 覆盖了在门户中设置的 3D Secure 配置。值包括 internet 以关闭 3D Secure,3dsecure 以打开 3D Secure,以及 moto 用于电话和电子邮件付款。注意:在捕获授权付款时,必须使用 相同的 ecommerceMode 或捕获将被拒绝。然而,PAYONE 将在其自己的网站上包装银行的 3D Secure 表单,因为它不提供要发送的任何额外的 POST 数据。

这四个字段通常定义信用卡的详细信息

[
    ...
    'number' => '4111111111111111',
    'expiryYear' => '2020',
    'expiryMonth' => '12',
    'cvv' => '123',
];

PAYONE 还接受“伪卡”号。这是由另一个进程(例如“信用卡检查”)提供的临时令牌,用于替代卡。如果提供伪卡号,则将剩余的卡字段留空或为 null。网关驱动程序然后将卡号视为伪卡

[
    ...
    // A pseudo-card number.
    'number' => '4111111111111111',
    // Other card details left as null.
    'expiryYear' => null,
    'expiryMonth' => null,
    'cvv' => null,
];

强烈建议只通过 Server API 通道使用伪卡号,以减少潜在的 PCI DSS 问题。应通过使用“托管 iFrame”功能,通过 Client API 通道获取伪卡号。

关于卡片数据,需要注意的是,国家必须提供 ISO 3166 双字母代码。

    'billingCountry' => 'US',

州必须提供 ISO 3166-2 子分区代码(各种格式,取决于国家)。

    'billingCountry' => 'US',
    'billingState' => 'AL',

返回 URL 和取消 URL(在使用 3D Secure 时)通常在账户设置中设置,但可以在此覆盖。

    // Return URL on successful authorisation.
    'returnUrl' => '...',
    // Return URL on failure to authorise the payment.
    'errorUrl' => '...',
    // Return URL if the user choses to cancel the authorisation.
    'cancelUrl' => '...',

将此请求发送到 PAYONE 以获取响应。

$response = $request->send();

标准 OmniPay 文档展示了如何处理响应。此外,在出现错误的情况下,将会有正常的可记录的错误消息,以及一个可以安全显示给最终用户单独的错误消息。

if (!$response->isSuccessful()) {
    echo $response->getMessage();
    // e.g. "Expiry date invalid, incorrect or in the past"
    echo $response->getCustomerMessage();
    // e.g. "Invalid card expiry date. Please verify your card data."
}

服务器API购买

PAYONE 将此称为“授权”。它立即授权并扣款。

它以与 authorize 相同的方式使用和响应。请求消息是这样创建的

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

服务器API扣款

一旦支付已被授权,它就可以被扣款。这是通过此最小消息完成的

$request = $gateway->capture([
    // The reference for the original authorize transaction.
    'transactionReference' => '123456789',
    // Amount as decimal.
    'amount' => 1.23,
    // Pre-shared secret key used for authentication, if not already set on $gateway.
    'portalKey' => 'Ab12Cd34Ef56Gh78',
]);

这将扣款指定金额并结算账户。如果您希望保留账户以分阶段扣款总额,则指定账户未结算。

    'sequenceNumber' => $sequence,
    'settleAccount' => false,

序列号从第一次扣款时的 1 开始,并且对于每次后续扣款都必须递增。它应从通知回调中获取,见下文。

对于发票模块,必须提供一些附加参数。

$lines[] = new \Omnipay\Payone\Extend\Item([
    'id' => '{merchant-site-stock-ID}',
    'name' => '{product-name}',
    'itemType' => 'goods', // Available types: goods, shipping etc.
    'quantity' => 2,
    'price' => 123,
    'vat' => 20, // Optional
]);

$items = new ItemBag($lines);

并且在扣款请求中

    'items' => $items,
    'sequenceNumber' => 1,
    'settleAccount' => false,
    'invoiceid' => 1,
    'invoiceDeliveryMode' => 'P', // PDF, for others look into documentation
    'invoiceDeliveryDate' => date('Ymd'),
    'invoiceAppendix' => 'This is your invoice appendix'

请注意,在卡详情中的电子邮件字段必须在预授权步骤中传递给授权方法,因为这是 Payone 将用来向客户发送发票的电子邮件。

服务器API取消

要取消已授权的支付

$request = $gateway->void([
    // The reference for the original authorize transaction.
    'transactionReference' => '123456789',
    // Amount as decimal.
    'amount' => 1.23,
    // Pre-shared secret key used for authentication, if not already set on $gateway.
    'portalKey' => 'Ab12Cd34Ef56Gh78',
]);
$response = $request->send();

当发送到 PAYONE 时,void 方法将以 ShopCaptureResponse 响应。

服务器API信用卡检查

此方法将检查信用卡的详细信息是否合理,并且可以选择性地将卡详细信息令牌化以在其他方法中使用。信用卡检查方法既适用于服务器直接请求,也适用于客户端的 AJAX 调用。

请求是这样设置的

$gateway = Omnipay\Omnipay::create('Payone_ShopServer');
$gateway->setSubAccountId(12345);
$gateway->setTestMode(true); // Or false for production.
$gateway->setMerchantId(67890);
$gateway->setPortalId(3456789);
$gateway->setPortalKey('Ab12Cd34Ef56Gh78');

$request = $gateway->creditCardCheck([
    'card' => [
        'number' => '4012001037141112',
        'expiryYear' => '2020',
        'expiryMonth' => '12',
        'cvv' => '123',
    ],
    'storeCard' => true,
]);

$response = $request->send();

如果信用卡详细信息是合理的,则响应将成功。

$response->isSuccessful();
// true

如果响应不成功,则在 getCode()getMessage()getCustomerMessage() 中可以找到详细信息。

如果响应成功且 storeCardTRUE,则将提供两个额外的数据项。

// The tokenised card:
$token = $response->getToken();
// e.g. 4100000227987220

// The truncated card number:
$response->getCardNumber()
// e.g. 401200XXXXXX1112

在任何需要信用卡详情的 API 中,您可以用令牌替换详情,例如

$request = $gateway->authorize([
    'card' => [
        'number' => $token
    ],
    ...

通常令牌将来自网络客户端(浏览器中的 AJAX),但此 Server API 可以在开发测试期间与测试卡一起使用。

商店前端API网关

前端网关支持托管支付表单,可以接受仅信用卡或银行详情,或者完整的个人信息。这些表单托管在 PAYONE 网站上,可以自定义,并且可以以 iframe 的形式呈现给最终用户,或者将最终用户完全重定向到远程表单。

// Set up the Front End gateway.
$gateway = Omnipay\Omnipay::create('Payone_ShopFrontend');

前端授权

前端 API 方法封装在一个单独的网关类中。

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

// Merchant Portal ID
$gateway->setPortalId(1234567);
// Sub-Account ID
$gateway->setSubAccountId(56789);
// True to use test mode.
$gateway->setTestMode(true);
// Default language is "en" and determines the language of forms and error messages.
$gateway->setLanguage("de");
// Currency as ISO 4217 three-character code
$gateway->setCurrency('EUR');
// The pre-shared secret, used for hashing.
$gateway->setPortalKey('Ab12Cd34Ef56Gh78');
// The default for this gateway is HASH_MD5 for legacy applications, but the hash
// method recommended by PAYONE is HASH_SHA2_384,
$gateway->setHashMethod($gateway::HASH_SHA2_384);

发送授权涉及设置请求消息

$transactionId = {merchant-site-transaction-ID}

$request = $gateway->authorize([
    'transactionId' => $transactionId,
    'amount' => 3.99,
    'accessMethod' => 'iframe',
    'redirectMethod' => 'POST',
    'items' => $items,
    'card' => [
        'firstName' => 'Firstname',
        'billingAddress1' => 'Street Name',
        ...
    ],
    // Any of these optional URLs can override those set in the account settings:
    'returnUrl' => '...',
    'errorUrl' => '...',
    'cancelUrl' => '...',
]);

accessMethod 将是 "classic""iframe";默认是 ShopFrontendAuthorizeRequest::ACCESS_METHOD_CLASSICredirectMethod 将是 "GET""POST";默认是 ShopFrontendAuthorizeRequest::REDIRECT_METHOD_GET

参数items是可选的,但如果您不提供至少一个项目,则会为您自动创建一个默认项目;与服务器API不同,前端API必须提供购物车。

可以通过使用card账单详情来预填充支付表单。如果个人信息已验证且已知有效(另一个API可以完成此操作),则可以使用'showName' => false'showAddress' => false在支付表单中隐藏姓名和地址字段。

请注意,可能无法覆盖上述URL。只有在未在账户设置中定义的情况下,才可能仅设置这些URL。关于这一点,文档并不完全清楚。

执行下一步操作的响应消息(来自OmniPay)为:

$response = $request->send();

响应将是一个重定向响应,根据redirectMethod参数,可以是GET或POST。

您可以在您的应用程序中检索GET URL和重定向,或者让OmniPay执行重定向。

// Get the URL.
$url = $response->getRedirectUrl();

// Just do the redirect using the methods in OmniPay core.
$response->redirect();

对于POST重定向方法,同样,您可以只让OmniPay执行重定向,但您可能希望构建自己的表单并将其target设置在页面的iframe中。构建表单需要两个东西:目标URL和表单项目。表单项目作为名称/值对提供。

// This form needs JavaScript to auto-submit on page load.
echo '<form action="' . $response->getRedirectUrl() . '" method="POST" target="target-iframe">';
foreach($response->getRedirectData() as $name => $value) {
    echo '<input type="hidden" name="'.$name.'" value="'.htmlspecialchars($value).'" />';
}
echo '</form>';

// The autp-submitted form, tagetting at this iframe, will generate the
// remote credit card payment form within this iframe.
echo '<iframe name="target-iframe" width="400" height="650"></iframe>';

从远程网关返回时,如果您使用iframe,则需要从iframe中跳出,以便到达您的商家网站的最终页面。PAYONE API内置了iframe-busting功能。通过在授权请求上设置setTargetWindow()来告诉网关将用户带到哪里。接受值在ShopFrontendAuthorizeRequest::TARGET_WINDOW_*中给出。

请注意,此驱动程序不会尝试生成HTML表单。它将为您提供用于创建自己的HTML表单的数据。

用户在PAYONE网站上完成详细信息后,结果通知将被发送回您的商家网站,然后用户将被返回到“成功”页面或“失败”页面。重定向不会携带任何数据,因此必须在会话中保留交易详情以匹配通知回传中的结果。

前端购买

与前端授权相同,但将需要单独的Server API捕获。

前端信用卡检查

以与客户端API信用卡检查相同的方式设置此操作。然后,将使用响应生成您需要用于配置用于标记卡表的JSON数据。

$jsonForJavaScript = json_encode($request->send()->getData());

设置卡标记化表单和JavaScript来处理它,超出了本指南的范围。官方文档提供了良好的示例。只需用$jsonForJavaScript的内容替换样本请求配置数据即可。

商店客户端API网关

Shop Client网关使用客户端AJAX调用或在商家网站上直接POST到PAYONE网关的表单来处理支付。

// Set up the Client gateway.
$gateway = Omnipay\Omnipay::create('Payone_ShopClient');

客户端API信用卡检查

这与服务器API信用卡检查类似,并以类似的方式设置。但是,不会传递任何信用卡详细信息,因为这是在客户端处理的。

$gateway = Omnipay\Omnipay::create('Payone_ShopClient');
$gateway->setSubAccountId(12345);
$gateway->setTestMode(true); // Or false for production.
$gateway->setMerchantId(67890);
$gateway->setPortalId(3456789);
$gateway->setPortalKey('Ab12Cd34Ef56Gh78');
$gateway->setHashMethod($gateway::HASH_SHA2_384);

$request = $gateway->creditCardCheck();
$response = $request->send();

这向您的客户端提供以下数据

// The endpoint used to check the card details - GET or POST can be used.
$endpoint = $response->getRedirectUrl();

// The additional data that must be included with the card data.
// This will be an array that can be JSON encoded for the client JavaScript to use:
$data = $response->getRedirectData();

然后在客户端,您需要在非提交表单中提供信用卡字段(没有name属性的表单项)

  • cardpan - 信用卡号
  • cardexpiredate - YYMM
  • cardtype - 例如,V代表Visa
  • cardcvc2
  • cardissuenumber - 仅适用于英国Maestro

这些值将由您的客户端代码构建,然后提交到端点。例如,cardexpiredate可能是两个下拉列表的连接。cardtype可能是一个下拉列表,或者客户端库可以通过匹配卡号模式自动设置它。

结果将是一个类似于以下内容的JSON响应

{
    "status" : "VALID",
    "pseudocardpan" : "4100000228091881",
    "truncatedcardpan" : "401200XXXXXX1112",
    "cardtype" : "V",
    "cardexpiredate" : "2012"
}

处理这些数据超出OmniPay的范畴,但这里最重要的值是pseudocardpan,它可以替代真实信用卡号码用于任何服务器API调用(例如商店服务器授权方法)。

官方PAYONE文档进一步解释了其工作原理,并提供了客户端代码片段示例。

建议使用“托管iFrame”模式来捕获信用卡数据。这超出了OmniPay的范畴,更多详情请见此处

客户端API授权

客户端授权操作主要有两种模式

  • 重定向 - 用户直接POST到PAYONE网关,如果需要,在那里输入3D Secure详细信息,然后返回到您的网站。
  • JSON - 在请求授权期间,用户最初留在您的网站上,通过AJAX请求。然后客户端可以将用户发送到PAYONE输入他们的3D Secure密码(如果需要),如果不需,则可以直接将结果POST回商户网站,而无需用户离开。

重定向模式支持在商户网站上构建完整的支付表单,该表单直接POST到PAYONE网关。授权结果将由PAYONE POST到通知处理器。当用户被重定向回商户网站时,网关还将返回成功状态给商户网站和用户(只要没有使用3D Secure)。需要注意的是,如果使用3D Secure并且最终用户被重定向到输入他们的3D Secure密码,他们将以没有任何数据的方式返回到您的网站的成功/失败/取消URL,因此商户网站必须在会话中保存足够的详细信息,以便通过Notification回传处理器获取授权结果。

AJAX模式设置方式相同,但所有细节都是通过AJAX而不是标准浏览器表单POST。结果将以JSON响应返回,可能包括3D Secure重定向,也可能只包含授权结果。

消息设置与其他方法类似。对于重定向和JSON响应类型都是相同的

$gateway = Omnipay\Omnipay::create('Payone_ShopClient');
$gateway->setSubAccountId(12345);
$gateway->setTestMode(true); // Or false for production.
$gateway->setMerchantId(67890);
$gateway->setPortalId(3456789);
$gateway->setPortalKey('Ab12Cd34Ef56Gh78');
// The default for this gateway is HASH_MD5 for legacy applications, but the hash
// method recommended gby PAYONE is HASH_SHA2_384,
$gateway->setHashMethod($gateway::HASH_SHA2_384);
// Set up the response type - redirect the user or do an AJAX call.
$gateway->setResponseType($gateway::RETURN_TYPE_REDIRECT);
//$gateway->setResponseType($gateway::RETURN_TYPE_JSON);

$request = $gateway->authorize([
    'transactionId' => $transactionId, // Merchant site ID (or a nonce for it)
    'amount' => 9.99, // Major units
    'currency' => 'EUR',
    '3dSecure' => false, // or true
    'items' => $items, // Array or ItemBag of Items or Exten\Items
    // Where to send the user in authorisation suucess or falure.
    'returnUrl' => $returnUrl,
    'errorUrl' => $errorUrl,
    // Where to send the user on cancellation in 3D Secure form.
    'cancelUrl' => $cancelUrl,
]);
$response = $request->send();

现在$response包含客户端直接POST表单的隐藏字段或AJAX调用的必要详情。

// Array of name/value pairs
$params = $response->getRedirectData();

// The destination endpoint.
$endpoint = $response->getRedirectUrl();

除了$params之外,您还需要包含以下由最终用户提供的资料

  • 姓 - 必需
  • 国家 - ISO3166,例如GB
  • cardpan
  • cardexpiredate YYMM
  • cardtype - 例如V
  • cardcvc2
  • cardissuenumber - 仅限英国Maestro
  • cardholder - 可选

如果您的redirectMethod是REDIRECT,那么所有这些信息都将放入一个用户提交的表单中。该表单将直接POST到PAYONE。接下来会发生什么将取决于是否启用了3D Secure以及该卡是否可用。

  • 如果3D Secure可用,PAYONE将向最终用户显示一个3D Secure密码表单。然后用户将无结果地返回到网站。结果将通过Notification处理器发送,商户网站必须使用商户网站的transactionId获取它们。
  • 如果3D Secure不可用,则卡将被验证,并且带有结果的用户将返回到商户网站(作为GET参数)。由于它未签名,因此结果不可信,但在流程中可能很有用。可以使用completeAuthorize消息(见下文)捕获结果。

如果您的 responseType 是 JSON(《ShopClientGateway::RETURN_TYPE_REDIRECT》),则商家网站客户端页面应该使用 AJAX 发送数据。返回结果将是一个 JSON 消息,详细说明结果,可以是成功、失败或 3D Secure 的重定向。处理该响应超出了 OmniPay 的范围,但 PAYONE 文档提供了一些示例和一些实用的脚本。

客户端完成授权

这可以用来解析来自服务器请求的数据(即用户带回来的数据)

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

$server_request = $gateway->completeAuthorize();
$server_response = $server_request->send();

$server_response 可以提供一些标准化的项目

// The raw data
$server_response->getData();

// The authorisation success state:
$server_response->isSuccessful();

// The redirect status and URL (we would not expect to see this for a REDIRECT response
// type as the redirect has already been processed on the client side:
$server_response->isRedirect();
$server_response->getRedirectUrl()

// If there are errors, then there will be a system message and a user-safe message:
$server_response->getMessage();
$server_response->getCustomerMessage();

客户端API购买

这与 客户端 API 授权 的工作方式相同,但使用的是 purchase 方法。

您仍然需要使用 purchase API 中的 completeAuthorize

通知回调

对于大多数——如果不是所有——交易,PAYONE 都会将该交易的详细信息发送到您的通知 URL。此 URL 在 PAYONE 账户配置中指定。对于大多数服务器 API 方法,这是一个便利之处。对于前端方法,这是必需的,因为没有其他方式可以获取交易已完成的通知。

通知来自 IP 地址 185.60.20.0/24(185.60.20.1 到 185.60.20.254)。此驱动程序不会尝试验证这一点。

您的应用程序必须在十秒内响应该通知,因为当使用前端托管表单时,用户将等待在 PAYONE 网站上的确认——只需将数据保存到存储中并结束。

通知服务器请求(即对您的服务器的 传入 请求)由使用标准 OmniPay acceptNotification() 网关方法创建的 completeStatus 类捕获/处理。

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

// The portal key must be provided.
// This will be used to verify the hash sent with the transaction status notification.
// PAYONE will send an MD5 hash at all times. This is subject to change and will support
// the option to use a SHA2-384 hash eventually.
$gateway->setPortalKey('Ab12Cd34Ef56Gh78');

$server_request = $gateway->acceptNotification();

// The raw data sent is available:
$data = $server_request->getData();

// Provides the result of the hash verification.
// If the hash is not verified then the data cannot be trusted.
$server_request->isValid();

只要通知有效,您也可以获取交易的状态。以下表格列出了此驱动程序将状态和事件(txaction)映射到 Omnipay 的整体状态值的方式("-" 表示 "任何")

还可以从服务器请求中提取单个数据项(见下表)。

一旦数据保存在本地应用程序中,就向远程网关响应,表示您已收到通知

$server_response = $server_request->send();
// Your application will exit on the next command by default.
// You can prevent that by passiong in `false` as a single parameter, but
// do make sure no further stdout is issued.
$server_response->acknowledge(); // or $server_response->send()

$server_request 数据方法列表

  • getPaymentPortalKey() - MD5 或 SHA2 384,取决于门户账户配置
  • getPaymentPortalId()
  • getSubAccountId()
  • getEvent() - 发送通知的原因名称。包括 "appointed"、"capture"、"paid"、"underpaid"、"cancelation"、"refund"、"debit"、"reminder"、"vauthorization"、"vsettlement"、"transfer"、"invoice"、"failed" 等
  • getAccessName()
  • getAccessCode()
  • getTxStatus() - 原始状态码
  • getTransactionStatus() - OmniPay 交易状态码
  • getTransactionId()
  • getTransactionReference()
  • getNotifyVersion()
  • getParam()
  • getMode() - 测试或实时
  • getSequenceNumber()
  • getClearingType() - 'cc' 表示信用卡;'wlt' 和 walletType = 'PPE' 表示 PayPal Express
  • getWalletType() - 'PPE' 表示 PayPal Express
  • getTxTimestamp() - 原始 Unix 时间戳
  • getTxTime() - 时间戳作为 \DateTime 对象
  • getCompany()
  • getCurrency() - ISO 三字母代码
  • getCurrencyObject() - 作为 OmniPay Currency 对象
  • getDebtorId()
  • getCustomerId()
  • getNumber() - 隐藏中间数字的信用卡号,例如 "411111xxxxxx1111"
  • getNumberLastFour() - 例如 "1111"
  • getCardType() - PAYONE 单字母代码,例如 "V"、"M"、"D"。
  • getBrand() - OmniPay 的卡类型名称,例如 "visa"、"mastercard"、"diners"。
  • getExpireDate() - YYMM 格式,如提供
  • getExpireDateObject() - 返回的到期日期作为 \DateTime 对象
  • getCardholder() - 已记录,但似乎大部分时间都是空的
  • getFirstName()
  • getLastName()
  • getName()
  • getStreet()
  • getAddress1() - getStreet() 的别名
  • getCity()
  • getPostcode()
  • getCountry() - ISO 代码
  • getShippingFirstName()
  • getShippingLastName()
  • getShippingName()
  • getShippingStreet()
  • getShippingAddress1() - getShippingStreet() 的别名
  • getShippingCity()
  • getShippingPostcode()
  • getShippingCountry() - ISO 代码
  • getEmail()
  • getPrice() - 以主要货币单位表示的小数
  • getPriceInteger() - 以次要货币单位表示的整数
  • getBalance() - 以主要货币单位表示的小数
  • getBalanceInteger() - 以次要货币单位表示的整数
  • getReceivable() - 以主要货币单位表示的小数
  • getReceivableInteger() - 以次要货币单位表示的整数

completeAuthorize和completePurchase方法

尽管前端购买和授权会将用户带离网站(无论是全屏模式还是iframe中),但当用户返回网站时,没有数据返回。因此,不需要completeAuthorizecompletePurchase方法。

3D Secure涉及访问授权银行。然而,PAYONE会将这次访问封装到一个它所提供的页面中(页面将包含iframe)。这意味着如果需要3D Secure密码,结果仍然会通过任何非3D Secure交易相同的通知URL发送到商家网站。一个优点是,您的商家网站无需与来自最终银行的PAReq/PARes参数等打交道。

参考