Completed
Pull Request — master (#1)
by Leith
02:11
created

WebservicePurchaseRequest::sendData()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 50
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 50
ccs 26
cts 26
cp 1
rs 9.3333
c 0
b 0
f 0
cc 3
eloc 24
nc 4
nop 1
crap 3
1
<?php
2
3
namespace Omnipay\Redsys\Message;
4
5
use Exception;
6
use SimpleXMLElement;
7
8
/**
9
 * Redsys Webservice Purchase Request
10
 */
11
class WebservicePurchaseRequest extends PurchaseRequest
12
{
13
    /** @var string */
14
    protected $liveEndpoint = "https://sis.redsys.es/sis/services/SerClsWSEntrada";
15
    /** @var string */
16
    protected $testEndpoint = "https://sis-t.redsys.es:25443/sis/services/SerClsWSEntrada";
17
 
18 5
    public function getData()
19
    {
20 5
        $this->validate('merchantId', 'terminalId', 'amount', 'currency', 'card');
21 5
        $card = $this->getCard();
22
        // test cards aparently don't validate
23 5
        if (!$this->getTestMode()) {
24 1
            $card->validate();
25 1
        }
26
27
        $data = array(
28 5
            'DS_MERCHANT_AMOUNT'           => $this->getAmountInteger(),
29 5
            'DS_MERCHANT_ORDER'            => $this->getTransactionId(),
30 5
            'DS_MERCHANT_MERCHANTCODE'     => $this->getMerchantId(),
31 5
            'DS_MERCHANT_CURRENCY'         => $this->getCurrencyNumeric(),  // uses ISO-4217 codes
32 5
            'DS_MERCHANT_PAN'              => $card->getNumber(),
33 5
            'DS_MERCHANT_CVV2'             => $card->getCvv(),
34 5
            'DS_MERCHANT_TRANSACTIONTYPE'  => 'A',                          // 'Traditional payment'
35 5
            'DS_MERCHANT_TERMINAL'         => $this->getTerminalId(),
36 5
            'DS_MERCHANT_EXPIRYDATE'       => $card->getExpiryDate('ym'),
37
            // undocumented fields
38 5
            'DS_MERCHANT_MERCHANTDATA'     => $this->getMerchantData(),
39 5
            'DS_MERCHANT_MERCHANTNAME'     => $this->getMerchantName(),
40 5
            'DS_MERCHANT_CONSUMERLANGUAGE' => $this->getConsumerLanguage(),
41 5
        );
42
43
44 5
        $request = new SimpleXMLElement('<REQUEST/>');
45 5
        $requestData = $request->addChild('DATOSENTRADA');
46 5
        foreach ($data as $tag => $value) {
47 5
            $requestData->addChild($tag, $value);
48 5
        }
49
50 5
        $security = new Security;
51
52 5
        $request->addChild('DS_SIGNATUREVERSION', Security::VERSION);
53 5
        $request->addChild('DS_SIGNATURE', $security->createSignature(
54 5
            $requestData->asXML(),
55 5
            $data['DS_MERCHANT_ORDER'],
56 5
            $this->getHmacKey()
57 5
        ));
58
59
        // keep data as nested array for method signature compatibility
60
        return array(
61 5
            'DATOSENTRADA'        => $data,
62 5
            'DS_SIGNATUREVERSION' => (string)$request->DS_SIGNATUREVERSION,
63 5
            'DS_SIGNATURE'        => (string)$request->DS_SIGNATURE,
64 5
        );
65
    }
66
67
    /**
68
     * Send the data
69
     *
70
     * Uses its own SOAP wrapper instead of PHP's SoapClient
71
     */
72 4
    public function sendData($data)
73
    {
74
        // re-create the XML
75 4
        $request = new SimpleXMLElement('<REQUEST/>');
76 4
        $requestData = $request->addChild('DATOSENTRADA');
77 4
        foreach ($data['DATOSENTRADA'] as $tag => $value) {
78 4
            $requestData->addChild($tag, $value);
79 4
        }
80 4
        $request->addChild('DS_SIGNATUREVERSION', $data['DS_SIGNATUREVERSION']);
81 4
        $request->addChild('DS_SIGNATURE', $data['DS_SIGNATURE']);
82
83
        // wrap in SOAP envelope
84
        $requestEnvelope = "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
85
              <soapenv:Header/>
86
              <soapenv:Body>
87
                <impl:trataPeticion xmlns:impl='http://webservice.sis.sermepa.es'>
88
                  <impl:datosEntrada>
89 4
                    ".htmlspecialchars($request->asXML())."
90
                  </impl:datosEntrada>
91
                </impl:trataPeticion>
92
              </soapenv:Body>
93 4
            </soapenv:Envelope>";
94
95
        // send the actual SOAP request
96 4
        $httpResponse = $this->httpClient->post(
97 4
            $this->getEndpoint(),
98 4
            array('SOAPAction' => 'trataPeticion'),
99
            $requestEnvelope
100 4
        )->send();
101
102
        // unwrap httpResponse into actual data as SimpleXMLElement tree
103 4
        $responseEnvelope = $httpResponse->xml();
104 4
        $responseData = new SimpleXMLElement(htmlspecialchars_decode(
105 4
            $responseEnvelope->children("http://schemas.xmlsoap.org/soap/envelope/")
106 4
            ->Body->children("http://webservice.sis.sermepa.es")
107 4
            ->trataPeticionResponse
108 4
            ->trataPeticionReturn
109 4
        ));
110
111
112
        // remove any reflected request data (this happens on SIS errors, and includes card number)
113 4
        if (isset($responseData->RECIBIDO)) {
114 1
            unset($responseData->RECIBIDO);
115 1
        }
116
117
        // convert to nested arrays (drop the 'true' to use simple objects)
118 4
        $responseData = json_decode(json_encode($responseData), true);
119
120 4
        return $this->response = new WebservicePurchaseResponse($this, $responseData);
121
    }
122
}
123