verifone / core
Requires
- php: >=7.1.0
- lamiaoy/httpclient: 1.0.*
- lamiaoy/validation: 1.0.*
- phpseclib/phpseclib: 2.0.* || ~3.0.9
Requires (Dev)
- phpunit/phpunit: 5.3.2
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)