2
+----------------------------------------------------------------------+
4
+----------------------------------------------------------------------+
5
| Copyright (c) 1997-2004 The PHP Group |
6
+----------------------------------------------------------------------+
7
| This source file is subject to version 3.0 of the PHP license, |
8
| that is bundled with this package in the file LICENSE, and is |
9
| available through the world-wide-web at the following url: |
10
| http://www.php.net/license/3_0.txt. |
11
| If you did not receive a copy of the PHP license and are unable to |
12
| obtain it through the world-wide-web, please send a note to |
13
| license@php.net so we can mail you a copy immediately. |
14
+----------------------------------------------------------------------+
15
| Authors: David Croft <david@infotrek.co.uk>, |
16
| John Donagher <john@webmeta.com> |
17
+----------------------------------------------------------------------+
20
/* $Id: pfpro.c,v 1.33 2004/05/20 00:11:11 iliaa Exp $ */
27
#include "php_pfpro.h"
33
#include "ext/standard/info.h"
34
#include "ext/standard/php_string.h"
39
ZEND_DECLARE_MODULE_GLOBALS(pfpro)
42
/* {{{ Function table */
43
function_entry pfpro_functions[] = {
44
PHP_FE(pfpro_version, NULL)
45
PHP_FE(pfpro_init, NULL)
46
PHP_FE(pfpro_cleanup, NULL)
47
PHP_FE(pfpro_process_raw, NULL)
48
PHP_FE(pfpro_process, NULL)
53
/* {{{ Zend module entry */
54
zend_module_entry pfpro_module_entry = {
55
STANDARD_MODULE_HEADER,
60
PHP_RINIT(pfpro), /* request start */
61
PHP_RSHUTDOWN(pfpro), /* request end */
64
STANDARD_MODULE_PROPERTIES
69
#ifdef COMPILE_DL_PFPRO
70
ZEND_GET_MODULE(pfpro)
74
/* {{{ initialization defaults */
76
STD_PHP_INI_ENTRY("pfpro.defaulthost", "test-payflow.verisign.com", PHP_INI_ALL, OnUpdateString, defaulthost, zend_pfpro_globals, pfpro_globals)
77
STD_PHP_INI_ENTRY("pfpro.defaultport", "443", PHP_INI_ALL, OnUpdateLong, defaultport, zend_pfpro_globals, pfpro_globals)
78
STD_PHP_INI_ENTRY("pfpro.defaulttimeout", "30", PHP_INI_ALL, OnUpdateLong, defaulttimeout, zend_pfpro_globals, pfpro_globals)
79
STD_PHP_INI_ENTRY("pfpro.proxyaddress", "", PHP_INI_ALL, OnUpdateString, proxyaddress, zend_pfpro_globals, pfpro_globals)
80
STD_PHP_INI_ENTRY("pfpro.proxyport", "", PHP_INI_ALL, OnUpdateLong, proxyport, zend_pfpro_globals, pfpro_globals)
81
STD_PHP_INI_ENTRY("pfpro.proxylogon", "", PHP_INI_ALL, OnUpdateString, proxylogon, zend_pfpro_globals, pfpro_globals)
82
STD_PHP_INI_ENTRY("pfpro.proxypassword", "", PHP_INI_ALL, OnUpdateString, proxypassword, zend_pfpro_globals, pfpro_globals)
85
/* {{{ php_extname_init_globals
87
static void php_pfpro_init_globals(zend_pfpro_globals *pfpro_globals)
89
pfpro_globals->initialized = 0;
90
pfpro_globals->defaulthost = NULL;
91
pfpro_globals->defaultport = 0;
92
pfpro_globals->defaulttimeout = 0;
93
pfpro_globals->proxyaddress = NULL;
94
pfpro_globals->proxyport = 0;
95
pfpro_globals->proxylogon = NULL;
96
pfpro_globals->proxypassword = NULL;
100
PHP_MINIT_FUNCTION(pfpro)
102
ZEND_INIT_MODULE_GLOBALS(pfpro, php_pfpro_init_globals, NULL);
103
REGISTER_INI_ENTRIES();
107
PHP_MSHUTDOWN_FUNCTION(pfpro)
109
UNREGISTER_INI_ENTRIES();
113
PHP_RINIT_FUNCTION(pfpro)
115
PFPROG(initialized) = 0;
120
PHP_RSHUTDOWN_FUNCTION(pfpro)
122
if (PFPROG(initialized) == 1) {
130
/* {{{ minfo registration */
131
PHP_MINFO_FUNCTION(pfpro)
133
php_info_print_table_start();
134
php_info_print_table_row(2, "Verisign Payflow Pro support", "enabled");
135
php_info_print_table_row(2, "libpfpro version", pfproVersion());
136
php_info_print_table_end();
138
DISPLAY_INI_ENTRIES();
142
/* {{{ proto string pfpro_version()
143
Returns the version of the Payflow Pro library */
144
PHP_FUNCTION(pfpro_version)
146
if (ZEND_NUM_ARGS() != 0) {
150
RETURN_STRING((char *)pfproVersion(), 1);
154
/* {{{ proto bool pfpro_init()
155
Initializes the Payflow Pro library */
156
PHP_FUNCTION(pfpro_init)
158
if (ZEND_NUM_ARGS() != 0) {
164
PFPROG(initialized) = 1;
170
/* {{{ proto bool pfpro_cleanup()
171
Shuts down the Payflow Pro library */
172
PHP_FUNCTION(pfpro_cleanup)
174
if (ZEND_NUM_ARGS() != 0) {
180
PFPROG(initialized) = 0;
186
/* {{{ proto string pfpro_process_raw(string parmlist [, string hostaddress [, int port, [, int timeout [, string proxyAddress [, int proxyPort [, string proxyLogon [, string proxyPassword]]]]]]])
187
Raw Payflow Pro transaction processing */
188
PHP_FUNCTION(pfpro_process_raw)
191
char *parmlist = NULL;
192
char *address = NULL;
193
int port = PFPROG(defaultport);
194
int timeout = PFPROG(defaulttimeout);
195
char *proxyAddress = PFPROG(proxyaddress);
196
int proxyPort = PFPROG(proxyport);
197
char *proxyLogon = PFPROG(proxylogon);
198
char *proxyPassword = PFPROG(proxypassword);
200
#if PFPRO_VERSION < 3
201
char response[512] = "";
207
if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
211
args = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0);
213
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
214
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to read parameters in pfpro_process_raw()");
219
switch (ZEND_NUM_ARGS()) {
221
convert_to_string_ex(args[7]);
222
proxyPassword = Z_STRVAL_PP(args[7]);
226
convert_to_string_ex(args[6]);
227
proxyLogon = Z_STRVAL_PP(args[6]);
231
convert_to_long_ex(args[5]);
232
proxyPort = Z_LVAL_PP(args[5]);
236
convert_to_string_ex(args[4]);
237
proxyAddress = Z_STRVAL_PP(args[4]);
241
convert_to_long_ex(args[3]);
242
timeout = Z_LVAL_PP(args[3]);
246
convert_to_long_ex(args[2]);
247
port = Z_LVAL_PP(args[2]);
251
convert_to_string_ex(args[1]);
252
address = Z_STRVAL_PP(args[1]);
255
convert_to_string_ex(args[0]);
256
parmlist = Z_STRVAL_PP(args[0]);
260
if (address == NULL) {
261
address = estrdup(PFPROG(defaulthost));
265
#if PFPRO_VERSION < 3
266
/* Blank the response buffer */
267
memset(response, 0, sizeof(response));
270
/* Initialize the library if needed */
272
if (PFPROG(initialized) == 0) {
274
PFPROG(initialized) = 1;
277
/* Perform the transaction */
279
#if PFPRO_VERSION < 3
280
ProcessPNTransaction(address, port, proxyAddress, proxyPort, proxyLogon, proxyPassword, parmlist, strlen(parmlist), timeout, response);
282
pfproCreateContext(&context, address, port, timeout, proxyAddress, proxyPort, proxyLogon, proxyPassword);
283
pfproSubmitTransaction(context, parmlist, strlen(parmlist), &response);
284
pfproDestroyContext(context);
291
RETURN_STRING(response, 1);
295
/* {{{ proto array pfpro_process(array parmlist [, string hostaddress [, int port, [, int timeout [, string proxyAddress [, int proxyPort [, string proxyLogon [, string proxyPassword]]]]]]])
296
Payflow Pro transaction processing using arrays */
297
PHP_FUNCTION(pfpro_process)
300
HashTable *target_hash;
305
char *parmlist = NULL;
306
char *address = NULL;
307
int port = PFPROG(defaultport);
308
int timeout = PFPROG(defaulttimeout);
309
char *proxyAddress = PFPROG(proxyaddress);
310
int proxyPort = PFPROG(proxyport);
311
char *proxyLogon = PFPROG(proxylogon);
312
char *proxyPassword = PFPROG(proxypassword);
315
#if PFPRO_VERSION < 3
316
char response[512] = "";
322
char *var,*val,*strtok_buf=NULL; /* Pointers for string manipulation */
324
if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
328
args = (zval ***) safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0);
330
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
332
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to read parameters in pfpro_process()");
336
if (Z_TYPE_PP(args[0]) != IS_ARRAY) {
338
php_error_docref(NULL TSRMLS_CC, E_ERROR, "First parameter to pfpro_process() must be an array");
342
switch (ZEND_NUM_ARGS()) {
344
convert_to_string_ex(args[7]);
345
proxyPassword = Z_STRVAL_PP(args[7]);
349
convert_to_string_ex(args[6]);
350
proxyLogon = Z_STRVAL_PP(args[6]);
354
convert_to_long_ex(args[5]);
355
proxyPort = Z_LVAL_PP(args[5]);
359
convert_to_string_ex(args[4]);
360
proxyAddress = Z_STRVAL_PP(args[4]);
364
convert_to_long_ex(args[3]);
365
timeout = Z_LVAL_PP(args[3]);
369
convert_to_long_ex(args[2]);
370
port = Z_LVAL_PP(args[2]);
374
convert_to_string_ex(args[1]);
375
address = Z_STRVAL_PP(args[1]);
378
/* Concatenate the passed array as specified by Verisign.
379
Basically it's all key=value&key=value, the only exception
380
being if the value contains = or &, in which case we also
381
encode the length, e.g. key[5]=bl&ah */
383
target_hash = HASH_OF(*args[0]);
385
for (pass = 0; pass <= 1; pass ++) {
388
/* we go around the array twice. the first time to calculate
389
the string length, the second time to actually store it */
391
zend_hash_internal_pointer_reset(target_hash);
393
while (zend_hash_get_current_data(target_hash, (void **)&entry) == SUCCESS) {
395
if (parmlength > 0) {
397
strcpy(parmlist + parmlength, "&");
401
switch (zend_hash_get_current_key(target_hash, &string_key, &num_key, 0)) {
403
case HASH_KEY_IS_STRING:
406
strcpy(parmlist + parmlength, string_key);
407
parmlength += strlen(string_key);
411
case HASH_KEY_IS_LONG:
413
sprintf(tmpbuf, "%ld", num_key);
415
strcpy(parmlist + parmlength, tmpbuf);
416
parmlength += strlen(tmpbuf);
425
php_error_docref(NULL TSRMLS_CC, E_ERROR, "pfpro_process() array keys must be strings or integers");
430
switch (Z_TYPE_PP(entry)) {
432
if (strchr(Z_STRVAL_PP(entry), '&')
433
|| strchr(Z_STRVAL_PP(entry), '=')) {
434
sprintf(tmpbuf, "[%d]=", Z_STRLEN_PP(entry));
436
strcpy(parmlist + parmlength, tmpbuf);
437
parmlength += strlen(tmpbuf);
440
strcpy(parmlist + parmlength, "=");
445
strcpy(parmlist + parmlength, Z_STRVAL_PP(entry));
446
parmlength += Z_STRLEN_PP(entry);
451
sprintf(tmpbuf, "=%ld", Z_LVAL_PP(entry));
453
strcpy(parmlist + parmlength, tmpbuf);
454
parmlength += strlen(tmpbuf);
459
sprintf(tmpbuf, "=%.2f", Z_DVAL_PP(entry));
461
strcpy(parmlist + parmlength, tmpbuf);
462
parmlength += strlen(tmpbuf);
471
php_error_docref(NULL TSRMLS_CC, E_ERROR, "pfpro_process() array values must be strings, ints or floats");
474
zend_hash_move_forward(target_hash);
478
parmlist = emalloc(parmlength + 1);
484
if (address == NULL) {
485
address = estrdup(PFPROG(defaulthost));
489
/* Allocate the array for the response now - so we catch any errors
490
from this BEFORE we knock it off to the bank */
492
array_init(return_value);
494
#if PFPRO_VERSION < 3
495
/* Blank the response buffer */
496
memset(response, 0, sizeof(response));
499
/* Initialize the library if needed */
501
if (PFPROG(initialized) == 0) {
503
PFPROG(initialized) = 1;
506
/* Perform the transaction */
508
#if PFPRO_VERSION < 3
509
ProcessPNTransaction(address, port, proxyAddress, proxyPort, proxyLogon, proxyPassword, parmlist, strlen(parmlist), timeout, response);
511
pfproCreateContext(&context, address, port, timeout, proxyAddress, proxyPort, proxyLogon, proxyPassword);
512
pfproSubmitTransaction(context, parmlist, strlen(parmlist), &response);
513
pfproDestroyContext(context);
524
/* This final chunk of code is to walk the returned string
525
* and build the return array to the user.
527
var = php_strtok_r(response, "&", &strtok_buf);
530
val = strchr(var, '=');
531
if (val) { /* have a value */
533
add_assoc_string(return_value, var, val, 1);
535
var = php_strtok_r(NULL, "&", &strtok_buf);
540
#endif /* HAVE_PFPRO */
547
* vim600: sw=4 ts=4 fdm=marker