namshi/innovate

A PHP客户端,用于通过Innovate支付网关进行支付。

4.0.0 2016-01-17 11:35 UTC

README

Build Status

SensioLabsInsight

此库提供对Innovate支付网关的支持,使用Guzzle

版本

从3.0.0版本开始,客户端构造函数已更改。现在它接受两个额外的参数

/* 2.x version */
$client = new Namshi\Innovate\Client('storeid', 'key');
/* 3.x version */
$client = new Namshi\Innovate\Client('storeid', 'merchantid', 'key', 'searchkey');

添加的参数用于获取与购物车ID相关的交易(见下文)。

安装

您可以通过composer安装此库:查看packagist上的包

然后将其包含在您的composer.json

"namshi/innovate": "1.0.*",

根据您的需求选择主版本和次版本。

用法

要使用此库,您需要Namshi\Innovate\Client类的实例。此库还将提供辅助类,描述Innovate API所需的数据。

use Namshi\Innovate\Payment\Transaction;
use Namshi\Innovate\Payment\BillingInformation;
use Namshi\Innovate\Payment\Browser;
use Namshi\Innovate\Payment\Billing\Customer;
use Namshi\Innovate\Payment\Billing\Address;
use Namshi\Innovate\Payment\Card;
use Namshi\Innovate\Client;

$client      = new Client('storeid', 'merchantid', 'key', 'searchkey'); // get them from your innovate account

$transaction = new Transaction('sale', 'ecom', true, 'ORDER_NUMBER', 'DESCRIPTION', 'USD', 40, 'AN OPTIONAL REFERENCE TO YOUR TRANSACTION');
$card        = new Card('1234123412341234', '111', new \DateTime($cardExpiryDate));
$customer    = new Customer('Mr', 'John', 'Doe');
$address     = new Address('My address info 1', 'My address info 2', 'My address info 3', 'San Francisco', 'California', 'US', '00000');
$billing     = new BillingInformation($customer, $address, "customers's-email@gmail.com", $customerIpAddress);
$browser     = new Browser($customerUserAgent, $requestAcceptHeader);

$response    = $client->performPayment($transaction, $card, $billing, $browser);

如果您愿意,也可以注入您自己的Guzzle客户端实例(只要它扩展了\Guzzle\Service\Client

$myGuzzleClient = MyGuzzleClient(...);

$client = new Client('storeid', 'merchantid', 'key', 'searchkey', $myGuzzleClient);

工作原理

有两种类型的交易

我们无法事先理解哪一个是哪一个。我们可以通过检查Innovate的响应来了解我们是否正在处理3-D Secure交易。

use Namshi\Innovate\Http\Response\Redirect;

$response = $client->performPayment($transaction, $card, $billing, $browser);

if ($response instanceOf Redirect) {
    // 3D secure transactions
} else {
    // Normal transactions
}

授权状态

任何付款都会先执行授权请求,然后是付款请求。

如果授权被拒绝,您将收到一个包含失败消息和400 Bad Request状态码的响应。

普通交易

普通交易将遵循已描述的授权和付款步骤。在您的端,您只需要检查响应的状态码是否为200。库将处理其余部分。

$response = $client->performPayment($transaction, $card, $billing, $browser);

if ($response->getStatusCode() === 200) {
    // payment done
} else {
    // transaction failed
}

3D secure交易

3D secure交易比普通交易多一个步骤。

当库请求3D secure交易的授权时,Innovate将返回一个客户应该重定向到的URL。重定向应由您的应用程序执行(如下所述)。

一旦客户完成3D secure步骤,她将被重定向回应用程序,在那里您可以使用此库进行实际付款。

注意:当交易是3D secure时,库将返回'Namshi\Innovate\Http\Response\Redirect'实例。

以下示例描述了执行3D secure付款的代码

use Namshi\Innovate\Http\Response\Redirect;

$response = $client->performPayment($transaction, $card, $billing, $browser);

if ($response instanceof Redirect) {
    // build a form
}

响应对象将包含以下值

  • targetUrl
  • session
  • paReq

您需要这些作为隐藏字段来执行到Innovate的重定向

$targetUrl = $response->getTargetUrl();
$session   = $response->getSession();
$pareq     = $response->getPareq();

将客户重定向到正确参数的一个简单方法是构建一个表单,并将这些值作为隐藏字段添加

必须发送到targetUrl

<form name="acsform" action="[targetUrl from the response]" method="post">
    <input type="hidden" name="PaReq" value="[The pareq data from response]">
    <input type="hidden" name="MD" value="[Value that identifies the transaction on our end. It will be sent back unchanged in the the 3d secure response. (i.e.: you could use the session id to complete the transaction]">
    <input type="hidden" name="TermUrl" value="[return URL on your site]">
    <noscript><input type="Submit"></noscript>
</form>

注意termUrl是Innovate在3D secure步骤完成后将客户重定向到的URL。

本示例的例子在这里:ACS (访问控制服务器) 表单

提交表单最简单的方法是使用JavaScript(无需让客户操作)

<script>
    function autosub() {
        document.forms['acsform'].submit();
    }
    document.onload=autosub;
</script>

表单提交后,客户将被重定向到3D-Secure页面,该页面要求提供额外的凭据。然后她将被重定向到包含两个值('PaRes','MD')的termUrl

我们可以使用这些值来执行实际的支付请求

$mpiData = array(
    'PaRes'     => $request->get('PaRes'),
    'session'   => $request->get('MD'),
);

$finalResponse = $client->perform3DSecurePayment($transaction, $card, $billingInformation, $browser, $mpiData);

最终响应让我们检查支付是否成功或被拒绝

if ($finalResponse->getStatusCode() === 200) {
    // payment done
} else {
    // payment failed
}

获取与购物车ID相关的交易

从3.0.0版本开始,有一个新的方法 Namshi\Innovate\Client::searchTransactionsByCartId,它允许您根据innovate购物车ID获取交易。

此方法将返回一个包含innovate响应的\SimpleXMLElement对象,或者在发生异常时抛出异常(Namshi\Innovate\Exception\InnovateException)。

信用卡的令牌化

在4.0.0版本中,我们增加了请求信用卡令牌的功能

  • 从信用卡请求令牌
  • 使用令牌而不是信用卡发起普通交易
  • 使用令牌而不是信用卡发起3D Secure交易

要请求令牌,您应使用以下方法

$client = new Client('storeid', 'merchantid', 'key', 'searchkey');

$card = new TokenizedCard('4000000000000002', new \DateTime('2025-5'));
$billing = new TokenizedBillingInfo(
    new Customer('Forenames', 'Surname', 'Mr'),
    new Address('STREET_ADDRESS_LINE_1', 'STREET_ADDRESS_LINE_2', 'STREET_ADDRESS_LINE_3', 'CITY', 'REGION', 'COUNTRY', '12345'),
    'test@namshi.com'
);

$response = $client->tokenize($card, $billing);

/* response body
<?xml version="1.0" encoding="UTF-8"?>
<remote>
  <result>1</result>
  <token>
    <ref>123400012340002</ref>
    <description>Visa Credit ending 0002</description>
  </token>
</remote>
*/

要使用令牌执行普通交易或3D Secure交易,流程与上述相同,唯一的区别是

  • 使用Namshi\Innovate\Tokenized\Token的实例而不是Namshi\Innovate\Payment\Card
  • 使用Namshi\Innovate\Tokenized\CustomerInformation的实例而不是Namshi\Innovate\Payment\BillingInformation

测试

您可以通过首先安装依赖项然后运行PHPUnit来运行测试套件

php composer.phar install

./vendor/bin/phpunit -c .

有一个集成测试,它实际上验证了库的完美工作。

要运行它,您需要在项目目录中创建一个名为.innovate.config的文件,并包含4个参数

<?php

$configs = array(
    'storeId'           => 'xxxxx',  // your store Id in Innovate
    'merchantId'        => 'xxxxx',  // your merchant Id in Innovate
    'authenticationKey' => 'xxxxxxxxxxx',  // your authentication key
    'searchKey'         => 'xxxxxxxxxxx',  // your search key
);

// Card info
$cardInfo = array(
    'number'    => '111111111111111',
    'cvv'       => 'XXX',
);

// The card which need redirection for 3d secured
$redirectUrlCardInfo = array(
    'number'    => '111111111111111',
    'cvv'       => 'XXX',

);

// your ip and should be in Innovate white list
$ip = 'xxx.xxx.xxx.xxx';

然后运行

phpunit tests/Namshi/Innovate/Test/Integration/ServiceTest.php