Skip to content

Commit 2ba96e5

Browse files
committed
Fix name value pair encoding
1 parent 3ba09e3 commit 2ba96e5

File tree

6 files changed

+116
-8
lines changed

6 files changed

+116
-8
lines changed

src/Omnipay/Payflow/Message/AuthorizeRequest.php

+18-1
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,28 @@ public function getData()
9191

9292
public function sendData($data)
9393
{
94-
$httpResponse = $this->httpClient->post($this->getEndpoint(), null, $data)->send();
94+
$httpResponse = $this->httpClient->post(
95+
$this->getEndpoint(),
96+
null,
97+
$this->encodeData($data)
98+
)->send();
9599

96100
return $this->response = new Response($this, $httpResponse->getBody());
97101
}
98102

103+
/**
104+
* Encode absurd name value pair format
105+
*/
106+
public function encodeData(array $data)
107+
{
108+
$output = array();
109+
foreach ($data as $key => $value) {
110+
$output[] = $key.'['.strlen($value).']='.$value;
111+
}
112+
113+
return implode('&', $output);
114+
}
115+
99116
protected function getEndpoint()
100117
{
101118
return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;

src/Omnipay/Payflow/Message/Response.php

+26-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,32 @@ public function __construct(RequestInterface $request, $data)
1919
throw new InvalidResponseException;
2020
}
2121

22-
parse_str($data, $this->data);
22+
$this->data = $this->decodeData($data);
23+
}
24+
25+
/**
26+
* Decode absurd name value pair format
27+
*/
28+
public function decodeData($data)
29+
{
30+
$output = array();
31+
while (strlen($data) > 0) {
32+
preg_match('/(\w+)(\[(\d+)\])?=/', $data, $matches);
33+
$key = $matches[1];
34+
$data = substr($data, strlen($matches[0]));
35+
36+
if (isset($matches[3])) {
37+
$value = substr($data, 0, $matches[3]);
38+
} else {
39+
$next = strpos($data, '&');
40+
$value = $next === false ? $data : substr($data, 0, $next);
41+
}
42+
43+
$data = substr($data, strlen($value) + 1);
44+
$output[$key] = $value;
45+
}
46+
47+
return $output;
2348
}
2449

2550
public function isSuccessful()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Omnipay\Payflow\Message;
4+
5+
use Omnipay\Tests\TestCase;
6+
7+
class AuthorizeRequestTest extends TestCase
8+
{
9+
public function setUp()
10+
{
11+
$this->request = new AuthorizeRequest($this->getHttpClient(), $this->getHttpRequest());
12+
$this->request->initialize(
13+
array(
14+
'amount' => '12.00',
15+
'currency' => 'USD',
16+
'card' => $this->getValidCard(),
17+
)
18+
);
19+
}
20+
21+
public function testEncodeData()
22+
{
23+
$data = array(
24+
'foo' => 'bar',
25+
'key' => 'value &= reference',
26+
);
27+
28+
$expected = 'foo[3]=bar&key[18]=value &= reference';
29+
$this->assertSame($expected, $this->request->encodeData($data));
30+
}
31+
}

tests/Omnipay/Payflow/Message/ResponseTest.php

+31-1
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,44 @@ public function testConstructEmpty()
1414
$response = new Response($this->getMockRequest(), '');
1515
}
1616

17+
public function testDecodeData()
18+
{
19+
$response = new Response($this->getMockRequest(), 'x=y');
20+
$data = 'BILLTOFIRSTNAME=Adrian&BILLTOLASTNAME[6]=&= Foo&TEST=Hi';
21+
22+
$expected = array(
23+
'BILLTOFIRSTNAME' => 'Adrian',
24+
'BILLTOLASTNAME' => '&= Foo',
25+
'TEST' => 'Hi',
26+
);
27+
28+
$this->assertSame($expected, $response->decodeData($data));
29+
}
30+
31+
public function testDecodeDataSimple()
32+
{
33+
$response = new Response($this->getMockRequest(), 'x=y');
34+
$data = 'foo=bar';
35+
$expected = array('foo' => 'bar');
36+
$this->assertSame($expected, $response->decodeData($data));
37+
}
38+
39+
public function testDecodeDataEmpty()
40+
{
41+
$response = new Response($this->getMockRequest(), 'x=y');
42+
$data = '';
43+
$expected = array();
44+
$this->assertSame($expected, $response->decodeData($data));
45+
}
46+
1747
public function testPurchaseSuccess()
1848
{
1949
$httpResponse = $this->getMockHttpResponse('PurchaseSuccess.txt');
2050
$response = new Response($this->getMockRequest(), $httpResponse->getBody());
2151

2252
$this->assertTrue($response->isSuccessful());
2353
$this->assertFalse($response->isRedirect());
24-
$this->assertEquals('V19R3EF62FBE', $response->getTransactionReference());
54+
$this->assertEquals('A10A6AE7042E', $response->getTransactionReference());
2555
$this->assertEquals('Approved', $response->getMessage());
2656
}
2757

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
HTTP/1.1 200 OK
2+
Connection: close
3+
Server: VPS-3.033.00
4+
Date: Tue, 11 Feb 2014 02:34:58 GMT
5+
Content-type: text/namevalue
6+
Content-length: 269
27

3-
RESULT=0&PNREF=V19R3EF62FBE&RESPMSG=Approved&AUTHCODE=048747&CVV2MATCH=Y
8+
RESULT=0&PNREF=A10A6AE7042E&RESPMSG=Approved&AUTHCODE=331PNI&AVSADDR=X&AVSZIP=X&CVV2MATCH=Y&HOSTCODE=A&PROCAVS=U&PROCCVV2=M&VISACARDLEVEL=12&TRANSTIME=2014-02-10 18:34:58&BILLTOFIRSTNAME=Adrian&BILLTOLASTNAME[5]=& Foo&AMT=362.45&ACCT=1111&EXPDATE=0316&CARDTYPE=0&IAVS=X

tests/Omnipay/Payflow/ProGatewayTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function testAuthorizeSuccess()
3333
$response = $this->gateway->authorize($this->options)->send();
3434

3535
$this->assertTrue($response->isSuccessful());
36-
$this->assertEquals('V19R3EF62FBE', $response->getTransactionReference());
36+
$this->assertEquals('A10A6AE7042E', $response->getTransactionReference());
3737
}
3838

3939
public function testAuthorizeError()
@@ -58,7 +58,7 @@ public function testCapture()
5858
$response = $this->gateway->capture($options)->send();
5959

6060
$this->assertTrue($response->isSuccessful());
61-
$this->assertEquals('V19R3EF62FBE', $response->getTransactionReference());
61+
$this->assertEquals('A10A6AE7042E', $response->getTransactionReference());
6262
}
6363

6464
public function testPurchaseSuccess()
@@ -68,7 +68,7 @@ public function testPurchaseSuccess()
6868
$response = $this->gateway->purchase($this->options)->send();
6969

7070
$this->assertTrue($response->isSuccessful());
71-
$this->assertEquals('V19R3EF62FBE', $response->getTransactionReference());
71+
$this->assertEquals('A10A6AE7042E', $response->getTransactionReference());
7272
}
7373

7474
public function testPurchaseError()
@@ -93,6 +93,6 @@ public function testRefund()
9393
$response = $this->gateway->refund($options)->send();
9494

9595
$this->assertTrue($response->isSuccessful());
96-
$this->assertEquals('V19R3EF62FBE', $response->getTransactionReference());
96+
$this->assertEquals('A10A6AE7042E', $response->getTransactionReference());
9797
}
9898
}

0 commit comments

Comments
 (0)