1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Omnipay\Redsys\Message; |
4
|
|
|
|
5
|
|
|
use SimpleXMLElement; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Redsys Webservice Purchase Request |
9
|
|
|
*/ |
10
|
|
|
class WebservicePurchaseRequest extends PurchaseRequest |
11
|
|
|
{ |
12
|
|
|
/** @var string */ |
13
|
|
|
protected $liveWsdl = __DIR__ . "/redsys-webservice-live.wsdl"; |
|
|
|
|
14
|
|
|
/** @var string */ |
15
|
|
|
protected $testWsdl = __DIR__ . "/redsys-webservice-test.wsdl"; |
|
|
|
|
16
|
|
|
/** @var string */ |
17
|
|
|
protected $liveEndpoint = "https://sis.redsys.es/sis/services/SerClsWSEntrada"; |
|
|
|
|
18
|
|
|
/** @var string */ |
19
|
|
|
protected $testEndpoint = "https://sis-t.redsys.es:25443/sis/services/SerClsWSEntrada"; |
|
|
|
|
20
|
|
|
|
21
|
|
|
public function getData() |
22
|
|
|
{ |
23
|
|
|
$this->validate('merchantId', 'terminalId', 'amount', 'currency', 'card'); |
24
|
|
|
$card = $this->getCard(); |
25
|
|
|
// @todo given test card doesn't validate? |
26
|
|
|
if (!$this->getTestMode()) { |
27
|
|
|
$card->validate(); |
28
|
|
|
} |
29
|
|
|
|
30
|
|
|
$data = array( |
31
|
|
|
'DS_MERCHANT_AMOUNT' => $this->getAmountInteger(), |
32
|
|
|
'DS_MERCHANT_ORDER' => $this->getTransactionId(), |
33
|
|
|
'DS_MERCHANT_MERCHANTCODE' => $this->getMerchantId(), |
34
|
|
|
'DS_MERCHANT_CURRENCY' => $this->getCurrencyNumeric(), // uses ISO-4217 codes |
35
|
|
|
'DS_MERCHANT_PAN' => $card->getNumber(), |
36
|
|
|
'DS_MERCHANT_CVV2' => $card->getCvv(), |
37
|
|
|
'DS_MERCHANT_TRANSACTIONTYPE' => 'A', // 'Traditional payment' |
38
|
|
|
'DS_MERCHANT_TERMINAL' => $this->getTerminalId(), |
39
|
|
|
'DS_MERCHANT_EXPIRYDATE' => $card->getExpiryDate('ym'), |
40
|
|
|
); |
41
|
|
|
|
42
|
|
|
|
43
|
|
|
$request = new SimpleXMLElement('<REQUEST/>'); |
|
|
|
|
44
|
|
|
$requestData = $request->addChild('DATOSENTRADA'); |
45
|
|
|
foreach ($data as $tag => $value) { |
46
|
|
|
$requestData->addChild($tag, $value); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
$security = new Security; |
50
|
|
|
|
51
|
|
|
$request->addChild('DS_SIGNATUREVERSION', Security::VERSION); |
52
|
|
|
$request->addChild('DS_SIGNATURE', $security->createSignature( |
53
|
|
|
$requestData->asXML(), |
54
|
|
|
$data['DS_MERCHANT_ORDER'], |
55
|
|
|
base64_decode($this->getHmacKey()) |
56
|
|
|
)); |
57
|
|
|
|
58
|
|
|
return $request; |
59
|
|
|
// array( |
60
|
|
|
// 'DATOSENTRADA' => $data, |
|
|
|
|
61
|
|
|
// 'DS_SIGNATUREVERSION' => $request->DS_SIGNATUREVERSION, |
|
|
|
|
62
|
|
|
// 'DS_SIGNATURE' => $request->DS_SIGNATURE, |
|
|
|
|
63
|
|
|
// ); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
public function sendData($data) |
67
|
|
|
{ |
68
|
|
|
|
69
|
|
|
// @todo either use SOAP client here, or wrap in soap yourself and just guzzle it |
70
|
|
|
/* |
|
|
|
|
71
|
|
|
use SoapClient; |
72
|
|
|
$s = new SoapClient($fs, array('trace' => $this->debug, 'exceptions' => true)); |
73
|
|
|
$result = $s->trataPeticion( |
74
|
|
|
// $data as nested array rather than XML? |
75
|
|
|
); |
76
|
|
|
|
77
|
|
|
*/ |
78
|
|
|
|
79
|
|
|
// DIY SOAP WRAPPER |
80
|
|
|
$envelope = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> |
81
|
|
|
<soapenv:Header/> |
82
|
|
|
<soapenv:Body> |
83
|
|
|
<impl:trataPeticion xmlns:impl='http://webservice.sis.sermepa.es'> |
84
|
|
|
<impl:datosEntrada> |
85
|
|
|
".htmlspecialchars($data->asXML())." |
|
|
|
|
86
|
|
|
</impl:datosEntrada> |
87
|
|
|
</impl:trataPeticion> |
88
|
|
|
</soapenv:Body> |
89
|
|
|
</soapenv:Envelope>"; |
90
|
|
|
|
91
|
|
|
$httpResponse = $this->httpClient->post( |
92
|
|
|
$this->getEndpoint(), |
93
|
|
|
array('SOAPAction' => 'trataPeticion'), |
94
|
|
|
$envelope |
95
|
|
|
)->send(); |
96
|
|
|
|
97
|
|
|
// unwrap httpResponse into actual data as SimpleXMLElement tree |
98
|
|
|
$envelope = $httpResponse->xml(); |
|
|
|
|
99
|
|
|
$response_data = new SimpleXMLElement(htmlspecialchars_decode( |
100
|
|
|
$envelope->children("http://schemas.xmlsoap.org/soap/envelope/") |
|
|
|
|
101
|
|
|
->Body->children("http://webservice.sis.sermepa.es") |
|
|
|
|
102
|
|
|
->trataPeticionResponse |
103
|
|
|
->trataPeticionReturn |
104
|
|
|
)); |
105
|
|
|
|
106
|
|
|
// remove any reflected request data (this happens on error, including card number) |
107
|
|
|
// if (isset($response_data->RECIBIDO)) { |
|
|
|
|
108
|
|
|
// unset($response_data->RECIBIDO); |
|
|
|
|
109
|
|
|
// } |
110
|
|
|
|
111
|
|
|
|
112
|
|
|
return $this->response = new WebservicePurchaseResponse($this, $response_data); |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
PHP provides two ways to mark string literals. Either with single quotes
'literal'
or with double quotes"literal"
. The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (
\'
) and the backslash (\\
). Every other character is displayed as is.Double quoted string literals may contain other variables or more complex escape sequences.
will print an indented:
Single is Value
If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.
For more information on PHP string literals and available escape sequences see the PHP core documentation.