verifone/core

此包最新版本(1.2.0)没有可用的许可证信息。

1.2.0 2022-07-27 13:37 UTC

This package is auto-updated.

Last update: 2024-09-27 18:22:06 UTC


README

此仓库包含用于北欧的Verifone BlueCommerce支付网关的实现。与Verifone Global eCommerce Gateway(https://verifone.cloud/)不兼容

目录

1. 安装

composer require verifone/core

2. 基本信息摘要

2.1 联系方式

如果您想联系支持或客户服务,请发送电子邮件至: asiakaspalvelu@verifone.fi

2.2 配置 - 开发模式

库提供开发模式的功能。

对于开发模式,您必须使用以下配置

库提供测试密钥

  • 商店的私钥可在 Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem 中找到
  • 支付服务的公钥可在 Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem 中找到

如果您想使用开发模式,您必须联系客户服务,因为我们的IT部门必须将IP地址添加到允许列表

2.3 配置 - 生产模式

对于生产模式,您必须添加生成新密钥对的可能性,并将公钥提供给支付服务。生成新密钥对的代码示例在此: 3.2 生成RSA密钥

商户可以从TCS客户门户找到Verifone的公钥。

对于生产模式,您必须使用以下示例中的配置

商户ID可以由商户从TCS客户中找到。

2.4 延迟URL / S2S回调

Verifone服务在带有交易信息的URL上发送请求。当响应代码与200不同时,Verifone服务将在原始请求后的24小时内重复请求。

商户必须将延迟URL提供给Verifone的TCS客户,因此必须从模块中获取该URL。

3. 使用方法

该库有集成和单元测试。如果您想,您可以在那里找到有关实现示例的更多信息。

3.1 获取可用的支付方式

每个商户都有自己的支付方式。要获取所有可用的支付方式,您必须使用 GetAvailablePaymentMethodsService

获取支付方式后,应将其存储在系统中。

3.1.1 代码示例

<?php

require_once('vendor/autoload.php');

use \Verifone\Core\DependencyInjection\Configuration\Backend\GetAvailablePaymentMethodsConfigurationImpl;
use \Verifone\Core\DependencyInjection\CoreResponse\PaymentMethodImpl;
use \Verifone\Core\DependencyInjection\Transporter\CoreResponse;
use \Verifone\Core\ExecutorContainer;
use \Verifone\Core\Executor\BackendServiceExecutor;
use \Verifone\Core\ServiceFactory;
use \Verifone\Core\Service\Backend\GetAvailablePaymentMethodsService;

$configObject = new GetAvailablePaymentMethodsConfigurationImpl(
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'), // merchant private key
    'demo-merchant-agreement', // merchant agreement code
    'testSystem', // software name
    '1.2.3.4', // software version
    ['https://epayment.test.point.fi/pw/serverinterface'], // payment service URLs
    '978', // currency used in system - in example EUR
    false // disable Rsa Blinding
);

/** @var GetAvailablePaymentMethodsService $service */
$service = ServiceFactory::createService($configObject, 'Backend\GetAvailablePaymentMethodsService');
$container = new ExecutorContainer();

/** @var BackendServiceExecutor $exec */
$exec = $container->getExecutor('backend');

/** @var CoreResponse $response */
$response = $exec->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

if (!$response->getStatusCode()) {
    return null;
}

$body = $response->getBody();
$availableMethods = ['all']; // Default payment method - redirects to page with possibility to select payment methods

/** @var PaymentMethodImpl $item */
foreach ($body as $item) {
    $availableMethods[] = $item->getCode();
}

// Now, you could store $availableMethods in the database.

备注部分的所有可用支付方式: 支付方式

3.2 生成RSA密钥

为了启用实时(生产)模式,商户必须将商店公钥提供给Verifone客户服务。公钥和私钥在每次请求/响应操作中使用,与Verifone服务交互。

库提供生成新密钥对的功能。

3.2.1 代码示例

<?php

require_once('vendor/autoload.php');

use \Verifone\Core\DependencyInjection\CryptUtils\RsaKeyGenerator;

$generator = new RsaKeyGenerator();
$result = $generator->generate();

if ($result) {
    // You could store keys in the file or in the database
    // For example
    file_put_contents('shop_public_key.pem', $generator->getPublicKey());
    file_put_contents('shop_private_key.pem', $generator->getPrivateKey());
} else {
    // RSA keys are not generated properly.
}

3.3 创建支付请求

3.3.1 代码示例

<?php

require_once('vendor/autoload.php');

use Verifone\Core\DependencyInjection\Configuration\Frontend\FrontendConfigurationImpl;
use Verifone\Core\DependencyInjection\Configuration\Frontend\RedirectUrlsImpl;
use Verifone\Core\DependencyInjection\Service\AddressImpl;
use Verifone\Core\DependencyInjection\Service\CustomerImpl;
use Verifone\Core\DependencyInjection\Service\OrderImpl;
use Verifone\Core\DependencyInjection\Service\PaymentInfoImpl;
use Verifone\Core\DependencyInjection\Service\ProductImpl;
use Verifone\Core\DependencyInjection\Service\TransactionImpl;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\Service\Frontend\CreateNewOrderService;
use Verifone\Core\ServiceFactory;

$urls = new RedirectUrlsImpl(
    'http://www.testikauppa.fi/success', // Return URL for success payment action
    'http://www.testikauppa.fi/rejected', // Return URL for rejected payment action
    'http://www.testikauppa.fi/cancel', // Return URL for cancelled payment action
    'http://www.testikauppa.fi/expired', // Return URL for expired payment action
    'http://www.testikauppa.fi/error' // Return URL for error payment action
);

$address = new AddressImpl(
    'Street 1', // Address - line 1
    '', // Address - line 2
    '', // Address - line 3
    'Helsinki', // City
    '00100', // Postal code
    '246', // Country code
    'John', // First name
    'Doe' // Last name
);

$customer = new CustomerImpl(
    'John', // First name
    'Doe', // Last name
    '0401234567', // Phone number
    'example@domain.fi', // Email number
    $address
);

$order = new OrderImpl(
    '1000000260', // Order identification number
    '2021-05-23 11:58:16', // Order create date
    '978', // Currency code
    '1845', // Order total include tax
    '1500', // Order total exclude tax
    '345' // Order tax
);

$container = new ExecutorContainer(array(ExecutorContainer::REQUEST_CONVERTER => ExecutorContainer::REQUEST_CONVERTER_TYPE_HTML));
$executor = $container->getExecutor('frontend');

$config = new FrontendConfigurationImpl(
    $urls,
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    '1' // skip confirmation page after success payment
);
/**
 * @var CreateNewOrderService $service
 */
$service = ServiceFactory::createService($config, 'Frontend\CreateNewOrderService');

$product1 = new ProductImpl(
    'Test product', // Product name
    '1000', // Unit price, tax excluded. Price for EUR is provided in cents - applicable for all price fields
    '1000', // Price for all units, tax excluded
    '1230', // Price for all units, tax included
    '1', // Quantity
    '0' // Discount for product
);
$product2 = new ProductImpl(
    'Shipment',
    '500',
    '500',
    '615',
    '1',
    '0'
);
$payment = new PaymentInfoImpl(
    'fi_FI', // Payment page language
    PaymentInfoImpl::SAVE_METHOD_AUTO_NO_SAVE // Save method 
);

$transactionInfo = new TransactionImpl(
    'visa', // Payment method 
    '' // Payment number - mostly used for refund
);

$service->insertCustomer($customer);
$service->insertOrder($order);
$service->insertPaymentInfo($payment);
$service->insertTransaction($transactionInfo);
$service->insertProduct($product1);
$service->insertProduct($product2);

$form = $executor->executeService($service, array('https://epayment.test.point.fi/pw/payment'));

现在您可以在HTML页面上附加$form,系统将自动将客户重定向到支付服务。

如果您想以JSON(数组)的形式获取数据,可以使用该代码创建$container

$container = new ExecutorContainer(array(ExecutorContainer::REQUEST_CONVERTER => ExecutorContainer::REQUEST_CONVERTER_TYPE_JSON));

3.4 解析支付响应

Verifone具有重发支付确认的功能。但是,为此,您必须创建一个控制器来处理与常规相同的响应。

3.4.1 代码示例

<?php

require_once('vendor/autoload.php');

use \Verifone\Core\DependencyInjection\Service\OrderImpl;
use \Verifone\Core\ServiceFactory;
use \Verifone\Core\Service\FrontendResponse\FrontendResponseServiceImpl;
use \Verifone\Core\DependencyInjection\Transporter\CoreResponse;
use \Verifone\Core\ExecutorContainer;
use \Verifone\Core\DependencyInjection\CoreResponse\PaymentResponseImpl;
use \Verifone\Core\Converter\Response\CoreResponseConverter;

$exampleResponse = [
    'i-f-1-11_interface-version' => '5',
    'i-f-1-3_order-currency-code' => '978',
    'l-f-1-20_order-gross-amount' => '1845',
    'l-f-1-20_transaction-number' => '4516533313',
    's-f-1-10_software-version' => '1.92.1.64j',
    's-f-1-30_payment-method-code' => 'visa',
    's-f-1-36_order-number' => '1000000260',
    's-t-1-26_filing-code' => '210418261011',
    's-t-1-36_order-note' => '',
    's-t-256-256_signature-one' => '6F7E4A2DAACA57C0AA91F933A6C991DDA38B0E17B6438334478846E42D0C9D6BC3FDFEA02B9B7E21296BA51BCC992181E1D79DBF81382EFFE1BF48A5F689F46AD1B7BB35061C9183733A3C0C3E5463759B4F8DE18EAEC2A8F85A89FE5C79EA0D712C79DBF58D91A542AEC8918DF09DA4663A4C1E66BF665099C512CBB45D8BCA',
    's-t-256-256_signature-two' => '7849E6D685D09C1E8A365BFA5CA46519E040BDB6ABDD4739779248FD7E4DE474473BB96FCD1B05E709B97013DEB94390CB7BE9100668B5F162C09A921CF559F469C8FE5F21AB6981246458C7F7735535215C7CF9BCC9D60F5FD1E8AC998D255B24944522EC781BE1E11F7BE58395E646898D18008E85509222154E51B2A7911C',
    't-f-14-19_order-timestamp' => '2021-05-23 11:58:16',
];

/** @var FrontendResponseServiceImpl $service */
$service = ServiceFactory::createResponseService($exampleResponse);

$orderNumber = $service->getOrderNumber();

// order information
$order = new OrderImpl(
    '1000000260',
    '2021-05-23 11:58:16',
    '978',
    '1845',
    '1500',
    '345'
);

/** @var FrontendResponseServiceImpl $service */
$service->insertOrder($order);
$container = new ExecutorContainer(array('responseConversion.class' => 'Converter\Response\FrontendServiceResponseConverter'));
$exec = $container->getExecutor(ExecutorContainer::EXECUTOR_TYPE_FRONTEND_RESPONSE);

/** @var CoreResponse $parseResponse */
$parsedResponse = $exec->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

/** @var PaymentResponseImpl $body */
$responseBody = $parsedResponse->getBody();
$validate = true;

if ($parsedResponse->getStatusCode() == CoreResponseConverter::STATUS_OK
    && empty($responseBody->getCancelMessage())
) {
    $transactionId = $responseBody->getTransactionNumber();
    $paymentMethod = $responseBody->getPaymentMethodCode();
    
    // Store $paymentMethod and $transactionId in the order data
    // If you need, you could fetch paid amount with: `$responseBody->getOrderGrossAmount() / 100;`
}

3.5 检查支付状态

有时,由于许多原因,支付验证可能需要更多时间。

例如,客户可能在返回商店之前关闭浏览器标签或验证订单是否已退款(部分或全部)。

对于这种情况(以及类似情况),您可以创建(例如)一个cron任务来检索订单的所有交易,或者创建一个控制器操作。

创建延迟成功动作时不需要cron功能。Verifone服务在URL上发送包含交易信息的请求。当响应代码与200不同时,Verifone服务将从原始请求之日起重复请求24小时。

3.5.1 代码示例

<?php

use Verifone\Core\DependencyInjection\Configuration\Backend\BackendConfigurationImpl;
use Verifone\Core\DependencyInjection\Service\OrderImpl;
use Verifone\Core\DependencyInjection\Service\TransactionImpl;
use Verifone\Core\DependencyInjection\Transporter\CoreResponse;
use Verifone\Core\Executor\BackendServiceExecutor;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\Service\Backend\GetPaymentStatusService;
use Verifone\Core\Service\Backend\ListTransactionNumbersService;
use Verifone\Core\ServiceFactory;

require_once('vendor/autoload.php');

$config = new BackendConfigurationImpl(
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    ['https://epayment.test.point.fi/pw/serverinterface']
);


$order = new OrderImpl(
    '1000000260',
    '',
    '',
    '',
    '',
    ''
);

/** @var ListTransactionNumbersService $service */
$service = ServiceFactory::createService($config, 'Backend\ListTransactionNumbersService');
$service->insertOrder($order);

$container = new ExecutorContainer();

/** @var BackendServiceExecutor $executor */
$executor = $container->getExecutor('backend');

/** @var CoreResponse $response */
$response = $executor->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

$transactions = $response->getStatusCode() ? $response->getBody() : [];

/** @var TransactionImpl $transaction */
foreach ($transactions as $transaction) {
    $transaction = new TransactionImpl($transaction->getMethodCode(), $transaction->getNumber());

    /** @var GetPaymentStatusService $service */
    $paymentStatusService = ServiceFactory::createService($config, 'Backend\GetPaymentStatusService');
    $paymentStatusService->insertTransaction($transaction);

    $response = $executor->executeService($paymentStatusService, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));
}

3.6 创建退款请求

3.6.1 代码示例

<?php

use Verifone\Core\DependencyInjection\Configuration\Backend\BackendConfigurationImpl;
use Verifone\Core\DependencyInjection\Service\TransactionImpl;
use Verifone\Core\Executor\BackendServiceExecutor;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\Service\Backend\RefundPaymentService;
use Verifone\Core\ServiceFactory;

require_once('vendor/autoload.php');

$config = new BackendConfigurationImpl(
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    ['https://epayment.test.point.fi/pw/serverinterface']
);

$transaction = new TransactionImpl(
    'visa', // Payment method
    '4516533313', // Transaction code
    '100', // Refund amount
    '978' // Currency code - EUR in the example
);

/** @var RefundPaymentService $service */
$service = ServiceFactory::createService($config, 'Backend\RefundPaymentService');
$service->insertTransaction($transaction);

$container = new ExecutorContainer();
/** @var BackendServiceExecutor $executor */
$executor = $container->getExecutor('backend');

$response = $executor->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

// if success then store information about refund

4516533313是支付响应中的交易号。请参阅3.4.1中的$transactionId

3.7 信用卡

3.7.1 添加新卡 - 代码示例

<?php

require_once('vendor/autoload.php');

use Verifone\Core\DependencyInjection\Configuration\Frontend\FrontendConfigurationImpl;
use Verifone\Core\DependencyInjection\Configuration\Frontend\RedirectUrlsImpl;
use Verifone\Core\DependencyInjection\Service\AddressImpl;
use Verifone\Core\DependencyInjection\Service\CustomerImpl;
use Verifone\Core\DependencyInjection\Service\OrderImpl;
use Verifone\Core\DependencyInjection\Service\PaymentInfoImpl;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\Service\Frontend\AddNewCardService;
use Verifone\Core\ServiceFactory;

$urls = new RedirectUrlsImpl(
    'http://www.testikauppa.fi/success',
    'http://www.testikauppa.fi/rejected',
    'http://www.testikauppa.fi/cancel',
    'http://www.testikauppa.fi/expired',
    'http://www.testikauppa.fi/error'
);

$address = new AddressImpl(
    'Street 1',
    '',
    '',
    'Helsinki',
    '00100',
    '246',
    'John',
    'Doe'
);

$customer = new CustomerImpl(
    'John',
    'Doe',
    '0401234567',
    'example@domain.fi',
    $address
);

$order = new OrderImpl(
    '1000000260',
    '2021-05-23 11:58:16',
    '978',
    '1',
    '1',
    '0'
);

$container = new ExecutorContainer(array(ExecutorContainer::REQUEST_CONVERTER => ExecutorContainer::REQUEST_CONVERTER_TYPE_HTML));
$executor = $container->getExecutor('frontend');

$config = new FrontendConfigurationImpl(
    $urls,
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    '1'
);

/**
 * @var AddNewCardService $service
 */
$service = ServiceFactory::createService($config, 'Frontend\AddNewCardService');

$payment = new PaymentInfoImpl('fi_FI', PaymentInfoImpl::SAVE_METHOD_SAVE_ONLY);

$service->insertCustomer($customer);
$service->insertPaymentInfo($payment);
$service->insertOrder($order);
$form = $executor->executeService($service, array('https://epayment.test.point.fi/pw/payment'));

现在您可以在HTML页面上附加$form,系统将自动将客户重定向到支付服务。

如果您想以JSON(数组)的形式获取数据,可以使用该代码创建$container

如果您需要添加周期性卡,可以按照这种方式实现:

<?php
require_once('vendor/autoload.php');

use Verifone\Core\DependencyInjection\Service\PaymentInfoImpl;
use Verifone\Core\DependencyInjection\Service\RecurringImpl;

// Same implementation as above

$recurring = new RecurringImpl('Test', 'test');
$payment = new PaymentInfoImpl(
    'fi_FI', 
    PaymentInfoImpl::SAVE_METHOD_SAVE_ONLY, 
    '', 
    '', 
    false,
    $recurring
);

// Same implementation as above

3.7.2 获取可用的支付卡 - 代码示例

<?php

require_once('vendor/autoload.php');

use Verifone\Core\Executor\BackendServiceExecutor;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\DependencyInjection\Configuration\Backend\BackendConfigurationImpl;
use Verifone\Core\DependencyInjection\Service\CustomerImpl;
use Verifone\Core\Service\Backend\GetSavedCreditCardsService;
use Verifone\Core\ServiceFactory;

$customer = new CustomerImpl(
    'John',
    'Doe',
    '0401234567',
    'example@domain.fi'
);

$config = new BackendConfigurationImpl(
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    ['https://epayment.test.point.fi/pw/serverinterface']
);

/** @var GetSavedCreditCardsService $service */
$service = ServiceFactory::createService($config, 'Backend\GetSavedCreditCardsService');
$service->insertCustomer($customer);

$container = new ExecutorContainer();
/** @var BackendServiceExecutor $executor */
$executor = $container->getExecutor('backend');

$response = $executor->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

3.7.3 删除支付卡 - 代码示例

<?php

require_once('vendor/autoload.php');

use Verifone\Core\Executor\BackendServiceExecutor;
use Verifone\Core\ExecutorContainer;
use Verifone\Core\DependencyInjection\Service\PaymentInfoImpl;
use Verifone\Core\DependencyInjection\Configuration\Backend\BackendConfigurationImpl;
use Verifone\Core\DependencyInjection\Service\CustomerImpl;
use Verifone\Core\Service\Backend\RemoveSavedCreditCardsService;
use Verifone\Core\ServiceFactory;


$customer = new CustomerImpl(
    'John',
    'Doe',
    '0401234567',
    'example@domain.fi'
);

$config = new BackendConfigurationImpl(
    file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/demo-merchant-agreement-private.pem'),
    'demo-merchant-agreement',
    'testSystem',
    '1.2.3.4',
    ['https://epayment.test.point.fi/pw/serverinterface']
);

$payment = new PaymentInfoImpl(
    '', 
    '', 
    '123456789' // Saved payment method id
);

/** @var RemoveSavedCreditCardsService $service */
$service = ServiceFactory::createService($config, 'Backend\RemoveSavedCreditCardsService');
$service->insertCustomer($customer);
$service->insertPaymentInfo($payment);

$container = new ExecutorContainer();
/** @var BackendServiceExecutor $executor */
$executor = $container->getExecutor('backend');

$response = $executor->executeService($service, file_get_contents('vendor/verifone/core/Verifone/Core/Tests/Integration/Assets/point-e-commerce-test-public-key.pem'));

4. 备注

4.1 支付方式

4.2 货币

系统使用ISO 4217标准的货币代码。更多信息:[ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)

示例

  • EUR - 978
  • SEK - 752

4.3 语言

支付服务中可用的语言

  • fi_FI
  • sv_SE
  • no_NO
  • dk_DK
  • sv_FI
  • en_GB

如果您使用不可用的代码,则默认使用en_GB。

4.4 国家

系统使用ISO 3166-1数字标准的国家代码。更多信息:[ISO 3166-1_numeric](https://en.wikipedia.org/wiki/ISO_3166-1_numeric)