1
|
|
|
<?php
|
2
|
|
|
|
3
|
|
|
#******************************************************************************
|
4
|
|
|
#* Name : PxPay_Curl.inc.php
|
5
|
|
|
#* Description : Classes used interact with the PxPay interface using PHP with the cURL extension installed
|
6
|
|
|
#* Copyright : Payment Express 2017(c)
|
7
|
|
|
#* Date : 2017-04-10
|
8
|
|
|
#*@version : 2.0
|
9
|
|
|
#* Author : Payment Express DevSupport
|
10
|
|
|
#******************************************************************************
|
11
|
|
|
# Use this class to parse an XML document
|
12
|
|
|
class MifMessage
|
|
|
|
|
13
|
|
|
{
|
14
|
|
|
var $xml_;
|
|
|
|
|
15
|
|
|
var $xml_index_;
|
|
|
|
|
16
|
|
|
var $xml_value_;
|
|
|
|
|
17
|
|
|
|
18
|
|
|
# Constructor:
|
19
|
|
|
# Create a MifMessage with the specified XML text.
|
20
|
|
|
# The constructor returns a null object if there is a parsing error.
|
21
|
|
|
function __construct($xml)
|
|
|
|
|
22
|
|
|
{
|
23
|
|
|
$p = xml_parser_create();
|
24
|
|
|
xml_parser_set_option($p,XML_OPTION_CASE_FOLDING,0);
|
25
|
|
|
$ok = xml_parse_into_struct($p, $xml, $value, $index);
|
26
|
|
|
xml_parser_free($p);
|
27
|
|
|
if ($ok)
|
28
|
|
|
{
|
29
|
|
|
$this->xml_ = $xml;
|
30
|
|
|
$this->xml_value_ = $value;
|
31
|
|
|
$this->xml_index_ = $index;
|
32
|
|
|
}
|
33
|
|
|
}
|
34
|
|
|
|
35
|
|
|
# Return the value of the specified top-level attribute.
|
36
|
|
|
# This method can only return attributes of the root element.
|
37
|
|
|
# If the attribute is not found, return "".
|
38
|
|
|
function get_attribute($attribute)
|
|
|
|
|
39
|
|
|
{
|
40
|
|
|
$attributes = $this->xml_value_[0]["attributes"];
|
41
|
|
|
return $attributes[$attribute];
|
42
|
|
|
}
|
43
|
|
|
|
44
|
|
|
# Return the text of the specified element.
|
45
|
|
|
# The element is given as a simplified XPath-like name.
|
46
|
|
|
# For example, "Link/ServerOk" refers to the ServerOk element
|
47
|
|
|
# nested in the Link element (nested in the root element).
|
48
|
|
|
# If the element is not found, return "".
|
49
|
|
|
function get_element_text($element)
|
|
|
|
|
50
|
|
|
{
|
51
|
|
|
$index = $this->get_element_index($element, 0);
|
52
|
|
|
if ($index == 0)
|
53
|
|
|
{
|
54
|
|
|
return "";
|
55
|
|
|
}
|
56
|
|
|
else
|
57
|
|
|
{
|
58
|
|
|
#When element existent but empty
|
59
|
|
|
$elementObj = $this->xml_value_[$index];
|
60
|
|
|
if (! array_key_exists("value", $elementObj))
|
61
|
|
|
return "";
|
62
|
|
|
|
63
|
|
|
return $this->xml_value_[$index]["value"];
|
64
|
|
|
}
|
65
|
|
|
}
|
66
|
|
|
|
67
|
|
|
# (internal method)
|
68
|
|
|
# Return the index of the specified element,
|
69
|
|
|
# relative to some given root element index.
|
70
|
|
|
#
|
71
|
|
|
function get_element_index($element, $rootindex = 0)
|
|
|
|
|
72
|
|
|
{
|
73
|
|
|
#$element = strtoupper($element);
|
|
|
|
|
74
|
|
|
$pos = strpos($element, "/");
|
75
|
|
|
if ($pos !== false)
|
76
|
|
|
{
|
77
|
|
|
# element contains '/': find first part
|
78
|
|
|
$start_path = substr($element,0,$pos);
|
79
|
|
|
$remain_path = substr($element,$pos+1);
|
80
|
|
|
$index = $this->get_element_index($start_path, $rootindex);
|
81
|
|
|
if ($index == 0)
|
82
|
|
|
{
|
83
|
|
|
# couldn't find first part give up.
|
84
|
|
|
return 0;
|
85
|
|
|
}
|
86
|
|
|
# recursively find rest
|
87
|
|
|
return $this->get_element_index($remain_path, $index);
|
88
|
|
|
}
|
89
|
|
|
else
|
90
|
|
|
{
|
91
|
|
|
# search from the parent across all its children
|
92
|
|
|
# i.e. until we get the parent's close tag.
|
93
|
|
|
$level = $this->xml_value_[$rootindex]["level"];
|
94
|
|
|
if ($this->xml_value_[$rootindex]["type"] == "complete")
|
95
|
|
|
{
|
96
|
|
|
return 0; # no children
|
97
|
|
|
}
|
98
|
|
|
$index = $rootindex+1;
|
99
|
|
|
while ($index<count($this->xml_value_) &&
|
100
|
|
|
!($this->xml_value_[$index]["level"]==$level &&
|
101
|
|
|
$this->xml_value_[$index]["type"]=="close"))
|
102
|
|
|
{
|
103
|
|
|
# if one below parent and tag matches, bingo
|
104
|
|
|
if ($this->xml_value_[$index]["level"] == $level+1 &&
|
105
|
|
|
$this->xml_value_[$index]["tag"] == $element)
|
106
|
|
|
{
|
107
|
|
|
return $index;
|
108
|
|
|
}
|
109
|
|
|
$index++;
|
110
|
|
|
}
|
111
|
|
|
return 0;
|
112
|
|
|
}
|
113
|
|
|
}
|
114
|
|
|
}
|
115
|
|
|
|
116
|
|
|
class PxPay_Curl
|
|
|
|
|
117
|
|
|
{
|
118
|
|
|
var $PxPay_Key;
|
|
|
|
|
119
|
|
|
var $PxPay_Url;
|
|
|
|
|
120
|
|
|
var $PxPay_Userid;
|
|
|
|
|
121
|
|
|
function __construct($Url, $UserId, $Key){
|
|
|
|
|
122
|
|
|
error_reporting(E_ERROR);
|
123
|
|
|
$this->PxPay_Key = $Key;
|
124
|
|
|
$this->PxPay_Url = $Url;
|
125
|
|
|
$this->PxPay_Userid = $UserId;
|
126
|
|
|
}
|
127
|
|
|
|
128
|
|
|
#******************************************************************************
|
129
|
|
|
# Create a request for the PxPay interface
|
130
|
|
|
#******************************************************************************
|
131
|
|
|
function makeRequest($request)
|
|
|
|
|
132
|
|
|
{
|
133
|
|
|
#Validate the Request
|
134
|
|
|
if($request->validData() == false) return "" ;
|
135
|
|
|
|
136
|
|
|
$request->setUserId($this->PxPay_Userid);
|
137
|
|
|
$request->setKey($this->PxPay_Key);
|
138
|
|
|
|
139
|
|
|
$xml = $request->toXml();
|
140
|
|
|
|
141
|
|
|
$result = $this->submitXml($xml);
|
142
|
|
|
|
143
|
|
|
return $result;
|
144
|
|
|
|
145
|
|
|
}
|
146
|
|
|
|
147
|
|
|
#******************************************************************************
|
148
|
|
|
# Return the transaction outcome details
|
149
|
|
|
#******************************************************************************
|
150
|
|
|
function getResponse($result){
|
|
|
|
|
151
|
|
|
|
152
|
|
|
$inputXml = "<ProcessResponse><PxPayUserId>".$this->PxPay_Userid."</PxPayUserId><PxPayKey>".$this->PxPay_Key.
|
153
|
|
|
"</PxPayKey><Response>".$result."</Response></ProcessResponse>";
|
154
|
|
|
|
155
|
|
|
$outputXml = $this->submitXml($inputXml);
|
156
|
|
|
|
157
|
|
|
$pxresp = new PxPayResponse($outputXml);
|
158
|
|
|
return $pxresp;
|
159
|
|
|
}
|
160
|
|
|
|
161
|
|
|
#******************************************************************************
|
162
|
|
|
# Actual submission of XML using cURL. Returns output XML
|
163
|
|
|
#******************************************************************************
|
164
|
|
|
function submitXml($inputXml){
|
|
|
|
|
165
|
|
|
|
166
|
|
|
$ch = curl_init();
|
167
|
|
|
curl_setopt($ch, CURLOPT_URL, $this->PxPay_Url);
|
168
|
|
|
|
169
|
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
170
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS,$inputXml);
|
171
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
172
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
173
|
|
|
|
174
|
|
|
#set up proxy, this may change depending on ISP, please contact your ISP to get the correct cURL settings
|
175
|
|
|
#curl_setopt($ch,CURLOPT_PROXY , "proxy:8080");
|
|
|
|
|
176
|
|
|
#curl_setopt($ch,CURLOPT_PROXYUSERPWD,"username:password");
|
|
|
|
|
177
|
|
|
|
178
|
|
|
$outputXml = curl_exec ($ch);
|
179
|
|
|
|
180
|
|
|
curl_close ($ch);
|
181
|
|
|
|
182
|
|
|
return $outputXml;
|
183
|
|
|
}
|
184
|
|
|
|
185
|
|
|
}
|
186
|
|
|
|
187
|
|
|
#******************************************************************************
|
188
|
|
|
# Class for PxPay request messages.
|
189
|
|
|
#******************************************************************************
|
190
|
|
|
class PxPayRequest extends PxPayMessage
|
|
|
|
|
191
|
|
|
{
|
192
|
|
|
var $UrlFail,$UrlSuccess;
|
|
|
|
|
193
|
|
|
var $AmountInput;
|
|
|
|
|
194
|
|
|
var $EnableAddBillCard;
|
|
|
|
|
195
|
|
|
var $PxPayUserId;
|
|
|
|
|
196
|
|
|
var $PxPayKey;
|
|
|
|
|
197
|
|
|
var $Opt;
|
|
|
|
|
198
|
|
|
|
199
|
|
|
|
200
|
|
|
#Constructor
|
201
|
|
|
function __construct(){
|
|
|
|
|
202
|
|
|
parent::__construct();
|
203
|
|
|
|
204
|
|
|
}
|
205
|
|
|
|
206
|
|
|
function setEnableAddBillCard($EnableBillAddCard){
|
|
|
|
|
207
|
|
|
$this->EnableAddBillCard = $EnableBillAddCard;
|
208
|
|
|
}
|
209
|
|
|
function setUrlFail($UrlFail){
|
|
|
|
|
210
|
|
|
$this->UrlFail = $UrlFail;
|
211
|
|
|
}
|
212
|
|
|
function setUrlSuccess($UrlSuccess){
|
|
|
|
|
213
|
|
|
$this->UrlSuccess = $UrlSuccess;
|
214
|
|
|
}
|
215
|
|
|
function setAmountInput($AmountInput){
|
|
|
|
|
216
|
|
|
$this->AmountInput = sprintf("%9.2f",$AmountInput);
|
217
|
|
|
}
|
218
|
|
|
function setUserId($UserId){
|
|
|
|
|
219
|
|
|
$this->PxPayUserId = $UserId;
|
220
|
|
|
}
|
221
|
|
|
function setKey($Key){
|
|
|
|
|
222
|
|
|
$this->PxPayKey = $Key;
|
223
|
|
|
}
|
224
|
|
|
function setOpt($Opt){
|
|
|
|
|
225
|
|
|
$this->Opt = $Opt;
|
226
|
|
|
}
|
227
|
|
|
|
228
|
|
|
|
229
|
|
|
#******************************************************************
|
230
|
|
|
#Data validation
|
231
|
|
|
#******************************************************************
|
232
|
|
|
function validData(){
|
|
|
|
|
233
|
|
|
$msg = "";
|
234
|
|
|
if($this->TxnType != "Purchase")
|
235
|
|
|
if($this->TxnType != "Auth")
|
236
|
|
|
$msg = "Invalid TxnType[$this->TxnType]<br>";
|
237
|
|
|
|
238
|
|
|
if(strlen($this->MerchantReference) > 64)
|
239
|
|
|
$msg = "Invalid MerchantReference [$this->MerchantReference]<br>";
|
240
|
|
|
|
241
|
|
|
if(strlen($this->TxnId) > 16)
|
242
|
|
|
$msg = "Invalid TxnId [$this->TxnId]<br>";
|
243
|
|
|
if(strlen($this->TxnData1) > 255)
|
244
|
|
|
$msg = "Invalid TxnData1 [$this->TxnData1]<br>";
|
245
|
|
|
if(strlen($this->TxnData2) > 255)
|
246
|
|
|
$msg = "Invalid TxnData2 [$this->TxnData2]<br>";
|
247
|
|
|
if(strlen($this->TxnData3) > 255)
|
248
|
|
|
$msg = "Invalid TxnData3 [$this->TxnData3]<br>";
|
249
|
|
|
|
250
|
|
|
if(strlen($this->EmailAddress) > 255)
|
251
|
|
|
$msg = "Invalid EmailAddress [$this->EmailAddress]<br>";
|
252
|
|
|
|
253
|
|
|
if(strlen($this->UrlFail) > 255)
|
254
|
|
|
$msg = "Invalid UrlFail [$this->UrlFail]<br>";
|
255
|
|
|
if(strlen($this->UrlSuccess) > 255)
|
256
|
|
|
$msg = "Invalid UrlSuccess [$this->UrlSuccess]<br>";
|
257
|
|
|
if(strlen($this->BillingId) > 32)
|
258
|
|
|
$msg = "Invalid BillingId [$this->BillingId]<br>";
|
259
|
|
|
|
260
|
|
|
if ($msg != "") {
|
261
|
|
|
trigger_error($msg,E_USER_ERROR);
|
262
|
|
|
return false;
|
263
|
|
|
}
|
264
|
|
|
return true;
|
265
|
|
|
}
|
266
|
|
|
|
267
|
|
|
}
|
268
|
|
|
|
269
|
|
|
#******************************************************************************
|
270
|
|
|
# Abstract base class for PxPay messages.
|
271
|
|
|
# These are messages with certain defined elements, which can be serialized to XML.
|
272
|
|
|
|
273
|
|
|
#******************************************************************************
|
274
|
|
|
class PxPayMessage {
|
|
|
|
|
275
|
|
|
var $TxnType;
|
|
|
|
|
276
|
|
|
var $CurrencyInput;
|
|
|
|
|
277
|
|
|
var $TxnData1;
|
|
|
|
|
278
|
|
|
var $TxnData2;
|
|
|
|
|
279
|
|
|
var $TxnData3;
|
|
|
|
|
280
|
|
|
var $MerchantReference;
|
|
|
|
|
281
|
|
|
var $EmailAddress;
|
|
|
|
|
282
|
|
|
var $BillingId;
|
|
|
|
|
283
|
|
|
var $TxnId;
|
|
|
|
|
284
|
|
|
|
285
|
|
|
function __construct(){
|
|
|
|
|
286
|
|
|
|
287
|
|
|
}
|
288
|
|
|
|
289
|
|
|
function setBillingId($BillingId){
|
|
|
|
|
290
|
|
|
$this->BillingId = $BillingId;
|
291
|
|
|
}
|
292
|
|
|
function getBillingId(){
|
|
|
|
|
293
|
|
|
return $this->BillingId;
|
294
|
|
|
}
|
295
|
|
|
function setTxnType($TxnType){
|
|
|
|
|
296
|
|
|
$this->TxnType = $TxnType;
|
297
|
|
|
}
|
298
|
|
|
function getTxnType(){
|
|
|
|
|
299
|
|
|
return $this->TxnType;
|
300
|
|
|
}
|
301
|
|
|
function setCurrencyInput($CurrencyInput){
|
|
|
|
|
302
|
|
|
$this->CurrencyInput = $CurrencyInput;
|
303
|
|
|
}
|
304
|
|
|
function getCurrencyInput(){
|
|
|
|
|
305
|
|
|
return $this->CurrencyInput;
|
306
|
|
|
}
|
307
|
|
|
function setMerchantReference($MerchantReference){
|
|
|
|
|
308
|
|
|
$this->MerchantReference = $MerchantReference;
|
309
|
|
|
}
|
310
|
|
|
function getMerchantReference(){
|
|
|
|
|
311
|
|
|
return $this->MerchantReference;
|
312
|
|
|
}
|
313
|
|
|
function setEmailAddress($EmailAddress){
|
|
|
|
|
314
|
|
|
$this->EmailAddress = $EmailAddress;
|
315
|
|
|
}
|
316
|
|
|
function getEmailAddress(){
|
|
|
|
|
317
|
|
|
return $this->EmailAddress;
|
318
|
|
|
}
|
319
|
|
|
function setTxnData1($TxnData1){
|
|
|
|
|
320
|
|
|
$this->TxnData1 = $TxnData1;
|
321
|
|
|
}
|
322
|
|
|
function getTxnData1(){
|
|
|
|
|
323
|
|
|
return $this->TxnData1;
|
324
|
|
|
}
|
325
|
|
|
function setTxnData2($TxnData2){
|
|
|
|
|
326
|
|
|
$this->TxnData2 = $TxnData2;
|
327
|
|
|
}
|
328
|
|
|
function getTxnData2(){
|
|
|
|
|
329
|
|
|
return $this->TxnData2;
|
330
|
|
|
}
|
331
|
|
|
function getTxnData3(){
|
|
|
|
|
332
|
|
|
return $this->TxnData3;
|
333
|
|
|
}
|
334
|
|
|
function setTxnData3($TxnData3){
|
|
|
|
|
335
|
|
|
$this->TxnData3 = $TxnData3;
|
336
|
|
|
}
|
337
|
|
|
function setTxnId( $TxnId)
|
|
|
|
|
338
|
|
|
{
|
339
|
|
|
$this->TxnId = $TxnId;
|
340
|
|
|
}
|
341
|
|
|
function getTxnId(){
|
|
|
|
|
342
|
|
|
return $this->TxnId;
|
343
|
|
|
}
|
344
|
|
|
|
345
|
|
|
function toXml(){
|
|
|
|
|
346
|
|
|
$arr = get_object_vars($this);
|
347
|
|
|
|
348
|
|
|
$xml = "<GenerateRequest>";
|
349
|
|
|
while (list($prop, $val) = each($arr))
|
350
|
|
|
$xml .= "<$prop>$val</$prop>" ;
|
351
|
|
|
|
352
|
|
|
$xml .= "</GenerateRequest>";
|
353
|
|
|
return $xml;
|
354
|
|
|
}
|
355
|
|
|
|
356
|
|
|
|
357
|
|
|
}
|
358
|
|
|
|
359
|
|
|
#******************************************************************************
|
360
|
|
|
# Class for PxPay response messages.
|
361
|
|
|
#******************************************************************************
|
362
|
|
|
|
363
|
|
|
class PxPayResponse extends PxPayMessage
|
|
|
|
|
364
|
|
|
{
|
365
|
|
|
var $Success;
|
|
|
|
|
366
|
|
|
var $AuthCode;
|
|
|
|
|
367
|
|
|
var $CardName;
|
|
|
|
|
368
|
|
|
var $CardHolderName;
|
|
|
|
|
369
|
|
|
var $CardNumber;
|
|
|
|
|
370
|
|
|
var $DateExpiry;
|
|
|
|
|
371
|
|
|
var $ClientInfo;
|
|
|
|
|
372
|
|
|
var $DpsTxnRef;
|
|
|
|
|
373
|
|
|
var $DpsBillingId;
|
|
|
|
|
374
|
|
|
var $AmountSettlement;
|
|
|
|
|
375
|
|
|
var $CurrencySettlement;
|
|
|
|
|
376
|
|
|
var $TxnMac;
|
|
|
|
|
377
|
|
|
var $ResponseText;
|
|
|
|
|
378
|
|
|
|
379
|
|
|
|
380
|
|
|
function __construct($xml){
|
|
|
|
|
381
|
|
|
$msg = new MifMessage($xml);
|
382
|
|
|
parent::__construct();
|
383
|
|
|
|
384
|
|
|
$this->Success = $msg->get_element_text("Success");
|
385
|
|
|
$this->setTxnType($msg->get_element_text("TxnType"));
|
386
|
|
|
$this->CurrencyInput = $msg->get_element_text("CurrencyInput");
|
387
|
|
|
$this->setMerchantReference($msg->get_element_text("MerchantReference"));
|
388
|
|
|
$this->setTxnData1($msg->get_element_text("TxnData1"));
|
389
|
|
|
$this->setTxnData2($msg->get_element_text("TxnData2"));
|
390
|
|
|
$this->setTxnData3($msg->get_element_text("TxnData3"));
|
391
|
|
|
$this->AuthCode = $msg->get_element_text("AuthCode");
|
392
|
|
|
$this->CardName = $msg->get_element_text("CardName");
|
393
|
|
|
$this->CardHolderName = $msg->get_element_text("CardHolderName");
|
394
|
|
|
$this->CardNumber = $msg->get_element_text("CardNumber");
|
395
|
|
|
$this->DateExpiry = $msg->get_element_text("DateExpiry");
|
396
|
|
|
$this->ClientInfo = $msg->get_element_text("ClientInfo");
|
397
|
|
|
$this->TxnId = $msg->get_element_text("TxnId");
|
398
|
|
|
$this->setEmailAddress($msg->get_element_text("EmailAddress"));
|
399
|
|
|
$this->DpsTxnRef = $msg->get_element_text("DpsTxnRef");
|
400
|
|
|
$this->BillingId = $msg->get_element_text("BillingId");
|
401
|
|
|
$this->DpsBillingId = $msg->get_element_text("DpsBillingId");
|
402
|
|
|
$this->AmountSettlement = $msg->get_element_text("AmountSettlement");
|
403
|
|
|
$this->CurrencySettlement = $msg->get_element_text("CurrencySettlement");
|
404
|
|
|
$this->TxnMac = $msg->get_element_text("TxnMac");
|
405
|
|
|
$this->ResponseText = $msg->get_element_text("ResponseText");
|
406
|
|
|
|
407
|
|
|
}
|
408
|
|
|
|
409
|
|
|
|
410
|
|
|
function getSuccess(){
|
|
|
|
|
411
|
|
|
return $this->Success;
|
412
|
|
|
}
|
413
|
|
|
function getAuthCode(){
|
|
|
|
|
414
|
|
|
return $this->AuthCode;
|
415
|
|
|
}
|
416
|
|
|
function getCardName(){
|
|
|
|
|
417
|
|
|
return $this->CardName;
|
418
|
|
|
}
|
419
|
|
|
function getCardHolderName(){
|
|
|
|
|
420
|
|
|
return $this->CardHolderName;
|
421
|
|
|
}
|
422
|
|
|
function getCardNumber(){
|
|
|
|
|
423
|
|
|
return $this->CardNumber;
|
424
|
|
|
}
|
425
|
|
|
function getDateExpiry(){
|
|
|
|
|
426
|
|
|
return $this->DateExpiry;
|
427
|
|
|
}
|
428
|
|
|
function getClientInfo(){
|
|
|
|
|
429
|
|
|
return $this->ClientInfo;
|
430
|
|
|
}
|
431
|
|
|
function getDpsTxnRef(){
|
|
|
|
|
432
|
|
|
return $this->DpsTxnRef;
|
433
|
|
|
}
|
434
|
|
|
function getDpsBillingId(){
|
|
|
|
|
435
|
|
|
return $this->DpsBillingId;
|
436
|
|
|
}
|
437
|
|
|
function getAmountSettlement(){
|
|
|
|
|
438
|
|
|
return $this->AmountSettlement;
|
439
|
|
|
}
|
440
|
|
|
function getCurrencySettlement(){
|
|
|
|
|
441
|
|
|
$this->CurrencySettlement;
|
442
|
|
|
}
|
443
|
|
|
function getTxnMac(){
|
|
|
|
|
444
|
|
|
return $this->TxnMac;
|
445
|
|
|
}
|
446
|
|
|
function getResponseText(){
|
|
|
|
|
447
|
|
|
return $this->ResponseText;
|
448
|
|
|
}
|
449
|
|
|
}
|
450
|
|
|
|
451
|
|
|
?> |
|
|
|
|
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.