-
Notifications
You must be signed in to change notification settings - Fork 4
/
Api.php
280 lines (226 loc) · 6.79 KB
/
Api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<?php
namespace Payum\Paypal\ProCheckout\Nvp;
use Http\Message\MessageFactory;
use Payum\Core\Bridge\Spl\ArrayObject;
use Payum\Core\Exception\Http\HttpException;
use Payum\Core\Exception\LogicException;
use Payum\Core\HttpClientInterface;
/**
* @author Ton Sharp <Forma-PRO@66ton99.org.ua>
* @see https://www.x.com/sites/default/files/payflowgateway_guide.pdf
*/
class Api
{
/**
* Use an AMOUNT of $1000 or less
* For all processors except Global Payments Central (MAPP) and FDI
* Credit (C) and force (F) transactions will always be approved regardless of dollar amount or card number
* @var int
*/
public const RESULT_SUCCESS = 0;
/**
* Use an invalid PWD
* @var int
*/
public const RESULT_USER_AUTH_FAIL = 1;
/**
* Use an invalid TENDER, such as G
* @var int
*/
public const RESULT_INVALID_TENDER = 2;
/**
* Use an invalid TRXTYPE, such as G
* Use the AMOUNT 10402
* @var int
*/
public const RESULT_INVALID_TRANSACTION_TYPE = 3;
/**
* Use an invalid AMOUNT, such as –1
* Use any of these as AMOUNT: 10400, 10401, 10403, 10404
* @var int
*/
public const RESULT_INVALID_AMOUNT = 4;
/**
* Use the AMOUNT1005 - Applies only to the following processors:
* Global Payments East
* Global Payments Central
* American Express
* Use any of these as AMOUNT: 10548, 10549
* @var int
*/
public const RESULT_INVALID_MERCHANT_INFORMATION = 5;
/**
* Submit a delayed capture transaction with no ORIGID
* Use any of these as AMOUNT: 10405, 10406, 10407, 10408, 10409, 10410, 10412, 10413, 10416, 10419, 10420, 10421,
* 10509, 10512, 10513, 10514, 10515, 10516, 10517, 10518, 10540, 10542
* @var int
*/
public const RESULT_FIELD_FORMAT_ERROR = 7;
/**
* Use the AMOUNT1012 or an AMOUNT of 2001 or more
* Use any of these as AMOUNT: 10417, 15002, 15005, 15006, 15028, 15039, 10544, 10545, 10546
* @var int
*/
public const RESULT_DECLINED = 12;
/**
* Use the AMOUNT1013
* Use the AMOUNT 10422
* @var int
*/
public const RESULT_REFERRAL = 13;
/**
* Use any of these as AMOUNT: 10519, 10521, 10522, 10527, 10535, 10541, 10543
* @var int
*/
public const RESULT_INVALID_ACCOUNT_NUMBER = 23;
/**
* Use any of these as AMOUNT: 10502, 10508
* @var int
*/
public const RESULT_INVALID_EXPIRATION_DATE = 24;
/**
* Use the AMOUNT 10536
* @var int
*/
public const RESULT_DUPLICATE_TRANSACTION = 30;
/**
* Attempt to credit an authorization
* @var int
*/
public const RESULT_CREDIT_ERROR = 105;
/**
* Use the AMOUNT 10505
* @var int
*/
public const RESULT_FAILED_AVS_CHECK = 112;
/**
* Use the AMOUNT 10504
* @var int
*/
public const RESULT_CVV2_MISMATCH = 114;
// Here more error codes
/**
* Fraud Protection Services Filter — Declined by filters
* @var int
*/
public const RESULT_DECLINED_BY_FILTERS = 125;
// Here more error codes
/**
* Use an AMOUNT other than those listed in this column
* @var int
*/
public const RESULT_GENERIC_HOST_OR_PROCESSOR_ERROR = 1000;
public const TRXTYPE_SALE = 'S';
public const TRXTYPE_CREDIT = 'C';
public const TRXTYPE_AUTHORIZATION = 'A';
public const TRXTYPE_DELAYED_CAPUTER = 'D';
public const TRXTYPE_VOID = 'V';
public const TRXTYPE_VOICE_AUTHORIZATION = 'F';
public const TRXTYPE_INQUIRY = 'I';
public const TRXTYPE_DUPLICATE_TRANSACTION = 'N';
public const TENDER_AUTOMATED_CLEARINGHOUSE = 'A';
public const TENDER_CREDIT_CARD = 'C';
public const TENDER_PINLESS_DEBIT = 'D';
public const TENDER_TELECHECK = 'K';
public const TENDER_PAYPAL = 'P';
/**
* @var HttpClientInterface
*/
protected $client;
/**
* @var MessageFactory
*/
protected $messageFactory;
/**
* @var array
*/
protected $options = [
'username' => '',
'password' => '',
'partner' => '',
'vendor' => '',
'tender' => self::TENDER_CREDIT_CARD,
'sandbox' => true,
];
/**
* @throw InvalidArgumentException
*/
public function __construct(array $options, HttpClientInterface $client, MessageFactory $messageFactory)
{
$options = ArrayObject::ensureArrayObject($options);
$options->defaults($this->options);
$options->validateNotEmpty([
'username',
'password',
'partner',
'vendor',
'tender',
]);
if (! is_bool($options['sandbox'])) {
throw new LogicException('The boolean sandbox option must be set.');
}
$this->options = $options;
$this->client = $client;
$this->messageFactory = $messageFactory;
}
/**
* @return array
*/
public function doSale(array $fields)
{
$fields['TRXTYPE'] = self::TRXTYPE_SALE;
$this->addAuthorizeFields($fields);
$result = $this->doRequest($fields);
$result['TRXTYPE'] = self::TRXTYPE_SALE;
return $result;
}
/**
* @return array
*/
public function doCredit(array $fields)
{
$fields['TRXTYPE'] = self::TRXTYPE_CREDIT;
$this->addAuthorizeFields($fields);
$result = $this->doRequest($fields);
$result['TRXTYPE'] = self::TRXTYPE_CREDIT;
return $result;
}
/**
* @return array
*/
protected function doRequest(array $fields)
{
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
];
$request = $this->messageFactory->createRequest('POST', $this->getApiEndpoint(), $headers, http_build_query($fields));
$response = $this->client->send($request);
if (! ($response->getStatusCode() >= 200 && $response->getStatusCode() < 300)) {
throw HttpException::factory($request, $response);
}
$result = [];
parse_str($response->getBody()->getContents(), $result);
foreach ($result as &$value) {
$value = urldecode($value);
}
return $result;
}
/**
* @return string
*/
protected function getApiEndpoint()
{
return $this->options['sandbox'] ?
'https://pilot-payflowpro.paypal.com/' :
'https://payflowpro.paypal.com/'
;
}
protected function addAuthorizeFields(array &$fields): void
{
$fields['USER'] = $this->options['username'];
$fields['PWD'] = $this->options['password'];
$fields['PARTNER'] = $this->options['partner'];
$fields['VENDOR'] = $this->options['vendor'];
$fields['TENDER'] = $this->options['tender'];
}
}