Skip to content

Commit

Permalink
Issue thephpleague#112 Recode Sage Pay Form data from UTF-8 to ISO885…
Browse files Browse the repository at this point in the history
…9-1 by default.

Provide an option to disable this for when the merchant site handles
it already. In the vast number of cases, the conversion should stand.
That is, until Sage Pay get their ISO8859 technical debt sorted out
for good.
  • Loading branch information
judgej committed Oct 13, 2018
1 parent 471a4fb commit 1fa282a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,15 @@ $gateway = OmniPay::create('SagePay\Form')->initialize([

The `encryptionKey` is generated in "My Sage Pay" when logged in as the administrator.

Note that this gateway will assume all inout data (names, addresses etc.)
are UTF-8 encoded.
It will then recode the data to ISO8859-1 before encrypting it for the gateway,
as the gateway strictly accepts ISO8859-1 only, regardless of what encoding is
used to submit the form from the merchant site.
If you do not want this conversion to happen, it can be disabled with this parameter:

'disableUtf8Decode' => true,

The authorize must be given a `returnUrl` (the return URL on success, or on failure
if no separate `failureUrl` is provided).

Expand All @@ -639,10 +648,11 @@ At the gateway, the user will authenticate or authorise their credit card,
perform any 3D Secure actions that may be requested, then will return to the
merchant site.

To get the result, the transaction is "completed":
To get the result details, the transaction is "completed":

```php
// The result will in read and decrypted from the return URL query parameters:
// The result will be read and decrypted from the return URL (or failure URL)
// query parameters:

$result = $gateway->completeAuthorize()->send();

Expand All @@ -651,6 +661,14 @@ $result->getTransactionReference();
// etc.
```

If you already have the encrypted response string, then it can be optionally
passed in:

$result = $gateway->completeAuthorize(['crypt' => $crypt])->send();

This should normally not be necessary, but is handy for testing or if the
current page query parameters are not available in a particular architecture.

### Form Purchase

This is the same as `authorize()`, but the `purchase()` request is used instead,
Expand Down
16 changes: 12 additions & 4 deletions src/Message/Form/AuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,26 @@ public function generateCrypt(array $data)

// Build the data in a query string.

// CHECKME: what happens with UTF-8 data? Do we need to convert
// any special characters not in the correct ranges?
// What about options for URL encoding of other characters?
// The encrypted data MUST be ISO8859-1 regardless of what encoding
// is used to submit the form, because that is how the gateway treats
// the data internally.
// This package assumes input data will be UTF-8 by default, and will
// comvert it accordingly. This can be disabled if the data is already
// ISO8859-1.
// For the Server and Direct gateway methods, the POST encoding type
// will tell the gateway how to interpret the character encoding, and
// the gateway will do any encoding conversions necessary.

// We cannot use http_build_query() because the gateway does
// not decode the string as any standard encoded query string.
// We just join the names and values with "=" and "&" and the
// gateway somehow decodes ambiguous strings.

$disableUtf8Decode = (bool)$this->getDisableUtf8Decode();

$query = [];
foreach ($data as $name => $value) {
$query[] = $name . '=' . $value;
$query[] = $name . '=' . ($disableUtf8Decode ? $value : utf8_decode($value));
}
$query = implode('&', $query);

Expand Down
20 changes: 20 additions & 0 deletions src/Traits/GatewayParamsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,24 @@ public function setBillingForShipping($value)
{
return $this->setParameter('billingForShipping', $value);
}

/**
* @return mixed
*/
public function getDisableUtf8Decode()
{
return $this->getParameter('disableUtf8Decode');
}

/**
* The Form API will convert all input data from an assumed UTF-8
* encoding to ISO8859-1 by default, unless disabled here.
*
* @param mixed $value Will be evaluated as boolean.
* @return $this
*/
public function setDisableUtf8Decode($value)
{
return $this->setParameter('disableUtf8Decode', $value);
}
}

0 comments on commit 1fa282a

Please sign in to comment.