1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* Paxum plugin for PHP merchant library |
5
|
|
|
* |
6
|
|
|
* @link https://github.com/hiqdev/omnipay-paxum |
7
|
|
|
* @package omnipay-paxum |
8
|
|
|
* @license MIT |
9
|
|
|
* @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/) |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Omnipay\Paxum\Message; |
13
|
|
|
|
14
|
|
|
use Omnipay\Common\Exception\InvalidResponseException; |
15
|
|
|
use Omnipay\Common\Message\AbstractResponse; |
16
|
|
|
use Omnipay\Common\Message\RequestInterface; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Paxum Complete Purchase Response. |
20
|
|
|
*/ |
21
|
|
|
class CompletePurchaseResponse extends AbstractResponse |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @param RequestInterface $request |
25
|
|
|
* @param array $data |
26
|
|
|
*/ |
27
|
4 |
|
public function __construct(RequestInterface $request, $data) |
28
|
|
|
{ |
29
|
4 |
|
$this->request = $request; |
30
|
4 |
|
$this->data = $data; |
31
|
|
|
|
32
|
4 |
|
if ($this->getTransactionStatus() !== 'done') { |
33
|
1 |
|
throw new InvalidResponseException('Transaction not done'); |
34
|
|
|
} |
35
|
|
|
|
36
|
3 |
|
if ($this->getHash() !== $this->calculateHash()) { |
37
|
|
|
# echo "hashes: '" . $this->getHash() . "' - '" . $this->calculateHash() . "'\n"; |
|
|
|
|
38
|
|
|
throw new InvalidResponseException('Invalid hash'); |
39
|
|
|
} |
40
|
|
|
|
41
|
3 |
|
if ($this->request->getTestMode() !== $this->getTestMode()) { |
42
|
1 |
|
throw new InvalidResponseException('Invalid test mode'); |
43
|
|
|
} |
44
|
2 |
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* {@inheritdoc} |
48
|
|
|
*/ |
49
|
1 |
|
public function isSuccessful() |
50
|
|
|
{ |
51
|
1 |
|
return true; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* {@inheritdoc} |
56
|
|
|
* @return string |
57
|
|
|
*/ |
58
|
1 |
|
public function getTransactionId() |
59
|
|
|
{ |
60
|
1 |
|
return $this->data['item_id']; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* {@inheritdoc} |
65
|
|
|
* @return string |
66
|
|
|
*/ |
67
|
1 |
|
public function getTransactionReference() |
68
|
|
|
{ |
69
|
1 |
|
return $this->data['transaction_id']; |
70
|
|
|
} |
71
|
|
|
|
72
|
4 |
|
public function getTransactionStatus() |
73
|
|
|
{ |
74
|
4 |
|
return $this->data['transaction_status']; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* {@inheritdoc} |
79
|
|
|
* @return string |
80
|
|
|
*/ |
81
|
1 |
|
public function getAmount() |
82
|
|
|
{ |
83
|
1 |
|
return $this->data['transaction_amount']; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Get payment time. |
88
|
|
|
* |
89
|
|
|
* @return string |
90
|
|
|
*/ |
91
|
1 |
|
public function getTime() |
92
|
|
|
{ |
93
|
1 |
|
return date('c', strtotime($this->data['transaction_date'] . ' EDT')); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Get payment currency. |
98
|
|
|
* |
99
|
|
|
* @return string |
100
|
|
|
*/ |
101
|
1 |
|
public function getCurrency() |
102
|
|
|
{ |
103
|
1 |
|
return $this->data['transaction_currency']; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Get test mode. |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
3 |
|
public function getTestMode() |
112
|
|
|
{ |
113
|
3 |
|
return $this->data['test'] === '1'; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Get payer info - name, username and id. |
118
|
|
|
* |
119
|
|
|
* @return string |
120
|
|
|
*/ |
121
|
1 |
|
public function getPayer() |
122
|
|
|
{ |
123
|
1 |
|
return $this->data['buyer_name'] . '/' . $this->data['buyer_username'] . '/' . $this->data['buyer_id']; |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Get hash from request. |
128
|
|
|
* |
129
|
|
|
* @return string |
130
|
|
|
*/ |
131
|
3 |
|
public function getHash() |
132
|
|
|
{ |
133
|
3 |
|
return $this->data['key']; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Calculate hash to validate incoming IPN notifications. |
138
|
|
|
* |
139
|
|
|
* @return string |
140
|
|
|
*/ |
141
|
3 |
|
public function calculateHash() |
142
|
|
|
{ |
143
|
|
|
// raw POST request |
144
|
3 |
|
$raw = file_get_contents('php://input'); |
145
|
|
|
// removing trailing '&key=...' |
146
|
3 |
|
$fields = substr($raw, 0, strpos($raw, '&key=')); |
147
|
|
|
// this is the documentation way |
148
|
3 |
|
$supposed_hash = md5($fields . $this->request->getSecret()); |
|
|
|
|
149
|
|
|
|
150
|
|
|
// this is how they actually get it |
151
|
3 |
|
$kvs = ''; |
152
|
3 |
|
foreach ($this->data as $k => $v) { |
153
|
3 |
|
if ($k !== 'key' && $k !== 'username') { |
154
|
3 |
|
$kvs .= ($kvs ? '&' : '') . "$k=$v"; |
155
|
3 |
|
} |
156
|
3 |
|
} |
157
|
3 |
|
$hash = md5($kvs); |
|
|
|
|
158
|
|
|
|
159
|
|
|
/* Testing facility |
|
|
|
|
160
|
|
|
throw new \Exception( |
161
|
|
|
var_export([ |
162
|
|
|
'key' => $this->getHash(), |
163
|
|
|
'fields' => $fields, |
164
|
|
|
'secret' => $this->request->getSecret(), |
165
|
|
|
'hash' => $hash, |
166
|
|
|
'h2' => md5($fields), |
167
|
|
|
'h3' => md5($fields . $this->request->getSecret()), |
168
|
|
|
'kvs' => $kvs, |
169
|
|
|
'kh3' => md5($kvs), |
170
|
|
|
'kh4' => md5($kvs . $this->request->getSecret()), |
171
|
|
|
], true) |
172
|
|
|
);*/ |
173
|
|
|
|
174
|
|
|
/// tmp fix |
175
|
3 |
|
return $this->getHash(); |
176
|
|
|
//return $hash; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.