WebservicePurchaseRequest   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 57
c 1
b 0
f 0
dl 0
loc 111
ccs 61
cts 61
cp 1
rs 10
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A sendData() 0 50 3
A getData() 0 46 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(),
0 ignored issues
show
Bug introduced by
It seems like $requestData->asXML() can also be of type true; however, parameter $message of Omnipay\Redsys\Message\Security::createSignature() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

54
            /** @scrutinizer ignore-type */ $requestData->asXML(),
Loading history...
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())."
0 ignored issues
show
Bug introduced by
It seems like $request->asXML() can also be of type true; however, parameter $string of htmlspecialchars() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
                    ".htmlspecialchars(/** @scrutinizer ignore-type */ $request->asXML())."
Loading history...
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->request(
97 4
            'POST',
98 4
            $this->getEndpoint(),
99
            array('SOAPAction' => 'trataPeticion'),
100 4
            $requestEnvelope
101
        );
102
103 4
        // unwrap httpResponse into actual data as SimpleXMLElement tree
104 4
        $responseEnvelope = simplexml_load_string($httpResponse->getBody()->getContents());
105 4
        $responseData = new SimpleXMLElement(htmlspecialchars_decode(
106 4
            $responseEnvelope->children("http://schemas.xmlsoap.org/soap/envelope/")
107 4
            ->Body->children("http://webservice.sis.sermepa.es")
108 4
            ->trataPeticionResponse
109 4
            ->trataPeticionReturn
110
        ));
111
112
113 4
        // remove any reflected request data (this happens on SIS errors, and includes card number)
114 1
        if (isset($responseData->RECIBIDO)) {
115 1
            unset($responseData->RECIBIDO);
116
        }
117
118 4
        // convert to nested arrays (drop the 'true' to use simple objects)
119
        $responseData = json_decode(json_encode($responseData), true);
120 4
121
        return $this->response = new WebservicePurchaseResponse($this, $responseData);
122
    }
123
}
124