Skip to content

Commit a20d585

Browse files
committed
Add stricter validation for state and postcode for US/CA address field compliance
1 parent 611da7c commit a20d585

File tree

2 files changed

+71
-7
lines changed

2 files changed

+71
-7
lines changed

src/Message/PurchaseRequest.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,19 +186,37 @@ public function getData()
186186
// billing details
187187
$card = $this->getCard();
188188
if ($card) {
189+
$country = $card->getCountry();
190+
$state = $card->getState();
191+
$post_code = $card->getPostcode();
192+
// US/CA have strict state/post code validators if the fields are present
193+
// better set blank here (and filtered out further down) than wrong as can be filled out at gateway end
194+
if ($country == 'US' || $country == 'CA') {
195+
$state = substr(strtoupper($state), 0, 2);
196+
if ($country == 'US') {
197+
if (preg_match('/^[0-9]{5}-[0-9]{4}$/', $post_code) !== 1) {
198+
$post_code = '';
199+
}
200+
} elseif ($country == 'CA') {
201+
$post_code = strtoupper($post_code);
202+
// Strictly, CA Post is '/^[ABCEGHJ-NPRSTVXY][0-9][ABCEGHJ-NPRSTV-Z] [0-9][ABCEGHJ-NPRSTV-Z][0-9]$/'
203+
if (preg_match('/^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$/', $post_code) !== 1) {
204+
$post_code = '';
205+
}
206+
}
207+
} else {
208+
$state = substr($state, 0, 60);
209+
$post_code = substr($post_code, 0, 10);
210+
}
189211
$optional_data += array(
190212
'bill_to_forename' => $card->getFirstName(),
191213
'bill_to_surname' => $card->getLastName(),
192214
'bill_to_address_line1' => $card->getAddress1(),
193215
'bill_to_address_line2' => $card->getAddress2(),
194216
'bill_to_address_city' => $card->getCity(),
195-
//alphanumeric,2 [ISO state code; req for US/CA]
196-
// @todo should this kind of reformatting (or error) happen in driver, or at merchant end?
197-
'bill_to_address_state' => $card->getState(),
198-
// alphanumeric,10 [strict format check for US/CA addresses]
199-
// @todo should this kind of reformatting (or error) happen in driver, or at merchant end?
200-
'bill_to_address_postal_code' => $card->getPostcode(),
201-
'bill_to_address_country' => $card->getCountry(),
217+
'bill_to_address_state' => $state,
218+
'bill_to_address_postal_code' => $post_code,
219+
'bill_to_address_country' => $country,
202220
'bill_to_email' => $card->getEmail(),
203221
'bill_to_phone' => $card->getPhone(),
204222
);

tests/Message/PurchaseRequestTest.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,50 @@ public function testSetLocale()
127127
$this->request->setLocale('en-nz');
128128
$this->assertSame('en-nz', $this->request->getLocale());
129129
}
130+
131+
public function testInvalidCanadianAddress()
132+
{
133+
$this->request->setCard(array(
134+
'firstName' => 'Test',
135+
'lastName' => 'Customer',
136+
'billingAddress1' => '1 Some St',
137+
'billingAddress2' => 'Suburbia',
138+
'billingCity' => 'Toronto',
139+
'billingPostcode' => '123 456',
140+
'billingState' => 'XYZ',
141+
'billingCountry' => 'CA',
142+
'billingPhone' => '123456789',
143+
'email' => '[email protected]',
144+
));
145+
$data = $this->request->getData();
146+
$this->assertSame('1 Some St', $data['bill_to_address_line1']);
147+
$this->assertSame('Suburbia', $data['bill_to_address_line2']);
148+
$this->assertSame('Toronto', $data['bill_to_address_city']);
149+
$this->assertSame('XY', $data['bill_to_address_state']);
150+
$this->assertFalse(array_key_exists('bill_to_address_postal_code', $data));
151+
$this->assertSame('CA', $data['bill_to_address_country']);
152+
}
153+
154+
public function testInvalidAmericanAddress()
155+
{
156+
$this->request->setCard(array(
157+
'firstName' => 'Test',
158+
'lastName' => 'Customer',
159+
'billingAddress1' => '1 Some St',
160+
'billingAddress2' => 'Suburbia',
161+
'billingCity' => 'New York',
162+
'billingPostcode' => '123 456',
163+
'billingState' => 'XYZ',
164+
'billingCountry' => 'US',
165+
'billingPhone' => '123456789',
166+
'email' => '[email protected]',
167+
));
168+
$data = $this->request->getData();
169+
$this->assertSame('1 Some St', $data['bill_to_address_line1']);
170+
$this->assertSame('Suburbia', $data['bill_to_address_line2']);
171+
$this->assertSame('New York', $data['bill_to_address_city']);
172+
$this->assertSame('XY', $data['bill_to_address_state']);
173+
$this->assertFalse(array_key_exists('bill_to_address_postal_code', $data));
174+
$this->assertSame('US', $data['bill_to_address_country']);
175+
}
130176
}

0 commit comments

Comments
 (0)